diff options
87 files changed, 751 insertions, 552 deletions
diff --git a/Documentation/technical/api-diff.txt b/Documentation/technical/api-diff.txt index 8b001de0db..30fc0e9c93 100644 --- a/Documentation/technical/api-diff.txt +++ b/Documentation/technical/api-diff.txt @@ -18,8 +18,8 @@ Calling sequence ---------------- * Prepare `struct diff_options` to record the set of diff options, and - then call `diff_setup()` to initialize this structure. This sets up - the vanilla default. + then call `repo_diff_setup()` to initialize this structure. This + sets up the vanilla default. * Fill in the options structure to specify desired output format, rename detection, etc. `diff_opt_parse()` can be used to parse options given diff --git a/Documentation/technical/api-revision-walking.txt b/Documentation/technical/api-revision-walking.txt index 55b878ade8..03f9ea6ac4 100644 --- a/Documentation/technical/api-revision-walking.txt +++ b/Documentation/technical/api-revision-walking.txt @@ -15,9 +15,9 @@ revision list. Functions --------- -`init_revisions`:: +`repo_init_revisions`:: - Initialize a rev_info structure with default values. The second + Initialize a rev_info structure with default values. The third parameter may be NULL or can be prefix path, and then the `.prefix` variable will be set to it. This is typically the first function you want to call when you want to deal with a revision list. After calling @@ -2131,10 +2131,12 @@ static int parse_chunk(struct apply_state *state, char *buffer, unsigned long si if (!use_patch(state, patch)) patch->ws_rule = 0; + else if (patch->new_name) + patch->ws_rule = whitespace_rule(state->repo->index, + patch->new_name); else - patch->ws_rule = whitespace_rule(patch->new_name - ? patch->new_name - : patch->old_name); + patch->ws_rule = whitespace_rule(state->repo->index, + patch->old_name); patchsize = parse_single_patch(state, buffer + offset + hdrsize, @@ -3467,7 +3469,8 @@ static int load_preimage(struct apply_state *state, return 0; } -static int three_way_merge(struct image *image, +static int three_way_merge(struct apply_state *state, + struct image *image, char *path, const struct object_id *base, const struct object_id *ours, @@ -3483,7 +3486,9 @@ static int three_way_merge(struct image *image, status = ll_merge(&result, path, &base_file, "base", &our_file, "ours", - &their_file, "theirs", NULL); + &their_file, "theirs", + state->repo->index, + NULL); free(base_file.ptr); free(our_file.ptr); free(their_file.ptr); @@ -3595,7 +3600,7 @@ static int try_threeway(struct apply_state *state, clear_image(&tmp_image); /* in-core three-way merge between post and our using pre as base */ - status = three_way_merge(image, patch->new_name, + status = three_way_merge(state, image, patch->new_name, &pre_oid, &our_oid, &post_oid); if (status < 0) { if (state->apply_verbosity > verbosity_silent) @@ -4627,7 +4632,7 @@ static int write_out_results(struct apply_state *state, struct patch *list) } string_list_clear(&cpath, 0); - rerere(0); + repo_rerere(state->repo, 0); } return errs; diff --git a/archive-zip.c b/archive-zip.c index 5a62351ab1..155ee4a779 100644 --- a/archive-zip.c +++ b/archive-zip.c @@ -264,9 +264,10 @@ static int has_only_ascii(const char *s) } } -static int entry_is_binary(const char *path, const void *buffer, size_t size) +static int entry_is_binary(struct index_state *istate, const char *path, + const void *buffer, size_t size) { - struct userdiff_driver *driver = userdiff_find_by_path(path); + struct userdiff_driver *driver = userdiff_find_by_path(istate, path); if (!driver) driver = userdiff_find_by_name("default"); if (driver->binary != -1) @@ -352,7 +353,8 @@ static int write_zip_entry(struct archiver_args *args, return error(_("cannot read %s"), oid_to_hex(oid)); crc = crc32(crc, buffer, size); - is_binary = entry_is_binary(path_without_prefix, + is_binary = entry_is_binary(args->repo->index, + path_without_prefix, buffer, size); out = buffer; } @@ -428,7 +430,8 @@ static int write_zip_entry(struct archiver_args *args, break; crc = crc32(crc, buf, readlen); if (is_binary == -1) - is_binary = entry_is_binary(path_without_prefix, + is_binary = entry_is_binary(args->repo->index, + path_without_prefix, buf, readlen); write_or_die(1, buf, readlen); } @@ -460,7 +463,8 @@ static int write_zip_entry(struct archiver_args *args, break; crc = crc32(crc, buf, readlen); if (is_binary == -1) - is_binary = entry_is_binary(path_without_prefix, + is_binary = entry_is_binary(args->repo->index, + path_without_prefix, buf, readlen); zstream.next_in = buf; @@ -392,7 +392,7 @@ static void parse_treeish_arg(const char **argv, if (get_oid(name, &oid)) die("Not a valid object name"); - commit = lookup_commit_reference_gently(the_repository, &oid, 1); + commit = lookup_commit_reference_gently(ar_args->repo, &oid, 1); if (commit) { commit_sha1 = commit->object.oid.hash; archive_time = commit->date; @@ -633,7 +633,7 @@ static void bisect_rev_setup(struct rev_info *revs, const char *prefix, struct argv_array rev_argv = ARGV_ARRAY_INIT; int i; - init_revisions(revs, prefix); + repo_init_revisions(the_repository, revs, prefix); revs->abbrev = 0; revs->commit_format = CMIT_FMT_UNSPECIFIED; @@ -890,7 +890,7 @@ static void show_diff_tree(const char *prefix, struct commit *commit) struct rev_info opt; /* diff-tree init */ - init_revisions(&opt, prefix); + repo_init_revisions(the_repository, &opt, prefix); git_config(git_diff_basic_config, NULL); /* no "diff" UI options */ opt.abbrev = 0; opt.diff = 1; @@ -90,7 +90,7 @@ static struct blame_origin *get_origin(struct commit *commit, const char *path) -static void verify_working_tree_path(struct repository *repo, +static void verify_working_tree_path(struct repository *r, struct commit *work_tree, const char *path) { struct commit_list *parents; @@ -102,15 +102,15 @@ static void verify_working_tree_path(struct repository *repo, unsigned mode; if (!get_tree_entry(commit_oid, path, &blob_oid, &mode) && - oid_object_info(repo, &blob_oid, NULL) == OBJ_BLOB) + oid_object_info(r, &blob_oid, NULL) == OBJ_BLOB) return; } - pos = index_name_pos(repo->index, path, strlen(path)); + pos = index_name_pos(r->index, path, strlen(path)); if (pos >= 0) ; /* path is in the index */ - else if (-1 - pos < repo->index->cache_nr && - !strcmp(repo->index->cache[-1 - pos]->name, path)) + else if (-1 - pos < r->index->cache_nr && + !strcmp(r->index->cache[-1 - pos]->name, path)) ; /* path is in the index, unmerged */ else die("no such path '%s' in HEAD", path); @@ -166,7 +166,7 @@ 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 repository *repo, +static struct commit *fake_working_tree_commit(struct repository *r, struct diff_options *opt, const char *path, const char *contents_from) @@ -183,7 +183,7 @@ static struct commit *fake_working_tree_commit(struct repository *repo, unsigned mode; struct strbuf msg = STRBUF_INIT; - read_index(repo->index); + read_index(r->index); time(&now); commit = alloc_commit_node(the_repository); commit->object.parsed = 1; @@ -195,7 +195,7 @@ static struct commit *fake_working_tree_commit(struct repository *repo, parent_tail = append_parent(parent_tail, &head_oid); append_merge_parents(parent_tail); - verify_working_tree_path(repo, commit, path); + verify_working_tree_path(r, commit, path); origin = make_origin(commit, path); @@ -234,7 +234,7 @@ static struct commit *fake_working_tree_commit(struct repository *repo, switch (st.st_mode & S_IFMT) { case S_IFREG: if (opt->flags.allow_textconv && - textconv_object(read_from, mode, &null_oid, 0, &buf_ptr, &buf_len)) + textconv_object(r, read_from, mode, &null_oid, 0, &buf_ptr, &buf_len)) strbuf_attach(&buf, buf_ptr, buf_len, buf_len + 1); else if (strbuf_read_file(&buf, read_from, st.st_size) != st.st_size) die_errno("cannot open or read '%s'", read_from); @@ -253,7 +253,7 @@ static struct commit *fake_working_tree_commit(struct repository *repo, if (strbuf_read(&buf, 0, 0) < 0) die_errno("failed to read from stdin"); } - convert_to_git(repo->index, path, buf.buf, buf.len, &buf, 0); + convert_to_git(r->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); @@ -264,28 +264,28 @@ static struct commit *fake_working_tree_commit(struct repository *repo, * bits; we are not going to write this index out -- we just * want to run "diff-index --cached". */ - discard_index(repo->index); - read_index(repo->index); + discard_index(r->index); + read_index(r->index); len = strlen(path); if (!mode) { - int pos = index_name_pos(repo->index, path, len); + int pos = index_name_pos(r->index, path, len); if (0 <= pos) - mode = repo->index->cache[pos]->ce_mode; + mode = r->index->cache[pos]->ce_mode; else /* Let's not bother reading from HEAD tree */ mode = S_IFREG | 0644; } - ce = make_empty_cache_entry(repo->index, len); + ce = make_empty_cache_entry(r->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_index_entry(repo->index, ce, + add_index_entry(r->index, ce, ADD_CACHE_OK_TO_ADD | ADD_CACHE_OK_TO_REPLACE); - cache_tree_invalidate_path(repo->index, path); + cache_tree_invalidate_path(r->index, path); return commit; } @@ -318,7 +318,8 @@ static void fill_origin_blob(struct diff_options *opt, (*num_read_blob)++; if (opt->flags.allow_textconv && - textconv_object(o->path, o->mode, &o->blob_oid, 1, &file->ptr, &file_size)) + textconv_object(opt->repo, o->path, o->mode, + &o->blob_oid, 1, &file->ptr, &file_size)) ; else file->ptr = read_object_file(&o->blob_oid, &type, @@ -520,14 +521,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 repository *repo, +static int fill_blob_sha1_and_mode(struct repository *r, 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(repo, &origin->blob_oid, NULL) != OBJ_BLOB) + if (oid_object_info(r, &origin->blob_oid, NULL) != OBJ_BLOB) goto error_out; return 0; error_out: @@ -540,8 +541,9 @@ static int fill_blob_sha1_and_mode(struct repository *repo, * We have an origin -- check if the same path exists in the * parent and return an origin structure to represent it. */ -static struct blame_origin *find_origin(struct commit *parent, - struct blame_origin *origin) +static struct blame_origin *find_origin(struct repository *r, + struct commit *parent, + struct blame_origin *origin) { struct blame_origin *porigin; struct diff_options diff_opts; @@ -561,7 +563,7 @@ static struct blame_origin *find_origin(struct commit *parent, * and origin first. Most of the time they are the * same and diff-tree is fairly efficient about this. */ - diff_setup(&diff_opts); + repo_diff_setup(r, &diff_opts); diff_opts.flags.recursive = 1; diff_opts.detect_rename = 0; diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT; @@ -628,14 +630,15 @@ static struct blame_origin *find_origin(struct commit *parent, * We have an origin -- find the path that corresponds to it in its * parent and return an origin structure to represent it. */ -static struct blame_origin *find_rename(struct commit *parent, - struct blame_origin *origin) +static struct blame_origin *find_rename(struct repository *r, + struct commit *parent, + struct blame_origin *origin) { struct blame_origin *porigin = NULL; struct diff_options diff_opts; int i; - diff_setup(&diff_opts); + repo_diff_setup(r, &diff_opts); diff_opts.flags.recursive = 1; diff_opts.detect_rename = DIFF_DETECT_RENAME; diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT; @@ -1259,7 +1262,7 @@ static void find_copy_in_parent(struct blame_scoreboard *sb, if (!unblamed) return; /* nothing remains for this target */ - diff_setup(&diff_opts); + repo_diff_setup(sb->repo, &diff_opts); diff_opts.flags.recursive = 1; diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT; @@ -1441,7 +1444,7 @@ static void pass_blame(struct blame_scoreboard *sb, struct blame_origin *origin, * common cases, then we look for renames in the second pass. */ for (pass = 0; pass < 2 - sb->no_whole_file_rename; pass++) { - struct blame_origin *(*find)(struct commit *, struct blame_origin *); + struct blame_origin *(*find)(struct repository *, struct commit *, struct blame_origin *); find = pass ? find_rename : find_origin; for (i = 0, sg = first_scapegoat(revs, commit, sb->reverse); @@ -1454,7 +1457,7 @@ static void pass_blame(struct blame_scoreboard *sb, struct blame_origin *origin, continue; if (parse_commit(p)) continue; - porigin = find(p, origin); + porigin = find(sb->repo, p, origin); if (!porigin) continue; if (oideq(&porigin->blob_oid, &origin->blob_oid)) { @@ -1857,7 +1860,7 @@ void setup_scoreboard(struct blame_scoreboard *sb, die(_("no such path %s in %s"), path, final_commit_name); if (sb->revs->diffopt.flags.allow_textconv && - textconv_object(path, o->mode, &o->blob_oid, 1, (char **) &sb->final_buf, + textconv_object(sb->repo, path, o->mode, &o->blob_oid, 1, (char **) &sb->final_buf, &sb->final_buf_size)) ; else diff --git a/builtin/add.c b/builtin/add.c index 0b64bcdebe..ad49806ebf 100644 --- a/builtin/add.c +++ b/builtin/add.c @@ -110,7 +110,7 @@ int add_files_to_cache(const char *prefix, memset(&data, 0, sizeof(data)); data.flags = flags; - init_revisions(&rev, prefix); + repo_init_revisions(the_repository, &rev, prefix); setup_revisions(0, NULL, &rev, NULL); if (pathspec) copy_pathspec(&rev.prune_data, pathspec); @@ -232,7 +232,7 @@ static int edit_patch(int argc, const char **argv, const char *prefix) if (read_cache() < 0) die(_("Could not read the index")); - init_revisions(&rev, prefix); + repo_init_revisions(the_repository, &rev, prefix); rev.diffopt.context = 7; argc = setup_revisions(argc, argv, &rev, NULL); diff --git a/builtin/am.c b/builtin/am.c index 5e643e2a3e..d79f092a96 100644 --- a/builtin/am.c +++ b/builtin/am.c @@ -1376,7 +1376,7 @@ static void write_commit_patch(const struct am_state *state, struct commit *comm FILE *fp; fp = xfopen(am_path(state, "patch"), "w"); - init_revisions(&rev_info, NULL); + repo_init_revisions(the_repository, &rev_info, NULL); rev_info.diff = 1; rev_info.abbrev = 0; rev_info.disable_stdin = 1; @@ -1411,7 +1411,7 @@ static void write_index_patch(const struct am_state *state) the_repository->hash_algo->empty_tree); fp = xfopen(am_path(state, "patch"), "w"); - init_revisions(&rev_info, NULL); + repo_init_revisions(the_repository, &rev_info, NULL); rev_info.diff = 1; rev_info.disable_stdin = 1; rev_info.no_commit_id = 1; @@ -1569,7 +1569,7 @@ static int fall_back_threeway(const struct am_state *state, const char *index_pa struct rev_info rev_info; const char *diff_filter_str = "--diff-filter=AM"; - init_revisions(&rev_info, NULL); + repo_init_revisions(the_repository, &rev_info, NULL); rev_info.diffopt.output_format = DIFF_FORMAT_NAME_STATUS; diff_opt_parse(&rev_info.diffopt, &diff_filter_str, 1, rev_info.prefix); add_pending_oid(&rev_info, "HEAD", &our_tree, 0); @@ -1608,7 +1608,7 @@ static int fall_back_threeway(const struct am_state *state, const char *index_pa o.verbosity = 0; if (merge_recursive_generic(&o, &our_tree, &their_tree, 1, bases, &result)) { - rerere(state->allow_rerere_autoupdate); + repo_rerere(the_repository, state->allow_rerere_autoupdate); free(their_tree_name); return error(_("Failed to merge in the changes.")); } @@ -1903,7 +1903,7 @@ static void am_resolve(struct am_state *state) goto next; } - rerere(0); + repo_rerere(the_repository, 0); do_commit(state); diff --git a/builtin/blame.c b/builtin/blame.c index c2da673ac8..a443af9ee9 100644 --- a/builtin/blame.c +++ b/builtin/blame.c @@ -830,7 +830,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix) setup_default_color_by_age(); git_config(git_blame_config, &output_option); - init_revisions(&revs, NULL); + repo_init_revisions(the_repository, &revs, NULL); revs.date_mode = blame_date_mode; revs.diffopt.flags.allow_textconv = 1; revs.diffopt.flags.follow_renames = 1; @@ -1001,7 +1001,7 @@ parse_done: long bottom, top; if (parse_range_arg(range_list.items[range_i].string, nth_line_cb, &sb, lno, anchor, - &bottom, &top, sb.path)) + &bottom, &top, sb.path, &the_index)) usage(blame_usage); if ((!lno && (top || bottom)) || lno < bottom) die(Q_("file %s has only %lu line", diff --git a/builtin/cat-file.c b/builtin/cat-file.c index 64ec1745ab..8d97c84725 100644 --- a/builtin/cat-file.c +++ b/builtin/cat-file.c @@ -113,7 +113,8 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name, die("git cat-file --textconv %s: <object> must be <sha1:path>", obj_name); - if (textconv_object(path, obj_context.mode, &oid, 1, &buf, &size)) + if (textconv_object(the_repository, path, obj_context.mode, + &oid, 1, &buf, &size)) break; /* else fallthrough */ @@ -305,7 +306,8 @@ static void print_object_or_die(struct batch_options *opt, struct expand_data *d oid_to_hex(oid), data->rest); } else if (opt->cmdmode == 'c') { enum object_type type; - if (!textconv_object(data->rest, 0100644, oid, + if (!textconv_object(the_repository, + data->rest, 0100644, oid, 1, &contents, &size)) contents = read_object_file(oid, &type, diff --git a/builtin/checkout.c b/builtin/checkout.c index 902c06702c..acdafc6e4c 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -214,7 +214,8 @@ static int checkout_merged(int pos, const struct checkout *state) * merge.renormalize set, too */ status = ll_merge(&result_buf, path, &ancestor, "base", - &ours, "ours", &theirs, "theirs", NULL); + &ours, "ours", &theirs, "theirs", + state->istate, NULL); free(ancestor.ptr); free(ours.ptr); free(theirs.ptr); @@ -397,7 +398,7 @@ static void show_local_changes(struct object *head, { struct rev_info rev; /* I think we want full paths, even if we're in a subdirectory. */ - init_revisions(&rev, NULL); + repo_init_revisions(the_repository, &rev, NULL); rev.diffopt.flags = opts->flags; rev.diffopt.output_format |= DIFF_FORMAT_NAME_STATUS; diff_setup_done(&rev.diffopt); @@ -899,7 +900,7 @@ static void orphaned_commit_warning(struct commit *old_commit, struct commit *ne struct rev_info revs; struct object *object = &old_commit->object; - init_revisions(&revs, NULL); + repo_init_revisions(the_repository, &revs, NULL); setup_revisions(0, NULL, &revs, NULL); object->flags &= ~UNINTERESTING; diff --git a/builtin/commit.c b/builtin/commit.c index 1d5292e4d8..79d557fb2b 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -983,7 +983,7 @@ static const char *find_author_by_nickname(const char *name) const char *av[20]; int ac = 0; - init_revisions(&revs, NULL); + repo_init_revisions(the_repository, &revs, NULL); strbuf_addf(&buf, "--author=%s", name); av[++ac] = "--all"; av[++ac] = "-i"; @@ -1657,7 +1657,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix) if (git_env_bool(GIT_TEST_COMMIT_GRAPH, 0)) write_commit_graph_reachable(get_object_directory(), 0, 0); - rerere(0); + repo_rerere(the_repository, 0); run_command_v_opt(argv_gc_auto, RUN_GIT_CMD); run_commit_hook(use_editor, get_index_file(), "post-commit", NULL); if (amend && !no_post_rewrite) { diff --git a/builtin/describe.c b/builtin/describe.c index 22c0541da5..c48c34e866 100644 --- a/builtin/describe.c +++ b/builtin/describe.c @@ -488,7 +488,7 @@ static void describe_blob(struct object_id oid, struct strbuf *dst) "--objects", "--in-commit-order", "--reverse", "HEAD", NULL); - init_revisions(&revs, NULL); + repo_init_revisions(the_repository, &revs, NULL); if (setup_revisions(args.argc, args.argv, &revs, NULL) > 1) BUG("setup_revisions could not handle all args?"); @@ -636,7 +636,7 @@ int cmd_describe(int argc, const char **argv, const char *prefix) if (0 <= fd) update_index_if_able(&the_index, &index_lock); - init_revisions(&revs, prefix); + repo_init_revisions(the_repository, &revs, prefix); argv_array_pushv(&args, diff_index_args); if (setup_revisions(args.argc, args.argv, &revs, NULL) != 1) BUG("malformed internal diff-index command line"); diff --git a/builtin/diff-files.c b/builtin/diff-files.c index e88493ffe5..48cfcb935d 100644 --- a/builtin/diff-files.c +++ b/builtin/diff-files.c @@ -25,7 +25,7 @@ int cmd_diff_files(int argc, const char **argv, const char *prefix) usage(diff_files_usage); git_config(git_diff_basic_config, NULL); /* no "diff" UI options */ - init_revisions(&rev, prefix); + repo_init_revisions(the_repository, &rev, prefix); rev.abbrev = 0; precompose_argv(argc, argv); diff --git a/builtin/diff-index.c b/builtin/diff-index.c index 522f4fdffd..fcccd1f10d 100644 --- a/builtin/diff-index.c +++ b/builtin/diff-index.c @@ -22,7 +22,7 @@ int cmd_diff_index(int argc, const char **argv, const char *prefix) usage(diff_cache_usage); git_config(git_diff_basic_config, NULL); /* no "diff" UI options */ - init_revisions(&rev, prefix); + repo_init_revisions(the_repository, &rev, prefix); rev.abbrev = 0; precompose_argv(argc, argv); diff --git a/builtin/diff-tree.c b/builtin/diff-tree.c index d07bf2e4c4..ef996126d7 100644 --- a/builtin/diff-tree.c +++ b/builtin/diff-tree.c @@ -110,7 +110,7 @@ int cmd_diff_tree(int argc, const char **argv, const char *prefix) usage(diff_tree_usage); git_config(git_diff_basic_config, NULL); /* no "diff" UI options */ - init_revisions(opt, prefix); + repo_init_revisions(the_repository, opt, prefix); if (read_cache() < 0) die(_("index file corrupt")); opt->abbrev = 0; diff --git a/builtin/diff.c b/builtin/diff.c index b3a8ba488f..f0393bba23 100644 --- a/builtin/diff.c +++ b/builtin/diff.c @@ -318,7 +318,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix) git_config(git_diff_ui_config, NULL); precompose_argv(argc, argv); - init_revisions(&rev, prefix); + repo_init_revisions(the_repository, &rev, prefix); if (no_index && argc != i + 2) { if (no_index == DIFF_NO_INDEX_IMPLICIT) { @@ -339,7 +339,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix) } if (no_index) /* If this is a no-index diff, just run it and exit there. */ - diff_no_index(&rev, argc, argv); + diff_no_index(the_repository, &rev, argc, argv); /* Otherwise, we are doing the usual "git" diff */ rev.diffopt.skip_stat_unmatch = !!diff_auto_refresh_index; diff --git a/builtin/difftool.c b/builtin/difftool.c index b41a9199ff..544b0e8639 100644 --- a/builtin/difftool.c +++ b/builtin/difftool.c @@ -112,7 +112,7 @@ static int use_wt_file(const char *workdir, const char *name, int fd = open(buf.buf, O_RDONLY); if (fd >= 0 && - !index_fd(&wt_oid, fd, &st, OBJ_BLOB, name, 0)) { + !index_fd(&the_index, &wt_oid, fd, &st, OBJ_BLOB, name, 0)) { if (is_null_oid(oid)) { oidcpy(oid, &wt_oid); use = 1; diff --git a/builtin/fast-export.c b/builtin/fast-export.c index 74f3bf5c96..456797c12a 100644 --- a/builtin/fast-export.c +++ b/builtin/fast-export.c @@ -1033,7 +1033,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix) /* we handle encodings */ git_config(git_default_config, NULL); - init_revisions(&revs, prefix); + repo_init_revisions(the_repository, &revs, prefix); init_revision_sources(&revision_sources); revs.topo_order = 1; revs.sources = &revision_sources; diff --git a/builtin/fmt-merge-msg.c b/builtin/fmt-merge-msg.c index 59a40342b6..a4615587fd 100644 --- a/builtin/fmt-merge-msg.c +++ b/builtin/fmt-merge-msg.c @@ -643,7 +643,7 @@ int fmt_merge_msg(struct strbuf *in, struct strbuf *out, struct rev_info rev; head = lookup_commit_or_die(&head_oid, "HEAD"); - init_revisions(&rev, NULL); + repo_init_revisions(the_repository, &rev, NULL); rev.commit_format = CMIT_FMT_ONELINE; rev.ignore_merges = 1; rev.limited = 1; diff --git a/builtin/grep.c b/builtin/grep.c index 601f801158..0c3527242e 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -103,7 +103,8 @@ static void add_work(struct grep_opt *opt, const struct grep_source *gs) todo[todo_end].source = *gs; if (opt->binary != GREP_BINARY_TEXT) - grep_source_load_driver(&todo[todo_end].source); + grep_source_load_driver(&todo[todo_end].source, + opt->repo->index); todo[todo_end].done = 0; strbuf_reset(&todo[todo_end].out); todo_end = (todo_end + 1) % ARRAY_SIZE(todo); @@ -904,9 +905,9 @@ int cmd_grep(int argc, const char **argv, const char *prefix) OPT_END() }; - init_grep_defaults(); + init_grep_defaults(the_repository); git_config(grep_cmd_config, NULL); - grep_init(&opt, prefix); + grep_init(&opt, the_repository, prefix); /* * If there is no -- then the paths must exist in the working diff --git a/builtin/hash-object.c b/builtin/hash-object.c index 9ada4f4dfd..d6f06ea32f 100644 --- a/builtin/hash-object.c +++ b/builtin/hash-object.c @@ -40,7 +40,7 @@ static void hash_fd(int fd, const char *type, const char *path, unsigned flags, if (fstat(fd, &st) < 0 || (literally ? hash_literally(&oid, fd, type, flags) - : index_fd(&oid, fd, &st, type_from_string(type), path, flags))) + : index_fd(&the_index, &oid, fd, &st, type_from_string(type), path, flags))) die((flags & HASH_WRITE_OBJECT) ? "Unable to add %s to database" : "Unable to hash %s", path); diff --git a/builtin/log.c b/builtin/log.c index 1dbb9d829b..061d4fd864 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -118,7 +118,7 @@ static int log_line_range_callback(const struct option *option, const char *arg, static void init_log_defaults(void) { - init_grep_defaults(); + init_grep_defaults(the_repository); init_diff_ui_defaults(); decoration_style = auto_decoration_style(); @@ -470,7 +470,7 @@ int cmd_whatchanged(int argc, const char **argv, const char *prefix) init_log_defaults(); git_config(git_log_config, NULL); - init_revisions(&rev, prefix); + repo_init_revisions(the_repository, &rev, prefix); rev.diff = 1; rev.simplify_history = 0; memset(&opt, 0, sizeof(opt)); @@ -510,7 +510,8 @@ static int show_blob_object(const struct object_id *oid, struct rev_info *rev, c &oidc, &obj_context)) die(_("Not a valid object name %s"), obj_name); if (!obj_context.path || - !textconv_object(obj_context.path, obj_context.mode, &oidc, 1, &buf, &size)) { + !textconv_object(the_repository, obj_context.path, + obj_context.mode, &oidc, 1, &buf, &size)) { free(obj_context.path); return stream_blob_to_fd(1, oid, NULL, 0); } @@ -587,7 +588,7 @@ int cmd_show(int argc, const char **argv, const char *prefix) git_config(git_log_config, NULL); memset(&match_all, 0, sizeof(match_all)); - init_revisions(&rev, prefix); + repo_init_revisions(the_repository, &rev, prefix); rev.diff = 1; rev.always_show_header = 1; rev.no_walk = REVISION_WALK_NO_WALK_SORTED; @@ -667,7 +668,7 @@ int cmd_log_reflog(int argc, const char **argv, const char *prefix) init_log_defaults(); git_config(git_log_config, NULL); - init_revisions(&rev, prefix); + repo_init_revisions(the_repository, &rev, prefix); init_reflog_walk(&rev.reflog_info); rev.verbose_header = 1; memset(&opt, 0, sizeof(opt)); @@ -706,7 +707,7 @@ int cmd_log(int argc, const char **argv, const char *prefix) init_log_defaults(); git_config(git_log_config, NULL); - init_revisions(&rev, prefix); + repo_init_revisions(the_repository, &rev, prefix); rev.always_show_header = 1; memset(&opt, 0, sizeof(opt)); opt.def = "HEAD"; @@ -916,10 +917,10 @@ static void get_patch_ids(struct rev_info *rev, struct patch_ids *ids) if ((flags1 & UNINTERESTING) == (flags2 & UNINTERESTING)) die(_("Not a range.")); - init_patch_ids(ids); + init_patch_ids(the_repository, ids); /* given a range a..b get all patch ids for b..a */ - init_revisions(&check_rev, rev->prefix); + repo_init_revisions(the_repository, &check_rev, rev->prefix); check_rev.max_parents = 1; o1->flags ^= UNINTERESTING; o2->flags ^= UNINTERESTING; @@ -1377,13 +1378,13 @@ static void prepare_bases(struct base_tree_info *bases, return; init_commit_base(&commit_base); - diff_setup(&diffopt); + repo_diff_setup(the_repository, &diffopt); diffopt.flags.recursive = 1; diff_setup_done(&diffopt); oidcpy(&bases->base_commit, &base->object.oid); - init_revisions(&revs, NULL); + repo_init_revisions(the_repository, &revs, NULL); revs.max_parents = 1; revs.topo_order = 1; for (i = 0; i < total; i++) { @@ -1588,7 +1589,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) extra_cc.strdup_strings = 1; init_log_defaults(); git_config(git_format_config, NULL); - init_revisions(&rev, prefix); + repo_init_revisions(the_repository, &rev, prefix); rev.commit_format = CMIT_FMT_EMAIL; rev.expand_tabs_in_log_default = 0; rev.verbose_header = 1; @@ -2038,7 +2039,7 @@ int cmd_cherry(int argc, const char **argv, const char *prefix) } } - init_revisions(&revs, prefix); + repo_init_revisions(the_repository, &revs, prefix); revs.max_parents = 1; if (add_pending_commit(head, &revs, 0)) diff --git a/builtin/merge-tree.c b/builtin/merge-tree.c index 8cea8a74f2..8fc108d305 100644 --- a/builtin/merge-tree.c +++ b/builtin/merge-tree.c @@ -76,7 +76,7 @@ static void *result(struct merge_list *entry, unsigned long *size) their = NULL; if (entry) their = entry->blob; - return merge_blobs(path, base, our, their, size); + return merge_blobs(&the_index, path, base, our, their, size); } static void *origin(struct merge_list *entry, unsigned long *size) diff --git a/builtin/merge.c b/builtin/merge.c index e331ca6d48..4aa6071598 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -390,7 +390,7 @@ static void squash_message(struct commit *commit, struct commit_list *remotehead printf(_("Squash commit -- not updating HEAD\n")); - init_revisions(&rev, NULL); + repo_init_revisions(the_repository, &rev, NULL); rev.ignore_merges = 1; rev.commit_format = CMIT_FMT_MEDIUM; @@ -453,7 +453,7 @@ static void finish(struct commit *head_commit, } if (new_head && show_diffstat) { struct diff_options opts; - diff_setup(&opts); + repo_diff_setup(the_repository, &opts); opts.stat_width = -1; /* use full terminal width */ opts.stat_graph_width = -1; /* respect statGraphWidth config */ opts.output_format |= @@ -729,8 +729,9 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common, die(_("unable to write %s"), get_index_file()); return clean ? 0 : 1; } else { - return try_merge_command(strategy, xopts_nr, xopts, - common, head_arg, remoteheads); + return try_merge_command(the_repository, + strategy, xopts_nr, xopts, + common, head_arg, remoteheads); } } @@ -899,7 +900,7 @@ static int suggest_conflicts(void) fputs(msgbuf.buf, fp); strbuf_release(&msgbuf); fclose(fp); - rerere(allow_rerere_auto); + repo_rerere(the_repository, allow_rerere_auto); printf(_("Automatic merge failed; " "fix conflicts and then commit the result.\n")); return 1; @@ -911,7 +912,7 @@ static int evaluate_result(void) struct rev_info rev; /* Check how many files differ. */ - init_revisions(&rev, ""); + repo_init_revisions(the_repository, &rev, ""); setup_revisions(0, NULL, &rev, NULL); rev.diffopt.output_format |= DIFF_FORMAT_CALLBACK; @@ -1471,7 +1472,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix) goto done; } - if (checkout_fast_forward(&head_commit->object.oid, + if (checkout_fast_forward(the_repository, + &head_commit->object.oid, &commit->object.oid, overwrite_ignore)) { ret = 1; diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index c6370f2716..b059b86aee 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -3106,7 +3106,7 @@ static void get_object_list(int ac, const char **av) char line[1000]; int flags = 0; - init_revisions(&revs, NULL); + repo_init_revisions(the_repository, &revs, NULL); save_commit_buffer = 0; setup_revisions(ac, av, &revs, NULL); diff --git a/builtin/prune.c b/builtin/prune.c index 4916a4daa2..41230f8215 100644 --- a/builtin/prune.c +++ b/builtin/prune.c @@ -120,7 +120,7 @@ int cmd_prune(int argc, const char **argv, const char *prefix) save_commit_buffer = 0; read_replace_refs = 0; ref_paranoia = 1; - init_revisions(&revs, prefix); + repo_init_revisions(the_repository, &revs, prefix); argc = parse_options(argc, argv, prefix, options, prune_usage, 0); diff --git a/builtin/pull.c b/builtin/pull.c index b2055d1dd6..798ecf7faf 100644 --- a/builtin/pull.c +++ b/builtin/pull.c @@ -563,7 +563,9 @@ static int pull_into_void(const struct object_id *merge_head, * index/worktree changes that the user already made on the unborn * branch. */ - if (checkout_fast_forward(the_hash_algo->empty_tree, merge_head, 0)) + if (checkout_fast_forward(the_repository, + the_hash_algo->empty_tree, + merge_head, 0)) return 1; if (update_ref("initial pull", "HEAD", merge_head, curr_head, 0, UPDATE_REFS_DIE_ON_ERR)) @@ -916,7 +918,8 @@ int cmd_pull(int argc, const char **argv, const char *prefix) "fast-forwarding your working tree from\n" "commit %s."), oid_to_hex(&orig_head)); - if (checkout_fast_forward(&orig_head, &curr_head, 0)) + if (checkout_fast_forward(the_repository, &orig_head, + &curr_head, 0)) die(_("Cannot fast-forward your working tree.\n" "After making sure that you saved anything precious from\n" "$ git diff %s\n" @@ -942,7 +945,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix) int ret = 0; if ((recurse_submodules == RECURSE_SUBMODULES_ON || recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND) && - submodule_touches_in_range(&rebase_fork_point, &curr_head)) + submodule_touches_in_range(&the_index, &rebase_fork_point, &curr_head)) die(_("cannot rebase with locally recorded submodule modifications")); if (!autostash) { struct commit_list *list = NULL; diff --git a/builtin/range-diff.c b/builtin/range-diff.c index 96af537493..f01a0be851 100644 --- a/builtin/range-diff.c +++ b/builtin/range-diff.c @@ -28,7 +28,7 @@ int cmd_range_diff(int argc, const char **argv, const char *prefix) git_config(git_diff_ui_config, NULL); - diff_setup(&diffopt); + repo_diff_setup(the_repository, &diffopt); argc = parse_options(argc, argv, NULL, options, builtin_range_diff_usage, PARSE_OPT_KEEP_UNKNOWN | diff --git a/builtin/reflog.c b/builtin/reflog.c index 3acef5a0ab..b5941c1ff3 100644 --- a/builtin/reflog.c +++ b/builtin/reflog.c @@ -567,7 +567,7 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix) * from reflog if the repository was pruned with older git. */ if (cb.cmd.stalefix) { - init_revisions(&cb.cmd.revs, prefix); + repo_init_revisions(the_repository, &cb.cmd.revs, prefix); if (flags & EXPIRE_REFLOGS_VERBOSE) printf("Marking reachable objects..."); mark_reachable_objects(&cb.cmd.revs, 0, 0, NULL); diff --git a/builtin/replace.c b/builtin/replace.c index 30a661ea0c..a58b9c6d13 100644 --- a/builtin/replace.c +++ b/builtin/replace.c @@ -295,7 +295,7 @@ static int import_object(struct object_id *oid, enum object_type type, close(fd); return -1; } - if (index_fd(oid, fd, &st, type, NULL, flags) < 0) + if (index_fd(&the_index, oid, fd, &st, type, NULL, flags) < 0) return error(_("unable to write object to database")); /* index_fd close()s fd for us */ } diff --git a/builtin/rerere.c b/builtin/rerere.c index 5ed941b91f..e89ccbc524 100644 --- a/builtin/rerere.c +++ b/builtin/rerere.c @@ -70,7 +70,7 @@ int cmd_rerere(int argc, const char **argv, const char *prefix) flags = RERERE_NOAUTOUPDATE; if (argc < 1) - return rerere(flags); + return repo_rerere(the_repository, flags); if (!strcmp(argv[0], "forget")) { struct pathspec pathspec; @@ -78,7 +78,7 @@ int cmd_rerere(int argc, const char **argv, const char *prefix) warning(_("'git rerere forget' without paths is deprecated")); parse_pathspec(&pathspec, 0, PATHSPEC_PREFER_CWD, prefix, argv + 1); - return rerere_forget(&pathspec); + return rerere_forget(the_repository, &pathspec); } if (!strcmp(argv[0], "clear")) { @@ -91,7 +91,7 @@ int cmd_rerere(int argc, const char **argv, const char *prefix) for (i = 0; i < merge_rr.nr; i++) printf("%s\n", merge_rr.items[i].string); } else if (!strcmp(argv[0], "remaining")) { - rerere_remaining(&merge_rr); + rerere_remaining(the_repository, &merge_rr); for (i = 0; i < merge_rr.nr; i++) { if (merge_rr.items[i].util != RERERE_RESOLVED) printf("%s\n", merge_rr.items[i].string); diff --git a/builtin/reset.c b/builtin/reset.c index 11cd0dcb8c..6d37a35e2e 100644 --- a/builtin/reset.c +++ b/builtin/reset.c @@ -159,6 +159,7 @@ static int read_from_tree(const struct pathspec *pathspec, opt.format_callback = update_index_from_diff; opt.format_callback_data = &intent_to_add; opt.flags.override_submodule_config = 1; + opt.repo = the_repository; if (do_diff_cache(tree_oid, &opt)) return 1; diff --git a/builtin/rev-list.c b/builtin/rev-list.c index ed0ea7dc5b..cc1b70522f 100644 --- a/builtin/rev-list.c +++ b/builtin/rev-list.c @@ -370,7 +370,7 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix) usage(rev_list_usage); git_config(git_default_config, NULL); - init_revisions(&revs, prefix); + repo_init_revisions(the_repository, &revs, prefix); revs.abbrev = DEFAULT_ABBREV; revs.commit_format = CMIT_FMT_UNSPECIFIED; diff --git a/builtin/revert.c b/builtin/revert.c index 9a66720cfc..c93393c89b 100644 --- a/builtin/revert.c +++ b/builtin/revert.c @@ -174,7 +174,7 @@ static int run_sequencer(int argc, const char **argv, struct replay_opts *opts) } else { struct setup_revision_opt s_r_opt; opts->revs = xmalloc(sizeof(*opts->revs)); - init_revisions(opts->revs, NULL); + repo_init_revisions(the_repository, opts->revs, NULL); opts->revs->no_walk = REVISION_WALK_NO_WALK_UNSORTED; if (argc < 2) usage_with_options(usage_str, options); diff --git a/builtin/shortlog.c b/builtin/shortlog.c index 3898a2c9c4..88f88e97b2 100644 --- a/builtin/shortlog.c +++ b/builtin/shortlog.c @@ -278,7 +278,7 @@ int cmd_shortlog(int argc, const char **argv, const char *prefix) git_config(git_default_config, NULL); shortlog_init(&log); - init_revisions(&rev, prefix); + repo_init_revisions(the_repository, &rev, prefix); parse_options_start(&ctx, argc, argv, prefix, options, PARSE_OPT_KEEP_DASHDASH | PARSE_OPT_KEEP_ARGV0); diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 247881189f..80474c3ff5 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -792,7 +792,7 @@ static void status_submodule(const char *path, const struct object_id *ce_oid, path, NULL); git_config(git_diff_basic_config, NULL); - init_revisions(&rev, prefix); + repo_init_revisions(the_repository, &rev, prefix); rev.abbrev = 0; diff_files_args.argc = setup_revisions(diff_files_args.argc, diff_files_args.argv, diff --git a/builtin/update-index.c b/builtin/update-index.c index e7fab78b3b..07c10bcb7d 100644 --- a/builtin/update-index.c +++ b/builtin/update-index.c @@ -282,7 +282,7 @@ static int add_one_path(const struct cache_entry *old, const char *path, int len fill_stat_cache_info(ce, st); ce->ce_mode = ce_mode_from_stat(old, st->st_mode); - if (index_path(&ce->oid, path, st, + if (index_path(&the_index, &ce->oid, path, st, info_only ? 0 : HASH_WRITE_OBJECT)) { discard_cache_entry(ce); return -1; @@ -140,7 +140,7 @@ int verify_bundle(struct bundle_header *header, int verbose) int i, ret = 0, req_nr; const char *message = _("Repository lacks these prerequisite commits:"); - init_revisions(&revs, NULL); + repo_init_revisions(the_repository, &revs, NULL); for (i = 0; i < p->nr; i++) { struct ref_list_entry *e = p->list + i; struct object *o = parse_object(the_repository, &e->oid); @@ -441,7 +441,7 @@ int create_bundle(struct bundle_header *header, const char *path, /* init revs to list objects for pack-objects later */ save_commit_buffer = 0; - init_revisions(&revs, NULL); + repo_init_revisions(the_repository, &revs, NULL); /* write prerequisites */ if (compute_and_write_prerequisites(bundle_fd, &revs, argc, argv)) @@ -703,7 +703,7 @@ extern int unmerged_index(const struct index_state *); * provided, the space-separated list of files that differ will be appended * to it. */ -extern int index_has_changes(const struct index_state *istate, +extern int index_has_changes(struct index_state *istate, struct tree *tree, struct strbuf *sb); @@ -787,8 +787,8 @@ extern int ie_modified(struct index_state *, const struct cache_entry *, struct #define HASH_WRITE_OBJECT 1 #define HASH_FORMAT_CHECK 2 #define HASH_RENORMALIZE 4 -extern int index_fd(struct object_id *oid, int fd, struct stat *st, enum object_type type, const char *path, unsigned flags); -extern int index_path(struct object_id *oid, const char *path, struct stat *st, unsigned flags); +extern int index_fd(struct index_state *istate, struct object_id *oid, int fd, struct stat *st, enum object_type type, const char *path, unsigned flags); +extern int index_path(struct index_state *istate, struct object_id *oid, const char *path, struct stat *st, unsigned flags); /* * Record to sd the data from st that we use to check whether a file @@ -1705,7 +1705,7 @@ void shift_tree_by(const struct object_id *, const struct object_id *, struct ob /* All WS_* -- when extended, adapt diff.c emit_symbol */ #define WS_RULE_MASK 07777 extern unsigned whitespace_rule_cfg; -extern unsigned whitespace_rule(const char *); +extern unsigned whitespace_rule(struct index_state *, const char *); extern unsigned parse_whitespace_rule(const char *); extern unsigned ws_check(const char *line, int len, unsigned ws_rule); extern void ws_check_emit(const char *line, int len, unsigned ws_rule, FILE *stream, const char *set, const char *reset, const char *ws); @@ -1727,10 +1727,12 @@ extern struct startup_info *startup_info; /* merge.c */ struct commit_list; -int try_merge_command(const char *strategy, size_t xopts_nr, +int try_merge_command(struct repository *r, + const char *strategy, size_t xopts_nr, const char **xopts, struct commit_list *common, const char *head_arg, struct commit_list *remotes); -int checkout_fast_forward(const struct object_id *from, +int checkout_fast_forward(struct repository *r, + const struct object_id *from, const struct object_id *to, int overwrite_ignore); diff --git a/combine-diff.c b/combine-diff.c index 0fed4ca529..10155e0ec8 100644 --- a/combine-diff.c +++ b/combine-diff.c @@ -285,7 +285,8 @@ static struct lline *coalesce_lines(struct lline *base, int *lenbase, return base; } -static char *grab_blob(const struct object_id *oid, unsigned int mode, +static char *grab_blob(struct repository *r, + const struct object_id *oid, unsigned int mode, unsigned long *size, struct userdiff_driver *textconv, const char *path) { @@ -304,7 +305,7 @@ static char *grab_blob(const struct object_id *oid, unsigned int mode, } else if (textconv) { struct diff_filespec *df = alloc_filespec(path); fill_filespec(df, oid, 1, mode); - *size = fill_textconv(textconv, df, &blob); + *size = fill_textconv(r, textconv, df, &blob); free_filespec(df); } else { blob = read_object_file(oid, &type, size); @@ -389,7 +390,8 @@ static void consume_line(void *state_, char *line, unsigned long len) } } -static void combine_diff(const struct object_id *parent, unsigned int mode, +static void combine_diff(struct repository *r, + const struct object_id *parent, unsigned int mode, mmfile_t *result_file, struct sline *sline, unsigned int cnt, int n, int num_parent, int result_deleted, @@ -407,7 +409,7 @@ static void combine_diff(const struct object_id *parent, unsigned int mode, if (result_deleted) return; /* result deleted */ - parent_file.ptr = grab_blob(parent, mode, &sz, textconv, path); + parent_file.ptr = grab_blob(r, parent, mode, &sz, textconv, path); parent_file.size = sz; memset(&xpp, 0, sizeof(xpp)); xpp.flags = flags; @@ -985,7 +987,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent, const char *line_prefix = diff_line_prefix(opt); context = opt->context; - userdiff = userdiff_find_by_path(elem->path); + userdiff = userdiff_find_by_path(opt->repo->index, elem->path); if (!userdiff) userdiff = userdiff_find_by_name("default"); if (opt->flags.allow_textconv) @@ -993,7 +995,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent, /* Read the result of merge first */ if (!working_tree_file) - result = grab_blob(&elem->oid, elem->mode, &result_size, + result = grab_blob(opt->repo, &elem->oid, elem->mode, &result_size, textconv, elem->path); else { /* Used by diff-tree to read from the working tree */ @@ -1016,15 +1018,16 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent, } else if (S_ISDIR(st.st_mode)) { struct object_id oid; if (resolve_gitlink_ref(elem->path, "HEAD", &oid) < 0) - result = grab_blob(&elem->oid, elem->mode, - &result_size, NULL, NULL); + result = grab_blob(opt->repo, &elem->oid, + elem->mode, &result_size, + NULL, NULL); else - result = grab_blob(&oid, elem->mode, + result = grab_blob(opt->repo, &oid, elem->mode, &result_size, NULL, NULL); } else if (textconv) { struct diff_filespec *df = alloc_filespec(elem->path); fill_filespec(df, &null_oid, 0, st.st_mode); - result_size = fill_textconv(textconv, df, &result); + result_size = fill_textconv(opt->repo, textconv, df, &result); free_filespec(df); } else if (0 <= (fd = open(elem->path, O_RDONLY))) { size_t len = xsize_t(st.st_size); @@ -1054,7 +1057,8 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent, if (is_file) { struct strbuf buf = STRBUF_INIT; - if (convert_to_git(&the_index, elem->path, result, len, &buf, global_conv_flags_eol)) { + if (convert_to_git(rev->diffopt.repo->index, + elem->path, result, len, &buf, global_conv_flags_eol)) { free(result); result = strbuf_detach(&buf, &len); result_size = len; @@ -1089,7 +1093,8 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent, for (i = 0; !is_binary && i < num_parent; i++) { char *buf; unsigned long size; - buf = grab_blob(&elem->parent[i].oid, + buf = grab_blob(opt->repo, + &elem->parent[i].oid, elem->parent[i].mode, &size, NULL, NULL); if (buffer_is_binary(buf, size)) @@ -1145,7 +1150,8 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent, } } if (i <= j) - combine_diff(&elem->parent[i].oid, + combine_diff(opt->repo, + &elem->parent[i].oid, elem->parent[i].mode, &result_file, sline, cnt, i, num_parent, result_deleted, diff --git a/diff-lib.c b/diff-lib.c index 30bf9a2399..83fce51518 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -70,7 +70,7 @@ static int match_stat_with_submodule(struct diff_options *diffopt, struct stat *st, unsigned ce_option, unsigned *dirty_submodule) { - int changed = ce_match_stat(ce, st, ce_option); + int changed = ie_match_stat(diffopt->repo->index, ce, st, ce_option); if (S_ISGITLINK(ce->ce_mode)) { struct diff_flags orig_flags = diffopt->flags; if (!diffopt->flags.override_submodule_config) @@ -93,15 +93,16 @@ int run_diff_files(struct rev_info *revs, unsigned int option) unsigned ce_option = ((option & DIFF_RACY_IS_MODIFIED) ? CE_MATCH_RACY_IS_DIRTY : 0); uint64_t start = getnanotime(); + struct index_state *istate = revs->diffopt.repo->index; diff_set_mnemonic_prefix(&revs->diffopt, "i/", "w/"); if (diff_unmerged_stage < 0) diff_unmerged_stage = 2; - entries = active_nr; + entries = istate->cache_nr; for (i = 0; i < entries; i++) { unsigned int oldmode, newmode; - struct cache_entry *ce = active_cache[i]; + struct cache_entry *ce = istate->cache[i]; int changed; unsigned dirty_submodule = 0; const struct object_id *old_oid, *new_oid; @@ -109,7 +110,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option) if (diff_can_quit_early(&revs->diffopt)) break; - if (!ce_path_match(&the_index, ce, &revs->prune_data, NULL)) + if (!ce_path_match(istate, ce, &revs->prune_data, NULL)) continue; if (ce_stage(ce)) { @@ -145,7 +146,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option) dpath->mode = wt_mode; while (i < entries) { - struct cache_entry *nce = active_cache[i]; + struct cache_entry *nce = istate->cache[i]; int stage; if (strcmp(ce->name, nce->name)) @@ -474,7 +475,9 @@ static int oneway_diff(const struct cache_entry * const *src, if (tree == o->df_conflict_entry) tree = NULL; - if (ce_path_match(&the_index, idx ? idx : tree, &revs->prune_data, NULL)) { + if (ce_path_match(revs->diffopt.repo->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; @@ -506,7 +509,7 @@ static int diff_cache(struct rev_info *revs, opts.merge = 1; opts.fn = oneway_diff; opts.unpack_data = revs; - opts.src_index = &the_index; + opts.src_index = revs->diffopt.repo->index; opts.dst_index = NULL; opts.pathspec = &revs->diffopt.pathspec; opts.pathspec->recursive = 1; @@ -539,7 +542,7 @@ int do_diff_cache(const struct object_id *tree_oid, struct diff_options *opt) { struct rev_info revs; - init_revisions(&revs, NULL); + repo_init_revisions(the_repository, &revs, NULL); copy_pathspec(&revs.prune_data, &opt->pathspec); revs.diffopt = *opt; @@ -554,7 +557,7 @@ int index_differs_from(const char *def, const struct diff_flags *flags, struct rev_info rev; struct setup_revision_opt opt; - init_revisions(&rev, NULL); + repo_init_revisions(the_repository, &rev, NULL); memset(&opt, 0, sizeof(opt)); opt.def = def; setup_revisions(0, NULL, &rev, &opt); diff --git a/diff-no-index.c b/diff-no-index.c index 0ed5f0f496..9414e922d1 100644 --- a/diff-no-index.c +++ b/diff-no-index.c @@ -233,7 +233,8 @@ static void fixup_paths(const char **path, struct strbuf *replacement) } } -void diff_no_index(struct rev_info *revs, +void diff_no_index(struct repository *r, + struct rev_info *revs, int argc, const char **argv) { int i; @@ -241,7 +242,11 @@ void diff_no_index(struct rev_info *revs, struct strbuf replacement = STRBUF_INIT; const char *prefix = revs->prefix; - diff_setup(&revs->diffopt); + /* + * FIXME: --no-index should not look at index and we should be + * able to pass NULL repo. Maybe later. + */ + repo_diff_setup(r, &revs->diffopt); for (i = 1; i < argc - 2; ) { int j; if (!strcmp(argv[i], "--no-index")) @@ -554,14 +554,15 @@ static int count_lines(const char *data, int size) return count; } -static int fill_mmfile(mmfile_t *mf, struct diff_filespec *one) +static int fill_mmfile(struct repository *r, mmfile_t *mf, + struct diff_filespec *one) { if (!DIFF_FILE_VALID(one)) { mf->ptr = (char *)""; /* does not matter */ mf->size = 0; return 0; } - else if (diff_populate_filespec(one, 0)) + else if (diff_populate_filespec(r, one, 0)) return -1; mf->ptr = one->data; @@ -570,11 +571,12 @@ static int fill_mmfile(mmfile_t *mf, struct diff_filespec *one) } /* like fill_mmfile, but only for size, so we can avoid retrieving blob */ -static unsigned long diff_filespec_size(struct diff_filespec *one) +static unsigned long diff_filespec_size(struct repository *r, + struct diff_filespec *one) { if (!DIFF_FILE_VALID(one)) return 0; - diff_populate_filespec(one, CHECK_SIZE_ONLY); + diff_populate_filespec(r, one, CHECK_SIZE_ONLY); return one->size; } @@ -1714,12 +1716,12 @@ static void emit_rewrite_diff(const char *name_a, quote_two_c_style(&a_name, a_prefix, name_a, 0); quote_two_c_style(&b_name, b_prefix, name_b, 0); - size_one = fill_textconv(textconv_one, one, &data_one); - size_two = fill_textconv(textconv_two, two, &data_two); + size_one = fill_textconv(o->repo, textconv_one, one, &data_one); + size_two = fill_textconv(o->repo, textconv_two, two, &data_two); memset(&ecbdata, 0, sizeof(ecbdata)); ecbdata.color_diff = want_color(o->use_color); - ecbdata.ws_rule = whitespace_rule(name_b); + ecbdata.ws_rule = whitespace_rule(o->repo->index, name_b); ecbdata.opt = o; if (ecbdata.ws_rule & WS_BLANK_AT_EOF) { mmfile_t mf1, mf2; @@ -2107,23 +2109,25 @@ static void diff_words_flush(struct emit_callback *ecbdata) } } -static void diff_filespec_load_driver(struct diff_filespec *one) +static void diff_filespec_load_driver(struct diff_filespec *one, + struct index_state *istate) { /* Use already-loaded driver */ if (one->driver) return; if (S_ISREG(one->mode)) - one->driver = userdiff_find_by_path(one->path); + one->driver = userdiff_find_by_path(istate, one->path); /* Fallback to default settings */ if (!one->driver) one->driver = userdiff_find_by_name("default"); } -static const char *userdiff_word_regex(struct diff_filespec *one) +static const char *userdiff_word_regex(struct diff_filespec *one, + struct index_state *istate) { - diff_filespec_load_driver(one); + diff_filespec_load_driver(one, istate); return one->driver->word_regex; } @@ -2146,9 +2150,9 @@ static void init_diff_words_data(struct emit_callback *ecbdata, xcalloc(1, sizeof(struct emitted_diff_symbols)); if (!o->word_regex) - o->word_regex = userdiff_word_regex(one); + o->word_regex = userdiff_word_regex(one, o->repo->index); if (!o->word_regex) - o->word_regex = userdiff_word_regex(two); + o->word_regex = userdiff_word_regex(two, o->repo->index); if (!o->word_regex) o->word_regex = diff_word_regex_cfg; if (o->word_regex) { @@ -2976,18 +2980,19 @@ static void show_dirstat(struct diff_options *options) } if (DIFF_FILE_VALID(p->one) && DIFF_FILE_VALID(p->two)) { - diff_populate_filespec(p->one, 0); - diff_populate_filespec(p->two, 0); - diffcore_count_changes(p->one, p->two, NULL, NULL, + diff_populate_filespec(options->repo, p->one, 0); + diff_populate_filespec(options->repo, p->two, 0); + diffcore_count_changes(options->repo, + p->one, p->two, NULL, NULL, &copied, &added); diff_free_filespec_data(p->one); diff_free_filespec_data(p->two); } else if (DIFF_FILE_VALID(p->one)) { - diff_populate_filespec(p->one, CHECK_SIZE_ONLY); + diff_populate_filespec(options->repo, p->one, CHECK_SIZE_ONLY); copied = added = 0; diff_free_filespec_data(p->one); } else if (DIFF_FILE_VALID(p->two)) { - diff_populate_filespec(p->two, CHECK_SIZE_ONLY); + diff_populate_filespec(options->repo, p->two, CHECK_SIZE_ONLY); copied = 0; added = p->two->size; diff_free_filespec_data(p->two); @@ -3261,15 +3266,16 @@ static void emit_binary_diff(struct diff_options *o, emit_binary_diff_body(o, two, one); } -int diff_filespec_is_binary(struct diff_filespec *one) +int diff_filespec_is_binary(struct repository *r, + struct diff_filespec *one) { if (one->is_binary == -1) { - diff_filespec_load_driver(one); + diff_filespec_load_driver(one, r->index); if (one->driver->binary != -1) one->is_binary = one->driver->binary; else { if (!one->data && DIFF_FILE_VALID(one)) - diff_populate_filespec(one, CHECK_BINARY); + diff_populate_filespec(r, one, CHECK_BINARY); if (one->is_binary == -1 && one->data) one->is_binary = buffer_is_binary(one->data, one->size); @@ -3280,9 +3286,10 @@ int diff_filespec_is_binary(struct diff_filespec *one) return one->is_binary; } -static const struct userdiff_funcname *diff_funcname_pattern(struct diff_filespec *one) +static const struct userdiff_funcname * +diff_funcname_pattern(struct diff_options *o, struct diff_filespec *one) { - diff_filespec_load_driver(one); + diff_filespec_load_driver(one, o->repo->index); return one->driver->funcname.pattern ? &one->driver->funcname : NULL; } @@ -3294,12 +3301,13 @@ void diff_set_mnemonic_prefix(struct diff_options *options, const char *a, const options->b_prefix = b; } -struct userdiff_driver *get_textconv(struct diff_filespec *one) +struct userdiff_driver *get_textconv(struct index_state *istate, + struct diff_filespec *one) { if (!DIFF_FILE_VALID(one)) return NULL; - diff_filespec_load_driver(one); + diff_filespec_load_driver(one, istate); return userdiff_get_textconv(one->driver); } @@ -3349,8 +3357,8 @@ static void builtin_diff(const char *name_a, } if (o->flags.allow_textconv) { - textconv_one = get_textconv(one); - textconv_two = get_textconv(two); + textconv_one = get_textconv(o->repo->index, one); + textconv_two = get_textconv(o->repo->index, two); } /* Never use a non-valid filename anywhere if at all possible */ @@ -3391,13 +3399,13 @@ static void builtin_diff(const char *name_a, if ((one->mode ^ two->mode) & S_IFMT) goto free_ab_and_return; if (complete_rewrite && - (textconv_one || !diff_filespec_is_binary(one)) && - (textconv_two || !diff_filespec_is_binary(two))) { + (textconv_one || !diff_filespec_is_binary(o->repo, one)) && + (textconv_two || !diff_filespec_is_binary(o->repo, two))) { emit_diff_symbol(o, DIFF_SYMBOL_HEADER, header.buf, header.len, 0); strbuf_reset(&header); emit_rewrite_diff(name_a, name_b, one, two, - textconv_one, textconv_two, o); + textconv_one, textconv_two, o); o->found_changes = 1; goto free_ab_and_return; } @@ -3409,8 +3417,8 @@ static void builtin_diff(const char *name_a, strbuf_reset(&header); goto free_ab_and_return; } else if (!o->flags.text && - ( (!textconv_one && diff_filespec_is_binary(one)) || - (!textconv_two && diff_filespec_is_binary(two)) )) { + ( (!textconv_one && diff_filespec_is_binary(o->repo, one)) || + (!textconv_two && diff_filespec_is_binary(o->repo, two)) )) { struct strbuf sb = STRBUF_INIT; if (!one->data && !two->data && S_ISREG(one->mode) && S_ISREG(two->mode) && @@ -3431,7 +3439,8 @@ static void builtin_diff(const char *name_a, strbuf_release(&sb); goto free_ab_and_return; } - if (fill_mmfile(&mf1, one) < 0 || fill_mmfile(&mf2, two) < 0) + if (fill_mmfile(o->repo, &mf1, one) < 0 || + fill_mmfile(o->repo, &mf2, two) < 0) die("unable to read files to diff"); /* Quite common confusing case */ if (mf1.size == mf2.size && @@ -3468,12 +3477,12 @@ static void builtin_diff(const char *name_a, strbuf_reset(&header); } - mf1.size = fill_textconv(textconv_one, one, &mf1.ptr); - mf2.size = fill_textconv(textconv_two, two, &mf2.ptr); + mf1.size = fill_textconv(o->repo, textconv_one, one, &mf1.ptr); + mf2.size = fill_textconv(o->repo, textconv_two, two, &mf2.ptr); - pe = diff_funcname_pattern(one); + pe = diff_funcname_pattern(o, one); if (!pe) - pe = diff_funcname_pattern(two); + pe = diff_funcname_pattern(o, two); memset(&xpp, 0, sizeof(xpp)); memset(&xecfg, 0, sizeof(xecfg)); @@ -3482,7 +3491,7 @@ static void builtin_diff(const char *name_a, lbl[0] = NULL; ecbdata.label_path = lbl; ecbdata.color_diff = want_color(o->use_color); - ecbdata.ws_rule = whitespace_rule(name_b); + ecbdata.ws_rule = whitespace_rule(o->repo->index, name_b); if (ecbdata.ws_rule & WS_BLANK_AT_EOF) check_blank_at_eof(&mf1, &mf2, &ecbdata); ecbdata.opt = o; @@ -3582,20 +3591,21 @@ static void builtin_diffstat(const char *name_a, const char *name_b, same_contents = oideq(&one->oid, &two->oid); - if (diff_filespec_is_binary(one) || diff_filespec_is_binary(two)) { + if (diff_filespec_is_binary(o->repo, one) || + diff_filespec_is_binary(o->repo, two)) { data->is_binary = 1; if (same_contents) { data->added = 0; data->deleted = 0; } else { - data->added = diff_filespec_size(two); - data->deleted = diff_filespec_size(one); + data->added = diff_filespec_size(o->repo, two); + data->deleted = diff_filespec_size(o->repo, one); } } else if (complete_rewrite) { - diff_populate_filespec(one, 0); - diff_populate_filespec(two, 0); + diff_populate_filespec(o->repo, one, 0); + diff_populate_filespec(o->repo, two, 0); data->deleted = count_lines(one->data, one->size); data->added = count_lines(two->data, two->size); } @@ -3605,7 +3615,8 @@ static void builtin_diffstat(const char *name_a, const char *name_b, xpparam_t xpp; xdemitconf_t xecfg; - if (fill_mmfile(&mf1, one) < 0 || fill_mmfile(&mf2, two) < 0) + if (fill_mmfile(o->repo, &mf1, one) < 0 || + fill_mmfile(o->repo, &mf2, two) < 0) die("unable to read files to diff"); memset(&xpp, 0, sizeof(xpp)); @@ -3640,10 +3651,11 @@ static void builtin_checkdiff(const char *name_a, const char *name_b, data.filename = name_b ? name_b : name_a; data.lineno = 0; data.o = o; - data.ws_rule = whitespace_rule(attr_path); - data.conflict_marker_size = ll_merge_marker_size(attr_path); + data.ws_rule = whitespace_rule(o->repo->index, attr_path); + data.conflict_marker_size = ll_merge_marker_size(o->repo->index, attr_path); - if (fill_mmfile(&mf1, one) < 0 || fill_mmfile(&mf2, two) < 0) + if (fill_mmfile(o->repo, &mf1, one) < 0 || + fill_mmfile(o->repo, &mf2, two) < 0) die("unable to read files to diff"); /* @@ -3652,7 +3664,7 @@ static void builtin_checkdiff(const char *name_a, const char *name_b, * introduced changes, and as long as the "new" side is text, we * can and should check what it introduces. */ - if (diff_filespec_is_binary(two)) + if (diff_filespec_is_binary(o->repo, two)) goto free_and_return; else { /* Crazy xdl interfaces.. */ @@ -3725,7 +3737,10 @@ void fill_filespec(struct diff_filespec *spec, const struct object_id *oid, * the work tree has that object contents, return true, so that * prepare_temp_file() does not have to inflate and extract. */ -static int reuse_worktree_file(const char *name, const struct object_id *oid, int want_file) +static int reuse_worktree_file(struct index_state *istate, + const char *name, + const struct object_id *oid, + int want_file) { const struct cache_entry *ce; struct stat st; @@ -3744,7 +3759,7 @@ static int reuse_worktree_file(const char *name, const struct object_id *oid, in * by diff-cache --cached, which does read the cache before * calling us. */ - if (!active_cache) + if (!istate->cache) return 0; /* We want to avoid the working directory if our caller @@ -3763,14 +3778,14 @@ static int reuse_worktree_file(const char *name, const struct object_id *oid, in * Similarly, if we'd have to convert the file contents anyway, that * makes the optimization not worthwhile. */ - if (!want_file && would_convert_to_git(&the_index, name)) + if (!want_file && would_convert_to_git(istate, name)) return 0; len = strlen(name); - pos = cache_name_pos(name, len); + pos = index_name_pos(istate, name, len); if (pos < 0) return 0; - ce = active_cache[pos]; + ce = istate->cache[pos]; /* * This is not the sha1 we are looking for, or @@ -3790,7 +3805,7 @@ static int reuse_worktree_file(const char *name, const struct object_id *oid, in * If ce matches the file in the work tree, we can reuse it. */ if (ce_uptodate(ce) || - (!lstat(name, &st) && !ce_match_stat(ce, &st, 0))) + (!lstat(name, &st) && !ie_match_stat(istate, ce, &st, 0))) return 1; return 0; @@ -3823,7 +3838,9 @@ static int diff_populate_gitlink(struct diff_filespec *s, int size_only) * grab the data for the blob (or file) for our own in-core comparison. * diff_filespec has data and size fields for this purpose. */ -int diff_populate_filespec(struct diff_filespec *s, unsigned int flags) +int diff_populate_filespec(struct repository *r, + struct diff_filespec *s, + unsigned int flags) { int size_only = flags & CHECK_SIZE_ONLY; int err = 0; @@ -3850,7 +3867,7 @@ int diff_populate_filespec(struct diff_filespec *s, unsigned int flags) return diff_populate_gitlink(s, size_only); if (!s->oid_valid || - reuse_worktree_file(s->path, &s->oid, 0)) { + reuse_worktree_file(r->index, s->path, &s->oid, 0)) { struct strbuf buf = STRBUF_INIT; struct stat st; int fd; @@ -3883,7 +3900,7 @@ int diff_populate_filespec(struct diff_filespec *s, unsigned int flags) * point if the path requires us to run the content * conversion. */ - if (size_only && !would_convert_to_git(&the_index, s->path)) + if (size_only && !would_convert_to_git(r->index, s->path)) return 0; /* @@ -3910,7 +3927,7 @@ int diff_populate_filespec(struct diff_filespec *s, unsigned int flags) /* * Convert from working tree format to canonical git format */ - if (convert_to_git(&the_index, s->path, s->data, s->size, &buf, conv_flags)) { + if (convert_to_git(r->index, s->path, s->data, s->size, &buf, conv_flags)) { size_t size = 0; munmap(s->data, s->size); s->should_munmap = 0; @@ -3922,8 +3939,7 @@ int diff_populate_filespec(struct diff_filespec *s, unsigned int flags) else { enum object_type type; if (size_only || (flags & CHECK_BINARY)) { - type = oid_object_info(the_repository, &s->oid, - &s->size); + type = oid_object_info(r, &s->oid, &s->size); if (type < 0) die("unable to read %s", oid_to_hex(&s->oid)); @@ -3961,7 +3977,8 @@ void diff_free_filespec_data(struct diff_filespec *s) FREE_AND_NULL(s->cnt_data); } -static void prep_temp_blob(const char *path, struct diff_tempfile *temp, +static void prep_temp_blob(struct index_state *istate, + const char *path, struct diff_tempfile *temp, void *blob, unsigned long size, const struct object_id *oid, @@ -3979,7 +3996,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(&the_index, path, + if (convert_to_working_tree(istate, path, (const char *)blob, (size_t)size, &buf)) { blob = buf.buf; size = buf.len; @@ -3995,8 +4012,9 @@ static void prep_temp_blob(const char *path, struct diff_tempfile *temp, free(path_dup); } -static struct diff_tempfile *prepare_temp_file(const char *name, - struct diff_filespec *one) +static struct diff_tempfile *prepare_temp_file(struct repository *r, + const char *name, + struct diff_filespec *one) { struct diff_tempfile *temp = claim_diff_tempfile(); @@ -4013,7 +4031,7 @@ static struct diff_tempfile *prepare_temp_file(const char *name, if (!S_ISGITLINK(one->mode) && (!one->oid_valid || - reuse_worktree_file(name, &one->oid, 1))) { + reuse_worktree_file(r->index, name, &one->oid, 1))) { struct stat st; if (lstat(name, &st) < 0) { if (errno == ENOENT) @@ -4024,7 +4042,7 @@ static struct diff_tempfile *prepare_temp_file(const char *name, struct strbuf sb = STRBUF_INIT; if (strbuf_readlink(&sb, name, st.st_size) < 0) die_errno("readlink(%s)", name); - prep_temp_blob(name, temp, sb.buf, sb.len, + prep_temp_blob(r->index, name, temp, sb.buf, sb.len, (one->oid_valid ? &one->oid : &null_oid), (one->oid_valid ? @@ -4049,19 +4067,21 @@ static struct diff_tempfile *prepare_temp_file(const char *name, return temp; } else { - if (diff_populate_filespec(one, 0)) + if (diff_populate_filespec(r, one, 0)) die("cannot read data blob for %s", one->path); - prep_temp_blob(name, temp, one->data, one->size, + prep_temp_blob(r->index, name, temp, + one->data, one->size, &one->oid, one->mode); } return temp; } -static void add_external_diff_name(struct argv_array *argv, +static void add_external_diff_name(struct repository *r, + struct argv_array *argv, const char *name, struct diff_filespec *df) { - struct diff_tempfile *temp = prepare_temp_file(name, df); + struct diff_tempfile *temp = prepare_temp_file(r, name, df); argv_array_push(argv, temp->name); argv_array_push(argv, temp->hex); argv_array_push(argv, temp->mode); @@ -4090,11 +4110,11 @@ static void run_external_diff(const char *pgm, argv_array_push(&argv, name); if (one && two) { - add_external_diff_name(&argv, name, one); + add_external_diff_name(o->repo, &argv, name, one); if (!other) - add_external_diff_name(&argv, name, two); + add_external_diff_name(o->repo, &argv, name, two); else { - add_external_diff_name(&argv, other, two); + add_external_diff_name(o->repo, &argv, other, two); argv_array_push(&argv, other); argv_array_push(&argv, xfrm_msg); } @@ -4187,8 +4207,10 @@ static void fill_metainfo(struct strbuf *msg, if (o->flags.binary) { mmfile_t mf; - if ((!fill_mmfile(&mf, one) && diff_filespec_is_binary(one)) || - (!fill_mmfile(&mf, two) && diff_filespec_is_binary(two))) + if ((!fill_mmfile(o->repo, &mf, one) && + diff_filespec_is_binary(o->repo, one)) || + (!fill_mmfile(o->repo, &mf, two) && + diff_filespec_is_binary(o->repo, two))) abbrev = hexsz; } strbuf_addf(msg, "%s%sindex %s..%s", line_prefix, set, @@ -4216,7 +4238,9 @@ static void run_diff_cmd(const char *pgm, if (o->flags.allow_external) { - struct userdiff_driver *drv = userdiff_find_by_path(attr_path); + struct userdiff_driver *drv; + + drv = userdiff_find_by_path(o->repo->index, attr_path); if (drv && drv->external) pgm = drv->external; } @@ -4245,7 +4269,7 @@ static void run_diff_cmd(const char *pgm, fprintf(o->file, "* Unmerged path %s\n", name); } -static void diff_fill_oid_info(struct diff_filespec *one) +static void diff_fill_oid_info(struct diff_filespec *one, struct index_state *istate) { if (DIFF_FILE_VALID(one)) { if (!one->oid_valid) { @@ -4256,7 +4280,7 @@ static void diff_fill_oid_info(struct diff_filespec *one) } if (lstat(one->path, &st) < 0) die_errno("stat '%s'", one->path); - if (index_path(&one->oid, one->path, &st, 0)) + if (index_path(istate, &one->oid, one->path, &st, 0)) die("cannot hash %s", one->path); } } @@ -4304,8 +4328,8 @@ static void run_diff(struct diff_filepair *p, struct diff_options *o) return; } - diff_fill_oid_info(one); - diff_fill_oid_info(two); + diff_fill_oid_info(one, o->repo->index); + diff_fill_oid_info(two, o->repo->index); if (!pgm && DIFF_FILE_VALID(one) && DIFF_FILE_VALID(two) && @@ -4316,7 +4340,8 @@ static void run_diff(struct diff_filepair *p, struct diff_options *o) */ struct diff_filespec *null = alloc_filespec(two->path); run_diff_cmd(NULL, name, other, attr_path, - one, null, &msg, o, p); + one, null, &msg, + o, p); free(null); strbuf_release(&msg); @@ -4340,7 +4365,8 @@ static void run_diffstat(struct diff_filepair *p, struct diff_options *o, if (DIFF_PAIR_UNMERGED(p)) { /* unmerged */ - builtin_diffstat(p->one->path, NULL, NULL, NULL, diffstat, o, p); + builtin_diffstat(p->one->path, NULL, NULL, NULL, + diffstat, o, p); return; } @@ -4350,10 +4376,11 @@ static void run_diffstat(struct diff_filepair *p, struct diff_options *o, if (o->prefix_length) strip_prefix(o->prefix_length, &name, &other); - diff_fill_oid_info(p->one); - diff_fill_oid_info(p->two); + diff_fill_oid_info(p->one, o->repo->index); + diff_fill_oid_info(p->two, o->repo->index); - builtin_diffstat(name, other, p->one, p->two, diffstat, o, p); + builtin_diffstat(name, other, p->one, p->two, + diffstat, o, p); } static void run_checkdiff(struct diff_filepair *p, struct diff_options *o) @@ -4374,17 +4401,18 @@ static void run_checkdiff(struct diff_filepair *p, struct diff_options *o) if (o->prefix_length) strip_prefix(o->prefix_length, &name, &other); - diff_fill_oid_info(p->one); - diff_fill_oid_info(p->two); + diff_fill_oid_info(p->one, o->repo->index); + diff_fill_oid_info(p->two, o->repo->index); builtin_checkdiff(name, other, attr_path, p->one, p->two, o); } -void diff_setup(struct diff_options *options) +void repo_diff_setup(struct repository *r, struct diff_options *options) { memcpy(options, &default_diff_options, sizeof(*options)); options->file = stdout; + options->repo = r; options->output_indicators[OUTPUT_INDICATOR_NEW] = '+'; options->output_indicators[OUTPUT_INDICATOR_OLD] = '-'; @@ -5683,8 +5711,8 @@ static int diff_get_patch_id(struct diff_options *options, struct object_id *oid if (DIFF_PAIR_UNMERGED(p)) continue; - diff_fill_oid_info(p->one); - diff_fill_oid_info(p->two); + diff_fill_oid_info(p->one, options->repo->index); + diff_fill_oid_info(p->two, options->repo->index); len1 = remove_space(p->one->path, strlen(p->one->path)); len2 = remove_space(p->two->path, strlen(p->two->path)); @@ -5716,12 +5744,12 @@ static int diff_get_patch_id(struct diff_options *options, struct object_id *oid if (diff_header_only) continue; - if (fill_mmfile(&mf1, p->one) < 0 || - fill_mmfile(&mf2, p->two) < 0) + if (fill_mmfile(options->repo, &mf1, p->one) < 0 || + fill_mmfile(options->repo, &mf2, p->two) < 0) return error("unable to read files to diff"); - if (diff_filespec_is_binary(p->one) || - diff_filespec_is_binary(p->two)) { + if (diff_filespec_is_binary(options->repo, p->one) || + diff_filespec_is_binary(options->repo, p->two)) { git_SHA1_Update(&ctx, oid_to_hex(&p->one->oid), GIT_SHA1_HEXSZ); git_SHA1_Update(&ctx, oid_to_hex(&p->two->oid), @@ -6024,19 +6052,21 @@ static void diffcore_apply_filter(struct diff_options *options) } /* Check whether two filespecs with the same mode and size are identical */ -static int diff_filespec_is_identical(struct diff_filespec *one, +static int diff_filespec_is_identical(struct repository *r, + struct diff_filespec *one, struct diff_filespec *two) { if (S_ISGITLINK(one->mode)) return 0; - if (diff_populate_filespec(one, 0)) + if (diff_populate_filespec(r, one, 0)) return 0; - if (diff_populate_filespec(two, 0)) + if (diff_populate_filespec(r, two, 0)) return 0; return !memcmp(one->data, two->data, one->size); } -static int diff_filespec_check_stat_unmatch(struct diff_filepair *p) +static int diff_filespec_check_stat_unmatch(struct repository *r, + struct diff_filepair *p) { if (p->done_skip_stat_unmatch) return p->skip_stat_unmatch_result; @@ -6060,10 +6090,10 @@ static int diff_filespec_check_stat_unmatch(struct diff_filepair *p) !DIFF_FILE_VALID(p->two) || (p->one->oid_valid && p->two->oid_valid) || (p->one->mode != p->two->mode) || - diff_populate_filespec(p->one, CHECK_SIZE_ONLY) || - diff_populate_filespec(p->two, CHECK_SIZE_ONLY) || + diff_populate_filespec(r, p->one, CHECK_SIZE_ONLY) || + diff_populate_filespec(r, p->two, CHECK_SIZE_ONLY) || (p->one->size != p->two->size) || - !diff_filespec_is_identical(p->one, p->two)) /* (2) */ + !diff_filespec_is_identical(r, p->one, p->two)) /* (2) */ p->skip_stat_unmatch_result = 1; return p->skip_stat_unmatch_result; } @@ -6078,7 +6108,7 @@ static void diffcore_skip_stat_unmatch(struct diff_options *diffopt) for (i = 0; i < q->nr; i++) { struct diff_filepair *p = q->queue[i]; - if (diff_filespec_check_stat_unmatch(p)) + if (diff_filespec_check_stat_unmatch(diffopt->repo, p)) diff_q(&outq, p); else { /* @@ -6120,7 +6150,8 @@ void diffcore_std(struct diff_options *options) if (!options->found_follow) { /* See try_to_follow_renames() in tree-diff.c */ if (options->break_opt != -1) - diffcore_break(options->break_opt); + diffcore_break(options->repo, + options->break_opt); if (options->detect_rename) diffcore_rename(options); if (options->break_opt != -1) @@ -6271,7 +6302,7 @@ void diff_change(struct diff_options *options, return; if (options->flags.quick && options->skip_stat_unmatch && - !diff_filespec_check_stat_unmatch(p)) + !diff_filespec_check_stat_unmatch(options->repo, p)) return; options->flags.has_changes = 1; @@ -6293,8 +6324,10 @@ struct diff_filepair *diff_unmerge(struct diff_options *options, const char *pat return pair; } -static char *run_textconv(const char *pgm, struct diff_filespec *spec, - size_t *outsize) +static char *run_textconv(struct repository *r, + const char *pgm, + struct diff_filespec *spec, + size_t *outsize) { struct diff_tempfile *temp; const char *argv[3]; @@ -6303,7 +6336,7 @@ static char *run_textconv(const char *pgm, struct diff_filespec *spec, struct strbuf buf = STRBUF_INIT; int err = 0; - temp = prepare_temp_file(spec->path, spec); + temp = prepare_temp_file(r, spec->path, spec); *arg++ = pgm; *arg++ = temp->name; *arg = NULL; @@ -6330,7 +6363,8 @@ static char *run_textconv(const char *pgm, struct diff_filespec *spec, return strbuf_detach(&buf, outsize); } -size_t fill_textconv(struct userdiff_driver *driver, +size_t fill_textconv(struct repository *r, + struct userdiff_driver *driver, struct diff_filespec *df, char **outbuf) { @@ -6341,7 +6375,7 @@ size_t fill_textconv(struct userdiff_driver *driver, *outbuf = ""; return 0; } - if (diff_populate_filespec(df, 0)) + if (diff_populate_filespec(r, df, 0)) die("unable to read files to diff"); *outbuf = df->data; return df->size; @@ -6358,7 +6392,7 @@ size_t fill_textconv(struct userdiff_driver *driver, return size; } - *outbuf = run_textconv(driver->textconv, df, &size); + *outbuf = run_textconv(r, driver->textconv, df, &size); if (!*outbuf) die("unable to read files to diff"); @@ -6378,7 +6412,8 @@ size_t fill_textconv(struct userdiff_driver *driver, return size; } -int textconv_object(const char *path, +int textconv_object(struct repository *r, + const char *path, unsigned mode, const struct object_id *oid, int oid_valid, @@ -6390,13 +6425,13 @@ int textconv_object(const char *path, df = alloc_filespec(path); fill_filespec(df, oid, oid_valid, mode); - textconv = get_textconv(df); + textconv = get_textconv(r->index, df); if (!textconv) { free_filespec(df); return 0; } - *buf_size = fill_textconv(textconv, df, buf); + *buf_size = fill_textconv(r, textconv, df, buf); free_filespec(df); return 1; } @@ -18,6 +18,7 @@ struct userdiff_driver; struct oid_array; struct commit; struct combine_diff_path; +struct repository; typedef int (*pathchange_fn_t)(struct diff_options *options, struct combine_diff_path *path); @@ -225,6 +226,8 @@ struct diff_options { /* XDF_WHITESPACE_FLAGS regarding block detection are set at 2, 3, 4 */ #define COLOR_MOVED_WS_ALLOW_INDENTATION_CHANGE (1<<5) int color_moved_ws_handling; + + struct repository *repo; }; void diff_emit_submodule_del(struct diff_options *o, const char *line); @@ -338,7 +341,10 @@ int git_diff_basic_config(const char *var, const char *value, void *cb); int git_diff_heuristic_config(const char *var, const char *value, void *cb); void init_diff_ui_defaults(void); int git_diff_ui_config(const char *var, const char *value, void *cb); -void diff_setup(struct diff_options *); +#ifndef NO_THE_REPOSITORY_COMPATIBILITY_MACROS +#define diff_setup(diffopts) repo_diff_setup(the_repository, diffopts) +#endif +void repo_diff_setup(struct repository *, struct diff_options *); int diff_opt_parse(struct diff_options *, const char **, int, const char *); void diff_setup_done(struct diff_options *); int git_config_rename(const char *var, const char *value); @@ -428,7 +434,7 @@ int diff_flush_patch_id(struct diff_options *, struct object_id *, int); int diff_result_code(struct diff_options *, int); -void diff_no_index(struct rev_info *, int, const char **); +void diff_no_index(struct repository *, struct rev_info *, int, const char **); int index_differs_from(const char *def, const struct diff_flags *flags, int ita_invisible_in_index); @@ -444,7 +450,8 @@ int index_differs_from(const char *def, const struct diff_flags *flags, * struct. If it is non-NULL, then "outbuf" points to a newly allocated buffer * that should be freed by the caller. */ -size_t fill_textconv(struct userdiff_driver *driver, +size_t fill_textconv(struct repository *r, + struct userdiff_driver *driver, struct diff_filespec *df, char **outbuf); @@ -453,14 +460,19 @@ size_t fill_textconv(struct userdiff_driver *driver, * and only if it has textconv enabled (otherwise return NULL). The result * can be passed to fill_textconv(). */ -struct userdiff_driver *get_textconv(struct diff_filespec *one); +struct userdiff_driver *get_textconv(struct index_state *istate, + struct diff_filespec *one); /* * Prepare diff_filespec and convert it using diff textconv API * if the textconv driver exists. * Return 1 if the conversion succeeds, 0 otherwise. */ -int textconv_object(const char *path, unsigned mode, const struct object_id *oid, int oid_valid, char **buf, unsigned long *buf_size); +int textconv_object(struct repository *repo, + const char *path, + unsigned mode, + const struct object_id *oid, int oid_valid, + char **buf, unsigned long *buf_size); int parse_rename_score(const char **cp_p); diff --git a/diffcore-break.c b/diffcore-break.c index e11fcfdb39..875aefd3fe 100644 --- a/diffcore-break.c +++ b/diffcore-break.c @@ -5,7 +5,8 @@ #include "diff.h" #include "diffcore.h" -static int should_break(struct diff_filespec *src, +static int should_break(struct repository *r, + struct diff_filespec *src, struct diff_filespec *dst, int break_score, int *merge_score_p) @@ -61,7 +62,8 @@ static int should_break(struct diff_filespec *src, oideq(&src->oid, &dst->oid)) return 0; /* they are the same */ - if (diff_populate_filespec(src, 0) || diff_populate_filespec(dst, 0)) + if (diff_populate_filespec(r, src, 0) || + diff_populate_filespec(r, dst, 0)) return 0; /* error but caught downstream */ max_size = ((src->size > dst->size) ? src->size : dst->size); @@ -71,7 +73,7 @@ static int should_break(struct diff_filespec *src, if (!src->size) return 0; /* we do not let empty files get renamed */ - if (diffcore_count_changes(src, dst, + if (diffcore_count_changes(r, src, dst, &src->cnt_data, &dst->cnt_data, &src_copied, &literal_added)) return 0; @@ -114,7 +116,7 @@ static int should_break(struct diff_filespec *src, return 1; } -void diffcore_break(int break_score) +void diffcore_break(struct repository *r, int break_score) { struct diff_queue_struct *q = &diff_queued_diff; struct diff_queue_struct outq; @@ -178,7 +180,7 @@ void diffcore_break(int break_score) object_type(p->one->mode) == OBJ_BLOB && object_type(p->two->mode) == OBJ_BLOB && !strcmp(p->one->path, p->two->path)) { - if (should_break(p->one, p->two, + if (should_break(r, p->one, p->two, break_score, &score)) { /* Split this into delete and create */ struct diff_filespec *null_one, *null_two; diff --git a/diffcore-delta.c b/diffcore-delta.c index c83d45a047..5668ace60d 100644 --- a/diffcore-delta.c +++ b/diffcore-delta.c @@ -121,14 +121,15 @@ static int spanhash_cmp(const void *a_, const void *b_) a->hashval > b->hashval ? 1 : 0; } -static struct spanhash_top *hash_chars(struct diff_filespec *one) +static struct spanhash_top *hash_chars(struct repository *r, + struct diff_filespec *one) { int i, n; unsigned int accum1, accum2, hashval; struct spanhash_top *hash; unsigned char *buf = one->data; unsigned int sz = one->size; - int is_text = !diff_filespec_is_binary(one); + int is_text = !diff_filespec_is_binary(r, one); i = INITIAL_HASH_SIZE; hash = xmalloc(st_add(sizeof(*hash), @@ -162,7 +163,8 @@ static struct spanhash_top *hash_chars(struct diff_filespec *one) return hash; } -int diffcore_count_changes(struct diff_filespec *src, +int diffcore_count_changes(struct repository *r, + struct diff_filespec *src, struct diff_filespec *dst, void **src_count_p, void **dst_count_p, @@ -177,14 +179,14 @@ int diffcore_count_changes(struct diff_filespec *src, if (src_count_p) src_count = *src_count_p; if (!src_count) { - src_count = hash_chars(src); + src_count = hash_chars(r, src); if (src_count_p) *src_count_p = src_count; } if (dst_count_p) dst_count = *dst_count_p; if (!dst_count) { - dst_count = hash_chars(dst); + dst_count = hash_chars(r, dst); if (dst_count_p) *dst_count_p = dst_count; } diff --git a/diffcore-pickaxe.c b/diffcore-pickaxe.c index 800a899c86..d2361e06a1 100644 --- a/diffcore-pickaxe.c +++ b/diffcore-pickaxe.c @@ -139,8 +139,8 @@ static int pickaxe_match(struct diff_filepair *p, struct diff_options *o, return 0; if (o->flags.allow_textconv) { - textconv_one = get_textconv(p->one); - textconv_two = get_textconv(p->two); + textconv_one = get_textconv(o->repo->index, p->one); + textconv_two = get_textconv(o->repo->index, p->two); } /* @@ -153,8 +153,8 @@ static int pickaxe_match(struct diff_filepair *p, struct diff_options *o, if (textconv_one == textconv_two && diff_unmodified_pair(p)) return 0; - mf1.size = fill_textconv(textconv_one, p->one, &mf1.ptr); - mf2.size = fill_textconv(textconv_two, p->two, &mf2.ptr); + mf1.size = fill_textconv(o->repo, textconv_one, p->one, &mf1.ptr); + mf2.size = fill_textconv(o->repo, textconv_two, p->two, &mf2.ptr); ret = fn(DIFF_FILE_VALID(p->one) ? &mf1 : NULL, DIFF_FILE_VALID(p->two) ? &mf2 : NULL, diff --git a/diffcore-rename.c b/diffcore-rename.c index daddd9b28a..07bd34b631 100644 --- a/diffcore-rename.c +++ b/diffcore-rename.c @@ -128,7 +128,8 @@ struct diff_score { short name_score; }; -static int estimate_similarity(struct diff_filespec *src, +static int estimate_similarity(struct repository *r, + struct diff_filespec *src, struct diff_filespec *dst, int minimum_score) { @@ -165,10 +166,10 @@ static int estimate_similarity(struct diff_filespec *src, * say whether the size is valid or not!) */ if (!src->cnt_data && - diff_populate_filespec(src, CHECK_SIZE_ONLY)) + diff_populate_filespec(r, src, CHECK_SIZE_ONLY)) return 0; if (!dst->cnt_data && - diff_populate_filespec(dst, CHECK_SIZE_ONLY)) + diff_populate_filespec(r, dst, CHECK_SIZE_ONLY)) return 0; max_size = ((src->size > dst->size) ? src->size : dst->size); @@ -186,12 +187,12 @@ static int estimate_similarity(struct diff_filespec *src, if (max_size * (MAX_SCORE-minimum_score) < delta_size * MAX_SCORE) return 0; - if (!src->cnt_data && diff_populate_filespec(src, 0)) + if (!src->cnt_data && diff_populate_filespec(r, src, 0)) return 0; - if (!dst->cnt_data && diff_populate_filespec(dst, 0)) + if (!dst->cnt_data && diff_populate_filespec(r, dst, 0)) return 0; - if (diffcore_count_changes(src, dst, + if (diffcore_count_changes(r, src, dst, &src->cnt_data, &dst->cnt_data, &src_copied, &literal_added)) return 0; @@ -256,10 +257,11 @@ struct file_similarity { struct diff_filespec *filespec; }; -static unsigned int hash_filespec(struct diff_filespec *filespec) +static unsigned int hash_filespec(struct repository *r, + struct diff_filespec *filespec) { if (!filespec->oid_valid) { - if (diff_populate_filespec(filespec, 0)) + if (diff_populate_filespec(r, filespec, 0)) return 0; hash_object_file(filespec->data, filespec->size, "blob", &filespec->oid); @@ -280,7 +282,9 @@ static int find_identical_files(struct hashmap *srcs, /* * Find the best source match for specified destination. */ - p = hashmap_get_from_hash(srcs, hash_filespec(target), NULL); + p = hashmap_get_from_hash(srcs, + hash_filespec(options->repo, target), + NULL); for (; p; p = hashmap_get_next(srcs, p)) { int score; struct diff_filespec *source = p->filespec; @@ -316,14 +320,16 @@ static int find_identical_files(struct hashmap *srcs, return renames; } -static void insert_file_table(struct hashmap *table, int index, struct diff_filespec *filespec) +static void insert_file_table(struct repository *r, + struct hashmap *table, int index, + struct diff_filespec *filespec) { struct file_similarity *entry = xmalloc(sizeof(*entry)); entry->index = index; entry->filespec = filespec; - hashmap_entry_init(entry, hash_filespec(filespec)); + hashmap_entry_init(entry, hash_filespec(r, filespec)); hashmap_add(table, entry); } @@ -344,7 +350,9 @@ static int find_exact_renames(struct diff_options *options) */ hashmap_init(&file_table, NULL, NULL, rename_src_nr); for (i = rename_src_nr-1; i >= 0; i--) - insert_file_table(&file_table, i, rename_src[i].p->one); + insert_file_table(options->repo, + &file_table, i, + rename_src[i].p->one); /* Walk the destinations and find best source match */ for (i = 0; i < rename_dst_nr; i++) @@ -557,7 +565,8 @@ void diffcore_rename(struct diff_options *options) diff_unmodified_pair(rename_src[j].p)) continue; - this_src.score = estimate_similarity(one, two, + this_src.score = estimate_similarity(options->repo, + one, two, minimum_score); this_src.name_score = basename_same(one, two); this_src.dst = i; diff --git a/diffcore.h b/diffcore.h index 8d81a45f51..b651061c0e 100644 --- a/diffcore.h +++ b/diffcore.h @@ -7,6 +7,8 @@ #include "cache.h" struct diff_options; +struct repository; +struct userdiff_driver; /* This header file is internal between diff.c and its diff transformers * (e.g. diffcore-rename, diffcore-pickaxe). Never include this header @@ -26,8 +28,6 @@ struct diff_options; #define MINIMUM_BREAK_SIZE 400 /* do not break a file smaller than this */ -struct userdiff_driver; - struct diff_filespec { struct object_id oid; char *path; @@ -61,10 +61,10 @@ void fill_filespec(struct diff_filespec *, const struct object_id *, #define CHECK_SIZE_ONLY 1 #define CHECK_BINARY 2 -int diff_populate_filespec(struct diff_filespec *, unsigned int); +int diff_populate_filespec(struct repository *, struct diff_filespec *, unsigned int); void diff_free_filespec_data(struct diff_filespec *); void diff_free_filespec_blob(struct diff_filespec *); -int diff_filespec_is_binary(struct diff_filespec *); +int diff_filespec_is_binary(struct repository *, struct diff_filespec *); struct diff_filepair { struct diff_filespec *one; @@ -111,7 +111,7 @@ struct diff_filepair *diff_queue(struct diff_queue_struct *, struct diff_filespec *); void diff_q(struct diff_queue_struct *, struct diff_filepair *); -void diffcore_break(int); +void diffcore_break(struct repository *, int); void diffcore_rename(struct diff_options *); void diffcore_merge_broken(void); void diffcore_pickaxe(struct diff_options *); @@ -142,7 +142,8 @@ void diff_debug_queue(const char *, struct diff_queue_struct *); #define diff_debug_queue(a,b) do { /* nothing */ } while (0) #endif -int diffcore_count_changes(struct diff_filespec *src, +int diffcore_count_changes(struct repository *r, + struct diff_filespec *src, struct diff_filespec *dst, void **src_count_p, void **dst_count_p, @@ -11,7 +11,8 @@ #include "help.h" static int grep_source_load(struct grep_source *gs); -static int grep_source_is_binary(struct grep_source *gs); +static int grep_source_is_binary(struct grep_source *gs, + struct index_state *istate); static struct grep_opt grep_defaults; @@ -42,7 +43,7 @@ static void color_set(char *dst, const char *color_bytes) * We could let the compiler do this, but without C99 initializers * the code gets unwieldy and unreadable, so... */ -void init_grep_defaults(void) +void init_grep_defaults(struct repository *repo) { struct grep_opt *opt = &grep_defaults; static int run_once; @@ -52,6 +53,7 @@ void init_grep_defaults(void) run_once++; memset(opt, 0, sizeof(*opt)); + opt->repo = repo; opt->relative = 1; opt->pathname = 1; opt->max_depth = -1; @@ -149,12 +151,13 @@ int grep_config(const char *var, const char *value, void *cb) * default values from the template we read the configuration * information in an earlier call to git_config(grep_config). */ -void grep_init(struct grep_opt *opt, const char *prefix) +void grep_init(struct grep_opt *opt, struct repository *repo, const char *prefix) { struct grep_opt *def = &grep_defaults; int i; memset(opt, 0, sizeof(*opt)); + opt->repo = repo; opt->prefix = prefix; opt->prefix_length = (prefix && *prefix) ? strlen(prefix) : 0; opt->pattern_tail = &opt->pattern_list; @@ -1545,7 +1548,7 @@ static int match_funcname(struct grep_opt *opt, struct grep_source *gs, char *bo { xdemitconf_t *xecfg = opt->priv; if (xecfg && !xecfg->find_func) { - grep_source_load_driver(gs); + grep_source_load_driver(gs, opt->repo->index); if (gs->driver->funcname.pattern) { const struct userdiff_funcname *pe = &gs->driver->funcname; xdiff_set_find_func(xecfg, pe->pattern, pe->cflags); @@ -1708,7 +1711,8 @@ static int look_ahead(struct grep_opt *opt, return 0; } -static int fill_textconv_grep(struct userdiff_driver *driver, +static int fill_textconv_grep(struct repository *r, + struct userdiff_driver *driver, struct grep_source *gs) { struct diff_filespec *df; @@ -1741,7 +1745,7 @@ static int fill_textconv_grep(struct userdiff_driver *driver, * structure. */ grep_read_lock(); - size = fill_textconv(driver, df, &buf); + size = fill_textconv(r, driver, df, &buf); grep_read_unlock(); free_filespec(df); @@ -1801,7 +1805,7 @@ static int grep_source_1(struct grep_opt *opt, struct grep_source *gs, int colle opt->last_shown = 0; if (opt->allow_textconv) { - grep_source_load_driver(gs); + grep_source_load_driver(gs, opt->repo->index); /* * We might set up the shared textconv cache data here, which * is not thread-safe. @@ -1818,11 +1822,11 @@ static int grep_source_1(struct grep_opt *opt, struct grep_source *gs, int colle if (!textconv) { switch (opt->binary) { case GREP_BINARY_DEFAULT: - if (grep_source_is_binary(gs)) + if (grep_source_is_binary(gs, opt->repo->index)) binary_match_only = 1; break; case GREP_BINARY_NOMATCH: - if (grep_source_is_binary(gs)) + if (grep_source_is_binary(gs, opt->repo->index)) return 0; /* Assume unmatch */ break; case GREP_BINARY_TEXT: @@ -1837,7 +1841,7 @@ static int grep_source_1(struct grep_opt *opt, struct grep_source *gs, int colle try_lookahead = should_lookahead(opt); - if (fill_textconv_grep(textconv, gs) < 0) + if (fill_textconv_grep(opt->repo, textconv, gs) < 0) return 0; bol = gs->buf; @@ -2168,22 +2172,24 @@ static int grep_source_load(struct grep_source *gs) BUG("invalid grep_source type to load"); } -void grep_source_load_driver(struct grep_source *gs) +void grep_source_load_driver(struct grep_source *gs, + struct index_state *istate) { if (gs->driver) return; grep_attr_lock(); if (gs->path) - gs->driver = userdiff_find_by_path(gs->path); + gs->driver = userdiff_find_by_path(istate, gs->path); if (!gs->driver) gs->driver = userdiff_find_by_name("default"); grep_attr_unlock(); } -static int grep_source_is_binary(struct grep_source *gs) +static int grep_source_is_binary(struct grep_source *gs, + struct index_state *istate) { - grep_source_load_driver(gs); + grep_source_load_driver(gs, istate); if (gs->driver->binary != -1) return gs->driver->binary; @@ -36,6 +36,8 @@ typedef int pcre2_jit_stack; #include "thread-utils.h" #include "userdiff.h" +struct repository; + enum grep_pat_token { GREP_PATTERN, GREP_PATTERN_HEAD, @@ -136,6 +138,7 @@ struct grep_opt { struct grep_pat *header_list; struct grep_pat **header_tail; struct grep_expr *pattern_expression; + struct repository *repo; const char *prefix; int prefix_length; regex_t regexp; @@ -183,9 +186,9 @@ struct grep_opt { void *output_priv; }; -extern void init_grep_defaults(void); +extern void init_grep_defaults(struct repository *); extern int grep_config(const char *var, const char *value, void *); -extern void grep_init(struct grep_opt *, const char *prefix); +extern void grep_init(struct grep_opt *, struct repository *repo, const char *prefix); void grep_commit_pattern_type(enum grep_pattern_type, struct grep_opt *opt); extern void append_grep_pat(struct grep_opt *opt, const char *pat, size_t patlen, const char *origin, int no, enum grep_pat_token t); @@ -217,7 +220,8 @@ void grep_source_init(struct grep_source *gs, enum grep_source_type type, const void *identifier); void grep_source_clear_data(struct grep_source *gs); void grep_source_clear(struct grep_source *gs); -void grep_source_load_driver(struct grep_source *gs); +void grep_source_load_driver(struct grep_source *gs, + struct index_state *istate); int grep_source(struct grep_opt *opt, struct grep_source *gs); diff --git a/http-push.c b/http-push.c index 1bbb0cdb6d..d1f52cbdf6 100644 --- a/http-push.c +++ b/http-push.c @@ -1925,7 +1925,7 @@ int cmd_main(int argc, const char **argv) if (!push_all && !is_null_oid(&ref->old_oid)) argv_array_pushf(&commit_argv, "^%s", oid_to_hex(&ref->old_oid)); - init_revisions(&revs, setup_git_directory()); + repo_init_revisions(the_repository, &revs, setup_git_directory()); setup_revisions(commit_argv.argc, commit_argv.argv, &revs, NULL); revs.edge_hint = 0; /* just in case */ diff --git a/line-log.c b/line-log.c index 72a5fed661..d1d429d738 100644 --- a/line-log.c +++ b/line-log.c @@ -508,7 +508,9 @@ static void fill_blob_sha1(struct commit *commit, struct diff_filespec *spec) return; } -static void fill_line_ends(struct diff_filespec *spec, long *lines, +static void fill_line_ends(struct repository *r, + struct diff_filespec *spec, + long *lines, unsigned long **line_ends) { int num = 0, size = 50; @@ -516,7 +518,7 @@ static void fill_line_ends(struct diff_filespec *spec, long *lines, unsigned long *ends = NULL; char *data = NULL; - if (diff_populate_filespec(spec, 0)) + if (diff_populate_filespec(r, spec, 0)) die("Cannot read blob %s", oid_to_hex(&spec->oid)); ALLOC_ARRAY(ends, size); @@ -555,7 +557,8 @@ static const char *nth_line(void *data, long line) } static struct line_log_data * -parse_lines(struct commit *commit, const char *prefix, struct string_list *args) +parse_lines(struct repository *r, struct commit *commit, + const char *prefix, struct string_list *args) { long lines = 0; unsigned long *ends = NULL; @@ -571,7 +574,7 @@ parse_lines(struct commit *commit, const char *prefix, struct string_list *args) long begin = 0, end = 0; long anchor; - name_part = skip_range_arg(item->string); + name_part = skip_range_arg(item->string, r->index); if (!name_part || *name_part != ':' || !name_part[1]) die("-L argument not 'start,end:file' or ':funcname:file': %s", item->string); @@ -583,7 +586,7 @@ parse_lines(struct commit *commit, const char *prefix, struct string_list *args) spec = alloc_filespec(full_name); fill_blob_sha1(commit, spec); - fill_line_ends(spec, &lines, &ends); + fill_line_ends(r, spec, &lines, &ends); cb_data.spec = spec; cb_data.lines = lines; cb_data.line_ends = ends; @@ -596,7 +599,7 @@ parse_lines(struct commit *commit, const char *prefix, struct string_list *args) if (parse_range_arg(range_part, nth_line, &cb_data, lines, anchor, &begin, &end, - full_name)) + full_name, r->index)) die("malformed -L argument '%s'", range_part); if ((!lines && (begin || end)) || lines < begin) die("file %s has only %lu lines", name_part, lines); @@ -739,7 +742,7 @@ void line_log_init(struct rev_info *rev, const char *prefix, struct string_list struct line_log_data *range; commit = check_single_commit(rev); - range = parse_lines(commit, prefix, args); + range = parse_lines(rev->diffopt.repo, commit, prefix, args); add_line_range(rev, commit, range); if (!rev->diffopt.detect_rename) { @@ -891,8 +894,8 @@ static void dump_diff_hacky_one(struct rev_info *rev, struct line_log_data *rang return; if (pair->one->oid_valid) - fill_line_ends(pair->one, &p_lines, &p_ends); - fill_line_ends(pair->two, &t_lines, &t_ends); + fill_line_ends(rev->diffopt.repo, pair->one, &p_lines, &p_ends); + fill_line_ends(rev->diffopt.repo, pair->two, &t_lines, &t_ends); fprintf(opt->file, "%s%sdiff --git a/%s b/%s%s\n", prefix, c_meta, pair->one->path, pair->two->path, c_reset); fprintf(opt->file, "%s%s--- %s%s%s\n", prefix, c_meta, @@ -1008,12 +1011,12 @@ static int process_diff_filepair(struct rev_info *rev, return 0; assert(pair->two->oid_valid); - diff_populate_filespec(pair->two, 0); + diff_populate_filespec(rev->diffopt.repo, pair->two, 0); file_target.ptr = pair->two->data; file_target.size = pair->two->size; if (pair->one->oid_valid) { - diff_populate_filespec(pair->one, 0); + diff_populate_filespec(rev->diffopt.repo, pair->one, 0); file_parent.ptr = pair->one->data; file_parent.size = pair->one->size; } else { diff --git a/line-range.c b/line-range.c index 232c3909ec..9b50583dc0 100644 --- a/line-range.c +++ b/line-range.c @@ -163,9 +163,10 @@ static const char *find_funcname_matching_regexp(xdemitconf_t *xecfg, const char } } -static const char *parse_range_funcname(const char *arg, nth_line_fn_t nth_line_cb, - void *cb_data, long lines, long anchor, long *begin, long *end, - const char *path) +static const char *parse_range_funcname( + const char *arg, nth_line_fn_t nth_line_cb, + void *cb_data, long lines, long anchor, long *begin, long *end, + const char *path, struct index_state *istate) { char *pattern; const char *term; @@ -198,7 +199,7 @@ static const char *parse_range_funcname(const char *arg, nth_line_fn_t nth_line_ anchor--; /* input is in human terms */ start = nth_line_cb(cb_data, anchor); - drv = userdiff_find_by_path(path); + drv = userdiff_find_by_path(istate, path); if (drv && drv->funcname.pattern) { const struct userdiff_funcname *pe = &drv->funcname; xecfg = xcalloc(1, sizeof(*xecfg)); @@ -244,7 +245,8 @@ static const char *parse_range_funcname(const char *arg, nth_line_fn_t nth_line_ int parse_range_arg(const char *arg, nth_line_fn_t nth_line_cb, void *cb_data, long lines, long anchor, - long *begin, long *end, const char *path) + long *begin, long *end, + const char *path, struct index_state *istate) { *begin = *end = 0; @@ -254,7 +256,9 @@ int parse_range_arg(const char *arg, nth_line_fn_t nth_line_cb, anchor = lines + 1; if (*arg == ':' || (*arg == '^' && *(arg + 1) == ':')) { - arg = parse_range_funcname(arg, nth_line_cb, cb_data, lines, anchor, begin, end, path); + arg = parse_range_funcname(arg, nth_line_cb, cb_data, + lines, anchor, begin, end, + path, istate); if (!arg || *arg) return -1; return 0; @@ -275,10 +279,12 @@ int parse_range_arg(const char *arg, nth_line_fn_t nth_line_cb, return 0; } -const char *skip_range_arg(const char *arg) +const char *skip_range_arg(const char *arg, struct index_state *istate) { if (*arg == ':' || (*arg == '^' && *(arg + 1) == ':')) - return parse_range_funcname(arg, NULL, NULL, 0, 0, NULL, NULL, NULL); + return parse_range_funcname(arg, NULL, NULL, + 0, 0, NULL, NULL, + NULL, istate); arg = parse_loc(arg, NULL, NULL, 0, -1, NULL); diff --git a/line-range.h b/line-range.h index d3c54e45aa..e69bf7c017 100644 --- a/line-range.h +++ b/line-range.h @@ -1,6 +1,8 @@ #ifndef LINE_RANGE_H #define LINE_RANGE_H +struct index_state; + /* * Parse one item in an -L begin,end option w.r.t. the notional file * object 'cb_data' consisting of 'lines' lines. @@ -23,7 +25,7 @@ int parse_range_arg(const char *arg, nth_line_fn_t nth_line_cb, void *cb_data, long lines, long anchor, long *begin, long *end, - const char *path); + const char *path, struct index_state *istate); /* * Scan past a range argument that could be parsed by @@ -34,6 +36,6 @@ int parse_range_arg(const char *arg, * NULL in case the argument is obviously malformed. */ -const char *skip_range_arg(const char *arg); +const char *skip_range_arg(const char *arg, struct index_state *istate); #endif /* LINE_RANGE_H */ diff --git a/list-objects.c b/list-objects.c index c99c47ac18..0c2989d5ca 100644 --- a/list-objects.c +++ b/list-objects.c @@ -196,7 +196,7 @@ static void mark_edge_parents_uninteresting(struct commit *commit, struct commit *parent = parents->item; if (!(parent->object.flags & UNINTERESTING)) continue; - mark_tree_uninteresting(get_commit_tree(parent)); + mark_tree_uninteresting(revs->repo, get_commit_tree(parent)); if (revs->edge_hint && !(parent->object.flags & SHOWN)) { parent->object.flags |= SHOWN; show_edge(parent); @@ -213,7 +213,8 @@ void mark_edges_uninteresting(struct rev_info *revs, show_edge_fn show_edge) struct commit *commit = list->item; if (commit->object.flags & UNINTERESTING) { - mark_tree_uninteresting(get_commit_tree(commit)); + mark_tree_uninteresting(revs->repo, + get_commit_tree(commit)); if (revs->edge_hint_aggressive && !(commit->object.flags & SHOWN)) { commit->object.flags |= SHOWN; show_edge(commit); @@ -228,7 +229,8 @@ void mark_edges_uninteresting(struct rev_info *revs, show_edge_fn show_edge) struct commit *commit = (struct commit *)obj; if (obj->type != OBJ_COMMIT || !(obj->flags & UNINTERESTING)) continue; - mark_tree_uninteresting(get_commit_tree(commit)); + mark_tree_uninteresting(revs->repo, + get_commit_tree(commit)); if (!(obj->flags & SHOWN)) { obj->flags |= SHOWN; show_edge(commit); diff --git a/ll-merge.c b/ll-merge.c index 1936fee9e1..3c8fb917e9 100644 --- a/ll-merge.c +++ b/ll-merge.c @@ -336,10 +336,10 @@ static const struct ll_merge_driver *find_ll_merge_driver(const char *merge_attr return &ll_merge_drv[LL_TEXT_MERGE]; } -static void normalize_file(mmfile_t *mm, const char *path) +static void normalize_file(mmfile_t *mm, const char *path, struct index_state *istate) { struct strbuf strbuf = STRBUF_INIT; - if (renormalize_buffer(&the_index, path, mm->ptr, mm->size, &strbuf)) { + if (renormalize_buffer(istate, path, mm->ptr, mm->size, &strbuf)) { free(mm->ptr); mm->size = strbuf.len; mm->ptr = strbuf_detach(&strbuf, NULL); @@ -351,6 +351,7 @@ int ll_merge(mmbuffer_t *result_buf, mmfile_t *ancestor, const char *ancestor_label, mmfile_t *ours, const char *our_label, mmfile_t *theirs, const char *their_label, + struct index_state *istate, const struct ll_merge_options *opts) { static struct attr_check *check; @@ -363,15 +364,15 @@ int ll_merge(mmbuffer_t *result_buf, opts = &default_opts; if (opts->renormalize) { - normalize_file(ancestor, path); - normalize_file(ours, path); - normalize_file(theirs, path); + normalize_file(ancestor, path, istate); + normalize_file(ours, path, istate); + normalize_file(theirs, path, istate); } if (!check) check = attr_check_initl("merge", "conflict-marker-size", NULL); - git_check_attr(&the_index, path, check); + git_check_attr(istate, path, check); ll_driver_name = check->items[0].value; if (check->items[1].value) { marker_size = atoi(check->items[1].value); @@ -390,14 +391,14 @@ int ll_merge(mmbuffer_t *result_buf, opts, marker_size); } -int ll_merge_marker_size(const char *path) +int ll_merge_marker_size(struct index_state *istate, const char *path) { static struct attr_check *check; int marker_size = DEFAULT_CONFLICT_MARKER_SIZE; if (!check) check = attr_check_initl("conflict-marker-size", NULL); - git_check_attr(&the_index, path, check); + git_check_attr(istate, path, check); if (check->items[0].value) { marker_size = atoi(check->items[0].value); if (marker_size <= 0) diff --git a/ll-merge.h b/ll-merge.h index b72b19921e..6c6e22e40d 100644 --- a/ll-merge.h +++ b/ll-merge.h @@ -7,6 +7,8 @@ #include "xdiff/xdiff.h" +struct index_state; + struct ll_merge_options { unsigned virtual_ancestor : 1; unsigned variant : 2; /* favor ours, favor theirs, or union merge */ @@ -19,8 +21,9 @@ int ll_merge(mmbuffer_t *result_buf, mmfile_t *ancestor, const char *ancestor_label, mmfile_t *ours, const char *our_label, mmfile_t *theirs, const char *their_label, + struct index_state *istate, const struct ll_merge_options *opts); -int ll_merge_marker_size(const char *path); +int ll_merge_marker_size(struct index_state *istate, const char *path); #endif diff --git a/merge-blobs.c b/merge-blobs.c index fabb8c19ce..ee0a0e90c9 100644 --- a/merge-blobs.c +++ b/merge-blobs.c @@ -29,7 +29,12 @@ static void free_mmfile(mmfile_t *f) free(f->ptr); } -static void *three_way_filemerge(const char *path, mmfile_t *base, mmfile_t *our, mmfile_t *their, unsigned long *size) +static void *three_way_filemerge(struct index_state *istate, + const char *path, + mmfile_t *base, + mmfile_t *our, + mmfile_t *their, + unsigned long *size) { int merge_status; mmbuffer_t res; @@ -41,7 +46,8 @@ static void *three_way_filemerge(const char *path, mmfile_t *base, mmfile_t *our * common ancestor. */ merge_status = ll_merge(&res, path, base, NULL, - our, ".our", their, ".their", NULL); + our, ".our", their, ".their", + istate, NULL); if (merge_status < 0) return NULL; @@ -49,7 +55,9 @@ static void *three_way_filemerge(const char *path, mmfile_t *base, mmfile_t *our return res.ptr; } -void *merge_blobs(const char *path, struct blob *base, struct blob *our, struct blob *their, unsigned long *size) +void *merge_blobs(struct index_state *istate, const char *path, + struct blob *base, struct blob *our, + struct blob *their, unsigned long *size) { void *res = NULL; mmfile_t f1, f2, common; @@ -82,7 +90,7 @@ void *merge_blobs(const char *path, struct blob *base, struct blob *our, struct common.ptr = xstrdup(""); common.size = 0; } - res = three_way_filemerge(path, &common, &f1, &f2, size); + res = three_way_filemerge(istate, path, &common, &f1, &f2, size); free_mmfile(&common); out_free_f2_f1: free_mmfile(&f2); diff --git a/merge-blobs.h b/merge-blobs.h index 62b569e472..cc31038b80 100644 --- a/merge-blobs.h +++ b/merge-blobs.h @@ -1,8 +1,11 @@ #ifndef MERGE_BLOBS_H #define MERGE_BLOBS_H -#include "blob.h" +struct blob; +struct index_state; -extern void *merge_blobs(const char *, struct blob *, struct blob *, struct blob *, unsigned long *); +extern void *merge_blobs(struct index_state *, const char *, + struct blob *, struct blob *, + struct blob *, unsigned long *); #endif /* MERGE_BLOBS_H */ diff --git a/merge-recursive.c b/merge-recursive.c index 0684dab779..c0fb83d285 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -1084,7 +1084,8 @@ static int merge_3way(struct merge_options *o, read_mmblob(&src2, &b->oid); merge_status = ll_merge(result_buf, a->path, &orig, base_name, - &src1, name1, &src2, name2, &ll_opts); + &src1, name1, &src2, name2, + &the_index, &ll_opts); free(base_name); free(name1); @@ -1115,7 +1116,7 @@ static int find_first_merges(struct object_array *result, const char *path, /* get all revisions that merge commit a */ xsnprintf(merged_revision, sizeof(merged_revision), "^%s", oid_to_hex(&a->object.oid)); - init_revisions(&revs, NULL); + repo_init_revisions(the_repository, &revs, NULL); rev_opts.submodule = path; /* FIXME: can't handle linked worktrees in submodules yet */ revs.single_worktree = path != NULL; @@ -1756,7 +1757,7 @@ static struct diff_queue_struct *get_diffpairs(struct merge_options *o, struct diff_queue_struct *ret; struct diff_options opts; - diff_setup(&opts); + repo_diff_setup(the_repository, &opts); opts.flags.recursive = 1; opts.flags.rename_empty = 0; opts.detect_rename = merge_detect_rename(o); @@ -14,7 +14,8 @@ static const char *merge_argument(struct commit *commit) return oid_to_hex(commit ? &commit->object.oid : the_hash_algo->empty_tree); } -int try_merge_command(const char *strategy, size_t xopts_nr, +int try_merge_command(struct repository *r, + const char *strategy, size_t xopts_nr, const char **xopts, struct commit_list *common, const char *head_arg, struct commit_list *remotes) { @@ -35,15 +36,16 @@ int try_merge_command(const char *strategy, size_t xopts_nr, ret = run_command_v_opt(args.argv, RUN_GIT_CMD); argv_array_clear(&args); - discard_cache(); - if (read_cache() < 0) + discard_index(r->index); + if (read_index(r->index) < 0) die(_("failed to read the cache")); - resolve_undo_clear(); + resolve_undo_clear_index(r->index); return ret; } -int checkout_fast_forward(const struct object_id *head, +int checkout_fast_forward(struct repository *r, + const struct object_id *head, const struct object_id *remote, int overwrite_ignore) { @@ -54,7 +56,7 @@ int checkout_fast_forward(const struct object_id *head, struct dir_struct dir; struct lock_file lock_file = LOCK_INIT; - refresh_cache(REFRESH_QUIET); + refresh_index(r->index, REFRESH_QUIET, NULL, NULL, NULL); if (hold_locked_index(&lock_file, LOCK_REPORT_ON_ERROR) < 0) return -1; @@ -86,8 +88,8 @@ int checkout_fast_forward(const struct object_id *head, } opts.head_idx = 1; - opts.src_index = &the_index; - opts.dst_index = &the_index; + opts.src_index = r->index; + opts.dst_index = r->index; opts.update = 1; opts.verbose_update = 1; opts.merge = 1; @@ -101,7 +103,7 @@ int checkout_fast_forward(const struct object_id *head, } clear_unpack_trees_porcelain(&opts); - if (write_locked_index(&the_index, &lock_file, COMMIT_LOCK)) + if (write_locked_index(r->index, &lock_file, COMMIT_LOCK)) return error(_("unable to write new index file")); return 0; } diff --git a/notes-merge.c b/notes-merge.c index 5764e2b0ef..bd05d50b05 100644 --- a/notes-merge.c +++ b/notes-merge.c @@ -127,7 +127,7 @@ static struct notes_merge_pair *diff_tree_remote(struct notes_merge_options *o, trace_printf("\tdiff_tree_remote(base = %.7s, remote = %.7s)\n", oid_to_hex(base), oid_to_hex(remote)); - diff_setup(&opt); + repo_diff_setup(the_repository, &opt); opt.flags.recursive = 1; opt.output_format = DIFF_FORMAT_NO_OUTPUT; diff_setup_done(&opt); @@ -190,7 +190,7 @@ static void diff_tree_local(struct notes_merge_options *o, trace_printf("\tdiff_tree_local(len = %i, base = %.7s, local = %.7s)\n", len, oid_to_hex(base), oid_to_hex(local)); - diff_setup(&opt); + repo_diff_setup(the_repository, &opt); opt.flags.recursive = 1; opt.output_format = DIFF_FORMAT_NO_OUTPUT; diff_setup_done(&opt); @@ -349,7 +349,8 @@ static int ll_merge_in_worktree(struct notes_merge_options *o, read_mmblob(&remote, &p->remote); status = ll_merge(&result_buf, oid_to_hex(&p->obj), &base, NULL, - &local, o->local_ref, &remote, o->remote_ref, NULL); + &local, o->local_ref, &remote, o->remote_ref, + &the_index, NULL); free(base.ptr); free(local.ptr); @@ -710,7 +711,7 @@ int notes_merge_commit(struct notes_merge_options *o, /* write file as blob, and add to partial_tree */ if (stat(path.buf, &st)) die_errno("Failed to stat '%s'", path.buf); - if (index_path(&blob_oid, path.buf, &st, HASH_WRITE_OBJECT)) + if (index_path(&the_index, &blob_oid, path.buf, &st, HASH_WRITE_OBJECT)) die("Failed to write blob object from '%s'", path.buf); if (add_note(partial_tree, &obj_oid, &blob_oid, NULL)) die("Failed to add resolved note '%s' to notes tree", diff --git a/pack-bitmap-write.c b/pack-bitmap-write.c index fc82f37a02..f2fd9d81ef 100644 --- a/pack-bitmap-write.c +++ b/pack-bitmap-write.c @@ -262,7 +262,7 @@ void bitmap_writer_build(struct packing_data *to_pack) if (writer.show_progress) writer.progress = start_progress("Building bitmaps", writer.selected_nr); - init_revisions(&revs, NULL); + repo_init_revisions(the_repository, &revs, NULL); revs.tag_objects = 1; revs.tree_objects = 1; revs.blob_objects = 1; diff --git a/patch-ids.c b/patch-ids.c index 960ea24054..c262e1be9c 100644 --- a/patch-ids.c +++ b/patch-ids.c @@ -56,10 +56,10 @@ static int patch_id_neq(const void *cmpfn_data, return !oideq(&a->patch_id, &b->patch_id); } -int init_patch_ids(struct patch_ids *ids) +int init_patch_ids(struct repository *r, struct patch_ids *ids) { memset(ids, 0, sizeof(*ids)); - diff_setup(&ids->diffopts); + repo_diff_setup(r, &ids->diffopts); ids->diffopts.detect_rename = 0; ids->diffopts.flags.recursive = 1; diff_setup_done(&ids->diffopts); diff --git a/patch-ids.h b/patch-ids.h index 79ac9a8498..82a12b66f8 100644 --- a/patch-ids.h +++ b/patch-ids.h @@ -6,6 +6,7 @@ struct commit; struct object_id; +struct repository; struct patch_id { struct hashmap_entry ent; @@ -20,7 +21,7 @@ struct patch_ids { int commit_patch_id(struct commit *commit, struct diff_options *options, struct object_id *oid, int); -int init_patch_ids(struct patch_ids *); +int init_patch_ids(struct repository *, struct patch_ids *); int free_patch_ids(struct patch_ids *); struct patch_id *add_commit_patch_id(struct commit *, struct patch_ids *); struct patch_id *has_commit_patch_id(struct commit *, struct patch_ids *); diff --git a/read-cache.c b/read-cache.c index 8d04d78a58..01859b7703 100644 --- a/read-cache.c +++ b/read-cache.c @@ -205,14 +205,16 @@ void fill_stat_cache_info(struct cache_entry *ce, struct stat *st) } } -static int ce_compare_data(const struct cache_entry *ce, struct stat *st) +static int ce_compare_data(struct index_state *istate, + const struct cache_entry *ce, + struct stat *st) { int match = -1; int fd = git_open_cloexec(ce->name, O_RDONLY); if (fd >= 0) { struct object_id oid; - if (!index_fd(&oid, fd, st, OBJ_BLOB, ce->name, 0)) + if (!index_fd(istate, &oid, fd, st, OBJ_BLOB, ce->name, 0)) match = !oideq(&oid, &ce->oid); /* index_fd() closed the file descriptor already */ } @@ -257,11 +259,13 @@ static int ce_compare_gitlink(const struct cache_entry *ce) return !oideq(&oid, &ce->oid); } -static int ce_modified_check_fs(const struct cache_entry *ce, struct stat *st) +static int ce_modified_check_fs(struct index_state *istate, + const struct cache_entry *ce, + struct stat *st) { switch (st->st_mode & S_IFMT) { case S_IFREG: - if (ce_compare_data(ce, st)) + if (ce_compare_data(istate, ce, st)) return DATA_CHANGED; break; case S_IFLNK: @@ -407,7 +411,7 @@ int ie_match_stat(struct index_state *istate, if (assume_racy_is_modified) changed |= DATA_CHANGED; else - changed |= ce_modified_check_fs(ce, st); + changed |= ce_modified_check_fs(istate, ce, st); } return changed; @@ -447,7 +451,7 @@ int ie_modified(struct index_state *istate, (S_ISGITLINK(ce->ce_mode) || ce->ce_stat_data.sd_size != 0)) return changed; - changed_fs = ce_modified_check_fs(ce, st); + changed_fs = ce_modified_check_fs(istate, ce, st); if (changed_fs) return changed | changed_fs; return 0; @@ -753,7 +757,7 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st, } } if (!intent_only) { - if (index_path(&ce->oid, path, st, newflags)) { + if (index_path(istate, &ce->oid, path, st, newflags)) { discard_cache_entry(ce); return error("unable to index file %s", path); } @@ -823,7 +827,7 @@ struct cache_entry *make_cache_entry(struct index_state *istate, ce->ce_namelen = len; ce->ce_mode = create_ce_mode(mode); - ret = refresh_cache_entry(&the_index, ce, refresh_options); + ret = refresh_cache_entry(istate, ce, refresh_options); if (ret != ce) discard_cache_entry(ce); return ret; @@ -1493,7 +1497,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(&the_index, ce, pathspec, seen)) + if (pathspec && !ce_path_match(istate, ce, pathspec, seen)) filtered = 1; if (ce_stage(ce)) { @@ -2123,7 +2127,7 @@ int unmerged_index(const struct index_state *istate) return 0; } -int index_has_changes(const struct index_state *istate, +int index_has_changes(struct index_state *istate, struct tree *tree, struct strbuf *sb) { @@ -2138,7 +2142,7 @@ int index_has_changes(const struct index_state *istate, if (tree || !get_oid_tree("HEAD", &cmp)) { struct diff_options opt; - diff_setup(&opt); + repo_diff_setup(the_repository, &opt); opt.flags.exit_with_status = 1; if (!sb) opt.flags.quick = 1; @@ -2231,7 +2235,8 @@ static int ce_flush(git_hash_ctx *context, int fd, unsigned char *hash) return (write_in_full(fd, write_buffer, left) < 0) ? -1 : 0; } -static void ce_smudge_racily_clean_entry(struct cache_entry *ce) +static void ce_smudge_racily_clean_entry(struct index_state *istate, + struct cache_entry *ce) { /* * The only thing we care about in this function is to smudge the @@ -2250,7 +2255,7 @@ static void ce_smudge_racily_clean_entry(struct cache_entry *ce) return; if (ce_match_stat_basic(ce, &st)) return; - if (ce_modified_check_fs(ce, &st)) { + if (ce_modified_check_fs(istate, ce, &st)) { /* This is "racily clean"; smudge it. Note that this * is a tricky code. At first glance, it may appear * that it can break with this sequence: @@ -2495,7 +2500,7 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile, if (ce->ce_flags & CE_REMOVE) continue; if (!ce_uptodate(ce) && is_racy_timestamp(istate, ce)) - ce_smudge_racily_clean_entry(ce); + ce_smudge_racily_clean_entry(istate, ce); if (is_null_oid(&ce->oid)) { static const char msg[] = "cache entry has null sha1: %s"; static int allow = -1; diff --git a/ref-filter.c b/ref-filter.c index e1bcb4ca8a..2a05619211 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -2010,7 +2010,7 @@ static void do_merge_filter(struct ref_filter_cbdata *ref_cbdata) struct ref_array *array = ref_cbdata->array; struct commit **to_clear = xcalloc(sizeof(struct commit *), array->nr); - init_revisions(&revs, NULL); + repo_init_revisions(the_repository, &revs, NULL); for (i = 0; i < array->nr; i++) { struct ref_array_item *item = array->items[i]; @@ -1855,7 +1855,7 @@ int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs, oid_to_hex(&theirs->object.oid)); argv_array_push(&argv, "--"); - init_revisions(&revs, NULL); + repo_init_revisions(the_repository, &revs, NULL); setup_revisions(argv.argc, argv.argv, &revs, NULL); if (prepare_revision_walk(&revs)) die("revision walk setup failed"); @@ -462,11 +462,12 @@ static int handle_path(unsigned char *sha1, struct rerere_io *io, int marker_siz * Scan the path for conflicts, do the "handle_path()" thing above, and * return the number of conflict hunks found. */ -static int handle_file(const char *path, unsigned char *sha1, const char *output) +static int handle_file(struct index_state *istate, const char *path, + unsigned char *sha1, const char *output) { int has_conflicts = 0; struct rerere_io_file io; - int marker_size = ll_merge_marker_size(path); + int marker_size = ll_merge_marker_size(istate, path); memset(&io, 0, sizeof(io)); io.io.getline = rerere_file_getline; @@ -511,9 +512,9 @@ static int handle_file(const char *path, unsigned char *sha1, const char *output * stages we have already looked at in this invocation of this * function. */ -static int check_one_conflict(int i, int *type) +static int check_one_conflict(struct index_state *istate, int i, int *type) { - const struct cache_entry *e = active_cache[i]; + const struct cache_entry *e = istate->cache[i]; if (!ce_stage(e)) { *type = RESOLVED; @@ -521,13 +522,13 @@ static int check_one_conflict(int i, int *type) } *type = PUNTED; - while (i < active_nr && ce_stage(active_cache[i]) == 1) + while (i < istate->cache_nr && ce_stage(istate->cache[i]) == 1) i++; /* Only handle regular files with both stages #2 and #3 */ - if (i + 1 < active_nr) { - const struct cache_entry *e2 = active_cache[i]; - const struct cache_entry *e3 = active_cache[i + 1]; + if (i + 1 < istate->cache_nr) { + const struct cache_entry *e2 = istate->cache[i]; + const struct cache_entry *e3 = istate->cache[i + 1]; if (ce_stage(e2) == 2 && ce_stage(e3) == 3 && ce_same_name(e, e3) && @@ -537,7 +538,7 @@ static int check_one_conflict(int i, int *type) } /* Skip the entries with the same name */ - while (i < active_nr && ce_same_name(e, active_cache[i])) + while (i < istate->cache_nr && ce_same_name(e, istate->cache[i])) i++; return i; } @@ -553,16 +554,17 @@ static int check_one_conflict(int i, int *type) * are identical to the previous round, might want to be handled, * though. */ -static int find_conflict(struct string_list *conflict) +static int find_conflict(struct repository *r, struct string_list *conflict) { int i; - if (read_cache() < 0) + + if (read_index(r->index) < 0) return error(_("index file corrupt")); - for (i = 0; i < active_nr;) { + for (i = 0; i < r->index->cache_nr;) { int conflict_type; - const struct cache_entry *e = active_cache[i]; - i = check_one_conflict(i, &conflict_type); + const struct cache_entry *e = r->index->cache[i]; + i = check_one_conflict(r->index, i, &conflict_type); if (conflict_type == THREE_STAGED) string_list_insert(conflict, (const char *)e->name); } @@ -584,18 +586,19 @@ static int find_conflict(struct string_list *conflict) * NEEDSWORK: we may want to fix the caller that implements "rerere * remaining" to do this without abusing merge_rr. */ -int rerere_remaining(struct string_list *merge_rr) +int rerere_remaining(struct repository *r, struct string_list *merge_rr) { int i; + if (setup_rerere(merge_rr, RERERE_READONLY)) return 0; - if (read_cache() < 0) + if (read_index(r->index) < 0) return error(_("index file corrupt")); - for (i = 0; i < active_nr;) { + for (i = 0; i < r->index->cache_nr;) { int conflict_type; - const struct cache_entry *e = active_cache[i]; - i = check_one_conflict(i, &conflict_type); + const struct cache_entry *e = r->index->cache[i]; + i = check_one_conflict(r->index, i, &conflict_type); if (conflict_type == PUNTED) string_list_insert(merge_rr, (const char *)e->name); else if (conflict_type == RESOLVED) { @@ -615,7 +618,8 @@ int rerere_remaining(struct string_list *merge_rr) * if that recorded conflict resolves cleanly what we * got in the "cur". */ -static int try_merge(const struct rerere_id *id, const char *path, +static int try_merge(struct index_state *istate, + const struct rerere_id *id, const char *path, mmfile_t *cur, mmbuffer_t *result) { int ret; @@ -629,7 +633,8 @@ static int try_merge(const struct rerere_id *id, const char *path, * A three-way merge. Note that this honors user-customizable * low-level merge driver settings. */ - ret = ll_merge(result, path, &base, NULL, cur, "", &other, "", NULL); + ret = ll_merge(result, path, &base, NULL, cur, "", &other, "", + istate, NULL); free(base.ptr); free(other.ptr); @@ -647,7 +652,7 @@ static int try_merge(const struct rerere_id *id, const char *path, * Returns 0 for successful replay of recorded resolution, or non-zero * for failure. */ -static int merge(const struct rerere_id *id, const char *path) +static int merge(struct index_state *istate, const struct rerere_id *id, const char *path) { FILE *f; int ret; @@ -658,13 +663,13 @@ static int merge(const struct rerere_id *id, const char *path) * Normalize the conflicts in path and write it out to * "thisimage" temporary file. */ - if ((handle_file(path, NULL, rerere_path(id, "thisimage")) < 0) || + if ((handle_file(istate, path, NULL, rerere_path(id, "thisimage")) < 0) || read_mmfile(&cur, rerere_path(id, "thisimage"))) { ret = 1; goto out; } - ret = try_merge(id, path, &cur, &result); + ret = try_merge(istate, id, path, &cur, &result); if (ret) goto out; @@ -692,7 +697,7 @@ out: return ret; } -static void update_paths(struct string_list *update) +static void update_paths(struct repository *r, struct string_list *update) { struct lock_file index_lock = LOCK_INIT; int i; @@ -701,13 +706,13 @@ static void update_paths(struct string_list *update) for (i = 0; i < update->nr; i++) { struct string_list_item *item = &update->items[i]; - if (add_file_to_cache(item->string, 0)) + if (add_file_to_index(r->index, item->string, 0)) exit(128); fprintf_ln(stderr, _("Staged '%s' using previous resolution."), item->string); } - if (write_locked_index(&the_index, &index_lock, + if (write_locked_index(r->index, &index_lock, COMMIT_LOCK | SKIP_IF_UNCHANGED)) die(_("unable to write new index file")); } @@ -726,7 +731,8 @@ static void remove_variant(struct rerere_id *id) * only have the preimage for that conflict, in which case the result * needs to be recorded as a resolution in a postimage file. */ -static void do_rerere_one_path(struct string_list_item *rr_item, +static void do_rerere_one_path(struct index_state *istate, + struct string_list_item *rr_item, struct string_list *update) { const char *path = rr_item->string; @@ -738,7 +744,7 @@ static void do_rerere_one_path(struct string_list_item *rr_item, /* Has the user resolved it already? */ if (variant >= 0) { - if (!handle_file(path, NULL, NULL)) { + if (!handle_file(istate, path, NULL, NULL)) { copy_file(rerere_path(id, "postimage"), path, 0666); id->collection->status[variant] |= RR_HAS_POSTIMAGE; fprintf_ln(stderr, _("Recorded resolution for '%s'."), path); @@ -762,7 +768,7 @@ static void do_rerere_one_path(struct string_list_item *rr_item, continue; vid.variant = variant; - if (merge(&vid, path)) + if (merge(istate, &vid, path)) continue; /* failed to replay */ /* @@ -787,7 +793,7 @@ static void do_rerere_one_path(struct string_list_item *rr_item, assign_variant(id); variant = id->variant; - handle_file(path, NULL, rerere_path(id, "preimage")); + handle_file(istate, path, NULL, rerere_path(id, "preimage")); if (id->collection->status[variant] & RR_HAS_POSTIMAGE) { const char *path = rerere_path(id, "postimage"); if (unlink(path)) @@ -798,13 +804,14 @@ static void do_rerere_one_path(struct string_list_item *rr_item, fprintf_ln(stderr, _("Recorded preimage for '%s'"), path); } -static int do_plain_rerere(struct string_list *rr, int fd) +static int do_plain_rerere(struct repository *r, + struct string_list *rr, int fd) { struct string_list conflict = STRING_LIST_INIT_DUP; struct string_list update = STRING_LIST_INIT_DUP; int i; - find_conflict(&conflict); + find_conflict(r, &conflict); /* * MERGE_RR records paths with conflicts immediately after @@ -823,7 +830,7 @@ static int do_plain_rerere(struct string_list *rr, int fd) * conflict ID. No need to write anything out * yet. */ - ret = handle_file(path, sha1, NULL); + ret = handle_file(r->index, path, sha1, NULL); if (ret != 0 && string_list_has_string(rr, path)) { remove_variant(string_list_lookup(rr, path)->util); string_list_remove(rr, path, 1); @@ -839,10 +846,10 @@ static int do_plain_rerere(struct string_list *rr, int fd) } for (i = 0; i < rr->nr; i++) - do_rerere_one_path(&rr->items[i], &update); + do_rerere_one_path(r->index, &rr->items[i], &update); if (update.nr) - update_paths(&update); + update_paths(r, &update); return write_rr(rr, fd); } @@ -897,7 +904,7 @@ int setup_rerere(struct string_list *merge_rr, int flags) * perform mergy operations, possibly leaving conflicted index entries * and working tree files. */ -int rerere(int flags) +int repo_rerere(struct repository *r, int flags) { struct string_list merge_rr = STRING_LIST_INIT_DUP; int fd, status; @@ -905,7 +912,7 @@ int rerere(int flags) fd = setup_rerere(&merge_rr, flags); if (fd < 0) return 0; - status = do_plain_rerere(&merge_rr, fd); + status = do_plain_rerere(r, &merge_rr, fd); free_rerere_dirs(); return status; } @@ -942,29 +949,30 @@ static int rerere_mem_getline(struct strbuf *sb, struct rerere_io *io_) return 0; } -static int handle_cache(const char *path, unsigned char *sha1, const char *output) +static int handle_cache(struct index_state *istate, const char *path, + unsigned char *sha1, const char *output) { mmfile_t mmfile[3] = {{NULL}}; mmbuffer_t result = {NULL, 0}; const struct cache_entry *ce; int pos, len, i, has_conflicts; struct rerere_io_mem io; - int marker_size = ll_merge_marker_size(path); + int marker_size = ll_merge_marker_size(istate, path); /* * Reproduce the conflicted merge in-core */ len = strlen(path); - pos = cache_name_pos(path, len); + pos = index_name_pos(istate, path, len); if (0 <= pos) return -1; pos = -pos - 1; - while (pos < active_nr) { + while (pos < istate->cache_nr) { enum object_type type; unsigned long size; - ce = active_cache[pos++]; + ce = istate->cache[pos++]; if (ce_namelen(ce) != len || memcmp(ce->name, path, len)) break; i = ce_stage(ce) - 1; @@ -984,7 +992,8 @@ static int handle_cache(const char *path, unsigned char *sha1, const char *outpu */ ll_merge(&result, path, &mmfile[0], NULL, &mmfile[1], "ours", - &mmfile[2], "theirs", NULL); + &mmfile[2], "theirs", + istate, NULL); for (i = 0; i < 3; i++) free(mmfile[i].ptr); @@ -1008,7 +1017,9 @@ static int handle_cache(const char *path, unsigned char *sha1, const char *outpu return has_conflicts; } -static int rerere_forget_one_path(const char *path, struct string_list *rr) +static int rerere_forget_one_path(struct index_state *istate, + const char *path, + struct string_list *rr) { const char *filename; struct rerere_id *id; @@ -1020,7 +1031,7 @@ static int rerere_forget_one_path(const char *path, struct string_list *rr) * Recreate the original conflict from the stages in the * index and compute the conflict ID */ - ret = handle_cache(path, sha1, NULL); + ret = handle_cache(istate, path, sha1, NULL); if (ret < 1) return error(_("could not parse conflict hunks in '%s'"), path); @@ -1037,13 +1048,13 @@ static int rerere_forget_one_path(const char *path, struct string_list *rr) if (!has_rerere_resolution(id)) continue; - handle_cache(path, sha1, rerere_path(id, "thisimage")); + handle_cache(istate, path, sha1, rerere_path(id, "thisimage")); if (read_mmfile(&cur, rerere_path(id, "thisimage"))) { free(cur.ptr); error(_("failed to update conflicted state in '%s'"), path); goto fail_exit; } - cleanly_resolved = !try_merge(id, path, &cur, &result); + cleanly_resolved = !try_merge(istate, id, path, &cur, &result); free(result.ptr); free(cur.ptr); if (cleanly_resolved) @@ -1069,7 +1080,7 @@ static int rerere_forget_one_path(const char *path, struct string_list *rr) * conflict in the working tree, run us again to record * the postimage. */ - handle_cache(path, sha1, rerere_path(id, "preimage")); + handle_cache(istate, path, sha1, rerere_path(id, "preimage")); fprintf_ln(stderr, _("Updated preimage for '%s'"), path); /* @@ -1087,13 +1098,13 @@ fail_exit: return -1; } -int rerere_forget(struct pathspec *pathspec) +int rerere_forget(struct repository *r, struct pathspec *pathspec) { int i, fd; struct string_list conflict = STRING_LIST_INIT_DUP; struct string_list merge_rr = STRING_LIST_INIT_DUP; - if (read_cache() < 0) + if (read_index(r->index) < 0) return error(_("index file corrupt")); fd = setup_rerere(&merge_rr, RERERE_NOAUTOUPDATE); @@ -1105,14 +1116,14 @@ int rerere_forget(struct pathspec *pathspec) * recover the original conflicted state and then * find the conflicted paths. */ - unmerge_cache(pathspec); - find_conflict(&conflict); + unmerge_index(r->index, pathspec); + find_conflict(r, &conflict); for (i = 0; i < conflict.nr; i++) { struct string_list_item *it = &conflict.items[i]; - if (!match_pathspec(&the_index, pathspec, it->string, + if (!match_pathspec(r->index, pathspec, it->string, strlen(it->string), 0, NULL, 0)) continue; - rerere_forget_one_path(it->string, &merge_rr); + rerere_forget_one_path(r->index, it->string, &merge_rr); } return write_rr(&merge_rr, fd); } @@ -4,6 +4,7 @@ #include "string-list.h" struct pathspec; +struct repository; #define RERERE_AUTOUPDATE 01 #define RERERE_NOAUTOUPDATE 02 @@ -23,7 +24,10 @@ struct rerere_id { }; int setup_rerere(struct string_list *, int); -int rerere(int); +#ifndef NO_THE_REPOSITORY_COMPATIBILITY_MACROS +#define rerere(flags) repo_rerere(the_repository, flags) +#endif +int repo_rerere(struct repository *, int); /* * Given the conflict ID and the name of a "file" used for replaying * the recorded resolution (e.g. "preimage", "postimage"), return the @@ -31,8 +35,8 @@ int rerere(int); * return the path to the directory that houses these files. */ const char *rerere_path(const struct rerere_id *, const char *file); -int rerere_forget(struct pathspec *); -int rerere_remaining(struct string_list *); +int rerere_forget(struct repository *, struct pathspec *); +int rerere_remaining(struct repository *, struct string_list *); void rerere_clear(struct string_list *); void rerere_gc(struct string_list *); diff --git a/revision.c b/revision.c index e18bd530e4..b5108b75ab 100644 --- a/revision.c +++ b/revision.c @@ -52,7 +52,8 @@ static void mark_blob_uninteresting(struct blob *blob) blob->object.flags |= UNINTERESTING; } -static void mark_tree_contents_uninteresting(struct tree *tree) +static void mark_tree_contents_uninteresting(struct repository *r, + struct tree *tree) { struct tree_desc desc; struct name_entry entry; @@ -64,10 +65,10 @@ static void mark_tree_contents_uninteresting(struct tree *tree) while (tree_entry(&desc, &entry)) { switch (object_type(entry.mode)) { case OBJ_TREE: - mark_tree_uninteresting(lookup_tree(the_repository, entry.oid)); + mark_tree_uninteresting(r, lookup_tree(r, entry.oid)); break; case OBJ_BLOB: - mark_blob_uninteresting(lookup_blob(the_repository, entry.oid)); + mark_blob_uninteresting(lookup_blob(r, entry.oid)); break; default: /* Subproject commit - not in this repository */ @@ -82,7 +83,7 @@ static void mark_tree_contents_uninteresting(struct tree *tree) free_tree_buffer(tree); } -void mark_tree_uninteresting(struct tree *tree) +void mark_tree_uninteresting(struct repository *r, struct tree *tree) { struct object *obj; @@ -93,7 +94,7 @@ void mark_tree_uninteresting(struct tree *tree) if (obj->flags & UNINTERESTING) return; obj->flags |= UNINTERESTING; - mark_tree_contents_uninteresting(tree); + mark_tree_contents_uninteresting(r, tree); } struct commit_stack { @@ -199,7 +200,7 @@ void add_head_to_pending(struct rev_info *revs) struct object *obj; if (get_oid("HEAD", &oid)) return; - obj = parse_object(the_repository, &oid); + obj = parse_object(revs->repo, &oid); if (!obj) return; add_pending_object(revs, obj, "HEAD"); @@ -211,7 +212,7 @@ static struct object *get_reference(struct rev_info *revs, const char *name, { struct object *object; - object = parse_object(the_repository, oid); + object = parse_object(revs->repo, oid); if (!object) { if (revs->ignore_missing) return object; @@ -248,7 +249,7 @@ static struct commit *handle_commit(struct rev_info *revs, add_pending_object(revs, object, tag->tag); if (!tag->tagged) die("bad tag"); - object = parse_object(the_repository, &tag->tagged->oid); + object = parse_object(revs->repo, &tag->tagged->oid); if (!object) { if (revs->ignore_missing_links || (flags & UNINTERESTING)) return NULL; @@ -298,7 +299,7 @@ static struct commit *handle_commit(struct rev_info *revs, if (!revs->tree_objects) return NULL; if (flags & UNINTERESTING) { - mark_tree_contents_uninteresting(tree); + mark_tree_contents_uninteresting(revs->repo, tree); return NULL; } add_pending_object_with_path(revs, object, name, mode, path); @@ -878,7 +879,7 @@ static void cherry_pick_list(struct commit_list *list, struct rev_info *revs) return; left_first = left_count < right_count; - init_patch_ids(&ids); + init_patch_ids(revs->repo, &ids); ids.diffopts.pathspec = revs->diffopt.pathspec; /* Compute patch-ids for one side */ @@ -1254,7 +1255,7 @@ static void handle_one_reflog_commit(struct object_id *oid, void *cb_data) { struct all_refs_cb *cb = cb_data; if (!is_null_oid(oid)) { - struct object *o = parse_object(the_repository, oid); + struct object *o = parse_object(cb->all_revs->repo, oid); if (o) { o->flags |= cb->all_flags; /* ??? CMDLINEFLAGS ??? */ @@ -1313,7 +1314,7 @@ void add_reflogs_to_pending(struct rev_info *revs, unsigned flags) cb.all_revs = revs; cb.all_flags = flags; - cb.refs = get_main_ref_store(the_repository); + cb.refs = get_main_ref_store(revs->repo); for_each_reflog(handle_one_reflog, &cb); if (!revs->single_worktree) @@ -1327,7 +1328,7 @@ static void add_cache_tree(struct cache_tree *it, struct rev_info *revs, int i; if (it->entry_count >= 0) { - struct tree *tree = lookup_tree(the_repository, &it->oid); + struct tree *tree = lookup_tree(revs->repo, &it->oid); add_pending_object_with_path(revs, &tree->object, "", 040000, path->buf); } @@ -1353,7 +1354,7 @@ static void do_add_index_objects_to_pending(struct rev_info *revs, if (S_ISGITLINK(ce->ce_mode)) continue; - blob = lookup_blob(the_repository, &ce->oid); + blob = lookup_blob(revs->repo, &ce->oid); if (!blob) die("unable to add index blob to traversal"); add_pending_object_with_path(revs, &blob->object, "", @@ -1371,8 +1372,8 @@ void add_index_objects_to_pending(struct rev_info *revs, unsigned int flags) { struct worktree **worktrees, **p; - read_cache(); - do_add_index_objects_to_pending(revs, &the_index); + read_index(revs->repo->index); + do_add_index_objects_to_pending(revs, revs->repo->index); if (revs->single_worktree) return; @@ -1440,10 +1441,13 @@ static int add_parents_only(struct rev_info *revs, const char *arg_, int flags, return 1; } -void init_revisions(struct rev_info *revs, const char *prefix) +void repo_init_revisions(struct repository *r, + struct rev_info *revs, + const char *prefix) { memset(revs, 0, sizeof(*revs)); + revs->repo = r; revs->abbrev = DEFAULT_ABBREV; revs->ignore_merges = 1; revs->simplify_history = 1; @@ -1465,11 +1469,11 @@ void init_revisions(struct rev_info *revs, const char *prefix) revs->commit_format = CMIT_FMT_DEFAULT; revs->expand_tabs_in_log_default = 8; - init_grep_defaults(); - grep_init(&revs->grep_filter, prefix); + init_grep_defaults(revs->repo); + grep_init(&revs->grep_filter, revs->repo, prefix); revs->grep_filter.status_only = 1; - diff_setup(&revs->diffopt); + repo_diff_setup(revs->repo, &revs->diffopt); if (prefix && !revs->diffopt.prefix) { revs->diffopt.prefix = prefix; revs->diffopt.prefix_length = strlen(prefix); @@ -1497,6 +1501,7 @@ static void prepare_show_merge(struct rev_info *revs) struct object_id oid; const char **prune = NULL; int i, prune_num = 1; /* counting terminating NULL */ + struct index_state *istate = revs->repo->index; if (get_oid("HEAD", &oid)) die("--merge without HEAD?"); @@ -1512,20 +1517,20 @@ static void prepare_show_merge(struct rev_info *revs) free_commit_list(bases); head->object.flags |= SYMMETRIC_LEFT; - if (!active_nr) - read_cache(); - for (i = 0; i < active_nr; i++) { - const struct cache_entry *ce = active_cache[i]; + if (!istate->cache_nr) + read_index(istate); + for (i = 0; i < istate->cache_nr; i++) { + const struct cache_entry *ce = istate->cache[i]; if (!ce_stage(ce)) continue; - if (ce_path_match(&the_index, ce, &revs->prune_data, NULL)) { + if (ce_path_match(istate, ce, &revs->prune_data, NULL)) { prune_num++; REALLOC_ARRAY(prune, prune_num); prune[prune_num-2] = ce->name; prune[prune_num-1] = NULL; } - while ((i+1 < active_nr) && - ce_same_name(ce, active_cache[i+1])) + while ((i+1 < istate->cache_nr) && + ce_same_name(ce, istate->cache[i+1])) i++; } clear_pathspec(&revs->prune_data); @@ -1582,8 +1587,8 @@ static int handle_dotdot_1(const char *arg, char *dotdot, *dotdot = '\0'; } - a_obj = parse_object(the_repository, &a_oid); - b_obj = parse_object(the_repository, &b_oid); + a_obj = parse_object(revs->repo, &a_oid); + b_obj = parse_object(revs->repo, &b_oid); if (!a_obj || !b_obj) return dotdot_missing(arg, dotdot, revs, symmetric); @@ -1596,8 +1601,8 @@ static int handle_dotdot_1(const char *arg, char *dotdot, struct commit *a, *b; struct commit_list *exclude; - a = lookup_commit_reference(the_repository, &a_obj->oid); - b = lookup_commit_reference(the_repository, &b_obj->oid); + a = lookup_commit_reference(revs->repo, &a_obj->oid); + b = lookup_commit_reference(revs->repo, &b_obj->oid); if (!a || !b) return dotdot_missing(arg, dotdot, revs, symmetric); @@ -2205,7 +2210,7 @@ static int handle_revision_pseudo_opt(const char *submodule, BUG("--single-worktree cannot be used together with submodule"); refs = get_submodule_ref_store(submodule); } else - refs = get_main_ref_store(the_repository); + refs = get_main_ref_store(revs->repo); /* * NOTE! @@ -2885,9 +2890,10 @@ void reset_revision_walk(void) static int mark_uninteresting(const struct object_id *oid, struct packed_git *pack, uint32_t pos, - void *unused) + void *cb) { - struct object *o = parse_object(the_repository, oid); + struct rev_info *revs = cb; + struct object *o = parse_object(revs->repo, oid); o->flags |= UNINTERESTING | SEEN; return 0; } @@ -2920,7 +2926,7 @@ int prepare_revision_walk(struct rev_info *revs) revs->treesame.name = "treesame"; if (revs->exclude_promisor_objects) { - for_each_packed_object(mark_uninteresting, NULL, + for_each_packed_object(mark_uninteresting, revs, FOR_EACH_OBJECT_PROMISOR_ONLY); } diff --git a/revision.h b/revision.h index 2b30ac270d..bc30a3023e 100644 --- a/revision.h +++ b/revision.h @@ -28,8 +28,9 @@ #define DECORATE_SHORT_REFS 1 #define DECORATE_FULL_REFS 2 -struct rev_info; struct log_info; +struct repository; +struct rev_info; struct string_list; struct saved_parents; define_shared_commit_slab(revision_sources, char *); @@ -60,6 +61,7 @@ struct rev_info { /* Starting list */ struct commit_list *commits; struct object_array pending; + struct repository *repo; /* Parents of shown commits */ struct object_array boundary_commits; @@ -264,12 +266,17 @@ extern volatile show_early_output_fn_t show_early_output; struct setup_revision_opt { const char *def; void (*tweak)(struct rev_info *, struct setup_revision_opt *); - const char *submodule; + const char *submodule; /* TODO: drop this and use rev_info->repo */ int assume_dashdash; unsigned revarg_opt; }; -void init_revisions(struct rev_info *revs, const char *prefix); +#ifndef NO_THE_REPOSITORY_COMPATIBILITY_MACROS +#define init_revisions(revs, prefix) repo_init_revisions(the_repository, revs, prefix) +#endif +void repo_init_revisions(struct repository *r, + struct rev_info *revs, + const char *prefix); int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct setup_revision_opt *); void parse_revision_opt(struct rev_info *revs, struct parse_opt_ctx_t *ctx, @@ -289,7 +296,7 @@ void put_revision_mark(const struct rev_info *revs, const struct commit *commit); void mark_parents_uninteresting(struct commit *commit); -void mark_tree_uninteresting(struct tree *tree); +void mark_tree_uninteresting(struct repository *r, struct tree *tree); void show_object_with_name(FILE *, struct object *, const char *); diff --git a/sequencer.c b/sequencer.c index 6387c9ee6e..83f17721d4 100644 --- a/sequencer.c +++ b/sequencer.c @@ -474,8 +474,8 @@ static int fast_forward_to(const struct object_id *to, const struct object_id *f struct strbuf sb = STRBUF_INIT; struct strbuf err = STRBUF_INIT; - read_cache(); - if (checkout_fast_forward(from, to, 1)) + read_index(&the_index); + if (checkout_fast_forward(the_repository, from, to, 1)) return -1; /* the callee should have complained already */ strbuf_addf(&sb, _("%s: fast-forward"), _(action_name(opts))); @@ -1176,7 +1176,7 @@ void print_commit_summary(const char *prefix, const struct object_id *oid, strbuf_release(&author_ident); strbuf_release(&committer_ident); - init_revisions(&rev, prefix); + repo_init_revisions(the_repository, &rev, prefix); setup_revisions(0, NULL, &rev, NULL); rev.diff = 1; @@ -1831,7 +1831,7 @@ static int do_pick_commit(enum todo_command command, struct commit *commit, commit_list_insert(base, &common); commit_list_insert(next, &remotes); - res |= try_merge_command(opts->strategy, + res |= try_merge_command(the_repository, opts->strategy, opts->xopts_nr, (const char **)opts->xopts, common, oid_to_hex(&head), remotes); free_commit_list(common); @@ -1860,7 +1860,7 @@ static int do_pick_commit(enum todo_command command, struct commit *commit, : _("could not apply %s... %s"), short_commit_name(commit), msg.subject); print_advice(res == 1, opts); - rerere(opts->allow_rerere_auto); + repo_rerere(the_repository, opts->allow_rerere_auto); goto leave; } @@ -2599,7 +2599,7 @@ static int make_patch(struct commit *commit, struct replay_opts *opts) strbuf_addf(&buf, "%s/patch", get_dir(opts)); memset(&log_tree_opt, 0, sizeof(log_tree_opt)); - init_revisions(&log_tree_opt, NULL); + repo_init_revisions(the_repository, &log_tree_opt, NULL); log_tree_opt.abbrev = 0; log_tree_opt.diff = 1; log_tree_opt.diffopt.output_format = DIFF_FORMAT_PATCH; @@ -3179,7 +3179,7 @@ static int do_merge(struct commit *commit, const char *arg, int arg_len, rollback_lock_file(&lock); if (ret) - rerere(opts->allow_rerere_auto); + repo_rerere(the_repository, opts->allow_rerere_auto); else /* * In case of problems, we now want to return a positive @@ -3510,7 +3510,7 @@ cleanup_head_ref: struct object_id orig, head; memset(&log_tree_opt, 0, sizeof(log_tree_opt)); - init_revisions(&log_tree_opt, NULL); + repo_init_revisions(the_repository, &log_tree_opt, NULL); log_tree_opt.diff = 1; log_tree_opt.diffopt.output_format = DIFF_FORMAT_DIFFSTAT; @@ -4254,7 +4254,7 @@ int sequencer_make_script(FILE *out, int argc, const char **argv, const char *insn = flags & TODO_LIST_ABBREVIATE_CMDS ? "p" : "pick"; int rebase_merges = flags & TODO_LIST_REBASE_MERGES; - init_revisions(&revs, NULL); + repo_init_revisions(the_repository, &revs, NULL); revs.verbose_header = 1; if (!rebase_merges) revs.max_parents = 1; diff --git a/sha1-file.c b/sha1-file.c index a4367b8f04..dd0b6aa873 100644 --- a/sha1-file.c +++ b/sha1-file.c @@ -1813,7 +1813,8 @@ static void check_tag(const void *buf, size_t size) die(_("corrupt tag")); } -static int index_mem(struct object_id *oid, void *buf, size_t size, +static int index_mem(struct index_state *istate, + struct object_id *oid, void *buf, size_t size, enum object_type type, const char *path, unsigned flags) { @@ -1828,7 +1829,7 @@ static int index_mem(struct object_id *oid, void *buf, size_t size, */ if ((type == OBJ_BLOB) && path) { struct strbuf nbuf = STRBUF_INIT; - if (convert_to_git(&the_index, path, buf, size, &nbuf, + if (convert_to_git(istate, path, buf, size, &nbuf, get_conv_flags(flags))) { buf = strbuf_detach(&nbuf, &size); re_allocated = 1; @@ -1852,17 +1853,20 @@ static int index_mem(struct object_id *oid, void *buf, size_t size, return ret; } -static int index_stream_convert_blob(struct object_id *oid, int fd, - const char *path, unsigned flags) +static int index_stream_convert_blob(struct index_state *istate, + struct object_id *oid, + int fd, + const char *path, + unsigned flags) { int ret; const int write_object = flags & HASH_WRITE_OBJECT; struct strbuf sbuf = STRBUF_INIT; assert(path); - assert(would_convert_to_git_filter_fd(&the_index, path)); + assert(would_convert_to_git_filter_fd(istate, path)); - convert_to_git_filter_fd(&the_index, path, fd, &sbuf, + convert_to_git_filter_fd(istate, path, fd, &sbuf, get_conv_flags(flags)); if (write_object) @@ -1875,14 +1879,15 @@ static int index_stream_convert_blob(struct object_id *oid, int fd, return ret; } -static int index_pipe(struct object_id *oid, int fd, enum object_type type, +static int index_pipe(struct index_state *istate, struct object_id *oid, + int fd, enum object_type type, const char *path, unsigned flags) { struct strbuf sbuf = STRBUF_INIT; int ret; if (strbuf_read(&sbuf, fd, 4096) >= 0) - ret = index_mem(oid, sbuf.buf, sbuf.len, type, path, flags); + ret = index_mem(istate, oid, sbuf.buf, sbuf.len, type, path, flags); else ret = -1; strbuf_release(&sbuf); @@ -1891,14 +1896,15 @@ static int index_pipe(struct object_id *oid, int fd, enum object_type type, #define SMALL_FILE_SIZE (32*1024) -static int index_core(struct object_id *oid, int fd, size_t size, +static int index_core(struct index_state *istate, + struct object_id *oid, int fd, size_t size, enum object_type type, const char *path, unsigned flags) { int ret; if (!size) { - ret = index_mem(oid, "", size, type, path, flags); + ret = index_mem(istate, oid, "", size, type, path, flags); } else if (size <= SMALL_FILE_SIZE) { char *buf = xmalloc(size); ssize_t read_result = read_in_full(fd, buf, size); @@ -1909,11 +1915,11 @@ static int index_core(struct object_id *oid, int fd, size_t size, ret = error(_("short read while indexing %s"), path ? path : "<unknown>"); else - ret = index_mem(oid, buf, size, type, path, flags); + ret = index_mem(istate, oid, buf, size, type, path, flags); free(buf); } else { void *buf = xmmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); - ret = index_mem(oid, buf, size, type, path, flags); + ret = index_mem(istate, oid, buf, size, type, path, flags); munmap(buf, size); } return ret; @@ -1941,7 +1947,8 @@ static int index_stream(struct object_id *oid, int fd, size_t size, return index_bulk_checkin(oid, fd, size, type, path, flags); } -int index_fd(struct object_id *oid, int fd, struct stat *st, +int index_fd(struct index_state *istate, struct object_id *oid, + int fd, struct stat *st, enum object_type type, const char *path, unsigned flags) { int ret; @@ -1950,14 +1957,14 @@ 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(&the_index, path)) - ret = index_stream_convert_blob(oid, fd, path, flags); + if (type == OBJ_BLOB && path && would_convert_to_git_filter_fd(istate, path)) + ret = index_stream_convert_blob(istate, oid, fd, path, flags); else if (!S_ISREG(st->st_mode)) - ret = index_pipe(oid, fd, type, path, flags); + ret = index_pipe(istate, oid, fd, type, path, flags); else if (st->st_size <= big_file_threshold || type != OBJ_BLOB || - (path && would_convert_to_git(&the_index, path))) - ret = index_core(oid, fd, xsize_t(st->st_size), type, path, - flags); + (path && would_convert_to_git(istate, path))) + ret = index_core(istate, oid, fd, xsize_t(st->st_size), + type, path, flags); else ret = index_stream(oid, fd, xsize_t(st->st_size), type, path, flags); @@ -1965,7 +1972,8 @@ int index_fd(struct object_id *oid, int fd, struct stat *st, return ret; } -int index_path(struct object_id *oid, const char *path, struct stat *st, unsigned flags) +int index_path(struct index_state *istate, struct object_id *oid, + const char *path, struct stat *st, unsigned flags) { int fd; struct strbuf sb = STRBUF_INIT; @@ -1976,7 +1984,7 @@ int index_path(struct object_id *oid, const char *path, struct stat *st, unsigne fd = open(path, O_RDONLY); if (fd < 0) return error_errno("open(\"%s\")", path); - if (index_fd(oid, fd, st, OBJ_BLOB, path, flags) < 0) + if (index_fd(istate, oid, fd, st, OBJ_BLOB, path, flags) < 0) return error(_("%s: failed to insert into database"), path); break; @@ -185,7 +185,7 @@ struct commit_list *get_shallow_commits_by_rev_list(int ac, const char **av, is_repository_shallow(the_repository); /* make sure shallows are read */ - init_revisions(&revs, NULL); + repo_init_revisions(the_repository, &revs, NULL); save_commit_buffer = 0; setup_revisions(ac, av, &revs, NULL); diff --git a/submodule.c b/submodule.c index b53cb6e9c4..25c6e5d5b9 100644 --- a/submodule.c +++ b/submodule.c @@ -428,7 +428,7 @@ static int prepare_submodule_summary(struct rev_info *rev, const char *path, { struct commit_list *list; - init_revisions(rev, NULL); + repo_init_revisions(the_repository, rev, NULL); setup_revisions(0, NULL, rev, NULL); rev->left_right = 1; rev->first_parent_only = 1; @@ -766,13 +766,14 @@ static void collect_changed_submodules_cb(struct diff_queue_struct *q, * have a corresponding 'struct oid_array' (in the 'util' field) which lists * what the submodule pointers were updated to during the change. */ -static void collect_changed_submodules(struct string_list *changed, +static void collect_changed_submodules(struct index_state *istate, + struct string_list *changed, struct argv_array *argv) { struct rev_info rev; const struct commit *commit; - init_revisions(&rev, NULL); + repo_init_revisions(the_repository, &rev, NULL); setup_revisions(argv->argc, argv->argv, &rev, NULL); if (prepare_revision_walk(&rev)) die("revision walk setup failed"); @@ -783,7 +784,7 @@ static void collect_changed_submodules(struct string_list *changed, data.changed = changed; data.commit_oid = &commit->object.oid; - init_revisions(&diff_rev, NULL); + repo_init_revisions(the_repository, &diff_rev, NULL); diff_rev.diffopt.output_format |= DIFF_FORMAT_CALLBACK; diff_rev.diffopt.format_callback = collect_changed_submodules_cb; diff_rev.diffopt.format_callback_data = &data; @@ -930,8 +931,10 @@ static int submodule_needs_pushing(const char *path, struct oid_array *commits) return 0; } -int find_unpushed_submodules(struct oid_array *commits, - const char *remotes_name, struct string_list *needs_pushing) +int find_unpushed_submodules(struct index_state *istate, + struct oid_array *commits, + const char *remotes_name, + struct string_list *needs_pushing) { struct string_list submodules = STRING_LIST_INIT_DUP; struct string_list_item *name; @@ -943,7 +946,7 @@ int find_unpushed_submodules(struct oid_array *commits, argv_array_push(&argv, "--not"); argv_array_pushf(&argv, "--remotes=%s", remotes_name); - collect_changed_submodules(&submodules, &argv); + collect_changed_submodules(istate, &submodules, &argv); for_each_string_list_item(name, &submodules) { struct oid_array *commits = name->util; @@ -1044,7 +1047,8 @@ static void submodule_push_check(const char *path, const char *head, die("process for submodule '%s' failed", path); } -int push_unpushed_submodules(struct oid_array *commits, +int push_unpushed_submodules(struct index_state *istate, + struct oid_array *commits, const struct remote *remote, const struct refspec *rs, const struct string_list *push_options, @@ -1053,7 +1057,8 @@ int push_unpushed_submodules(struct oid_array *commits, int i, ret = 1; struct string_list needs_pushing = STRING_LIST_INIT_DUP; - if (!find_unpushed_submodules(commits, remote->name, &needs_pushing)) + if (!find_unpushed_submodules(istate, commits, + remote->name, &needs_pushing)) return 1; /* @@ -1110,7 +1115,7 @@ void check_for_new_submodule_commits(struct object_id *oid) oid_array_append(&ref_tips_after_fetch, oid); } -static void calculate_changed_submodule_paths(void) +static void calculate_changed_submodule_paths(struct index_state *istate) { struct argv_array argv = ARGV_ARRAY_INIT; struct string_list changed_submodules = STRING_LIST_INIT_DUP; @@ -1131,7 +1136,7 @@ static void calculate_changed_submodule_paths(void) * Collect all submodules (whether checked out or not) for which new * commits have been recorded upstream in "changed_submodule_names". */ - collect_changed_submodules(&changed_submodules, &argv); + collect_changed_submodules(istate, &changed_submodules, &argv); for_each_string_list_item(name, &changed_submodules) { struct oid_array *commits = name->util; @@ -1158,7 +1163,8 @@ static void calculate_changed_submodule_paths(void) initialized_fetch_ref_tips = 0; } -int submodule_touches_in_range(struct object_id *excl_oid, +int submodule_touches_in_range(struct index_state *istate, + struct object_id *excl_oid, struct object_id *incl_oid) { struct string_list subs = STRING_LIST_INIT_DUP; @@ -1176,7 +1182,7 @@ int submodule_touches_in_range(struct object_id *excl_oid, argv_array_push(&args, oid_to_hex(excl_oid)); } - collect_changed_submodules(&subs, &args); + collect_changed_submodules(istate, &subs, &args); ret = subs.nr; argv_array_clear(&args); @@ -1346,7 +1352,7 @@ int fetch_populated_submodules(struct repository *r, argv_array_push(&spf.args, "--recurse-submodules-default"); /* default value, "--submodule-prefix" and its value are added later */ - calculate_changed_submodule_paths(); + calculate_changed_submodule_paths(r->index); run_processes_parallel(max_parallel_jobs, get_next_submodule, fetch_start_failure, diff --git a/submodule.h b/submodule.h index e452919aa4..4826601ff2 100644 --- a/submodule.h +++ b/submodule.h @@ -102,13 +102,16 @@ int add_submodule_odb(const char *path); * Checks if there are submodule changes in a..b. If a is the null OID, * checks b and all its ancestors instead. */ -int submodule_touches_in_range(struct object_id *a, +int submodule_touches_in_range(struct index_state *istate, + struct object_id *a, struct object_id *b); -int find_unpushed_submodules(struct oid_array *commits, +int find_unpushed_submodules(struct index_state *istate, + struct oid_array *commits, const char *remotes_name, struct string_list *needs_pushing); struct refspec; -int push_unpushed_submodules(struct oid_array *commits, +int push_unpushed_submodules(struct index_state *istate, + struct oid_array *commits, const struct remote *remote, const struct refspec *rs, const struct string_list *push_options, diff --git a/t/helper/test-revision-walking.c b/t/helper/test-revision-walking.c index 4f8bc75821..625b2dbf82 100644 --- a/t/helper/test-revision-walking.c +++ b/t/helper/test-revision-walking.c @@ -32,7 +32,7 @@ static int run_revision_walk(void) int argc = ARRAY_SIZE(argv) - 1; int got_revision = 0; - init_revisions(&rev, NULL); + repo_init_revisions(the_repository, &rev, NULL); setup_revisions(argc, argv, &rev, NULL); if (prepare_revision_walk(&rev)) die("revision walk setup failed"); diff --git a/transport.c b/transport.c index 1c76d64aba..dd7bd3436c 100644 --- a/transport.c +++ b/transport.c @@ -1139,7 +1139,8 @@ int transport_push(struct transport *transport, oid_array_append(&commits, &ref->new_oid); - if (!push_unpushed_submodules(&commits, + if (!push_unpushed_submodules(&the_index, + &commits, transport->remote, rs, transport->push_options, @@ -1163,8 +1164,10 @@ int transport_push(struct transport *transport, oid_array_append(&commits, &ref->new_oid); - if (find_unpushed_submodules(&commits, transport->remote->name, - &needs_pushing)) { + if (find_unpushed_submodules(&the_index, + &commits, + transport->remote->name, + &needs_pushing)) { oid_array_clear(&commits); die_with_unpushed_submodules(&needs_pushing); } diff --git a/tree-diff.c b/tree-diff.c index 425668e1e0..0e54324610 100644 --- a/tree-diff.c +++ b/tree-diff.c @@ -605,7 +605,7 @@ static void try_to_follow_renames(const struct object_id *old_oid, choice = q->queue[0]; q->nr = 0; - diff_setup(&diff_opts); + repo_diff_setup(opt->repo, &diff_opts); diff_opts.flags.recursive = 1; diff_opts.flags.find_copies_harder = 1; diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT; diff --git a/userdiff.c b/userdiff.c index f565f6731d..46d34cc2a4 100644 --- a/userdiff.c +++ b/userdiff.c @@ -270,7 +270,8 @@ struct userdiff_driver *userdiff_find_by_name(const char *name) { return userdiff_find_by_namelen(name, len); } -struct userdiff_driver *userdiff_find_by_path(const char *path) +struct userdiff_driver *userdiff_find_by_path(struct index_state *istate, + const char *path) { static struct attr_check *check; @@ -278,7 +279,7 @@ struct userdiff_driver *userdiff_find_by_path(const char *path) check = attr_check_initl("diff", NULL); if (!path) return NULL; - git_check_attr(&the_index, path, check); + git_check_attr(istate, path, check); if (ATTR_TRUE(check->items[0].value)) return &driver_true; diff --git a/userdiff.h b/userdiff.h index 2ef0ce5452..b072bfe89a 100644 --- a/userdiff.h +++ b/userdiff.h @@ -3,6 +3,8 @@ #include "notes-cache.h" +struct index_state; + struct userdiff_funcname { const char *pattern; int cflags; @@ -21,7 +23,8 @@ struct userdiff_driver { int userdiff_config(const char *k, const char *v); struct userdiff_driver *userdiff_find_by_name(const char *name); -struct userdiff_driver *userdiff_find_by_path(const char *path); +struct userdiff_driver *userdiff_find_by_path(struct index_state *istate, + const char *path); /* * Initialize any textconv-related fields in the driver and return it, or NULL @@ -3,7 +3,6 @@ * * Copyright (c) 2007 Junio C Hamano */ - #include "cache.h" #include "attr.h" @@ -71,7 +70,7 @@ unsigned parse_whitespace_rule(const char *string) return rule; } -unsigned whitespace_rule(const char *pathname) +unsigned whitespace_rule(struct index_state *istate, const char *pathname) { static struct attr_check *attr_whitespace_rule; const char *value; @@ -79,7 +78,7 @@ unsigned whitespace_rule(const char *pathname) if (!attr_whitespace_rule) attr_whitespace_rule = attr_check_initl("whitespace", NULL); - git_check_attr(&the_index, pathname, attr_whitespace_rule); + git_check_attr(istate, pathname, attr_whitespace_rule); value = attr_whitespace_rule->items[0].value; if (ATTR_TRUE(value)) { /* true (whitespace) */ diff --git a/wt-status.c b/wt-status.c index 1c8746d0ea..87042d4568 100644 --- a/wt-status.c +++ b/wt-status.c @@ -582,7 +582,7 @@ static void wt_status_collect_changes_worktree(struct wt_status *s) { struct rev_info rev; - init_revisions(&rev, NULL); + repo_init_revisions(the_repository, &rev, NULL); setup_revisions(0, NULL, &rev, NULL); rev.diffopt.output_format |= DIFF_FORMAT_CALLBACK; rev.diffopt.flags.dirty_submodules = 1; @@ -607,7 +607,7 @@ static void wt_status_collect_changes_index(struct wt_status *s) struct rev_info rev; struct setup_revision_opt opt; - init_revisions(&rev, NULL); + repo_init_revisions(the_repository, &rev, NULL); memset(&opt, 0, sizeof(opt)); opt.def = s->is_initial ? empty_tree_oid_hex() : s->reference; setup_revisions(0, NULL, &rev, &opt); @@ -982,7 +982,7 @@ static void wt_longstatus_print_verbose(struct wt_status *s) int dirty_submodules; const char *c = color(WT_STATUS_HEADER, s); - init_revisions(&rev, NULL); + repo_init_revisions(the_repository, &rev, NULL); rev.diffopt.flags.allow_textconv = 1; rev.diffopt.ita_invisible_in_index = 1; @@ -2314,7 +2314,7 @@ int has_unstaged_changes(int ignore_submodules) struct rev_info rev_info; int result; - init_revisions(&rev_info, NULL); + repo_init_revisions(the_repository, &rev_info, NULL); if (ignore_submodules) { rev_info.diffopt.flags.ignore_submodules = 1; rev_info.diffopt.flags.override_submodule_config = 1; @@ -2336,7 +2336,7 @@ int has_uncommitted_changes(int ignore_submodules) if (is_cache_unborn()) return 0; - init_revisions(&rev_info, NULL); + repo_init_revisions(the_repository, &rev_info, NULL); if (ignore_submodules) rev_info.diffopt.flags.ignore_submodules = 1; rev_info.diffopt.flags.quick = 1; |