From ff7fe37b0530c0ddb5a88fe41b963b68b3f66127 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Th=C3=A1i=20Ng=E1=BB=8Dc=20Duy?= Date: Mon, 13 Aug 2018 18:14:18 +0200 Subject: diff.c: move read_index() code back to the caller MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This code is only needed for diff-tree (since f0c6b2a2fd ([PATCH] Optimize diff-tree -[CM] --stdin - 2005-05-27)). Let the caller do the preparation instead and avoid read_index() in diff.c code. read_index() should be avoided (in addition to the_index) because it uses get_index_file() underneath to get the path $GIT_DIR/index. This effectively pulls the_repository in and may become the only reason to pull a 'struct repository *' in diff.c. Let's keep the dependencies as few as possible and kick it back to diff-tree.c Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano diff --git a/builtin/diff-tree.c b/builtin/diff-tree.c index 91ba670..d07bf2e 100644 --- a/builtin/diff-tree.c +++ b/builtin/diff-tree.c @@ -163,9 +163,11 @@ int cmd_diff_tree(int argc, const char **argv, const char *prefix) int saved_nrl = 0; int saved_dcctc = 0; - if (opt->diffopt.detect_rename) - opt->diffopt.setup |= (DIFF_SETUP_USE_SIZE_CACHE | - DIFF_SETUP_USE_CACHE); + if (opt->diffopt.detect_rename) { + if (!the_index.cache) + read_index(&the_index); + opt->diffopt.setup |= DIFF_SETUP_USE_SIZE_CACHE; + } while (fgets(line, sizeof(line), stdin)) { struct object_id oid; diff --git a/diff.c b/diff.c index 04d044b..72ce800 100644 --- a/diff.c +++ b/diff.c @@ -4414,16 +4414,6 @@ void diff_setup_done(struct diff_options *options) if (options->detect_rename && options->rename_limit < 0) options->rename_limit = diff_rename_limit_default; - if (options->setup & DIFF_SETUP_USE_CACHE) { - if (!active_cache) - /* read-cache does not die even when it fails - * so it is safe for us to do this here. Also - * it does not smudge active_cache or active_nr - * when it fails, so we do not have to worry about - * cleaning it up ourselves either. - */ - read_cache(); - } if (hexsz < options->abbrev) options->abbrev = hexsz; /* full */ diff --git a/diff.h b/diff.h index 20c697d..3ada6ad 100644 --- a/diff.h +++ b/diff.h @@ -312,7 +312,6 @@ void diff_change(struct diff_options *, struct diff_filepair *diff_unmerge(struct diff_options *, const char *path); #define DIFF_SETUP_REVERSE 1 -#define DIFF_SETUP_USE_CACHE 2 #define DIFF_SETUP_USE_SIZE_CACHE 4 /* -- cgit v0.10.2-6-g49f6 From 07096c969678a999c24816805d72bf7e0e840384 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Th=C3=A1i=20Ng=E1=BB=8Dc=20Duy?= Date: Mon, 13 Aug 2018 18:14:19 +0200 Subject: cache-tree: wrap the_index based wrappers with #ifdef MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This puts update_main_cache_tree() and write_cache_as_tree() in the same group of "index compat" functions that assume the_index implicitly, which should only be used within builtin/ or t/helper. sequencer.c is also updated to not use these functions. As of now, no files outside builtin/ use these functions anymore. Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano diff --git a/cache-tree.c b/cache-tree.c index 181d591..16ea022 100644 --- a/cache-tree.c +++ b/cache-tree.c @@ -652,11 +652,6 @@ out: return ret; } -int write_cache_as_tree(struct object_id *oid, int flags, const char *prefix) -{ - return write_index_as_tree(oid, &the_index, get_index_file(), flags, prefix); -} - static void prime_cache_tree_rec(struct cache_tree *it, struct tree *tree) { struct tree_desc desc; @@ -723,10 +718,3 @@ int cache_tree_matches_traversal(struct cache_tree *root, return it->entry_count; return 0; } - -int update_main_cache_tree(int flags) -{ - if (!the_index.cache_tree) - the_index.cache_tree = cache_tree(); - return cache_tree_update(&the_index, flags); -} diff --git a/cache-tree.h b/cache-tree.h index 9799e89..fc0c842 100644 --- a/cache-tree.h +++ b/cache-tree.h @@ -33,8 +33,6 @@ struct cache_tree *cache_tree_read(const char *buffer, unsigned long size); int cache_tree_fully_valid(struct cache_tree *); int cache_tree_update(struct index_state *, int); -int update_main_cache_tree(int); - /* bitmasks to write_cache_as_tree flags */ #define WRITE_TREE_MISSING_OK 1 #define WRITE_TREE_IGNORE_CACHE_TREE 2 @@ -48,9 +46,22 @@ int update_main_cache_tree(int); #define WRITE_TREE_PREFIX_ERROR (-3) int write_index_as_tree(struct object_id *oid, struct index_state *index_state, const char *index_path, int flags, const char *prefix); -int write_cache_as_tree(struct object_id *oid, int flags, const char *prefix); void prime_cache_tree(struct index_state *, struct tree *); int cache_tree_matches_traversal(struct cache_tree *, struct name_entry *ent, struct traverse_info *info); +#ifndef NO_THE_INDEX_COMPATIBILITY_MACROS +static inline int write_cache_as_tree(struct object_id *oid, int flags, const char *prefix) +{ + return write_index_as_tree(oid, &the_index, get_index_file(), flags, prefix); +} + +static inline int update_main_cache_tree(int flags) +{ + if (!the_index.cache_tree) + the_index.cache_tree = cache_tree(); + return cache_tree_update(&the_index, flags); +} +#endif + #endif diff --git a/sequencer.c b/sequencer.c index 3103847..4d40f50 100644 --- a/sequencer.c +++ b/sequencer.c @@ -1244,7 +1244,7 @@ static int try_to_commit(struct strbuf *msg, const char *author, commit_list_insert(current_head, &parents); } - if (write_cache_as_tree(&tree, 0, NULL)) { + if (write_index_as_tree(&tree, &the_index, get_index_file(), 0, NULL)) { res = error(_("git write-tree failed to write a tree")); goto out; } @@ -1630,7 +1630,7 @@ static int do_pick_commit(enum todo_command command, struct commit *commit, * that represents the "current" state for merge-recursive * to work on. */ - if (write_cache_as_tree(&head, 0, NULL)) + if (write_index_as_tree(&head, &the_index, get_index_file(), 0, NULL)) return error(_("your index file is unmerged.")); } else { unborn = get_oid("HEAD", &head); -- cgit v0.10.2-6-g49f6 From 7a400a2c0270f2085b70690e4ddbfd8d141e69ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Th=C3=A1i=20Ng=E1=BB=8Dc=20Duy?= Date: Mon, 13 Aug 2018 18:14:20 +0200 Subject: attr: remove an implicit dependency on the_index MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make the attr API take an index_state instead of assuming the_index in attr code. All call sites are converted blindly to keep the patch simple and retain current behavior. Individual call sites may receive further updates to use the right index instead of the_index. There is one ugly temporary workaround added in attr.c that needs some more explanation. Commit c24f3abace (apply: file commited with CRLF should roundtrip diff and apply - 2017-08-19) forces one convert_to_git() call to NOT read the index at all. But what do you know, we read it anyway by falling back to the_index. When "istate" from convert_to_git is now propagated down to read_attr_from_array() we will hit segfault somewhere inside read_blob_data_from_index. The right way of dealing with this is to kill "use_index" variable and only follow "istate" but at this stage we are not ready for that: while most git_attr_set_direction() calls just passes the_index to be assigned to use_index, unpack-trees passes a different one which is used by entry.c code, which has no way to know what index to use if we delete use_index. So this has to be done later. Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano diff --git a/archive.c b/archive.c index 78b0a39..a8397e6 100644 --- a/archive.c +++ b/archive.c @@ -109,7 +109,7 @@ static const struct attr_check *get_archive_attrs(const char *path) static struct attr_check *check; if (!check) check = attr_check_initl("export-ignore", "export-subst", NULL); - return git_check_attr(path, check) ? NULL : check; + return git_check_attr(&the_index, path, check) ? NULL : check; } static int check_attr_export_ignore(const struct attr_check *check) diff --git a/attr.c b/attr.c index 067fb9e..863fad3 100644 --- a/attr.c +++ b/attr.c @@ -708,10 +708,10 @@ static struct attr_stack *read_attr_from_array(const char **list) * another thread could potentially be calling into the attribute system. */ static enum git_attr_direction direction; -static struct index_state *use_index; +static const struct index_state *use_index; void git_attr_set_direction(enum git_attr_direction new_direction, - struct index_state *istate) + const struct index_state *istate) { if (is_bare_repository() && new_direction != GIT_ATTR_INDEX) BUG("non-INDEX attr direction in a bare repo"); @@ -743,13 +743,24 @@ static struct attr_stack *read_attr_from_file(const char *path, int macro_ok) return res; } -static struct attr_stack *read_attr_from_index(const char *path, int macro_ok) +static struct attr_stack *read_attr_from_index(const struct index_state *istate, + const char *path, + int macro_ok) { struct attr_stack *res; char *buf, *sp; int lineno = 0; + const struct index_state *to_read_from; - buf = read_blob_data_from_index(use_index ? use_index : &the_index, path, NULL); + /* + * Temporary workaround for c24f3abace (apply: file commited + * with CRLF should roundtrip diff and apply - 2017-08-19) + */ + to_read_from = use_index ? use_index : istate; + if (!to_read_from) + return NULL; + + buf = read_blob_data_from_index(to_read_from, path, NULL); if (!buf) return NULL; @@ -768,15 +779,16 @@ static struct attr_stack *read_attr_from_index(const char *path, int macro_ok) return res; } -static struct attr_stack *read_attr(const char *path, int macro_ok) +static struct attr_stack *read_attr(const struct index_state *istate, + const char *path, int macro_ok) { struct attr_stack *res = NULL; if (direction == GIT_ATTR_INDEX) { - res = read_attr_from_index(path, macro_ok); + res = read_attr_from_index(istate, path, macro_ok); } else if (!is_bare_repository()) { if (direction == GIT_ATTR_CHECKOUT) { - res = read_attr_from_index(path, macro_ok); + res = read_attr_from_index(istate, path, macro_ok); if (!res) res = read_attr_from_file(path, macro_ok); } else if (direction == GIT_ATTR_CHECKIN) { @@ -788,7 +800,7 @@ static struct attr_stack *read_attr(const char *path, int macro_ok) * We allow operation in a sparsely checked out * work tree, so read from it. */ - res = read_attr_from_index(path, macro_ok); + res = read_attr_from_index(istate, path, macro_ok); } } @@ -859,7 +871,8 @@ static void push_stack(struct attr_stack **attr_stack_p, } } -static void bootstrap_attr_stack(struct attr_stack **stack) +static void bootstrap_attr_stack(const struct index_state *istate, + struct attr_stack **stack) { struct attr_stack *e; @@ -883,7 +896,7 @@ static void bootstrap_attr_stack(struct attr_stack **stack) } /* root directory */ - e = read_attr(GITATTRIBUTES_FILE, 1); + e = read_attr(istate, GITATTRIBUTES_FILE, 1); push_stack(stack, e, xstrdup(""), 0); /* info frame */ @@ -896,7 +909,8 @@ static void bootstrap_attr_stack(struct attr_stack **stack) push_stack(stack, e, NULL, 0); } -static void prepare_attr_stack(const char *path, int dirlen, +static void prepare_attr_stack(const struct index_state *istate, + const char *path, int dirlen, struct attr_stack **stack) { struct attr_stack *info; @@ -917,7 +931,7 @@ static void prepare_attr_stack(const char *path, int dirlen, * .gitattributes in deeper directories to shallower ones, * and finally use the built-in set as the default. */ - bootstrap_attr_stack(stack); + bootstrap_attr_stack(istate, stack); /* * Pop the "info" one that is always at the top of the stack. @@ -973,7 +987,7 @@ static void prepare_attr_stack(const char *path, int dirlen, strbuf_add(&pathbuf, path + pathbuf.len, (len - pathbuf.len)); strbuf_addf(&pathbuf, "/%s", GITATTRIBUTES_FILE); - next = read_attr(pathbuf.buf, 0); + next = read_attr(istate, pathbuf.buf, 0); /* reset the pathbuf to not include "/.gitattributes" */ strbuf_setlen(&pathbuf, len); @@ -1095,7 +1109,9 @@ static void determine_macros(struct all_attrs_item *all_attrs, * If check->check_nr is non-zero, only attributes in check[] are collected. * Otherwise all attributes are collected. */ -static void collect_some_attrs(const char *path, struct attr_check *check) +static void collect_some_attrs(const struct index_state *istate, + const char *path, + struct attr_check *check) { int i, pathlen, rem, dirlen; const char *cp, *last_slash = NULL; @@ -1114,7 +1130,7 @@ static void collect_some_attrs(const char *path, struct attr_check *check) dirlen = 0; } - prepare_attr_stack(path, dirlen, &check->stack); + prepare_attr_stack(istate, path, dirlen, &check->stack); all_attrs_init(&g_attr_hashmap, check); determine_macros(check->all_attrs, check->stack); @@ -1136,11 +1152,13 @@ static void collect_some_attrs(const char *path, struct attr_check *check) fill(path, pathlen, basename_offset, check->stack, check->all_attrs, rem); } -int git_check_attr(const char *path, struct attr_check *check) +int git_check_attr(const struct index_state *istate, + const char *path, + struct attr_check *check) { int i; - collect_some_attrs(path, check); + collect_some_attrs(istate, path, check); for (i = 0; i < check->nr; i++) { size_t n = check->items[i].attr->attr_nr; @@ -1153,12 +1171,13 @@ int git_check_attr(const char *path, struct attr_check *check) return 0; } -void git_all_attrs(const char *path, struct attr_check *check) +void git_all_attrs(const struct index_state *istate, + const char *path, struct attr_check *check) { int i; attr_check_reset(check); - collect_some_attrs(path, check); + collect_some_attrs(istate, path, check); for (i = 0; i < check->all_attrs_nr; i++) { const char *name = check->all_attrs[i].attr->name; diff --git a/attr.h b/attr.h index 4634001..3daca3c 100644 --- a/attr.h +++ b/attr.h @@ -1,6 +1,8 @@ #ifndef ATTR_H #define ATTR_H +struct index_state; + /* An attribute is a pointer to this opaque structure */ struct git_attr; @@ -60,13 +62,15 @@ void attr_check_free(struct attr_check *check); */ const char *git_attr_name(const struct git_attr *); -int git_check_attr(const char *path, struct attr_check *check); +int git_check_attr(const struct index_state *istate, + const char *path, struct attr_check *check); /* * Retrieve all attributes that apply to the specified path. * check holds the attributes and their values. */ -void git_all_attrs(const char *path, struct attr_check *check); +void git_all_attrs(const struct index_state *istate, + const char *path, struct attr_check *check); enum git_attr_direction { GIT_ATTR_CHECKIN, @@ -74,7 +78,7 @@ enum git_attr_direction { GIT_ATTR_INDEX }; void git_attr_set_direction(enum git_attr_direction new_direction, - struct index_state *istate); + const struct index_state *istate); void attr_start(void); diff --git a/builtin/check-attr.c b/builtin/check-attr.c index 91444dc..f7b5999 100644 --- a/builtin/check-attr.c +++ b/builtin/check-attr.c @@ -63,9 +63,9 @@ static void check_attr(const char *prefix, prefix_path(prefix, prefix ? strlen(prefix) : 0, file); if (collect_all) { - git_all_attrs(full_path, check); + git_all_attrs(&the_index, full_path, check); } else { - if (git_check_attr(full_path, check)) + if (git_check_attr(&the_index, full_path, check)) die("git_check_attr died"); } output_attr(check, file); diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index 4391504..3ff6da4 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -945,7 +945,7 @@ static int no_try_delta(const char *path) if (!check) check = attr_check_initl("delta", NULL); - if (git_check_attr(path, check)) + if (git_check_attr(&the_index, path, check)) return 0; if (ATTR_FALSE(check->items[0].value)) return 1; diff --git a/convert.c b/convert.c index 7907efd..1935bde 100644 --- a/convert.c +++ b/convert.c @@ -1303,7 +1303,7 @@ static void convert_attrs(struct conv_attrs *ca, const char *path) git_config(read_convert_config, NULL); } - if (!git_check_attr(path, check)) { + if (!git_check_attr(&the_index, path, check)) { struct attr_check_item *ccheck = check->items; ca->crlf_action = git_path_check_crlf(ccheck + 4); if (ca->crlf_action == CRLF_UNDEFINED) diff --git a/dir.c b/dir.c index 21e6f25..29fbbd4 100644 --- a/dir.c +++ b/dir.c @@ -281,7 +281,7 @@ static int match_attrs(const char *name, int namelen, { int i; - git_check_attr(name, item->attr_check); + git_check_attr(&the_index, name, item->attr_check); for (i = 0; i < item->attr_match_nr; i++) { const char *value; int matched; diff --git a/ll-merge.c b/ll-merge.c index a6ad2ec..0e2800f 100644 --- a/ll-merge.c +++ b/ll-merge.c @@ -371,7 +371,7 @@ int ll_merge(mmbuffer_t *result_buf, if (!check) check = attr_check_initl("merge", "conflict-marker-size", NULL); - if (!git_check_attr(path, check)) { + if (!git_check_attr(&the_index, path, check)) { ll_driver_name = check->items[0].value; if (check->items[1].value) { marker_size = atoi(check->items[1].value); @@ -398,7 +398,7 @@ int ll_merge_marker_size(const char *path) if (!check) check = attr_check_initl("conflict-marker-size", NULL); - if (!git_check_attr(path, check) && check->items[0].value) { + if (!git_check_attr(&the_index, path, check) && check->items[0].value) { marker_size = atoi(check->items[0].value); if (marker_size <= 0) marker_size = DEFAULT_CONFLICT_MARKER_SIZE; diff --git a/userdiff.c b/userdiff.c index 36af25e..f3f4be5 100644 --- a/userdiff.c +++ b/userdiff.c @@ -278,7 +278,7 @@ struct userdiff_driver *userdiff_find_by_path(const char *path) check = attr_check_initl("diff", NULL); if (!path) return NULL; - if (git_check_attr(path, check)) + if (git_check_attr(&the_index, path, check)) return NULL; if (ATTR_TRUE(check->items[0].value)) diff --git a/ws.c b/ws.c index a07caed..5b67b42 100644 --- a/ws.c +++ b/ws.c @@ -78,7 +78,7 @@ unsigned whitespace_rule(const char *pathname) if (!attr_whitespace_rule) attr_whitespace_rule = attr_check_initl("whitespace", NULL); - if (!git_check_attr(pathname, attr_whitespace_rule)) { + if (!git_check_attr(&the_index, pathname, attr_whitespace_rule)) { const char *value; value = attr_whitespace_rule->items[0].value; -- cgit v0.10.2-6-g49f6 From 7f944e264ebe2fcf9a2c228a9fc9463ab3274d39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Th=C3=A1i=20Ng=E1=BB=8Dc=20Duy?= Date: Mon, 13 Aug 2018 18:14:21 +0200 Subject: convert.c: remove an implicit dependency on the_index MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make the convert API take an index_state instead of assuming the_index in convert.c. All external call sites are converted blindly to keep the patch simple and retain current behavior. Individual call sites may receive further updates to use the right index instead of the_index. Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano diff --git a/apply.c b/apply.c index 2594927..2476f06 100644 --- a/apply.c +++ b/apply.c @@ -4335,7 +4335,7 @@ static int try_create_file(const char *path, unsigned int mode, const char *buf, if (fd < 0) return 1; - if (convert_to_working_tree(path, buf, size, &nbuf)) { + if (convert_to_working_tree(&the_index, path, buf, size, &nbuf)) { size = nbuf.len; buf = nbuf.buf; } diff --git a/archive.c b/archive.c index a8397e6..31de1bb 100644 --- a/archive.c +++ b/archive.c @@ -79,7 +79,7 @@ void *object_file_to_archive(const struct archiver_args *args, size_t size = 0; strbuf_attach(&buf, buffer, *sizep, *sizep + 1); - convert_to_working_tree(path, buf.buf, buf.len, &buf); + convert_to_working_tree(&the_index, path, buf.buf, buf.len, &buf); if (commit) format_subst(commit, buf.buf, buf.len, &buf); buffer = strbuf_detach(&buf, &size); diff --git a/builtin/cat-file.c b/builtin/cat-file.c index 4a44b24..c726ee1 100644 --- a/builtin/cat-file.c +++ b/builtin/cat-file.c @@ -39,7 +39,7 @@ static int filter_object(const char *path, unsigned mode, oid_to_hex(oid), path); if ((type == OBJ_BLOB) && S_ISREG(mode)) { struct strbuf strbuf = STRBUF_INIT; - if (convert_to_working_tree(path, *buf, *size, &strbuf)) { + if (convert_to_working_tree(&the_index, path, *buf, *size, &strbuf)) { free(*buf); *size = strbuf.len; *buf = strbuf_detach(&strbuf, NULL); diff --git a/builtin/ls-files.c b/builtin/ls-files.c index 88bb201..d996734 100644 --- a/builtin/ls-files.c +++ b/builtin/ls-files.c @@ -63,7 +63,7 @@ static void write_eolinfo(const struct index_state *istate, struct stat st; const char *i_txt = ""; const char *w_txt = ""; - const char *a_txt = get_convert_attr_ascii(path); + const char *a_txt = get_convert_attr_ascii(&the_index, path); if (ce && S_ISREG(ce->ce_mode)) i_txt = get_cached_convert_stats_ascii(istate, ce->name); diff --git a/convert.c b/convert.c index 1935bde..8acfe8a 100644 --- a/convert.c +++ b/convert.c @@ -1291,7 +1291,8 @@ struct conv_attrs { const char *working_tree_encoding; /* Supported encoding or default encoding if NULL */ }; -static void convert_attrs(struct conv_attrs *ca, const char *path) +static void convert_attrs(const struct index_state *istate, + struct conv_attrs *ca, const char *path) { static struct attr_check *check; @@ -1303,7 +1304,7 @@ static void convert_attrs(struct conv_attrs *ca, const char *path) git_config(read_convert_config, NULL); } - if (!git_check_attr(&the_index, path, check)) { + if (!git_check_attr(istate, path, check)) { struct attr_check_item *ccheck = check->items; ca->crlf_action = git_path_check_crlf(ccheck + 4); if (ca->crlf_action == CRLF_UNDEFINED) @@ -1340,11 +1341,11 @@ static void convert_attrs(struct conv_attrs *ca, const char *path) ca->crlf_action = CRLF_AUTO_INPUT; } -int would_convert_to_git_filter_fd(const char *path) +int would_convert_to_git_filter_fd(const struct index_state *istate, const char *path) { struct conv_attrs ca; - convert_attrs(&ca, path); + convert_attrs(istate, &ca, path); if (!ca.drv) return 0; @@ -1359,11 +1360,11 @@ int would_convert_to_git_filter_fd(const char *path) return apply_filter(path, NULL, 0, -1, NULL, ca.drv, CAP_CLEAN, NULL); } -const char *get_convert_attr_ascii(const char *path) +const char *get_convert_attr_ascii(const struct index_state *istate, const char *path) { struct conv_attrs ca; - convert_attrs(&ca, path); + convert_attrs(istate, &ca, path); switch (ca.attr_action) { case CRLF_UNDEFINED: return ""; @@ -1392,7 +1393,7 @@ int convert_to_git(const struct index_state *istate, int ret = 0; struct conv_attrs ca; - convert_attrs(&ca, path); + convert_attrs(istate, &ca, path); ret |= apply_filter(path, src, len, -1, dst, ca.drv, CAP_CLEAN, NULL); if (!ret && ca.drv && ca.drv->required) @@ -1424,7 +1425,7 @@ void convert_to_git_filter_fd(const struct index_state *istate, int conv_flags) { struct conv_attrs ca; - convert_attrs(&ca, path); + convert_attrs(istate, &ca, path); assert(ca.drv); assert(ca.drv->clean || ca.drv->process); @@ -1437,14 +1438,15 @@ void convert_to_git_filter_fd(const struct index_state *istate, ident_to_git(path, dst->buf, dst->len, dst, ca.ident); } -static int convert_to_working_tree_internal(const char *path, const char *src, +static int convert_to_working_tree_internal(const struct index_state *istate, + const char *path, const char *src, size_t len, struct strbuf *dst, int normalizing, struct delayed_checkout *dco) { int ret = 0, ret_filter = 0; struct conv_attrs ca; - convert_attrs(&ca, path); + convert_attrs(istate, &ca, path); ret |= ident_to_worktree(path, src, len, dst, ca.ident); if (ret) { @@ -1478,22 +1480,25 @@ static int convert_to_working_tree_internal(const char *path, const char *src, return ret | ret_filter; } -int async_convert_to_working_tree(const char *path, const char *src, +int async_convert_to_working_tree(const struct index_state *istate, + const char *path, const char *src, size_t len, struct strbuf *dst, void *dco) { - return convert_to_working_tree_internal(path, src, len, dst, 0, dco); + return convert_to_working_tree_internal(istate, path, src, len, dst, 0, dco); } -int convert_to_working_tree(const char *path, const char *src, size_t len, struct strbuf *dst) +int convert_to_working_tree(const struct index_state *istate, + const char *path, const char *src, + size_t len, struct strbuf *dst) { - return convert_to_working_tree_internal(path, src, len, dst, 0, NULL); + return convert_to_working_tree_internal(istate, path, src, len, dst, 0, NULL); } int renormalize_buffer(const struct index_state *istate, const char *path, const char *src, size_t len, struct strbuf *dst) { - int ret = convert_to_working_tree_internal(path, src, len, dst, 1, NULL); + int ret = convert_to_working_tree_internal(istate, path, src, len, dst, 1, NULL); if (ret) { src = dst->buf; len = dst->len; @@ -1927,12 +1932,14 @@ static struct stream_filter *ident_filter(const struct object_id *oid) * Note that you would be crazy to set CRLF, smuge/clean or ident to a * large binary blob you would want us not to slurp into the memory! */ -struct stream_filter *get_stream_filter(const char *path, const struct object_id *oid) +struct stream_filter *get_stream_filter(const struct index_state *istate, + const char *path, + const struct object_id *oid) { struct conv_attrs ca; struct stream_filter *filter = NULL; - convert_attrs(&ca, path); + convert_attrs(istate, &ca, path); if (ca.drv && (ca.drv->process || ca.drv->smudge || ca.drv->clean)) return NULL; diff --git a/convert.h b/convert.h index 0a0fa15..6d0ee88 100644 --- a/convert.h +++ b/convert.h @@ -60,15 +60,18 @@ extern char *check_roundtrip_encoding; const char *get_cached_convert_stats_ascii(const struct index_state *istate, const char *path); const char *get_wt_convert_stats_ascii(const char *path); -const char *get_convert_attr_ascii(const char *path); +const char *get_convert_attr_ascii(const struct index_state *istate, + const char *path); /* returns 1 if *dst was used */ int convert_to_git(const struct index_state *istate, const char *path, const char *src, size_t len, struct strbuf *dst, int conv_flags); -int convert_to_working_tree(const char *path, const char *src, +int convert_to_working_tree(const struct index_state *istate, + const char *path, const char *src, size_t len, struct strbuf *dst); -int async_convert_to_working_tree(const char *path, const char *src, +int async_convert_to_working_tree(const struct index_state *istate, + const char *path, const char *src, size_t len, struct strbuf *dst, void *dco); int async_query_available_blobs(const char *cmd, @@ -86,7 +89,8 @@ void convert_to_git_filter_fd(const struct index_state *istate, const char *path, int fd, struct strbuf *dst, int conv_flags); -int would_convert_to_git_filter_fd(const char *path); +int would_convert_to_git_filter_fd(const struct index_state *istate, + const char *path); /***************************************************************** * @@ -96,7 +100,8 @@ int would_convert_to_git_filter_fd(const char *path); struct stream_filter; /* opaque */ -struct stream_filter *get_stream_filter(const char *path, +struct stream_filter *get_stream_filter(const struct index_state *istate, + const char *path, const struct object_id *); void free_stream_filter(struct stream_filter *); int is_null_stream_filter(struct stream_filter *); diff --git a/diff.c b/diff.c index 72ce800..3670206 100644 --- a/diff.c +++ b/diff.c @@ -3893,7 +3893,7 @@ static void prep_temp_blob(const char *path, struct diff_tempfile *temp, temp->tempfile = mks_tempfile_ts(tempfile.buf, strlen(base) + 1); if (!temp->tempfile) die_errno("unable to create temp-file"); - if (convert_to_working_tree(path, + if (convert_to_working_tree(&the_index, path, (const char *)blob, (size_t)size, &buf)) { blob = buf.buf; size = buf.len; diff --git a/entry.c b/entry.c index b5d1d3c..b2381fd 100644 --- a/entry.c +++ b/entry.c @@ -266,7 +266,7 @@ static int write_entry(struct cache_entry *ce, const struct submodule *sub; if (ce_mode_s_ifmt == S_IFREG) { - struct stream_filter *filter = get_stream_filter(ce->name, + struct stream_filter *filter = get_stream_filter(&the_index, ce->name, &ce->oid); if (filter && !streaming_write_entry(ce, path, filter, @@ -314,14 +314,14 @@ static int write_entry(struct cache_entry *ce, * Convert from git internal format to working tree format */ if (dco && dco->state != CE_NO_DELAY) { - ret = async_convert_to_working_tree(ce->name, new_blob, + ret = async_convert_to_working_tree(&the_index, ce->name, new_blob, size, &buf, dco); if (ret && string_list_has_string(&dco->paths, ce->name)) { free(new_blob); goto delayed; } } else - ret = convert_to_working_tree(ce->name, new_blob, size, &buf); + ret = convert_to_working_tree(&the_index, ce->name, new_blob, size, &buf); if (ret) { free(new_blob); diff --git a/merge-recursive.c b/merge-recursive.c index 1446e92..defcbff 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -966,7 +966,7 @@ static int update_file_flags(struct merge_options *o, } if (S_ISREG(mode)) { struct strbuf strbuf = STRBUF_INIT; - if (convert_to_working_tree(path, buf, size, &strbuf)) { + if (convert_to_working_tree(&the_index, path, buf, size, &strbuf)) { free(buf); size = strbuf.len; buf = strbuf_detach(&strbuf, NULL); diff --git a/sha1-file.c b/sha1-file.c index dfa8a35..0016d46 100644 --- a/sha1-file.c +++ b/sha1-file.c @@ -1860,7 +1860,7 @@ static int index_stream_convert_blob(struct object_id *oid, int fd, struct strbuf sbuf = STRBUF_INIT; assert(path); - assert(would_convert_to_git_filter_fd(path)); + assert(would_convert_to_git_filter_fd(&the_index, path)); convert_to_git_filter_fd(&the_index, path, fd, &sbuf, get_conv_flags(flags)); @@ -1950,7 +1950,7 @@ int index_fd(struct object_id *oid, int fd, struct stat *st, * Call xsize_t() only when needed to avoid potentially unnecessary * die() for large files. */ - if (type == OBJ_BLOB && path && would_convert_to_git_filter_fd(path)) + if (type == OBJ_BLOB && path && would_convert_to_git_filter_fd(&the_index, path)) ret = index_stream_convert_blob(oid, fd, path, flags); else if (!S_ISREG(st->st_mode)) ret = index_pipe(oid, fd, type, path, flags); -- cgit v0.10.2-6-g49f6 From 6d2df284e7f4d7cd9f46992282ef59a72a9db527 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Th=C3=A1i=20Ng=E1=BB=8Dc=20Duy?= Date: Mon, 13 Aug 2018 18:14:22 +0200 Subject: dir.c: remove an implicit dependency on the_index in pathspec code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make the match_patchspec API and friends take an index_state instead of assuming the_index in dir.c. All external call sites are converted blindly to keep the patch simple and retain current behavior. Individual call sites may receive further updates to use the right index instead of the_index. Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano diff --git a/archive.c b/archive.c index 31de1bb..c81e35b 100644 --- a/archive.c +++ b/archive.c @@ -313,7 +313,7 @@ static int reject_entry(const struct object_id *oid, struct strbuf *base, struct strbuf sb = STRBUF_INIT; strbuf_addbuf(&sb, base); strbuf_addstr(&sb, filename); - if (!match_pathspec(context, sb.buf, sb.len, 0, NULL, 1)) + if (!match_pathspec(&the_index, context, sb.buf, sb.len, 0, NULL, 1)) ret = READ_TREE_RECURSIVE; strbuf_release(&sb); } diff --git a/builtin/add.c b/builtin/add.c index 8a155dd..066623a 100644 --- a/builtin/add.c +++ b/builtin/add.c @@ -40,7 +40,7 @@ static void chmod_pathspec(struct pathspec *pathspec, char flip) for (i = 0; i < active_nr; i++) { struct cache_entry *ce = active_cache[i]; - if (pathspec && !ce_path_match(ce, pathspec, NULL)) + if (pathspec && !ce_path_match(&the_index, ce, pathspec, NULL)) continue; if (chmod_cache_entry(ce, flip) < 0) @@ -135,7 +135,7 @@ static int renormalize_tracked_files(const struct pathspec *pathspec, int flags) continue; /* do not touch unmerged paths */ if (!S_ISREG(ce->ce_mode) && !S_ISLNK(ce->ce_mode)) continue; /* do not touch non blobs */ - if (pathspec && !ce_path_match(ce, pathspec, NULL)) + if (pathspec && !ce_path_match(&the_index, ce, pathspec, NULL)) continue; retval |= add_file_to_cache(ce->name, flags | HASH_RENORMALIZE); } @@ -155,7 +155,7 @@ static char *prune_directory(struct dir_struct *dir, struct pathspec *pathspec, i = dir->nr; while (--i >= 0) { struct dir_entry *entry = *src++; - if (dir_path_match(entry, pathspec, prefix, seen)) + if (dir_path_match(&the_index, entry, pathspec, prefix, seen)) *dst++ = entry; } dir->nr = dst - dir->entries; diff --git a/builtin/checkout.c b/builtin/checkout.c index 516136a..54acb8d 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -318,7 +318,7 @@ static int checkout_paths(const struct checkout_opts *opts, * match_pathspec() for _all_ entries when * opts->source_tree != NULL. */ - if (ce_path_match(ce, &opts->pathspec, ps_matched)) + if (ce_path_match(&the_index, ce, &opts->pathspec, ps_matched)) ce->ce_flags |= CE_MATCHED; } diff --git a/builtin/clean.c b/builtin/clean.c index ab402c2..8d9a7dc 100644 --- a/builtin/clean.c +++ b/builtin/clean.c @@ -976,7 +976,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix) continue; if (pathspec.nr) - matches = dir_path_match(ent, &pathspec, 0, NULL); + matches = dir_path_match(&the_index, ent, &pathspec, 0, NULL); if (pathspec.nr && !matches) continue; diff --git a/builtin/commit.c b/builtin/commit.c index 158e3f8..21277dd 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -251,7 +251,7 @@ static int list_paths(struct string_list *list, const char *with_tree, if (ce->ce_flags & CE_UPDATE) continue; - if (!ce_path_match(ce, pattern, m)) + if (!ce_path_match(&the_index, ce, pattern, m)) continue; item = string_list_insert(list, ce->name); if (ce_skip_worktree(ce)) diff --git a/builtin/grep.c b/builtin/grep.c index 056161f..9d7ba87 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -497,7 +497,7 @@ static int grep_cache(struct grep_opt *opt, struct repository *repo, strbuf_addstr(&name, ce->name); if (S_ISREG(ce->ce_mode) && - match_pathspec(pathspec, name.buf, name.len, 0, NULL, + match_pathspec(&the_index, pathspec, name.buf, name.len, 0, NULL, S_ISDIR(ce->ce_mode) || S_ISGITLINK(ce->ce_mode))) { /* @@ -515,7 +515,7 @@ static int grep_cache(struct grep_opt *opt, struct repository *repo, hit |= grep_file(opt, name.buf); } } else if (recurse_submodules && S_ISGITLINK(ce->ce_mode) && - submodule_path_match(pathspec, name.buf, NULL)) { + submodule_path_match(&the_index, pathspec, name.buf, NULL)) { hit |= grep_submodule(opt, repo, pathspec, NULL, ce->name, ce->name); } else { continue; @@ -679,7 +679,7 @@ static int grep_directory(struct grep_opt *opt, const struct pathspec *pathspec, fill_directory(&dir, &the_index, pathspec); for (i = 0; i < dir.nr; i++) { - if (!dir_path_match(dir.entries[i], pathspec, 0, NULL)) + if (!dir_path_match(&the_index, dir.entries[i], pathspec, 0, NULL)) continue; hit |= grep_file(opt, dir.entries[i]->name); if (hit && opt->status_only) diff --git a/builtin/ls-files.c b/builtin/ls-files.c index d996734..7233b92 100644 --- a/builtin/ls-files.c +++ b/builtin/ls-files.c @@ -128,7 +128,7 @@ static void show_dir_entry(const char *tag, struct dir_entry *ent) if (len > ent->len) die("git ls-files: internal error - directory entry not superset of prefix"); - if (!dir_path_match(ent, &pathspec, len, ps_matched)) + if (!dir_path_match(&the_index, ent, &pathspec, len, ps_matched)) return; fputs(tag, stdout); @@ -228,7 +228,7 @@ static void show_ce(struct repository *repo, struct dir_struct *dir, if (recurse_submodules && S_ISGITLINK(ce->ce_mode) && is_submodule_active(repo, ce->name)) { show_submodule(repo, dir, ce->name); - } else if (match_pathspec(&pathspec, fullname, strlen(fullname), + } else if (match_pathspec(&the_index, &pathspec, fullname, strlen(fullname), max_prefix_len, ps_matched, S_ISDIR(ce->ce_mode) || S_ISGITLINK(ce->ce_mode))) { @@ -264,7 +264,7 @@ static void show_ru_info(const struct index_state *istate) len = strlen(path); if (len < max_prefix_len) continue; /* outside of the prefix */ - if (!match_pathspec(&pathspec, path, len, + if (!match_pathspec(&the_index, &pathspec, path, len, max_prefix_len, ps_matched, 0)) continue; /* uninterested */ for (i = 0; i < 3; i++) { diff --git a/builtin/rm.c b/builtin/rm.c index 65b448e..eebdc4a 100644 --- a/builtin/rm.c +++ b/builtin/rm.c @@ -278,7 +278,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix) for (i = 0; i < active_nr; i++) { const struct cache_entry *ce = active_cache[i]; - if (!ce_path_match(ce, &pathspec, seen)) + if (!ce_path_match(&the_index, ce, &pathspec, seen)) continue; ALLOC_GROW(list.entry, list.nr + 1, list.alloc); list.entry[list.nr].name = xstrdup(ce->name); diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index a3c4564..a4440a3 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -331,7 +331,7 @@ static int module_list_compute(int argc, const char **argv, for (i = 0; i < active_nr; i++) { const struct cache_entry *ce = active_cache[i]; - if (!match_pathspec(pathspec, ce->name, ce_namelen(ce), + if (!match_pathspec(&the_index, pathspec, ce->name, ce_namelen(ce), 0, ps_matched, 1) || !S_ISGITLINK(ce->ce_mode)) continue; diff --git a/builtin/update-index.c b/builtin/update-index.c index f5c0b6a..f75fd24 100644 --- a/builtin/update-index.c +++ b/builtin/update-index.c @@ -748,7 +748,7 @@ static int do_reupdate(int ac, const char **av, int save_nr; char *path; - if (ce_stage(ce) || !ce_path_match(ce, &pathspec, NULL)) + if (ce_stage(ce) || !ce_path_match(&the_index, ce, &pathspec, NULL)) continue; if (has_head) old = read_one_ent(NULL, &head_oid, diff --git a/diff-lib.c b/diff-lib.c index 732f684..88a98b1 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -109,7 +109,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option) if (diff_can_quit_early(&revs->diffopt)) break; - if (!ce_path_match(ce, &revs->prune_data, NULL)) + if (!ce_path_match(&the_index, ce, &revs->prune_data, NULL)) continue; if (ce_stage(ce)) { @@ -474,7 +474,7 @@ static int oneway_diff(const struct cache_entry * const *src, if (tree == o->df_conflict_entry) tree = NULL; - if (ce_path_match(idx ? idx : tree, &revs->prune_data, NULL)) { + if (ce_path_match(&the_index, idx ? idx : tree, &revs->prune_data, NULL)) { do_oneway_diff(o, idx, tree); if (diff_can_quit_early(&revs->diffopt)) { o->exiting_early = 1; diff --git a/dir.c b/dir.c index 29fbbd4..e25aed0 100644 --- a/dir.c +++ b/dir.c @@ -276,12 +276,13 @@ static int do_read_blob(const struct object_id *oid, struct oid_stat *oid_stat, #define DO_MATCH_DIRECTORY (1<<1) #define DO_MATCH_SUBMODULE (1<<2) -static int match_attrs(const char *name, int namelen, +static int match_attrs(const struct index_state *istate, + const char *name, int namelen, const struct pathspec_item *item) { int i; - git_check_attr(&the_index, name, item->attr_check); + git_check_attr(istate, name, item->attr_check); for (i = 0; i < item->attr_match_nr; i++) { const char *value; int matched; @@ -318,7 +319,8 @@ static int match_attrs(const char *name, int namelen, * * It returns 0 when there is no match. */ -static int match_pathspec_item(const struct pathspec_item *item, int prefix, +static int match_pathspec_item(const struct index_state *istate, + const struct pathspec_item *item, int prefix, const char *name, int namelen, unsigned flags) { /* name/namelen has prefix cut off by caller */ @@ -358,7 +360,7 @@ static int match_pathspec_item(const struct pathspec_item *item, int prefix, strncmp(item->match, name - prefix, item->prefix)) return 0; - if (item->attr_match_nr && !match_attrs(name, namelen, item)) + if (item->attr_match_nr && !match_attrs(istate, name, namelen, item)) return 0; /* If the match was just the prefix, we matched */ @@ -426,7 +428,8 @@ static int match_pathspec_item(const struct pathspec_item *item, int prefix, * pathspec did not match any names, which could indicate that the * user mistyped the nth pathspec. */ -static int do_match_pathspec(const struct pathspec *ps, +static int do_match_pathspec(const struct index_state *istate, + const struct pathspec *ps, const char *name, int namelen, int prefix, char *seen, unsigned flags) @@ -472,7 +475,7 @@ static int do_match_pathspec(const struct pathspec *ps, */ if (seen && ps->items[i].magic & PATHSPEC_EXCLUDE) seen[i] = MATCHED_FNMATCH; - how = match_pathspec_item(ps->items+i, prefix, name, + how = match_pathspec_item(istate, ps->items+i, prefix, name, namelen, flags); if (ps->recursive && (ps->magic & PATHSPEC_MAXDEPTH) && @@ -496,17 +499,18 @@ static int do_match_pathspec(const struct pathspec *ps, return retval; } -int match_pathspec(const struct pathspec *ps, +int match_pathspec(const struct index_state *istate, + const struct pathspec *ps, const char *name, int namelen, int prefix, char *seen, int is_dir) { int positive, negative; unsigned flags = is_dir ? DO_MATCH_DIRECTORY : 0; - positive = do_match_pathspec(ps, name, namelen, + positive = do_match_pathspec(istate, ps, name, namelen, prefix, seen, flags); if (!(ps->magic & PATHSPEC_EXCLUDE) || !positive) return positive; - negative = do_match_pathspec(ps, name, namelen, + negative = do_match_pathspec(istate, ps, name, namelen, prefix, seen, flags | DO_MATCH_EXCLUDE); return negative ? 0 : positive; @@ -515,11 +519,12 @@ int match_pathspec(const struct pathspec *ps, /** * Check if a submodule is a superset of the pathspec */ -int submodule_path_match(const struct pathspec *ps, +int submodule_path_match(const struct index_state *istate, + const struct pathspec *ps, const char *submodule_name, char *seen) { - int matched = do_match_pathspec(ps, submodule_name, + int matched = do_match_pathspec(istate, ps, submodule_name, strlen(submodule_name), 0, seen, DO_MATCH_DIRECTORY | diff --git a/dir.h b/dir.h index f5fdedb..e3ec261 100644 --- a/dir.h +++ b/dir.h @@ -216,7 +216,8 @@ extern int count_slashes(const char *s); extern int simple_length(const char *match); extern int no_wildcard(const char *string); extern char *common_prefix(const struct pathspec *pathspec); -extern int match_pathspec(const struct pathspec *pathspec, +extern int match_pathspec(const struct index_state *istate, + const struct pathspec *pathspec, const char *name, int namelen, int prefix, char *seen, int is_dir); extern int report_path_error(const char *ps_matched, const struct pathspec *pathspec, const char *prefix); @@ -326,25 +327,28 @@ extern int git_fnmatch(const struct pathspec_item *item, const char *pattern, const char *string, int prefix); -extern int submodule_path_match(const struct pathspec *ps, +extern int submodule_path_match(const struct index_state *istate, + const struct pathspec *ps, const char *submodule_name, char *seen); -static inline int ce_path_match(const struct cache_entry *ce, +static inline int ce_path_match(const struct index_state *istate, + const struct cache_entry *ce, const struct pathspec *pathspec, char *seen) { - return match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, seen, + return match_pathspec(istate, pathspec, ce->name, ce_namelen(ce), 0, seen, S_ISDIR(ce->ce_mode) || S_ISGITLINK(ce->ce_mode)); } -static inline int dir_path_match(const struct dir_entry *ent, +static inline int dir_path_match(const struct index_state *istate, + const struct dir_entry *ent, const struct pathspec *pathspec, int prefix, char *seen) { int has_trailing_dir = ent->len && ent->name[ent->len - 1] == '/'; int len = has_trailing_dir ? ent->len - 1 : ent->len; - return match_pathspec(pathspec, ent->name, len, prefix, seen, + return match_pathspec(istate, pathspec, ent->name, len, prefix, seen, has_trailing_dir); } diff --git a/pathspec.c b/pathspec.c index 27cd606..897cb9c 100644 --- a/pathspec.c +++ b/pathspec.c @@ -37,7 +37,7 @@ void add_pathspec_matches_against_index(const struct pathspec *pathspec, return; for (i = 0; i < istate->cache_nr; i++) { const struct cache_entry *ce = istate->cache[i]; - ce_path_match(ce, pathspec, seen); + ce_path_match(&the_index, ce, pathspec, seen); } } diff --git a/preload-index.c b/preload-index.c index 4d08d44..d61d766 100644 --- a/preload-index.c +++ b/preload-index.c @@ -58,7 +58,7 @@ static void *preload_thread(void *_data) continue; if (ce->ce_flags & CE_FSMONITOR_VALID) continue; - if (!ce_path_match(ce, &p->pathspec, NULL)) + if (!ce_path_match(&the_index, ce, &p->pathspec, NULL)) continue; if (threaded_has_symlink_leading_path(&cache, ce->name, ce_namelen(ce))) continue; diff --git a/read-cache.c b/read-cache.c index 880849f..3a930bb 100644 --- a/read-cache.c +++ b/read-cache.c @@ -1493,7 +1493,7 @@ int refresh_index(struct index_state *istate, unsigned int flags, if (ignore_submodules && S_ISGITLINK(ce->ce_mode)) continue; - if (pathspec && !ce_path_match(ce, pathspec, seen)) + if (pathspec && !ce_path_match(&the_index, ce, pathspec, seen)) filtered = 1; if (ce_stage(ce)) { diff --git a/rerere.c b/rerere.c index 16c8aac..c7787aa 100644 --- a/rerere.c +++ b/rerere.c @@ -1120,7 +1120,7 @@ int rerere_forget(struct pathspec *pathspec) find_conflict(&conflict); for (i = 0; i < conflict.nr; i++) { struct string_list_item *it = &conflict.items[i]; - if (!match_pathspec(pathspec, it->string, + if (!match_pathspec(&the_index, pathspec, it->string, strlen(it->string), 0, NULL, 0)) continue; rerere_forget_one_path(it->string, &merge_rr); diff --git a/resolve-undo.c b/resolve-undo.c index c30ae5c..d2e2d22 100644 --- a/resolve-undo.c +++ b/resolve-undo.c @@ -188,7 +188,7 @@ void unmerge_index(struct index_state *istate, const struct pathspec *pathspec) for (i = 0; i < istate->cache_nr; i++) { const struct cache_entry *ce = istate->cache[i]; - if (!ce_path_match(ce, pathspec, NULL)) + if (!ce_path_match(&the_index, ce, pathspec, NULL)) continue; i = unmerge_index_entry_at(istate, i); } diff --git a/revision.c b/revision.c index 0627494..de4dce6 100644 --- a/revision.c +++ b/revision.c @@ -1517,7 +1517,7 @@ static void prepare_show_merge(struct rev_info *revs) const struct cache_entry *ce = active_cache[i]; if (!ce_stage(ce)) continue; - if (ce_path_match(ce, &revs->prune_data, NULL)) { + if (ce_path_match(&the_index, ce, &revs->prune_data, NULL)) { prune_num++; REALLOC_ARRAY(prune, prune_num); prune[prune_num-2] = ce->name; diff --git a/submodule.c b/submodule.c index 6e14547..293efc2 100644 --- a/submodule.c +++ b/submodule.c @@ -258,7 +258,7 @@ int is_submodule_active(struct repository *repo, const char *path) } parse_pathspec(&ps, 0, 0, NULL, args.argv); - ret = match_pathspec(&ps, path, strlen(path), 0, NULL, 1); + ret = match_pathspec(&the_index, &ps, path, strlen(path), 0, NULL, 1); argv_array_clear(&args); clear_pathspec(&ps); diff --git a/wt-status.c b/wt-status.c index 6bf2fdb..5ffab61 100644 --- a/wt-status.c +++ b/wt-status.c @@ -647,7 +647,7 @@ static void wt_status_collect_changes_initial(struct wt_status *s) struct wt_status_change_data *d; const struct cache_entry *ce = active_cache[i]; - if (!ce_path_match(ce, &s->pathspec, NULL)) + if (!ce_path_match(&the_index, ce, &s->pathspec, NULL)) continue; if (ce_intent_to_add(ce)) continue; @@ -703,7 +703,7 @@ static void wt_status_collect_untracked(struct wt_status *s) for (i = 0; i < dir.nr; i++) { struct dir_entry *ent = dir.entries[i]; if (cache_name_is_other(ent->name, ent->len) && - dir_path_match(ent, &s->pathspec, 0, NULL)) + dir_path_match(&the_index, ent, &s->pathspec, 0, NULL)) string_list_insert(&s->untracked, ent->name); free(ent); } @@ -711,7 +711,7 @@ static void wt_status_collect_untracked(struct wt_status *s) for (i = 0; i < dir.ignored_nr; i++) { struct dir_entry *ent = dir.ignored[i]; if (cache_name_is_other(ent->name, ent->len) && - dir_path_match(ent, &s->pathspec, 0, NULL)) + dir_path_match(&the_index, ent, &s->pathspec, 0, NULL)) string_list_insert(&s->ignored, ent->name); free(ent); } -- cgit v0.10.2-6-g49f6 From f9beff0336f7819e3d66bf8511b953e7c866f8a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Th=C3=A1i=20Ng=E1=BB=8Dc=20Duy?= Date: Mon, 13 Aug 2018 18:14:23 +0200 Subject: preload-index.c: use the right index instead of the_index MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano diff --git a/preload-index.c b/preload-index.c index d61d766..71cd243 100644 --- a/preload-index.c +++ b/preload-index.c @@ -58,7 +58,7 @@ static void *preload_thread(void *_data) continue; if (ce->ce_flags & CE_FSMONITOR_VALID) continue; - if (!ce_path_match(&the_index, ce, &p->pathspec, NULL)) + if (!ce_path_match(index, ce, &p->pathspec, NULL)) continue; if (threaded_has_symlink_leading_path(&cache, ce->name, ce_namelen(ce))) continue; -- cgit v0.10.2-6-g49f6 From a52b321d2e2c314d305be86c0310b3627c1aa95b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Th=C3=A1i=20Ng=E1=BB=8Dc=20Duy?= Date: Mon, 13 Aug 2018 18:14:24 +0200 Subject: ls-files: correct index argument to get_convert_attr_ascii() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit write_eolinfo() does take an istate as function argument and it should be used instead of the_index. Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano diff --git a/builtin/ls-files.c b/builtin/ls-files.c index 7233b92..7f9919a 100644 --- a/builtin/ls-files.c +++ b/builtin/ls-files.c @@ -63,7 +63,7 @@ static void write_eolinfo(const struct index_state *istate, struct stat st; const char *i_txt = ""; const char *w_txt = ""; - const char *a_txt = get_convert_attr_ascii(&the_index, path); + const char *a_txt = get_convert_attr_ascii(istate, path); if (ce && S_ISREG(ce->ce_mode)) i_txt = get_cached_convert_stats_ascii(istate, ce->name); @@ -121,18 +121,19 @@ static void print_debug(const struct cache_entry *ce) } } -static void show_dir_entry(const char *tag, struct dir_entry *ent) +static void show_dir_entry(const struct index_state *istate, + const char *tag, struct dir_entry *ent) { int len = max_prefix_len; if (len > ent->len) die("git ls-files: internal error - directory entry not superset of prefix"); - if (!dir_path_match(&the_index, ent, &pathspec, len, ps_matched)) + if (!dir_path_match(istate, ent, &pathspec, len, ps_matched)) return; fputs(tag, stdout); - write_eolinfo(NULL, NULL, ent->name); + write_eolinfo(istate, NULL, ent->name); write_name(ent->name); } @@ -145,7 +146,7 @@ static void show_other_files(const struct index_state *istate, struct dir_entry *ent = dir->entries[i]; if (!index_name_is_other(istate, ent->name, ent->len)) continue; - show_dir_entry(tag_other, ent); + show_dir_entry(istate, tag_other, ent); } } @@ -196,7 +197,7 @@ static void show_killed_files(const struct index_state *istate, } } if (killed) - show_dir_entry(tag_killed, dir->entries[i]); + show_dir_entry(istate, tag_killed, dir->entries[i]); } } @@ -228,7 +229,7 @@ static void show_ce(struct repository *repo, struct dir_struct *dir, if (recurse_submodules && S_ISGITLINK(ce->ce_mode) && is_submodule_active(repo, ce->name)) { show_submodule(repo, dir, ce->name); - } else if (match_pathspec(&the_index, &pathspec, fullname, strlen(fullname), + } else if (match_pathspec(repo->index, &pathspec, fullname, strlen(fullname), max_prefix_len, ps_matched, S_ISDIR(ce->ce_mode) || S_ISGITLINK(ce->ce_mode))) { @@ -264,7 +265,7 @@ static void show_ru_info(const struct index_state *istate) len = strlen(path); if (len < max_prefix_len) continue; /* outside of the prefix */ - if (!match_pathspec(&the_index, &pathspec, path, len, + if (!match_pathspec(istate, &pathspec, path, len, max_prefix_len, ps_matched, 0)) continue; /* uninterested */ for (i = 0; i < 3; i++) { -- cgit v0.10.2-6-g49f6 From 340f4bc9f8686c813410ef954ee00b8c66c78e91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Th=C3=A1i=20Ng=E1=BB=8Dc=20Duy?= Date: Mon, 13 Aug 2018 18:14:25 +0200 Subject: unpack-trees: remove 'extern' on function declaration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano diff --git a/unpack-trees.h b/unpack-trees.h index c2b434c..534358f 100644 --- a/unpack-trees.h +++ b/unpack-trees.h @@ -82,8 +82,8 @@ struct unpack_trees_options { struct exclude_list *el; /* for internal use */ }; -extern int unpack_trees(unsigned n, struct tree_desc *t, - struct unpack_trees_options *options); +int unpack_trees(unsigned n, struct tree_desc *t, + struct unpack_trees_options *options); int verify_uptodate(const struct cache_entry *ce, struct unpack_trees_options *o); -- cgit v0.10.2-6-g49f6 From 383480ba4ffc15b975e324bf7abbc01324d9935e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Th=C3=A1i=20Ng=E1=BB=8Dc=20Duy?= Date: Mon, 13 Aug 2018 18:14:26 +0200 Subject: unpack-trees: add a note about path invalidation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano diff --git a/unpack-trees.c b/unpack-trees.c index f9efee08..c07a6cd 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -1552,6 +1552,17 @@ static int verify_uptodate_sparse(const struct cache_entry *ce, return verify_uptodate_1(ce, o, ERROR_SPARSE_NOT_UPTODATE_FILE); } +/* + * TODO: We should actually invalidate o->result, not src_index [1]. + * But since cache tree and untracked cache both are not copied to + * o->result until unpacking is complete, we invalidate them on + * src_index instead with the assumption that they will be copied to + * dst_index at the end. + * + * [1] src_index->cache_tree is also used in unpack_callback() so if + * we invalidate o->result, we need to update it to use + * o->result.cache_tree as well. + */ static void invalidate_ce_path(const struct cache_entry *ce, struct unpack_trees_options *o) { -- cgit v0.10.2-6-g49f6 From 86016ec3042ec52eef9f45386c50384419d030c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Th=C3=A1i=20Ng=E1=BB=8Dc=20Duy?= Date: Mon, 13 Aug 2018 18:14:27 +0200 Subject: unpack-trees: don't shadow global var the_index MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This function mark_new_skip_worktree() has an argument named the_index which is also the name of a global variable. While they have different types (the global the_index is not a pointer) mistakes can easily happen and it's also confusing for readers. Rename the function argument to something other than the_index. Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano diff --git a/unpack-trees.c b/unpack-trees.c index c07a6cd..f50b463 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -1238,7 +1238,7 @@ static int clear_ce_flags(struct cache_entry **cache, int nr, * Set/Clear CE_NEW_SKIP_WORKTREE according to $GIT_DIR/info/sparse-checkout */ static void mark_new_skip_worktree(struct exclude_list *el, - struct index_state *the_index, + struct index_state *istate, int select_flag, int skip_wt_flag) { int i; @@ -1247,8 +1247,8 @@ static void mark_new_skip_worktree(struct exclude_list *el, * 1. Pretend the narrowest worktree: only unmerged entries * are checked out */ - for (i = 0; i < the_index->cache_nr; i++) { - struct cache_entry *ce = the_index->cache[i]; + for (i = 0; i < istate->cache_nr; i++) { + struct cache_entry *ce = istate->cache[i]; if (select_flag && !(ce->ce_flags & select_flag)) continue; @@ -1263,8 +1263,7 @@ static void mark_new_skip_worktree(struct exclude_list *el, * 2. Widen worktree according to sparse-checkout file. * Matched entries will have skip_wt_flag cleared (i.e. "in") */ - clear_ce_flags(the_index->cache, the_index->cache_nr, - select_flag, skip_wt_flag, el); + clear_ce_flags(istate->cache, istate->cache_nr, select_flag, skip_wt_flag, el); } static int verify_absent(const struct cache_entry *, -- cgit v0.10.2-6-g49f6 From 27c82fb3b406e01bbcd6c7cb11dc1925b88f6a92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Th=C3=A1i=20Ng=E1=BB=8Dc=20Duy?= Date: Mon, 13 Aug 2018 18:14:28 +0200 Subject: unpack-trees: convert clear_ce_flags* to avoid the_index MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prior to fba92be8f7, this code implicitly (and incorrectly) assumes the_index when running the exclude machinery. fba92be8f7 helps show this problem clearer because unpack-trees operation is supposed to work on whatever index the caller specifies... not specifically the_index. Update the code to use "istate" argument that's originally from mark_new_skip_worktree(). From the call sites, both in unpack_trees(), you can see that this function works on two separate indexes: o->src_index and o->result. The second mark_new_skip_worktree() so far has incorecctly applied exclude rules on o->src_index instead of o->result. It's unclear what is the consequences of this, but it's definitely wrong. [1] fba92be8f7 (dir: convert is_excluded_from_list to take an index - 2017-05-05) Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano diff --git a/unpack-trees.c b/unpack-trees.c index f50b463..5d11f10 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -1092,13 +1092,15 @@ static int unpack_callback(int n, unsigned long mask, unsigned long dirmask, str return mask; } -static int clear_ce_flags_1(struct cache_entry **cache, int nr, +static int clear_ce_flags_1(struct index_state *istate, + struct cache_entry **cache, int nr, struct strbuf *prefix, int select_mask, int clear_mask, struct exclude_list *el, int defval); /* Whole directory matching */ -static int clear_ce_flags_dir(struct cache_entry **cache, int nr, +static int clear_ce_flags_dir(struct index_state *istate, + struct cache_entry **cache, int nr, struct strbuf *prefix, char *basename, int select_mask, int clear_mask, @@ -1107,7 +1109,7 @@ static int clear_ce_flags_dir(struct cache_entry **cache, int nr, struct cache_entry **cache_end; int dtype = DT_DIR; int ret = is_excluded_from_list(prefix->buf, prefix->len, - basename, &dtype, el, &the_index); + basename, &dtype, el, istate); int rc; strbuf_addch(prefix, '/'); @@ -1129,7 +1131,7 @@ static int clear_ce_flags_dir(struct cache_entry **cache, int nr, * calling clear_ce_flags_1(). That function will call * the expensive is_excluded_from_list() on every entry. */ - rc = clear_ce_flags_1(cache, cache_end - cache, + rc = clear_ce_flags_1(istate, cache, cache_end - cache, prefix, select_mask, clear_mask, el, ret); @@ -1152,7 +1154,8 @@ static int clear_ce_flags_dir(struct cache_entry **cache, int nr, * cache[0]->name[0..(prefix_len-1)] * Top level path has prefix_len zero. */ -static int clear_ce_flags_1(struct cache_entry **cache, int nr, +static int clear_ce_flags_1(struct index_state *istate, + struct cache_entry **cache, int nr, struct strbuf *prefix, int select_mask, int clear_mask, struct exclude_list *el, int defval) @@ -1186,7 +1189,7 @@ static int clear_ce_flags_1(struct cache_entry **cache, int nr, len = slash - name; strbuf_add(prefix, name, len); - processed = clear_ce_flags_dir(cache, cache_end - cache, + processed = clear_ce_flags_dir(istate, cache, cache_end - cache, prefix, prefix->buf + prefix->len - len, select_mask, clear_mask, @@ -1200,7 +1203,7 @@ static int clear_ce_flags_1(struct cache_entry **cache, int nr, } strbuf_addch(prefix, '/'); - cache += clear_ce_flags_1(cache, cache_end - cache, + cache += clear_ce_flags_1(istate, cache, cache_end - cache, prefix, select_mask, clear_mask, el, defval); strbuf_setlen(prefix, prefix->len - len - 1); @@ -1210,7 +1213,7 @@ static int clear_ce_flags_1(struct cache_entry **cache, int nr, /* Non-directory */ dtype = ce_to_dtype(ce); ret = is_excluded_from_list(ce->name, ce_namelen(ce), - name, &dtype, el, &the_index); + name, &dtype, el, istate); if (ret < 0) ret = defval; if (ret > 0) @@ -1220,15 +1223,17 @@ static int clear_ce_flags_1(struct cache_entry **cache, int nr, return nr - (cache_end - cache); } -static int clear_ce_flags(struct cache_entry **cache, int nr, - int select_mask, int clear_mask, - struct exclude_list *el) +static int clear_ce_flags(struct index_state *istate, + int select_mask, int clear_mask, + struct exclude_list *el) { static struct strbuf prefix = STRBUF_INIT; strbuf_reset(&prefix); - return clear_ce_flags_1(cache, nr, + return clear_ce_flags_1(istate, + istate->cache, + istate->cache_nr, &prefix, select_mask, clear_mask, el, 0); @@ -1263,7 +1268,7 @@ static void mark_new_skip_worktree(struct exclude_list *el, * 2. Widen worktree according to sparse-checkout file. * Matched entries will have skip_wt_flag cleared (i.e. "in") */ - clear_ce_flags(istate->cache, istate->cache_nr, select_flag, skip_wt_flag, el); + clear_ce_flags(istate, select_flag, skip_wt_flag, el); } static int verify_absent(const struct cache_entry *, -- cgit v0.10.2-6-g49f6 From c7f3259d0d343f17848b0135612f61c075c47690 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Th=C3=A1i=20Ng=E1=BB=8Dc=20Duy?= Date: Mon, 13 Aug 2018 18:14:29 +0200 Subject: unpack-trees: avoid the_index in verify_absent() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both functions that are updated in this commit are called by verify_absent(), which is part of the "unpack-trees" operation that is supposed to work on any index file specified by the caller. Thanks to Brandon [1] [2], an implicit dependency on the_index is exposed. This commit fixes it. In both functions, it makes sense to use src_index to check for exclusion because it's almost unchanged and should give us the same outcome as if running the exclude check before the unpack. It's "almost unchanged" because we do invalidate cache-tree and untracked cache in the source index. But this should not affect how exclude machinery uses the index: to see if a file is tracked, and to read a blob from the index instead of worktree if it's marked skip-worktree (i.e. it's not available in worktree) [1] a0bba65b10 (dir: convert is_excluded to take an index - 2017-05-05 [2] 2c1eb10454 (dir: convert read_directory to take an index - 2017-05-05) Helped-by: Elijah Newren Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano diff --git a/unpack-trees.c b/unpack-trees.c index 5d11f10..14e9043 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -1658,7 +1658,7 @@ static int verify_clean_subdirectory(const struct cache_entry *ce, memset(&d, 0, sizeof(d)); if (o->dir) d.exclude_per_dir = o->dir->exclude_per_dir; - i = read_directory(&d, &the_index, pathbuf, namelen+1, NULL); + i = read_directory(&d, o->src_index, pathbuf, namelen+1, NULL); if (i) return o->gently ? -1 : add_rejected_path(o, ERROR_NOT_UPTODATE_DIR, ce->name); @@ -1700,7 +1700,7 @@ static int check_ok_to_remove(const char *name, int len, int dtype, return 0; if (o->dir && - is_excluded(o->dir, &the_index, name, &dtype)) + is_excluded(o->dir, o->src_index, name, &dtype)) /* * ce->name is explicitly excluded, so it is Ok to * overwrite it. -- cgit v0.10.2-6-g49f6 From d17ef3a94e6ee33be568c33496a84f15fb5fd4ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Th=C3=A1i=20Ng=E1=BB=8Dc=20Duy?= Date: Mon, 13 Aug 2018 18:14:30 +0200 Subject: pathspec.c: use the right index instead of the_index MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano diff --git a/pathspec.c b/pathspec.c index 897cb9c..6f00599 100644 --- a/pathspec.c +++ b/pathspec.c @@ -37,7 +37,7 @@ void add_pathspec_matches_against_index(const struct pathspec *pathspec, return; for (i = 0; i < istate->cache_nr; i++) { const struct cache_entry *ce = istate->cache[i]; - ce_path_match(&the_index, ce, pathspec, seen); + ce_path_match(istate, ce, pathspec, seen); } } -- cgit v0.10.2-6-g49f6 From 68f08b4b235d09a95604c6bc8349208b37a2f41e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Th=C3=A1i=20Ng=E1=BB=8Dc=20Duy?= Date: Mon, 13 Aug 2018 18:14:31 +0200 Subject: submodule.c: use the right index instead of the_index MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano diff --git a/submodule.c b/submodule.c index 293efc2..50cbf5f 100644 --- a/submodule.c +++ b/submodule.c @@ -93,7 +93,7 @@ int update_path_in_gitmodules(const char *oldpath, const char *newpath) if (!file_exists(GITMODULES_FILE)) /* Do nothing without .gitmodules */ return -1; - if (is_gitmodules_unmerged(&the_index)) + if (is_gitmodules_unmerged(the_repository->index)) die(_("Cannot change unmerged .gitmodules, resolve merge conflicts first")); submodule = submodule_from_path(the_repository, &null_oid, oldpath); @@ -127,7 +127,7 @@ int remove_path_from_gitmodules(const char *path) if (!file_exists(GITMODULES_FILE)) /* Do nothing without .gitmodules */ return -1; - if (is_gitmodules_unmerged(&the_index)) + if (is_gitmodules_unmerged(the_repository->index)) die(_("Cannot change unmerged .gitmodules, resolve merge conflicts first")); submodule = submodule_from_path(the_repository, &null_oid, path); @@ -188,7 +188,7 @@ void set_diffopt_flags_from_submodule_config(struct diff_options *diffopt, if (ignore) handle_ignore_submodules_arg(diffopt, ignore); - else if (is_gitmodules_unmerged(&the_index)) + else if (is_gitmodules_unmerged(the_repository->index)) diffopt->flags.ignore_submodules = 1; } } @@ -258,7 +258,7 @@ int is_submodule_active(struct repository *repo, const char *path) } parse_pathspec(&ps, 0, 0, NULL, args.argv); - ret = match_pathspec(&the_index, &ps, path, strlen(path), 0, NULL, 1); + ret = match_pathspec(repo->index, &ps, path, strlen(path), 0, NULL, 1); argv_array_clear(&args); clear_pathspec(&ps); -- cgit v0.10.2-6-g49f6 From 74cfc0ee1d0b4e386b5a07f8b79fbcece94cdff8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Th=C3=A1i=20Ng=E1=BB=8Dc=20Duy?= Date: Mon, 13 Aug 2018 18:14:32 +0200 Subject: entry.c: use the right index instead of the_index MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit checkout-index.c needs update because if checkout->istate is NULL, ie_match_stat() will crash. Previously this is ie_match_stat(&the_index, ..) so it will not crash, but it is not technically correct either. Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano diff --git a/builtin/checkout-index.c b/builtin/checkout-index.c index a730f6a..d92db62 100644 --- a/builtin/checkout-index.c +++ b/builtin/checkout-index.c @@ -190,6 +190,7 @@ int cmd_checkout_index(int argc, const char **argv, const char *prefix) argc = parse_options(argc, argv, prefix, builtin_checkout_index_options, builtin_checkout_index_usage, 0); + state.istate = &the_index; state.force = force; state.quiet = quiet; state.not_new = not_new; diff --git a/entry.c b/entry.c index b2381fd..2a2ab6c 100644 --- a/entry.c +++ b/entry.c @@ -266,7 +266,7 @@ static int write_entry(struct cache_entry *ce, const struct submodule *sub; if (ce_mode_s_ifmt == S_IFREG) { - struct stream_filter *filter = get_stream_filter(&the_index, ce->name, + struct stream_filter *filter = get_stream_filter(state->istate, ce->name, &ce->oid); if (filter && !streaming_write_entry(ce, path, filter, @@ -314,14 +314,14 @@ static int write_entry(struct cache_entry *ce, * Convert from git internal format to working tree format */ if (dco && dco->state != CE_NO_DELAY) { - ret = async_convert_to_working_tree(&the_index, ce->name, new_blob, + ret = async_convert_to_working_tree(state->istate, ce->name, new_blob, size, &buf, dco); if (ret && string_list_has_string(&dco->paths, ce->name)) { free(new_blob); goto delayed; } } else - ret = convert_to_working_tree(&the_index, ce->name, new_blob, size, &buf); + ret = convert_to_working_tree(state->istate, ce->name, new_blob, size, &buf); if (ret) { free(new_blob); @@ -422,7 +422,8 @@ int checkout_entry(struct cache_entry *ce, if (!check_path(path.buf, path.len, &st, state->base_dir_len)) { const struct submodule *sub; - unsigned changed = ce_match_stat(ce, &st, CE_MATCH_IGNORE_VALID|CE_MATCH_IGNORE_SKIP_WORKTREE); + unsigned changed = ie_match_stat(state->istate, ce, &st, + CE_MATCH_IGNORE_VALID | CE_MATCH_IGNORE_SKIP_WORKTREE); /* * Needs to be checked before !changed returns early, * as the possibly empty directory was not changed -- cgit v0.10.2-6-g49f6 From c4500e251f89cbbc49fe90b832348ea9d4899946 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Th=C3=A1i=20Ng=E1=BB=8Dc=20Duy?= Date: Mon, 13 Aug 2018 18:14:33 +0200 Subject: attr: remove index from git_attr_set_direction() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since attr checking API now take the index, there's no need to set an index in advance with this call. Most call sites are straightforward because they either pass the_index or NULL (which defaults back to the_index previously). There's only one suspicious call site in unpack-trees.c where it sets a different index. This code in unpack-trees is about to check out entries from the new/temporary index after merging is done in it. The attributes will be used by entry.c code to do crlf conversion if needed. entry.c now respects struct checkout's istate field, and this field is correctly set in unpack-trees.c, there should be no regression from this change. Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano diff --git a/archive.c b/archive.c index c81e35b..aca9179 100644 --- a/archive.c +++ b/archive.c @@ -274,7 +274,7 @@ int write_archive_entries(struct archiver_args *args, init_tree_desc(&t, args->tree->buffer, args->tree->size); if (unpack_trees(1, &t, &opts)) return -1; - git_attr_set_direction(GIT_ATTR_INDEX, &the_index); + git_attr_set_direction(GIT_ATTR_INDEX); } err = read_tree_recursive(args->tree, "", 0, 0, &args->pathspec, diff --git a/attr.c b/attr.c index 863fad3..98e4953 100644 --- a/attr.c +++ b/attr.c @@ -708,10 +708,8 @@ static struct attr_stack *read_attr_from_array(const char **list) * another thread could potentially be calling into the attribute system. */ static enum git_attr_direction direction; -static const struct index_state *use_index; -void git_attr_set_direction(enum git_attr_direction new_direction, - const struct index_state *istate) +void git_attr_set_direction(enum git_attr_direction new_direction) { if (is_bare_repository() && new_direction != GIT_ATTR_INDEX) BUG("non-INDEX attr direction in a bare repo"); @@ -720,7 +718,6 @@ void git_attr_set_direction(enum git_attr_direction new_direction, drop_all_attr_stacks(); direction = new_direction; - use_index = istate; } static struct attr_stack *read_attr_from_file(const char *path, int macro_ok) @@ -750,17 +747,11 @@ static struct attr_stack *read_attr_from_index(const struct index_state *istate, struct attr_stack *res; char *buf, *sp; int lineno = 0; - const struct index_state *to_read_from; - /* - * Temporary workaround for c24f3abace (apply: file commited - * with CRLF should roundtrip diff and apply - 2017-08-19) - */ - to_read_from = use_index ? use_index : istate; - if (!to_read_from) + if (!istate) return NULL; - buf = read_blob_data_from_index(to_read_from, path, NULL); + buf = read_blob_data_from_index(istate, path, NULL); if (!buf) return NULL; diff --git a/attr.h b/attr.h index 3daca3c..01dab4a 100644 --- a/attr.h +++ b/attr.h @@ -77,8 +77,7 @@ enum git_attr_direction { GIT_ATTR_CHECKOUT, GIT_ATTR_INDEX }; -void git_attr_set_direction(enum git_attr_direction new_direction, - const struct index_state *istate); +void git_attr_set_direction(enum git_attr_direction new_direction); void attr_start(void); diff --git a/builtin/check-attr.c b/builtin/check-attr.c index f7b5999..c05573f 100644 --- a/builtin/check-attr.c +++ b/builtin/check-attr.c @@ -120,7 +120,7 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix) } if (cached_attrs) - git_attr_set_direction(GIT_ATTR_INDEX, NULL); + git_attr_set_direction(GIT_ATTR_INDEX); doubledash = -1; for (i = 0; doubledash < 0 && i < argc; i++) { diff --git a/unpack-trees.c b/unpack-trees.c index 14e9043..f25089b 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -353,7 +353,7 @@ static int check_updates(struct unpack_trees_options *o) progress = get_progress(o); if (o->update) - git_attr_set_direction(GIT_ATTR_CHECKOUT, index); + git_attr_set_direction(GIT_ATTR_CHECKOUT); if (should_update_submodules() && o->update && !o->dry_run) load_gitmodules_file(index, NULL); @@ -413,7 +413,7 @@ static int check_updates(struct unpack_trees_options *o) stop_progress(&progress); errs |= finish_delayed_checkout(&state); if (o->update) - git_attr_set_direction(GIT_ATTR_CHECKIN, NULL); + git_attr_set_direction(GIT_ATTR_CHECKIN); return errs != 0; } -- cgit v0.10.2-6-g49f6 From a4009b0b452550036a5e3dd4712797d14a3284a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Th=C3=A1i=20Ng=E1=BB=8Dc=20Duy?= Date: Mon, 13 Aug 2018 18:14:34 +0200 Subject: grep: use the right index instead of the_index MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano diff --git a/builtin/grep.c b/builtin/grep.c index 9d7ba87..b703395 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -497,7 +497,7 @@ static int grep_cache(struct grep_opt *opt, struct repository *repo, strbuf_addstr(&name, ce->name); if (S_ISREG(ce->ce_mode) && - match_pathspec(&the_index, pathspec, name.buf, name.len, 0, NULL, + match_pathspec(repo->index, pathspec, name.buf, name.len, 0, NULL, S_ISDIR(ce->ce_mode) || S_ISGITLINK(ce->ce_mode))) { /* @@ -515,7 +515,7 @@ static int grep_cache(struct grep_opt *opt, struct repository *repo, hit |= grep_file(opt, name.buf); } } else if (recurse_submodules && S_ISGITLINK(ce->ce_mode) && - submodule_path_match(&the_index, pathspec, name.buf, NULL)) { + submodule_path_match(repo->index, pathspec, name.buf, NULL)) { hit |= grep_submodule(opt, repo, pathspec, NULL, ce->name, ce->name); } else { continue; -- cgit v0.10.2-6-g49f6 From b612ee202a48f129f81f8f6a5af6cf71d1a9caef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Th=C3=A1i=20Ng=E1=BB=8Dc=20Duy?= Date: Mon, 13 Aug 2018 18:14:35 +0200 Subject: archive.c: avoid access to the_index MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano diff --git a/archive.c b/archive.c index aca9179..0a07b14 100644 --- a/archive.c +++ b/archive.c @@ -79,7 +79,7 @@ void *object_file_to_archive(const struct archiver_args *args, size_t size = 0; strbuf_attach(&buf, buffer, *sizep, *sizep + 1); - convert_to_working_tree(&the_index, path, buf.buf, buf.len, &buf); + convert_to_working_tree(args->repo->index, path, buf.buf, buf.len, &buf); if (commit) format_subst(commit, buf.buf, buf.len, &buf); buffer = strbuf_detach(&buf, &size); @@ -104,12 +104,13 @@ struct archiver_context { struct directory *bottom; }; -static const struct attr_check *get_archive_attrs(const char *path) +static const struct attr_check *get_archive_attrs(struct index_state *istate, + const char *path) { static struct attr_check *check; if (!check) check = attr_check_initl("export-ignore", "export-subst", NULL); - return git_check_attr(&the_index, path, check) ? NULL : check; + return git_check_attr(istate, path, check) ? NULL : check; } static int check_attr_export_ignore(const struct attr_check *check) @@ -145,7 +146,7 @@ static int write_archive_entry(const struct object_id *oid, const char *base, if (!S_ISDIR(mode)) { const struct attr_check *check; - check = get_archive_attrs(path_without_prefix); + check = get_archive_attrs(args->repo->index, path_without_prefix); if (check_attr_export_ignore(check)) return 0; args->convert = check_attr_export_subst(check); @@ -220,7 +221,7 @@ static int queue_or_write_archive_entry(const struct object_id *oid, /* Borrow base, but restore its original value when done. */ strbuf_addstr(base, filename); strbuf_addch(base, '/'); - check = get_archive_attrs(base->buf); + check = get_archive_attrs(c->args->repo->index, base->buf); strbuf_setlen(base, baselen); if (check_attr_export_ignore(check)) @@ -268,8 +269,8 @@ int write_archive_entries(struct archiver_args *args, memset(&opts, 0, sizeof(opts)); opts.index_only = 1; opts.head_idx = -1; - opts.src_index = &the_index; - opts.dst_index = &the_index; + opts.src_index = args->repo->index; + opts.dst_index = args->repo->index; opts.fn = oneway_merge; init_tree_desc(&t, args->tree->buffer, args->tree->size); if (unpack_trees(1, &t, &opts)) @@ -304,33 +305,43 @@ static const struct archiver *lookup_archiver(const char *name) return NULL; } +struct path_exists_context { + struct pathspec pathspec; + struct archiver_args *args; +}; + static int reject_entry(const struct object_id *oid, struct strbuf *base, const char *filename, unsigned mode, int stage, void *context) { int ret = -1; + struct path_exists_context *ctx = context; + if (S_ISDIR(mode)) { struct strbuf sb = STRBUF_INIT; strbuf_addbuf(&sb, base); strbuf_addstr(&sb, filename); - if (!match_pathspec(&the_index, context, sb.buf, sb.len, 0, NULL, 1)) + if (!match_pathspec(ctx->args->repo->index, + &ctx->pathspec, + sb.buf, sb.len, 0, NULL, 1)) ret = READ_TREE_RECURSIVE; strbuf_release(&sb); } return ret; } -static int path_exists(struct tree *tree, const char *path) +static int path_exists(struct archiver_args *args, const char *path) { const char *paths[] = { path, NULL }; - struct pathspec pathspec; + struct path_exists_context ctx; int ret; - parse_pathspec(&pathspec, 0, 0, "", paths); - pathspec.recursive = 1; - ret = read_tree_recursive(tree, "", 0, 0, &pathspec, - reject_entry, &pathspec); - clear_pathspec(&pathspec); + ctx.args = args; + parse_pathspec(&ctx.pathspec, 0, 0, "", paths); + ctx.pathspec.recursive = 1; + ret = read_tree_recursive(args->tree, "", 0, 0, &ctx.pathspec, + reject_entry, &ctx); + clear_pathspec(&ctx.pathspec); return ret != 0; } @@ -348,7 +359,7 @@ static void parse_pathspec_arg(const char **pathspec, ar_args->pathspec.recursive = 1; if (pathspec) { while (*pathspec) { - if (**pathspec && !path_exists(ar_args->tree, *pathspec)) + if (**pathspec && !path_exists(ar_args, *pathspec)) die(_("pathspec '%s' did not match any files"), *pathspec); pathspec++; } @@ -510,6 +521,7 @@ static int parse_archive_args(int argc, const char **argv, } int write_archive(int argc, const char **argv, const char *prefix, + struct repository *repo, const char *name_hint, int remote) { const struct archiver *ar = NULL; @@ -521,6 +533,7 @@ int write_archive(int argc, const char **argv, const char *prefix, init_tar_archiver(); init_zip_archiver(); + args.repo = repo; argc = parse_archive_args(argc, argv, &ar, &args, name_hint, remote); if (!startup_info->have_repository) { /* diff --git a/archive.h b/archive.h index 1f9954f..75b9a86 100644 --- a/archive.h +++ b/archive.h @@ -3,7 +3,10 @@ #include "pathspec.h" +struct repository; + struct archiver_args { + struct repository *repo; const char *base; size_t baselen; struct tree *tree; @@ -17,6 +20,16 @@ struct archiver_args { int compression_level; }; +/* main api */ + +extern int write_archive(int argc, const char **argv, const char *prefix, + struct repository *repo, + const char *name_hint, int remote); + +const char *archive_format_from_filename(const char *filename); + +/* archive backend stuff */ + #define ARCHIVER_WANT_COMPRESSION_LEVELS 1 #define ARCHIVER_REMOTE 2 struct archiver { @@ -36,9 +49,6 @@ typedef int (*write_archive_entry_fn_t)(struct archiver_args *args, unsigned int mode); extern int write_archive_entries(struct archiver_args *args, write_archive_entry_fn_t write_entry); -extern int write_archive(int argc, const char **argv, const char *prefix, const char *name_hint, int remote); - -const char *archive_format_from_filename(const char *filename); extern void *object_file_to_archive(const struct archiver_args *args, const char *path, const struct object_id *oid, unsigned int mode, enum object_type *type, diff --git a/builtin/archive.c b/builtin/archive.c index 73971d0..e74f675 100644 --- a/builtin/archive.c +++ b/builtin/archive.c @@ -105,5 +105,5 @@ int cmd_archive(int argc, const char **argv, const char *prefix) setvbuf(stderr, NULL, _IOLBF, BUFSIZ); - return write_archive(argc, argv, prefix, output, 0); + return write_archive(argc, argv, prefix, the_repository, output, 0); } diff --git a/builtin/upload-archive.c b/builtin/upload-archive.c index 84532ae..25d9116 100644 --- a/builtin/upload-archive.c +++ b/builtin/upload-archive.c @@ -43,7 +43,8 @@ int cmd_upload_archive_writer(int argc, const char **argv, const char *prefix) } /* parse all options sent by the client */ - return write_archive(sent_argv.argc, sent_argv.argv, prefix, NULL, 1); + return write_archive(sent_argv.argc, sent_argv.argv, prefix, + the_repository, NULL, 1); } __attribute__((format (printf, 1, 2))) -- cgit v0.10.2-6-g49f6 From b67b55127c3eb2a44429f6b7071ce196794d14e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Th=C3=A1i=20Ng=E1=BB=8Dc=20Duy?= Date: Mon, 13 Aug 2018 18:14:36 +0200 Subject: archive-*.c: use the right repository MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With 'struct archive_args' gaining new repository pointer, we don't have to assume the_repository in the archive backends anymore. Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano diff --git a/archive-tar.c b/archive-tar.c index 7df8565..69ff23d 100644 --- a/archive-tar.c +++ b/archive-tar.c @@ -277,7 +277,7 @@ static int write_tar_entry(struct archiver_args *args, memcpy(header.name, path, pathlen); if (S_ISREG(mode) && !args->convert && - oid_object_info(the_repository, oid, &size) == OBJ_BLOB && + oid_object_info(args->repo, oid, &size) == OBJ_BLOB && size > big_file_threshold) buffer = NULL; else if (S_ISLNK(mode) || S_ISREG(mode)) { diff --git a/archive-zip.c b/archive-zip.c index abc556e..107da5f 100644 --- a/archive-zip.c +++ b/archive-zip.c @@ -326,7 +326,7 @@ static int write_zip_entry(struct archiver_args *args, compressed_size = 0; buffer = NULL; } else if (S_ISREG(mode) || S_ISLNK(mode)) { - enum object_type type = oid_object_info(the_repository, oid, + enum object_type type = oid_object_info(args->repo, oid, &size); method = 0; -- cgit v0.10.2-6-g49f6 From ff82d1260f55836e18625fbae1697dbbe3090531 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Th=C3=A1i=20Ng=E1=BB=8Dc=20Duy?= Date: Mon, 13 Aug 2018 18:14:37 +0200 Subject: resolve-undo.c: use the right index instead of the_index MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano diff --git a/resolve-undo.c b/resolve-undo.c index d2e2d22..236320f 100644 --- a/resolve-undo.c +++ b/resolve-undo.c @@ -188,7 +188,7 @@ void unmerge_index(struct index_state *istate, const struct pathspec *pathspec) for (i = 0; i < istate->cache_nr; i++) { const struct cache_entry *ce = istate->cache[i]; - if (!ce_path_match(&the_index, ce, pathspec, NULL)) + if (!ce_path_match(istate, ce, pathspec, NULL)) continue; i = unmerge_index_entry_at(istate, i); } -- cgit v0.10.2-6-g49f6 From 332a82a52222da253cd5023cd4c5cde2d51636b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Th=C3=A1i=20Ng=E1=BB=8Dc=20Duy?= Date: Mon, 13 Aug 2018 18:14:38 +0200 Subject: apply.c: pass struct apply_state to more functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit we're going to remove the dependency on the_index by moving 'struct index_state *' to somewhere inside struct apply_state. Let's make sure relevant functions have access to this struct now and reduce the diff noise when the actual conversion happens. Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano diff --git a/apply.c b/apply.c index 2476f06..572cd63 100644 --- a/apply.c +++ b/apply.c @@ -3374,7 +3374,9 @@ static struct patch *previous_patch(struct apply_state *state, return previous; } -static int verify_index_match(const struct cache_entry *ce, struct stat *st) +static int verify_index_match(struct apply_state *state, + const struct cache_entry *ce, + struct stat *st) { if (S_ISGITLINK(ce->ce_mode)) { if (!S_ISDIR(st->st_mode)) @@ -3524,7 +3526,7 @@ static int load_current(struct apply_state *state, if (checkout_target(&the_index, ce, &st)) return -1; } - if (verify_index_match(ce, &st)) + if (verify_index_match(state, ce, &st)) return error(_("%s: does not match index"), name); status = load_patch_target(state, &buf, ce, &st, patch, name, mode); @@ -3694,7 +3696,7 @@ static int check_preimage(struct apply_state *state, if (checkout_target(&the_index, *ce, st)) return -1; } - if (!state->cached && verify_index_match(*ce, st)) + if (!state->cached && verify_index_match(state, *ce, st)) return error(_("%s: does not match index"), old_name); if (state->cached) st_mode = (*ce)->ce_mode; @@ -4313,7 +4315,9 @@ static int add_index_file(struct apply_state *state, * 0 if everything went well * 1 if a recoverable error happened */ -static int try_create_file(const char *path, unsigned int mode, const char *buf, unsigned long size) +static int try_create_file(struct apply_state *state, const char *path, + unsigned int mode, const char *buf, + unsigned long size) { int fd, res; struct strbuf nbuf = STRBUF_INIT; @@ -4371,7 +4375,7 @@ static int create_one_file(struct apply_state *state, if (state->cached) return 0; - res = try_create_file(path, mode, buf, size); + res = try_create_file(state, path, mode, buf, size); if (res < 0) return -1; if (!res) @@ -4380,7 +4384,7 @@ static int create_one_file(struct apply_state *state, if (errno == ENOENT) { if (safe_create_leading_directories(path)) return 0; - res = try_create_file(path, mode, buf, size); + res = try_create_file(state, path, mode, buf, size); if (res < 0) return -1; if (!res) @@ -4402,7 +4406,7 @@ static int create_one_file(struct apply_state *state, for (;;) { char newpath[PATH_MAX]; mksnpath(newpath, sizeof(newpath), "%s~%u", path, nr); - res = try_create_file(newpath, mode, buf, size); + res = try_create_file(state, newpath, mode, buf, size); if (res < 0) return -1; if (!res) { -- cgit v0.10.2-6-g49f6 From 82ea77eca7af238f1ee65f5cbc945a01e16ee97a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Th=C3=A1i=20Ng=E1=BB=8Dc=20Duy?= Date: Mon, 13 Aug 2018 18:14:39 +0200 Subject: apply.c: make init_apply_state() take a struct repository MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We're moving away from the_index in this code. "struct index_state *" could be added to struct apply_state. But let's aim long term and put struct repository here instead so that we could even avoid more global states in the future. The index will be available via apply_state->repo->index. Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano diff --git a/apply.c b/apply.c index 572cd63..3704850 100644 --- a/apply.c +++ b/apply.c @@ -76,10 +76,12 @@ static int parse_ignorewhitespace_option(struct apply_state *state, } int init_apply_state(struct apply_state *state, + struct repository *repo, const char *prefix) { memset(state, 0, sizeof(*state)); state->prefix = prefix; + state->repo = repo; state->apply = 1; state->line_termination = '\n'; state->p_value = 1; diff --git a/apply.h b/apply.h index 01963b5..78c8bcf 100644 --- a/apply.h +++ b/apply.h @@ -1,6 +1,8 @@ #ifndef APPLY_H #define APPLY_H +struct repository; + enum apply_ws_error_action { nowarn_ws_error, warn_on_ws_error, @@ -62,6 +64,7 @@ struct apply_state { int unsafe_paths; /* Other non boolean parameters */ + struct repository *repo; const char *index_file; enum apply_verbosity apply_verbosity; const char *fake_ancestor; @@ -116,6 +119,7 @@ int apply_parse_options(int argc, const char **argv, int *force_apply, int *options, const char * const *apply_usage); int init_apply_state(struct apply_state *state, + struct repository *repo, const char *prefix); void clear_apply_state(struct apply_state *state); int check_apply_state(struct apply_state *state, int force_apply); diff --git a/builtin/am.c b/builtin/am.c index 2c19e69..9f7ecf6 100644 --- a/builtin/am.c +++ b/builtin/am.c @@ -1464,7 +1464,7 @@ static int run_apply(const struct am_state *state, const char *index_file) int force_apply = 0; int options = 0; - if (init_apply_state(&apply_state, NULL)) + if (init_apply_state(&apply_state, the_repository, NULL)) BUG("init_apply_state() failed"); argv_array_push(&apply_opts, "apply"); diff --git a/builtin/apply.c b/builtin/apply.c index 48d3989..3f099b9 100644 --- a/builtin/apply.c +++ b/builtin/apply.c @@ -16,7 +16,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix) int ret; struct apply_state state; - if (init_apply_state(&state, prefix)) + if (init_apply_state(&state, the_repository, prefix)) exit(128); argc = apply_parse_options(argc, argv, -- cgit v0.10.2-6-g49f6 From 1b5c6c1e5309e8be24ad4958baa2553a003ee45e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Th=C3=A1i=20Ng=E1=BB=8Dc=20Duy?= Date: Mon, 13 Aug 2018 18:14:40 +0200 Subject: apply.c: remove implicit dependency on the_index MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use apply_state->repo->index instead of the_index (in most cases, unless we need to use a temporary index in some functions). Let the callers (am and apply) tell us what to use, instead of always assuming to operate on the_index. Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano diff --git a/apply.c b/apply.c index 3704850..e485fbc 100644 --- a/apply.c +++ b/apply.c @@ -3385,7 +3385,8 @@ static int verify_index_match(struct apply_state *state, return -1; return 0; } - return ce_match_stat(ce, st, CE_MATCH_IGNORE_VALID|CE_MATCH_IGNORE_SKIP_WORKTREE); + return ie_match_stat(state->repo->index, ce, st, + CE_MATCH_IGNORE_VALID | CE_MATCH_IGNORE_SKIP_WORKTREE); } #define SUBMODULE_PATCH_WITHOUT_INDEX 1 @@ -3518,14 +3519,14 @@ static int load_current(struct apply_state *state, if (!patch->is_new) BUG("patch to %s is not a creation", patch->old_name); - pos = cache_name_pos(name, strlen(name)); + pos = index_name_pos(state->repo->index, name, strlen(name)); if (pos < 0) return error(_("%s: does not exist in index"), name); - ce = active_cache[pos]; + ce = state->repo->index->cache[pos]; if (lstat(name, &st)) { if (errno != ENOENT) return error_errno("%s", name); - if (checkout_target(&the_index, ce, &st)) + if (checkout_target(state->repo->index, ce, &st)) return -1; } if (verify_index_match(state, ce, &st)) @@ -3687,15 +3688,16 @@ static int check_preimage(struct apply_state *state, } if (state->check_index && !previous) { - int pos = cache_name_pos(old_name, strlen(old_name)); + int pos = index_name_pos(state->repo->index, old_name, + strlen(old_name)); if (pos < 0) { if (patch->is_new < 0) goto is_new; return error(_("%s: does not exist in index"), old_name); } - *ce = active_cache[pos]; + *ce = state->repo->index->cache[pos]; if (stat_ret < 0) { - if (checkout_target(&the_index, *ce, st)) + if (checkout_target(state->repo->index, *ce, st)) return -1; } if (!state->cached && verify_index_match(state, *ce, st)) @@ -3742,7 +3744,7 @@ static int check_to_create(struct apply_state *state, struct stat nst; if (state->check_index && - cache_name_pos(new_name, strlen(new_name)) >= 0 && + index_name_pos(state->repo->index, new_name, strlen(new_name)) >= 0 && !ok_if_exists) return EXISTS_IN_INDEX; if (state->cached) @@ -3831,7 +3833,8 @@ static int path_is_beyond_symlink_1(struct apply_state *state, struct strbuf *na if (state->check_index) { struct cache_entry *ce; - ce = cache_file_exists(name->buf, name->len, ignore_case); + ce = index_file_exists(state->repo->index, name->buf, + name->len, ignore_case); if (ce && S_ISLNK(ce->ce_mode)) return 1; } else { @@ -4006,9 +4009,10 @@ static int check_patch_list(struct apply_state *state, struct patch *patch) static int read_apply_cache(struct apply_state *state) { if (state->index_file) - return read_cache_from(state->index_file); + return read_index_from(state->repo->index, state->index_file, + get_git_dir()); else - return read_cache(); + return read_index(state->repo->index); } /* This function tries to read the object name from the current index */ @@ -4019,10 +4023,10 @@ static int get_current_oid(struct apply_state *state, const char *path, if (read_apply_cache(state) < 0) return -1; - pos = cache_name_pos(path, strlen(path)); + pos = index_name_pos(state->repo->index, path, strlen(path)); if (pos < 0) return -1; - oidcpy(oid, &active_cache[pos]->oid); + oidcpy(oid, &state->repo->index->cache[pos]->oid); return 0; } @@ -4250,7 +4254,7 @@ static void patch_stats(struct apply_state *state, struct patch *patch) static int remove_file(struct apply_state *state, struct patch *patch, int rmdir_empty) { if (state->update_index && !state->ita_only) { - if (remove_file_from_cache(patch->old_name) < 0) + if (remove_file_from_index(state->repo->index, patch->old_name) < 0) return error(_("unable to remove %s from index"), patch->old_name); } if (!state->cached) { @@ -4271,7 +4275,7 @@ static int add_index_file(struct apply_state *state, struct cache_entry *ce; int namelen = strlen(path); - ce = make_empty_cache_entry(&the_index, namelen); + ce = make_empty_cache_entry(state->repo->index, namelen); memcpy(ce->name, path, namelen); ce->ce_mode = create_ce_mode(mode); ce->ce_flags = create_ce_flags(0); @@ -4303,7 +4307,7 @@ static int add_index_file(struct apply_state *state, "for newly created file %s"), path); } } - if (add_cache_entry(ce, ADD_CACHE_OK_TO_ADD) < 0) { + if (add_index_entry(state->repo->index, ce, ADD_CACHE_OK_TO_ADD) < 0) { discard_cache_entry(ce); return error(_("unable to add cache entry for %s"), path); } @@ -4341,7 +4345,7 @@ static int try_create_file(struct apply_state *state, const char *path, if (fd < 0) return 1; - if (convert_to_working_tree(&the_index, path, buf, size, &nbuf)) { + if (convert_to_working_tree(state->repo->index, path, buf, size, &nbuf)) { size = nbuf.len; buf = nbuf.buf; } @@ -4438,17 +4442,17 @@ static int add_conflicted_stages_file(struct apply_state *state, namelen = strlen(patch->new_name); mode = patch->new_mode ? patch->new_mode : (S_IFREG | 0644); - remove_file_from_cache(patch->new_name); + remove_file_from_index(state->repo->index, patch->new_name); for (stage = 1; stage < 4; stage++) { if (is_null_oid(&patch->threeway_stage[stage - 1])) continue; - ce = make_empty_cache_entry(&the_index, namelen); + ce = make_empty_cache_entry(state->repo->index, namelen); memcpy(ce->name, patch->new_name, namelen); ce->ce_mode = create_ce_mode(mode); ce->ce_flags = create_ce_flags(stage); ce->ce_namelen = namelen; oidcpy(&ce->oid, &patch->threeway_stage[stage - 1]); - if (add_cache_entry(ce, ADD_CACHE_OK_TO_ADD) < 0) { + if (add_index_entry(state->repo->index, ce, ADD_CACHE_OK_TO_ADD) < 0) { discard_cache_entry(ce); return error(_("unable to add cache entry for %s"), patch->new_name); @@ -4897,7 +4901,7 @@ int apply_all_patches(struct apply_state *state, } if (state->update_index) { - res = write_locked_index(&the_index, &state->lock_file, COMMIT_LOCK); + res = write_locked_index(state->repo->index, &state->lock_file, COMMIT_LOCK); if (res) { error(_("Unable to write new index file")); res = -128; -- cgit v0.10.2-6-g49f6 From ecbbc0a53b0393c3b835440b397dedfa9d28ec01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Th=C3=A1i=20Ng=E1=BB=8Dc=20Duy?= Date: Mon, 13 Aug 2018 18:14:41 +0200 Subject: blame.c: remove implicit dependency on the_index MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Side note, since we gain access to the right repository, we can stop rely on the_repository in this code as well. Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano diff --git a/blame.c b/blame.c index 58a7036..08c0c6c 100644 --- a/blame.c +++ b/blame.c @@ -90,7 +90,8 @@ static struct blame_origin *get_origin(struct commit *commit, const char *path) -static void verify_working_tree_path(struct commit *work_tree, const char *path) +static void verify_working_tree_path(struct repository *repo, + struct commit *work_tree, const char *path) { struct commit_list *parents; int pos; @@ -101,15 +102,15 @@ static void verify_working_tree_path(struct commit *work_tree, const char *path) unsigned mode; if (!get_tree_entry(commit_oid, path, &blob_oid, &mode) && - oid_object_info(the_repository, &blob_oid, NULL) == OBJ_BLOB) + oid_object_info(repo, &blob_oid, NULL) == OBJ_BLOB) return; } - pos = cache_name_pos(path, strlen(path)); + pos = index_name_pos(repo->index, path, strlen(path)); if (pos >= 0) ; /* path is in the index */ - else if (-1 - pos < active_nr && - !strcmp(active_cache[-1 - pos]->name, path)) + else if (-1 - pos < repo->index->cache_nr && + !strcmp(repo->index->cache[-1 - pos]->name, path)) ; /* path is in the index, unmerged */ else die("no such path '%s' in HEAD", path); @@ -165,7 +166,8 @@ static void set_commit_buffer_from_strbuf(struct commit *c, struct strbuf *sb) * Prepare a dummy commit that represents the work tree (or staged) item. * Note that annotating work tree item never works in the reverse. */ -static struct commit *fake_working_tree_commit(struct diff_options *opt, +static struct commit *fake_working_tree_commit(struct repository *repo, + struct diff_options *opt, const char *path, const char *contents_from) { @@ -181,7 +183,7 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt, unsigned mode; struct strbuf msg = STRBUF_INIT; - read_cache(); + read_index(repo->index); time(&now); commit = alloc_commit_node(the_repository); commit->object.parsed = 1; @@ -193,7 +195,7 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt, parent_tail = append_parent(parent_tail, &head_oid); append_merge_parents(parent_tail); - verify_working_tree_path(commit, path); + verify_working_tree_path(repo, commit, path); origin = make_origin(commit, path); @@ -251,7 +253,7 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt, if (strbuf_read(&buf, 0, 0) < 0) die_errno("failed to read from stdin"); } - convert_to_git(&the_index, path, buf.buf, buf.len, &buf, 0); + convert_to_git(repo->index, path, buf.buf, buf.len, &buf, 0); origin->file.ptr = buf.buf; origin->file.size = buf.len; pretend_object_file(buf.buf, buf.len, OBJ_BLOB, &origin->blob_oid); @@ -262,27 +264,28 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt, * bits; we are not going to write this index out -- we just * want to run "diff-index --cached". */ - discard_cache(); - read_cache(); + discard_index(repo->index); + read_index(repo->index); len = strlen(path); if (!mode) { - int pos = cache_name_pos(path, len); + int pos = index_name_pos(repo->index, path, len); if (0 <= pos) - mode = active_cache[pos]->ce_mode; + mode = repo->index->cache[pos]->ce_mode; else /* Let's not bother reading from HEAD tree */ mode = S_IFREG | 0644; } - ce = make_empty_cache_entry(&the_index, len); + ce = make_empty_cache_entry(repo->index, len); oidcpy(&ce->oid, &origin->blob_oid); memcpy(ce->name, path, len); ce->ce_flags = create_ce_flags(0); ce->ce_namelen = len; ce->ce_mode = create_ce_mode(mode); - add_cache_entry(ce, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE); + add_index_entry(repo->index, ce, + ADD_CACHE_OK_TO_ADD | ADD_CACHE_OK_TO_REPLACE); - cache_tree_invalidate_path(&the_index, path); + cache_tree_invalidate_path(repo->index, path); return commit; } @@ -519,13 +522,14 @@ static void queue_blames(struct blame_scoreboard *sb, struct blame_origin *porig * * This also fills origin->mode for corresponding tree path. */ -static int fill_blob_sha1_and_mode(struct blame_origin *origin) +static int fill_blob_sha1_and_mode(struct repository *repo, + struct blame_origin *origin) { if (!is_null_oid(&origin->blob_oid)) return 0; if (get_tree_entry(&origin->commit->object.oid, origin->path, &origin->blob_oid, &origin->mode)) goto error_out; - if (oid_object_info(the_repository, &origin->blob_oid, NULL) != OBJ_BLOB) + if (oid_object_info(repo, &origin->blob_oid, NULL) != OBJ_BLOB) goto error_out; return 0; error_out: @@ -1767,7 +1771,9 @@ void init_scoreboard(struct blame_scoreboard *sb) sb->copy_score = BLAME_DEFAULT_COPY_SCORE; } -void setup_scoreboard(struct blame_scoreboard *sb, const char *path, struct blame_origin **orig) +void setup_scoreboard(struct blame_scoreboard *sb, + const char *path, + struct blame_origin **orig) { const char *final_commit_name = NULL; struct blame_origin *o; @@ -1779,6 +1785,9 @@ void setup_scoreboard(struct blame_scoreboard *sb, const char *path, struct blam if (sb->reverse && sb->contents_from) die(_("--contents and --reverse do not blend well.")); + if (!sb->repo) + BUG("repo is NULL"); + if (!sb->reverse) { sb->final = find_single_final(sb->revs, &final_commit_name); sb->commits.compare = compare_commits_by_commit_date; @@ -1800,7 +1809,8 @@ void setup_scoreboard(struct blame_scoreboard *sb, const char *path, struct blam * or "--contents". */ setup_work_tree(); - sb->final = fake_working_tree_commit(&sb->revs->diffopt, + sb->final = fake_working_tree_commit(sb->repo, + &sb->revs->diffopt, path, sb->contents_from); add_pending_object(sb->revs, &(sb->final->object), ":"); } @@ -1845,7 +1855,7 @@ void setup_scoreboard(struct blame_scoreboard *sb, const char *path, struct blam } else { o = get_origin(sb->final, path); - if (fill_blob_sha1_and_mode(o)) + if (fill_blob_sha1_and_mode(sb->repo, o)) die(_("no such path %s in %s"), path, final_commit_name); if (sb->revs->diffopt.flags.allow_textconv && diff --git a/blame.h b/blame.h index 9b5240f..be3a895 100644 --- a/blame.h +++ b/blame.h @@ -102,6 +102,7 @@ struct blame_scoreboard { struct commit *final; /* Priority queue for commits with unassigned blame records */ struct prio_queue commits; + struct repository *repo; struct rev_info *revs; const char *path; diff --git a/builtin/blame.c b/builtin/blame.c index 5c93d16..cbbcb26 100644 --- a/builtin/blame.c +++ b/builtin/blame.c @@ -988,6 +988,7 @@ parse_done: sb.revs = &revs; sb.contents_from = contents_from; sb.reverse = reverse; + sb.repo = the_repository; setup_scoreboard(&sb, path, &o); lno = sb.num_lines; -- cgit v0.10.2-6-g49f6