From: Junio C Hamano Date: Fri, 30 Apr 2021 04:50:26 +0000 (+0900) Subject: Merge branch 'ds/sparse-index-protections' X-Git-Tag: v2.32.0-rc0~59 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8e97852919fa422bc5fe57bc7e71826cf2b5224d;p=thirdparty%2Fgit.git Merge branch 'ds/sparse-index-protections' Builds on top of the sparse-index infrastructure to mark operations that are not ready to mark with the sparse index, causing them to fall back on fully-populated index that they always have worked with. * ds/sparse-index-protections: (47 commits) name-hash: use expand_to_path() sparse-index: expand_to_path() name-hash: don't add directories to name_hash revision: ensure full index resolve-undo: ensure full index read-cache: ensure full index pathspec: ensure full index merge-recursive: ensure full index entry: ensure full index dir: ensure full index update-index: ensure full index stash: ensure full index rm: ensure full index merge-index: ensure full index ls-files: ensure full index grep: ensure full index fsck: ensure full index difftool: ensure full index commit: ensure full index checkout: ensure full index ... --- 8e97852919fa422bc5fe57bc7e71826cf2b5224d diff --cc attr.c index ac8ec7ce51,8de553293e..9e897e43f5 --- a/attr.c +++ b/attr.c @@@ -733,9 -718,9 +733,9 @@@ static struct attr_stack *read_attr_fro return res; } - static struct attr_stack *read_attr_from_index(const struct index_state *istate, + static struct attr_stack *read_attr_from_index(struct index_state *istate, const char *path, - int macro_ok) + unsigned flags) { struct attr_stack *res; char *buf, *sp; @@@ -763,8 -748,8 +763,8 @@@ return res; } - static struct attr_stack *read_attr(const struct index_state *istate, + static struct attr_stack *read_attr(struct index_state *istate, - const char *path, int macro_ok) + const char *path, unsigned flags) { struct attr_stack *res = NULL; diff --cc builtin/sparse-checkout.c index d7da50ada5,585343fa19..a4bdd7c494 --- a/builtin/sparse-checkout.c +++ b/builtin/sparse-checkout.c @@@ -321,8 -333,19 +333,19 @@@ static int sparse_checkout_init(int arg memset(&pl, 0, sizeof(pl)); sparse_filename = get_sparse_checkout_filename(); - res = add_patterns_from_file_to_list(sparse_filename, "", 0, &pl, NULL); + res = add_patterns_from_file_to_list(sparse_filename, "", 0, &pl, NULL, 0); + if (init_opts.sparse_index >= 0) { + if (set_sparse_index_config(the_repository, init_opts.sparse_index) < 0) + die(_("failed to modify sparse-index config")); + + /* force an index rewrite */ + repo_read_index(the_repository); + the_repository->index->updated_workdir = 1; + } + + core_apply_sparse_checkout = 1; + /* If we already have a sparse-checkout file, use it. */ if (res >= 0) { free(sparse_filename); diff --cc convert.c index 45ac75f80c,20b19abffa..fd9c84b025 --- a/convert.c +++ b/convert.c @@@ -485,10 -496,10 +485,10 @@@ static int encode_to_worktree(const cha return 1; } - static int crlf_to_git(const struct index_state *istate, + static int crlf_to_git(struct index_state *istate, const char *path, const char *src, size_t len, struct strbuf *buf, - enum crlf_action crlf_action, int conv_flags) + enum convert_crlf_action crlf_action, int conv_flags) { struct text_stat stats; char *dst; @@@ -1291,10 -1297,18 +1291,10 @@@ static int git_path_check_ident(struct return !!ATTR_TRUE(value); } -struct conv_attrs { - struct convert_driver *drv; - enum crlf_action attr_action; /* What attr says */ - enum crlf_action crlf_action; /* When no attr is set, use core.autocrlf */ - int ident; - const char *working_tree_encoding; /* Supported encoding or default encoding if NULL */ -}; - static struct attr_check *check; - void convert_attrs(const struct index_state *istate, -static void convert_attrs(struct index_state *istate, - struct conv_attrs *ca, const char *path) ++void convert_attrs(struct index_state *istate, + struct conv_attrs *ca, const char *path) { struct attr_check_item *ccheck = NULL; @@@ -1492,34 -1510,27 +1492,34 @@@ static int convert_to_working_tree_ca_i return ret | ret_filter; } -int async_convert_to_working_tree(struct index_state *istate, - const char *path, const char *src, - size_t len, struct strbuf *dst, - const struct checkout_metadata *meta, - void *dco) +int async_convert_to_working_tree_ca(const struct conv_attrs *ca, + const char *path, const char *src, + size_t len, struct strbuf *dst, + const struct checkout_metadata *meta, + void *dco) { - return convert_to_working_tree_internal(istate, path, src, len, dst, 0, meta, dco); + return convert_to_working_tree_ca_internal(ca, path, src, len, dst, 0, + meta, dco); } -int convert_to_working_tree(struct index_state *istate, - const char *path, const char *src, - size_t len, struct strbuf *dst, - const struct checkout_metadata *meta) +int convert_to_working_tree_ca(const struct conv_attrs *ca, + const char *path, const char *src, + size_t len, struct strbuf *dst, + const struct checkout_metadata *meta) { - return convert_to_working_tree_internal(istate, path, src, len, dst, 0, meta, NULL); + return convert_to_working_tree_ca_internal(ca, path, src, len, dst, 0, + meta, NULL); } - int renormalize_buffer(const struct index_state *istate, const char *path, + int renormalize_buffer(struct index_state *istate, const char *path, const char *src, size_t len, struct strbuf *dst) { - int ret = convert_to_working_tree_internal(istate, path, src, len, dst, 1, NULL, NULL); + struct conv_attrs ca; + int ret; + + convert_attrs(istate, &ca, path); + ret = convert_to_working_tree_ca_internal(&ca, path, src, len, dst, 1, + NULL, NULL); if (ret) { src = dst->buf; len = dst->len; @@@ -1972,15 -1992,6 +1972,15 @@@ struct stream_filter *get_stream_filter return filter; } - struct stream_filter *get_stream_filter(const struct index_state *istate, ++struct stream_filter *get_stream_filter(struct index_state *istate, + const char *path, + const struct object_id *oid) +{ + struct conv_attrs ca; + convert_attrs(istate, &ca, path); + return get_stream_filter_ca(&ca, oid); +} + void free_stream_filter(struct stream_filter *filter) { filter->vtbl->free(filter); diff --cc convert.h index 43e567a59b,0f7c8a1f04..5ee1c32205 --- a/convert.h +++ b/convert.h @@@ -63,76 -63,33 +63,76 @@@ struct checkout_metadata struct object_id blob; }; +enum convert_crlf_action { + CRLF_UNDEFINED, + CRLF_BINARY, + CRLF_TEXT, + CRLF_TEXT_INPUT, + CRLF_TEXT_CRLF, + CRLF_AUTO, + CRLF_AUTO_INPUT, + CRLF_AUTO_CRLF +}; + +struct convert_driver; + +struct conv_attrs { + struct convert_driver *drv; + enum convert_crlf_action attr_action; /* What attr says */ + enum convert_crlf_action crlf_action; /* When no attr is set, use core.autocrlf */ + int ident; + const char *working_tree_encoding; /* Supported encoding or default encoding if NULL */ +}; + - void convert_attrs(const struct index_state *istate, ++void convert_attrs(struct index_state *istate, + struct conv_attrs *ca, const char *path); + extern enum eol core_eol; extern char *check_roundtrip_encoding; - const char *get_cached_convert_stats_ascii(const struct index_state *istate, + const char *get_cached_convert_stats_ascii(struct index_state *istate, const char *path); const char *get_wt_convert_stats_ascii(const char *path); - const char *get_convert_attr_ascii(const struct index_state *istate, + const char *get_convert_attr_ascii(struct index_state *istate, const char *path); /* returns 1 if *dst was used */ - int convert_to_git(const struct index_state *istate, + int convert_to_git(struct index_state *istate, const char *path, const char *src, size_t len, struct strbuf *dst, int conv_flags); -int convert_to_working_tree(struct index_state *istate, - const char *path, const char *src, - size_t len, struct strbuf *dst, - const struct checkout_metadata *meta); -int async_convert_to_working_tree(struct index_state *istate, - const char *path, const char *src, - size_t len, struct strbuf *dst, - const struct checkout_metadata *meta, - void *dco); +int convert_to_working_tree_ca(const struct conv_attrs *ca, + const char *path, const char *src, + size_t len, struct strbuf *dst, + const struct checkout_metadata *meta); +int async_convert_to_working_tree_ca(const struct conv_attrs *ca, + const char *path, const char *src, + size_t len, struct strbuf *dst, + const struct checkout_metadata *meta, + void *dco); - static inline int convert_to_working_tree(const struct index_state *istate, ++static inline int convert_to_working_tree(struct index_state *istate, + const char *path, const char *src, + size_t len, struct strbuf *dst, + const struct checkout_metadata *meta) +{ + struct conv_attrs ca; + convert_attrs(istate, &ca, path); + return convert_to_working_tree_ca(&ca, path, src, len, dst, meta); +} - static inline int async_convert_to_working_tree(const struct index_state *istate, ++static inline int async_convert_to_working_tree(struct index_state *istate, + const char *path, const char *src, + size_t len, struct strbuf *dst, + const struct checkout_metadata *meta, + void *dco) +{ + struct conv_attrs ca; + convert_attrs(istate, &ca, path); + return async_convert_to_working_tree_ca(&ca, path, src, len, dst, meta, dco); +} int async_query_available_blobs(const char *cmd, struct string_list *available_paths); - int renormalize_buffer(const struct index_state *istate, + int renormalize_buffer(struct index_state *istate, const char *path, const char *src, size_t len, struct strbuf *dst); - static inline int would_convert_to_git(const struct index_state *istate, + static inline int would_convert_to_git(struct index_state *istate, const char *path) { return convert_to_git(istate, path, NULL, 0, NULL, 0); @@@ -176,11 -133,9 +176,11 @@@ void reset_parsed_attributes(void) struct stream_filter; /* opaque */ - struct stream_filter *get_stream_filter(const struct index_state *istate, + struct stream_filter *get_stream_filter(struct index_state *istate, const char *path, const struct object_id *); +struct stream_filter *get_stream_filter_ca(const struct conv_attrs *ca, + const struct object_id *oid); void free_stream_filter(struct stream_filter *); int is_null_stream_filter(struct stream_filter *); diff --cc merge-ort.c index b1795d838e,603d30c521..6c2792b10e --- a/merge-ort.c +++ b/merge-ort.c @@@ -2538,61 -2340,6 +2538,61 @@@ static int string_list_df_name_compare( return onelen - twolen; } +static int read_oid_strbuf(struct merge_options *opt, + const struct object_id *oid, + struct strbuf *dst) +{ + void *buf; + enum object_type type; + unsigned long size; + buf = read_object_file(oid, &type, &size); + if (!buf) + return err(opt, _("cannot read object %s"), oid_to_hex(oid)); + if (type != OBJ_BLOB) { + free(buf); + return err(opt, _("object %s is not a blob"), oid_to_hex(oid)); + } + strbuf_attach(dst, buf, size, size + 1); + return 0; +} + +static int blob_unchanged(struct merge_options *opt, + const struct version_info *base, + const struct version_info *side, + const char *path) +{ + struct strbuf basebuf = STRBUF_INIT; + struct strbuf sidebuf = STRBUF_INIT; + int ret = 0; /* assume changed for safety */ - const struct index_state *idx = &opt->priv->attr_index; ++ struct index_state *idx = &opt->priv->attr_index; + + if (!idx->initialized) + initialize_attr_index(opt); + + if (base->mode != side->mode) + return 0; + if (oideq(&base->oid, &side->oid)) + return 1; + + if (read_oid_strbuf(opt, &base->oid, &basebuf) || + read_oid_strbuf(opt, &side->oid, &sidebuf)) + goto error_return; + /* + * Note: binary | is used so that both renormalizations are + * performed. Comparison can be skipped if both files are + * unchanged since their sha1s have already been compared. + */ + if (renormalize_buffer(idx, path, basebuf.buf, basebuf.len, &basebuf) | + renormalize_buffer(idx, path, sidebuf.buf, sidebuf.len, &sidebuf)) + ret = (basebuf.len == sidebuf.len && + !memcmp(basebuf.buf, sidebuf.buf, basebuf.len)); + +error_return: + strbuf_release(&basebuf); + strbuf_release(&sidebuf); + return ret; +} + struct directory_versions { /* * versions: list of (basename -> version_info) diff --cc repository.c index 87b355e7a6,a8acae002f..448cd557d4 --- a/repository.c +++ b/repository.c @@@ -261,8 -262,10 +262,10 @@@ void repo_clear(struct repository *repo int repo_read_index(struct repository *repo) { + int res; + if (!repo->index) - repo->index = xcalloc(1, sizeof(*repo->index)); + CALLOC_ARRAY(repo->index, 1); /* Complete the double-reference */ if (!repo->index->repo)