git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH v4 00/23] Fix incorrect use of the_index

From
Elijah Newren <newren@gmail.com>
Date
Jun 14, 2018, 20:57 UTC
Message-ID
<CABPp-BH249etuVxQkYgE4a3C7wKFcicNsWzbOKdY2p4McdJYuw@mail.gmail.com>
In-Reply-To
<20180614171849.GA7675@duynguyen.home>
On Thu, Jun 14, 2018 at 10:18 AM, Duy Nguyen <pclouds@gmail.com> wrote:
Show 31 quoted lines
> On Mon, Jun 11, 2018 at 06:49:00PM +0200, Duy Nguyen wrote:
>> On Mon, Jun 11, 2018 at 6:44 PM Elijah Newren <newren@gmail.com> wrote:
>> > > What about merge-recursive.c? Given that this whole thing will take
>> > > many release cycles to finish, your work may get merged before mine
>> > > and I could do the conversion now (and resolve conflicts and resubmit
>> > > later). Of course if you like to keep merge-recursive.c the_index-free
>> > > now, I will not stop you ;-)
>> >
>> > I was just worried that since I was making changes in
>> > merge-recursive.c that it'd cause you conflict pain, so I offered to
>> > convert it.  If that pain doesn't bother you, feel free to do the
>> > conversion and we'll just work through the minor conflicts as we go.
>> > Besides, sounds like you've converted nearly all of git, so it may
>> > make sense to just keep it together in one big series.
>>
>> OK let's just "quickly" get your series in then. I still have a few
>> files to go and a couple more places to look back and ponder. I'm in
>> no hurry to convert merge-recursive now :D
>
> Actually could you quickly check if I pass the right index in the
> following patch? I realize you only have one extra index, but I don't
> know if it gets passed elsewhere and in some function I'm supposed to
> use another index than the default "o->repo->index". Sometimes
> o->repo->index is not the correct answer.
>
> It takes many patches to get to this stage, so if you diff context
> looks so strange to you, just ignore this for now. I'll eventually
> send this one out in a series.
>
> PS. I put a 'struct repository *' in 'struct merge_options' instead
> because it turns out we do need full repo struct in some function.
Yes, this looks right.

It'd be nice to be able to apply the patch locally so I could also look at the --color-words version, but it's not a real big deal.

In general, this is how the index stuff works in merge-recursive:
  * In unpack_trees_start(), we call unpack_trees() using the_index as
src, and tmp_index as dest.
  * As soon as unpack_trees() finishes, we swap: (orig_index,
the_index) = (the_index, tmp_index).
  * We ONLY use orig_index (also called unpack_opts.src_index) in the
was_*() family of functions, which query about what the index was like
before the merge started.  (To name these functions explicitly:
was_tracked_and_matches(), was_tracked(), and was_dirty()).  ALL other
callsites within merge-recursive.c should be operating on the_index,
or, after your patch, o->repo->index.

(Also, if you want to avoid merge conflicts, you might want to avoid unrelated changes like the whitespace and alignment fixes. You'll be happy to know, though, that I think I fixed them all up as part of the en/merge-recursive-cleanup series in pu.)

Elijah
Show 632 quoted lines
>
> -- 8< --
> diff --git a/builtin/am.c b/builtin/am.c
> index 3961878871..5d2ff9aa8c 100644
> --- a/builtin/am.c
> +++ b/builtin/am.c
> @@ -1592,7 +1592,7 @@ static int fall_back_threeway(const struct am_state *state, const char *index_pa
>          * changes.
>          */
>
> -       init_merge_options(&o);
> +       init_merge_options(&o, the_repository);
>
>         o.branch1 = "HEAD";
>         their_tree_name = xstrfmt("%.*s", linelen(state->msg), state->msg);
> diff --git a/builtin/checkout.c b/builtin/checkout.c
> index 528c6de7e1..4fd53cec6e 100644
> --- a/builtin/checkout.c
> +++ b/builtin/checkout.c
> @@ -570,7 +570,7 @@ static int merge_working_tree(const struct checkout_opts *opts,
>                          * a pain; plumb in an option to set
>                          * o.renormalize?
>                          */
> -                       init_merge_options(&o);
> +                       init_merge_options(&o, the_repository);
>                         o.verbosity = 0;
>                         work = write_tree_from_memory(&o);
>
> diff --git a/builtin/merge-recursive.c b/builtin/merge-recursive.c
> index 0dd9021958..c4a9e575d6 100644
> --- a/builtin/merge-recursive.c
> +++ b/builtin/merge-recursive.c
> @@ -28,7 +28,7 @@ int cmd_merge_recursive(int argc, const char **argv, const char *prefix)
>         struct merge_options o;
>         struct commit *result;
>
> -       init_merge_options(&o);
> +       init_merge_options(&o, the_repository);
>         if (argv[0] && ends_with(argv[0], "-subtree"))
>                 o.subtree_shift = "";
>
> diff --git a/builtin/merge.c b/builtin/merge.c
> index db460a35cf..2ebd939b76 100644
> --- a/builtin/merge.c
> +++ b/builtin/merge.c
> @@ -671,7 +671,7 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common,
>                         return 2;
>                 }
>
> -               init_merge_options(&o);
> +               init_merge_options(&o, the_repository);
>                 if (!strcmp(strategy, "subtree"))
>                         o.subtree_shift = "";
>
> diff --git a/merge-recursive.c b/merge-recursive.c
> index a296ba3874..fd6556b6de 100644
> --- a/merge-recursive.c
> +++ b/merge-recursive.c
> @@ -309,26 +309,29 @@ static void output_commit_title(struct merge_options *o, struct commit *commit)
>  }
>
>  static int add_cacheinfo(struct merge_options *o,
> -               unsigned int mode, const struct object_id *oid,
> -               const char *path, int stage, int refresh, int options)
> +                        unsigned int mode,
> +                        const struct object_id *oid,
> +                        const char *path, int stage,
> +                        int refresh, int options)
>  {
> +       struct index_state *istate = o->repo->index;
>         struct cache_entry *ce;
>         int ret;
>
> -       ce = make_index_entry(&the_index, mode, oid ? oid->hash : null_sha1, path, stage, 0);
> +       ce = make_index_entry(istate, mode, oid ? oid->hash : null_sha1, path, stage, 0);
>         if (!ce)
>                 return err(o, _("add_cacheinfo failed for path '%s'; merge aborting."), path);
>
> -       ret = add_index_entry(&the_index, ce, options);
> +       ret = add_index_entry(istate, ce, options);
>         if (refresh) {
>                 struct cache_entry *nce;
>
> -               nce = refresh_index_entry(&the_index, ce,
> +               nce = refresh_index_entry(istate, ce,
>                                           CE_MATCH_REFRESH | CE_MATCH_IGNORE_MISSING);
>                 if (!nce)
>                         return err(o, _("add_cacheinfo failed to refresh for path '%s'; merge aborting."), path);
>                 if (nce != ce)
> -                       ret = add_index_entry(&the_index, nce, options);
> +                       ret = add_index_entry(istate, nce, options);
>         }
>         return ret;
>  }
> @@ -356,7 +359,7 @@ static int unpack_trees_start(struct merge_options *o,
>         o->unpack_opts.merge = 1;
>         o->unpack_opts.head_idx = 2;
>         o->unpack_opts.fn = threeway_merge;
> -       o->unpack_opts.src_index = &the_index;
> +       o->unpack_opts.src_index = o->repo->index;
>         o->unpack_opts.dst_index = &tmp_index;
>         o->unpack_opts.aggressive = !merge_detect_rename(o);
>         setup_unpack_trees_porcelain(&o->unpack_opts, "merge");
> @@ -366,16 +369,16 @@ static int unpack_trees_start(struct merge_options *o,
>         init_tree_desc_from_tree(t+2, merge);
>
>         rc = unpack_trees(3, t, &o->unpack_opts);
> -       cache_tree_free(&the_index.cache_tree);
> +       cache_tree_free(&o->repo->index->cache_tree);
>
>         /*
> -        * Update the_index to match the new results, AFTER saving a copy
> +        * Update o->repo->index to match the new results, AFTER saving a copy
>          * in o->orig_index.  Update src_index to point to the saved copy.
>          * (verify_uptodate() checks src_index, and the original index is
>          * the one that had the necessary modification timestamps.)
>          */
> -       o->orig_index = the_index;
> -       the_index = tmp_index;
> +       o->orig_index = *o->repo->index;
> +       *o->repo->index = tmp_index;
>         o->unpack_opts.src_index = &o->orig_index;
>
>         return rc;
> @@ -390,12 +393,13 @@ static void unpack_trees_finish(struct merge_options *o)
>  struct tree *write_tree_from_memory(struct merge_options *o)
>  {
>         struct tree *result = NULL;
> +       struct index_state *istate = o->repo->index;
>
> -       if (unmerged_index(&the_index)) {
> +       if (unmerged_index(istate)) {
>                 int i;
>                 fprintf(stderr, "BUG: There are unmerged index entries:\n");
> -               for (i = 0; i < the_index.cache_nr; i++) {
> -                       const struct cache_entry *ce = the_index.cache[i];
> +               for (i = 0; i < istate->cache_nr; i++) {
> +                       const struct cache_entry *ce = istate->cache[i];
>                         if (ce_stage(ce))
>                                 fprintf(stderr, "BUG: %d %.*s\n", ce_stage(ce),
>                                         (int)ce_namelen(ce), ce->name);
> @@ -403,16 +407,16 @@ struct tree *write_tree_from_memory(struct merge_options *o)
>                 BUG("unmerged index entries in merge-recursive.c");
>         }
>
> -       if (!the_index.cache_tree)
> -               the_index.cache_tree = cache_tree();
> +       if (!istate->cache_tree)
> +               istate->cache_tree = cache_tree();
>
> -       if (!cache_tree_fully_valid(the_index.cache_tree) &&
> -           cache_tree_update(&the_index, 0) < 0) {
> +       if (!cache_tree_fully_valid(istate->cache_tree) &&
> +           cache_tree_update(istate, 0) < 0) {
>                 err(o, _("error building trees"));
>                 return NULL;
>         }
>
> -       result = lookup_tree(&the_index.cache_tree->oid);
> +       result = lookup_tree(&istate->cache_tree->oid);
>
>         return result;
>  }
> @@ -482,17 +486,17 @@ static struct stage_data *insert_stage_data(const char *path,
>   * Create a dictionary mapping file names to stage_data objects. The
>   * dictionary contains one entry for every path with a non-zero stage entry.
>   */
> -static struct string_list *get_unmerged(void)
> +static struct string_list *get_unmerged(struct index_state *istate)
>  {
>         struct string_list *unmerged = xcalloc(1, sizeof(struct string_list));
>         int i;
>
>         unmerged->strdup_strings = 1;
>
> -       for (i = 0; i < the_index.cache_nr; i++) {
> +       for (i = 0; i < istate->cache_nr; i++) {
>                 struct string_list_item *item;
>                 struct stage_data *e;
> -               const struct cache_entry *ce = the_index.cache[i];
> +               const struct cache_entry *ce = istate->cache[i];
>                 if (!ce_stage(ce))
>                         continue;
>
> @@ -652,7 +656,7 @@ static int update_stages(struct merge_options *opt, const char *path,
>         int clear = 1;
>         int options = ADD_CACHE_OK_TO_ADD | ADD_CACHE_SKIP_DFCHECK;
>         if (clear)
> -               if (remove_file_from_index(&the_index, path))
> +               if (remove_file_from_index(opt->repo->index, path))
>                         return -1;
>         if (o)
>                 if (add_cacheinfo(opt, o->mode, &o->oid, path, 1, 0, options))
> @@ -708,13 +712,13 @@ static int remove_file(struct merge_options *o, int clean,
>         int update_working_directory = !o->call_depth && !no_wd;
>
>         if (update_cache) {
> -               if (remove_file_from_index(&the_index, path))
> +               if (remove_file_from_index(o->repo->index, path))
>                         return -1;
>         }
>         if (update_working_directory) {
>                 if (ignore_case) {
>                         struct cache_entry *ce;
> -                       ce = index_file_exists(&the_index, path, strlen(path),
> +                       ce = index_file_exists(o->repo->index, path, strlen(path),
>                                                ignore_case);
>                         if (ce && ce_stage(ce) == 0 && strcmp(path, ce->name))
>                                 return 0;
> @@ -765,7 +769,8 @@ static char *unique_path(struct merge_options *o, const char *path, const char *
>   * check the working directory.  If empty_ok is non-zero, also return
>   * 0 in the case where the working-tree dir exists but is empty.
>   */
> -static int dir_in_way(const char *path, int check_working_copy, int empty_ok)
> +static int dir_in_way(struct index_state *istate, const char *path,
> +                     int check_working_copy, int empty_ok)
>  {
>         int pos;
>         struct strbuf dirpath = STRBUF_INIT;
> @@ -774,12 +779,12 @@ static int dir_in_way(const char *path, int check_working_copy, int empty_ok)
>         strbuf_addstr(&dirpath, path);
>         strbuf_addch(&dirpath, '/');
>
> -       pos = index_name_pos(&the_index, dirpath.buf, dirpath.len);
> +       pos = index_name_pos(istate, dirpath.buf, dirpath.len);
>
>         if (pos < 0)
>                 pos = -1 - pos;
> -       if (pos < the_index.cache_nr &&
> -           !strncmp(dirpath.buf, the_index.cache[pos]->name, dirpath.len)) {
> +       if (pos < istate->cache_nr &&
> +           !strncmp(dirpath.buf, istate->cache[pos]->name, dirpath.len)) {
>                 strbuf_release(&dirpath);
>                 return 1;
>         }
> @@ -822,7 +827,7 @@ static int was_tracked(struct merge_options *o, const char *path)
>         return 0;
>  }
>
> -static int would_lose_untracked(const char *path)
> +static int would_lose_untracked(struct index_state *istate, const char *path)
>  {
>         /*
>          * This may look like it can be simplified to:
> @@ -841,19 +846,19 @@ static int would_lose_untracked(const char *path)
>          * update_file()/would_lose_untracked(); see every comment in this
>          * file which mentions "update_stages".
>          */
> -       int pos = index_name_pos(&the_index, path, strlen(path));
> +       int pos = index_name_pos(istate, path, strlen(path));
>
>         if (pos < 0)
>                 pos = -1 - pos;
> -       while (pos < the_index.cache_nr &&
> -              !strcmp(path, the_index.cache[pos]->name)) {
> +       while (pos < istate->cache_nr &&
> +              !strcmp(path, istate->cache[pos]->name)) {
>                 /*
>                  * If stage #0, it is definitely tracked.
>                  * If it has stage #2 then it was tracked
>                  * before this merge started.  All other
>                  * cases the path was not tracked.
>                  */
> -               switch (ce_stage(the_index.cache[pos])) {
> +               switch (ce_stage(istate->cache[pos])) {
>                 case 0:
>                 case 2:
>                         return 0;
> @@ -913,7 +918,7 @@ static int make_room_for_path(struct merge_options *o, const char *path)
>          * Do not unlink a file in the work tree if we are not
>          * tracking it.
>          */
> -       if (would_lose_untracked(path))
> +       if (would_lose_untracked(o->repo->index, path))
>                 return err(o, _("refusing to lose untracked file at '%s'"),
>                              path);
>
> @@ -963,7 +968,7 @@ static int update_file_flags(struct merge_options *o,
>                 }
>                 if (S_ISREG(mode)) {
>                         struct strbuf strbuf = STRBUF_INIT;
> -                       if (convert_to_working_tree(&the_index, path, buf, size, &strbuf)) {
> +                       if (convert_to_working_tree(o->repo->index, path, buf, size, &strbuf)) {
>                                 free(buf);
>                                 size = strbuf.len;
>                                 buf = strbuf_detach(&strbuf, NULL);
> @@ -1081,7 +1086,7 @@ static int merge_3way(struct merge_options *o,
>
>         merge_status = ll_merge(result_buf, a->path, &orig, base_name,
>                                 &src1, name1, &src2, name2,
> -                               &the_index, &ll_opts);
> +                               o->repo->index, &ll_opts);
>
>         free(base_name);
>         free(name1);
> @@ -1092,8 +1097,9 @@ static int merge_3way(struct merge_options *o,
>         return merge_status;
>  }
>
> -static int find_first_merges(struct object_array *result, const char *path,
> -               struct commit *a, struct commit *b)
> +static int find_first_merges(struct repository *repo,
> +                            struct object_array *result, const char *path,
> +                            struct commit *a, struct commit *b)
>  {
>         int i, j;
>         struct object_array merges = OBJECT_ARRAY_INIT;
> @@ -1112,7 +1118,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, the_repository, NULL);
> +       init_revisions(&revs, repo, NULL);
>         rev_opts.submodule = path;
>         /* FIXME: can't handle linked worktrees in submodules yet */
>         revs.single_worktree = path != NULL;
> @@ -1242,7 +1248,8 @@ static int merge_submodule(struct merge_options *o,
>                 return 0;
>
>         /* find commit which merges them */
> -       parent_count = find_first_merges(&merges, path, commit_a, commit_b);
> +       parent_count = find_first_merges(o->repo, &merges, path,
> +                                        commit_a, commit_b);
>         switch (parent_count) {
>         case 0:
>                 output(o, 1, _("Failed to merge submodule %s (merge following commits not found)"), path);
> @@ -1420,7 +1427,7 @@ static int conflict_rename_dir(struct merge_options *o,
>  {
>         const struct diff_filespec *dest = pair->two;
>
> -       if (!o->call_depth && would_lose_untracked(dest->path)) {
> +       if (!o->call_depth && would_lose_untracked(o->repo->index, dest->path)) {
>                 char *alt_path = unique_path(o, dest->path, rename_branch);
>
>                 output(o, 1, _("Error: Refusing to lose untracked file at %s; "
> @@ -1458,8 +1465,8 @@ static int handle_change_delete(struct merge_options *o,
>         const char *update_path = path;
>         int ret = 0;
>
> -       if (dir_in_way(path, !o->call_depth, 0) ||
> -           (!o->call_depth && would_lose_untracked(path))) {
> +       if (dir_in_way(o->repo->index, path, !o->call_depth, 0) ||
> +           (!o->call_depth && would_lose_untracked(o->repo->index, path))) {
>                 update_path = alt_path = unique_path(o, path, change_branch);
>         }
>
> @@ -1469,7 +1476,7 @@ static int handle_change_delete(struct merge_options *o,
>                  * correct; since there is no true "middle point" between
>                  * them, simply reuse the base version for virtual merge base.
>                  */
> -               ret = remove_file_from_index(&the_index, path);
> +               ret = remove_file_from_index(o->repo->index, path);
>                 if (!ret)
>                         ret = update_file(o, 0, o_oid, o_mode, update_path);
>         } else {
> @@ -1530,7 +1537,7 @@ static int conflict_rename_delete(struct merge_options *o,
>                 return -1;
>
>         if (o->call_depth)
> -               return remove_file_from_index(&the_index, dest->path);
> +               return remove_file_from_index(o->repo->index, dest->path);
>         else
>                 return update_stages(o, dest->path, NULL,
>                                      rename_branch == o->branch1 ? dest : NULL,
> @@ -1592,12 +1599,12 @@ static int handle_file(struct merge_options *o,
>                 remove_file(o, 0, rename->path, ren_src_was_dirty);
>                 dst_name = unique_path(o, rename->path, cur_branch);
>         } else {
> -               if (dir_in_way(rename->path, !o->call_depth, 0)) {
> +               if (dir_in_way(o->repo->index, rename->path, !o->call_depth, 0)) {
>                         dst_name = unique_path(o, rename->path, cur_branch);
>                         output(o, 1, _("%s is a directory in %s adding as %s instead"),
>                                rename->path, other_branch, dst_name);
>                 } else if (!o->call_depth &&
> -                          would_lose_untracked(rename->path)) {
> +                          would_lose_untracked(o->repo->index, rename->path)) {
>                         dst_name = unique_path(o, rename->path, cur_branch);
>                         output(o, 1, _("Refusing to lose untracked file at %s; "
>                                        "adding as %s instead"),
> @@ -1665,14 +1672,14 @@ static int conflict_rename_rename_1to2(struct merge_options *o,
>                                 return -1;
>                 }
>                 else
> -                       remove_file_from_index(&the_index, a->path);
> +                       remove_file_from_index(o->repo->index, a->path);
>                 add = filespec_from_entry(&other, ci->dst_entry2, 3 ^ 1);
>                 if (add) {
>                         if (update_file(o, 0, &add->oid, add->mode, b->path))
>                                 return -1;
>                 }
>                 else
> -                       remove_file_from_index(&the_index, b->path);
> +                       remove_file_from_index(o->repo->index, b->path);
>         } else if (handle_file(o, a, 2, ci) || handle_file(o, b, 3, ci))
>                 return -1;
>
> @@ -1680,8 +1687,9 @@ static int conflict_rename_rename_1to2(struct merge_options *o,
>  }
>
>  static int conflict_rename_rename_2to1(struct merge_options *o,
> -                                       struct rename_conflict_info *ci)
> +                                      struct rename_conflict_info *ci)
>  {
> +       struct index_state *istate = o->repo->index;
>         /* Two files, a & b, were renamed to the same thing, c. */
>         struct diff_filespec *a = ci->pair1->one;
>         struct diff_filespec *b = ci->pair2->one;
> @@ -1700,8 +1708,12 @@ static int conflict_rename_rename_2to1(struct merge_options *o,
>                a->path, c1->path, ci->branch1,
>                b->path, c2->path, ci->branch2);
>
> -       remove_file(o, 1, a->path, o->call_depth || would_lose_untracked(a->path));
> -       remove_file(o, 1, b->path, o->call_depth || would_lose_untracked(b->path));
> +       remove_file(o, 1, a->path,
> +                   (o->call_depth ||
> +                    would_lose_untracked(istate, a->path)));
> +       remove_file(o, 1, b->path,
> +                   (o->call_depth ||
> +                    would_lose_untracked(istate, b->path)));
>
>         path_side_1_desc = xstrfmt("%s (was %s)", path, a->path);
>         path_side_2_desc = xstrfmt("%s (was %s)", path, b->path);
> @@ -1738,7 +1750,7 @@ static int conflict_rename_rename_2to1(struct merge_options *o,
>                 if (was_dirty(o, path))
>                         output(o, 1, _("Refusing to lose dirty file at %s"),
>                                path);
> -               else if (would_lose_untracked(path))
> +               else if (would_lose_untracked(istate, path))
>                         /*
>                          * Only way we get here is if both renames were from
>                          * a directory rename AND user had an untracked file
> @@ -1789,7 +1801,7 @@ static struct diff_queue_struct *get_diffpairs(struct merge_options *o,
>         struct diff_queue_struct *ret;
>         struct diff_options opts;
>
> -       diff_setup(&opts, &the_index);
> +       diff_setup(&opts, o->repo->index);
>         opts.flags.recursive = 1;
>         opts.flags.rename_empty = 0;
>         opts.detect_rename = merge_detect_rename(o);
> @@ -2949,8 +2961,8 @@ static int blob_unchanged(struct merge_options *opt,
>          * performed.  Comparison can be skipped if both files are
>          * unchanged since their sha1s have already been compared.
>          */
> -       if (renormalize_buffer(&the_index, path, o.buf, o.len, &o) |
> -           renormalize_buffer(&the_index, path, a.buf, a.len, &a))
> +       if (renormalize_buffer(opt->repo->index, path, o.buf, o.len, &o) |
> +           renormalize_buffer(opt->repo->index, path, a.buf, a.len, &a))
>                 ret = (o.len == a.len && !memcmp(o.buf, a.buf, o.len));
>
>  error_return:
> @@ -3028,7 +3040,7 @@ static int merge_content(struct merge_options *o,
>                          o->branch2 == rename_conflict_info->branch1) ?
>                         pair1->two->path : pair1->one->path;
>
> -               if (dir_in_way(path, !o->call_depth,
> +               if (dir_in_way(o->repo->index, path, !o->call_depth,
>                                S_ISGITLINK(pair1->two->mode)))
>                         df_conflict_remains = 1;
>         }
> @@ -3066,7 +3078,7 @@ static int merge_content(struct merge_options *o,
>         if (df_conflict_remains || is_dirty) {
>                 char *new_path;
>                 if (o->call_depth) {
> -                       remove_file_from_index(&the_index, path);
> +                       remove_file_from_index(o->repo->index, path);
>                 } else {
>                         if (!mfi.clean) {
>                                 if (update_stages(o, path, &one, &a, &b))
> @@ -3212,7 +3224,7 @@ static int process_entry(struct merge_options *o,
>                         oid = b_oid;
>                         conf = _("directory/file");
>                 }
> -               if (dir_in_way(path,
> +               if (dir_in_way(o->repo->index, path,
>                                !o->call_depth && !S_ISGITLINK(a_mode),
>                                0)) {
>                         char *new_path = unique_path(o, path, add_branch);
> @@ -3223,7 +3235,7 @@ static int process_entry(struct merge_options *o,
>                         if (update_file(o, 0, oid, mode, new_path))
>                                 clean_merge = -1;
>                         else if (o->call_depth)
> -                               remove_file_from_index(&the_index, path);
> +                               remove_file_from_index(o->repo->index, path);
>                         free(new_path);
>                 } else {
>                         output(o, 2, _("Adding %s"), path);
> @@ -3256,6 +3268,7 @@ int merge_trees(struct merge_options *o,
>                 struct tree *common,
>                 struct tree **result)
>  {
> +       struct index_state *istate = o->repo->index;
>         int code, clean;
>
>         if (o->subtree_shift) {
> @@ -3266,7 +3279,7 @@ int merge_trees(struct merge_options *o,
>         if (oid_eq(&common->object.oid, &merge->object.oid)) {
>                 struct strbuf sb = STRBUF_INIT;
>
> -               if (!o->call_depth && index_has_changes(&the_index, &sb)) {
> +               if (!o->call_depth && index_has_changes(istate, &sb)) {
>                         err(o, _("Dirty index: cannot merge (dirty: %s)"),
>                             sb.buf);
>                         return 0;
> @@ -3287,7 +3300,7 @@ int merge_trees(struct merge_options *o,
>                 return -1;
>         }
>
> -       if (unmerged_index(&the_index)) {
> +       if (unmerged_index(istate)) {
>                 struct string_list *entries;
>                 struct rename_info re_info;
>                 int i;
> @@ -3302,7 +3315,7 @@ int merge_trees(struct merge_options *o,
>                 get_files_dirs(o, head);
>                 get_files_dirs(o, merge);
>
> -               entries = get_unmerged();
> +               entries = get_unmerged(o->repo->index);
>                 clean = handle_renames(o, common, head, merge, entries,
>                                        &re_info);
>                 record_df_conflict_files(o, entries);
> @@ -3418,7 +3431,7 @@ int merge_recursive(struct merge_options *o,
>                  * overwritten it: the committed "conflicts" were
>                  * already resolved.
>                  */
> -               discard_index(&the_index);
> +               discard_index(o->repo->index);
>                 saved_b1 = o->branch1;
>                 saved_b2 = o->branch2;
>                 o->branch1 = "Temporary merge branch 1";
> @@ -3434,9 +3447,9 @@ int merge_recursive(struct merge_options *o,
>                         return err(o, _("merge returned no commit"));
>         }
>
> -       discard_index(&the_index);
> +       discard_index(o->repo->index);
>         if (!o->call_depth)
> -               repo_read_index(the_repository);
> +               repo_read_index(o->repo);
>
>         o->ancestor = "merged common ancestors";
>         clean = merge_trees(o, get_commit_tree(h1), get_commit_tree(h2),
> @@ -3501,7 +3514,7 @@ int merge_recursive_generic(struct merge_options *o,
>                 }
>         }
>
> -       repo_hold_locked_index(the_repository, &lock, LOCK_DIE_ON_ERROR);
> +       repo_hold_locked_index(o->repo, &lock, LOCK_DIE_ON_ERROR);
>         clean = merge_recursive(o, head_commit, next_commit, ca,
>                         result);
>         if (clean < 0) {
> @@ -3509,7 +3522,7 @@ int merge_recursive_generic(struct merge_options *o,
>                 return clean;
>         }
>
> -       if (write_locked_index(&the_index, &lock,
> +       if (write_locked_index(o->repo->index, &lock,
>                                COMMIT_LOCK | SKIP_IF_UNCHANGED))
>                 return err(o, _("Unable to write index."));
>
> @@ -3533,10 +3546,12 @@ static void merge_recursive_config(struct merge_options *o)
>         git_config(git_xmerge_config, NULL);
>  }
>
> -void init_merge_options(struct merge_options *o)
> +void init_merge_options(struct merge_options *o,
> +                       struct repository *repo)
>  {
>         const char *merge_verbosity;
>         memset(o, 0, sizeof(struct merge_options));
> +       o->repo = repo;
>         o->verbosity = 2;
>         o->buffer_output = 1;
>         o->diff_rename_limit = -1;
> diff --git a/merge-recursive.h b/merge-recursive.h
> index fa7bc6b683..b2985b621f 100644
> --- a/merge-recursive.h
> +++ b/merge-recursive.h
> @@ -4,6 +4,8 @@
>  #include "unpack-trees.h"
>  #include "string-list.h"
>
> +struct repository;
> +
>  struct merge_options {
>         const char *ancestor;
>         const char *branch1;
> @@ -31,6 +33,7 @@ struct merge_options {
>         struct string_list df_conflict_file_set;
>         struct unpack_trees_options unpack_opts;
>         struct index_state orig_index;
> +       struct repository *repo;
>  };
>
>  /*
> @@ -89,7 +92,8 @@ int merge_recursive_generic(struct merge_options *o,
>                             const struct object_id **ca,
>                             struct commit **result);
>
> -void init_merge_options(struct merge_options *o);
> +void init_merge_options(struct merge_options *o,
> +                       struct repository *repo);
>  struct tree *write_tree_from_memory(struct merge_options *o);
>
>  int parse_merge_opt(struct merge_options *out, const char *s);
> diff --git a/sequencer.c b/sequencer.c
> index 5be3b5c79d..a8fb1861a3 100644
> --- a/sequencer.c
> +++ b/sequencer.c
> @@ -532,7 +532,7 @@ static int do_recursive_merge(struct repository *repo,
>
>         repo_read_index(repo);
>
> -       init_merge_options(&o);
> +       init_merge_options(&o, repo);
>         o.ancestor = base ? base_label : "(empty tree)";
>         o.branch1 = "HEAD";
>         o.branch2 = next ? next_label : "(empty tree)";
> @@ -3022,7 +3022,7 @@ static int do_merge(struct repository *repo,
>         free_commit_list(bases);
>
>         repo_read_index(repo);
> -       init_merge_options(&o);
> +       init_merge_options(&o, repo);
>         o.branch1 = "HEAD";
>         o.branch2 = ref_name.buf;
>         o.buffer_output = 2;
> -- 8< --
>
>> --
>> Duy
Previous: Duy NguyenNext: Duy Nguyen
Message 91 of 92 in “unpack-trees.c: do not use "the_index"”
  1. unpack-trees.c: do not use "the_index"Nguyễn Thái Ngọc Duy, Jun 1, 2018
  2. Elijah NewrenJun 1, 2018
  3. Stefan BellerJun 1, 2018
  4. Duy NguyenJun 2, 2018
  5. Duy NguyenJun 2, 2018
  6. Elijah NewrenJun 3, 2018
  7. Brandon WilliamsJun 4, 2018
  8. 0/6 Fix "the_index" usage in unpack-trees.cNguyễn Thái Ngọc Duy, Jun 5, 2018
  9. 1/6 unpack-trees: remove 'extern' on function declarationNguyễn Thái Ngọc Duy, Jun 5, 2018
  10. 3/6 unpack-trees: don't shadow global var the_indexNguyễn Thái Ngọc Duy, Jun 5, 2018
  11. Ramsay JonesJun 5, 2018
  12. 4/6 unpack-tress: convert clear_ce_flags* to avoid the_indexNguyễn Thái Ngọc Duy, Jun 5, 2018
  13. Ramsay JonesJun 5, 2018
  14. 5/6 unpack-trees: avoid the_index in verify_absent()Nguyễn Thái Ngọc Duy, Jun 5, 2018
  15. 6/6 Forbid "the_index" in dir.c and unpack-trees.cNguyễn Thái Ngọc Duy, Jun 5, 2018
  16. Brandon WilliamsJun 5, 2018
  17. Duy NguyenJun 6, 2018
  18. 2/6 unpack-trees: add a note about path invalidationNguyễn Thái Ngọc Duy, Jun 5, 2018
  19. 0/5 Fix "the_index" usage in unpack-trees.cNguyễn Thái Ngọc Duy, Jun 6, 2018
  20. 1/5 unpack-trees: remove 'extern' on function declarationNguyễn Thái Ngọc Duy, Jun 6, 2018
  21. 4/5 unpack-tress: convert clear_ce_flags* to avoid the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  22. 3/5 unpack-trees: don't shadow global var the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  23. 2/5 unpack-trees: add a note about path invalidationNguyễn Thái Ngọc Duy, Jun 6, 2018
  24. 5/5 unpack-trees: avoid the_index in verify_absent()Nguyễn Thái Ngọc Duy, Jun 6, 2018
  25. 00/20 Fix incorrect use of the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  26. 02/20 unpack-trees: add a note about path invalidationNguyễn Thái Ngọc Duy, Jun 6, 2018
  27. 01/20 unpack-trees: remove 'extern' on function declarationNguyễn Thái Ngọc Duy, Jun 6, 2018
  28. 04/20 unpack-tress: convert clear_ce_flags* to avoid the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  29. 05/20 unpack-trees: avoid the_index in verify_absent()Nguyễn Thái Ngọc Duy, Jun 6, 2018
  30. 03/20 unpack-trees: don't shadow global var the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  31. 11/20 ls-files: correct index argument to get_convert_attr_ascii()Nguyễn Thái Ngọc Duy, Jun 6, 2018
  32. 10/20 dir.c: remove an implicit dependency on the_index in pathspec codeNguyễn Thái Ngọc Duy, Jun 6, 2018
  33. 14/20 entry.c: use the right index instead of the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  34. 09/20 convert.c: remove an implicit dependency on the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  35. 19/20 grep: use the right index instead of the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  36. 17/20 cache.c: remove an implicit dependency on the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  37. Brandon WilliamsJun 6, 2018
  38. 18/20 resolve-undo.c: use the right index instead of the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  39. 20/20 cache.h: make the_index part of "compatibility macros"Nguyễn Thái Ngọc Duy, Jun 6, 2018
  40. 16/20 preload-index.c: use the right index instead of the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  41. 12/20 pathspec.c: use the right index instead of the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  42. 15/20 attr: remove index from git_attr_set_direction()Nguyễn Thái Ngọc Duy, Jun 6, 2018
  43. Brandon WilliamsJun 6, 2018
  44. 08/20 convert.h: drop 'extern' from function declarationNguyễn Thái Ngọc Duy, Jun 6, 2018
  45. 13/20 submodule.c: use the right index instead of the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  46. 06/20 attr.h: drop extern from function declarationNguyễn Thái Ngọc Duy, Jun 6, 2018
  47. 07/20 attr: remove an implicit dependency on the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  48. Ramsay JonesJun 6, 2018
  49. Brandon WilliamsJun 6, 2018
  50. Duy NguyenJun 6, 2018
  51. Brandon WilliamsJun 6, 2018
  52. 00/23 Fix incorrect use of the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  53. 01/23 unpack-trees: remove 'extern' on function declarationNguyễn Thái Ngọc Duy, Jun 6, 2018
  54. 02/23 unpack-trees: add a note about path invalidationNguyễn Thái Ngọc Duy, Jun 6, 2018
  55. 04/23 unpack-tress: convert clear_ce_flags* to avoid the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  56. Elijah NewrenJun 7, 2018
  57. Duy NguyenJun 7, 2018
  58. Duy NguyenJun 8, 2018
  59. 03/23 unpack-trees: don't shadow global var the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  60. 05/23 unpack-trees: avoid the_index in verify_absent()Nguyễn Thái Ngọc Duy, Jun 6, 2018
  61. 06/23 attr.h: drop extern from function declarationNguyễn Thái Ngọc Duy, Jun 6, 2018
  62. 08/23 convert.h: drop 'extern' from function declarationNguyễn Thái Ngọc Duy, Jun 6, 2018
  63. 09/23 convert.c: remove an implicit dependency on the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  64. 11/23 ls-files: correct index argument to get_convert_attr_ascii()Nguyễn Thái Ngọc Duy, Jun 6, 2018
  65. 10/23 dir.c: remove an implicit dependency on the_index in pathspec codeNguyễn Thái Ngọc Duy, Jun 6, 2018
  66. 14/23 entry.c: use the right index instead of the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  67. 13/23 submodule.c: use the right index instead of the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  68. 16/23 preload-index.c: use the right index instead of the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  69. 20/23 checkout: avoid the_index when possibleNguyễn Thái Ngọc Duy, Jun 6, 2018
  70. 23/23 cache.h: make the_index part of "compatibility macros"Nguyễn Thái Ngọc Duy, Jun 6, 2018
  71. 22/23 grep: use the right index instead of the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  72. 19/23 difftool: use the right index instead of the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  73. 21/23 resolve-undo.c: use the right index instead of the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  74. 18/23 apply.c: use the right index instead of the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  75. 15/23 attr: remove index from git_attr_set_direction()Nguyễn Thái Ngọc Duy, Jun 6, 2018
  76. Elijah NewrenJun 9, 2018
  77. 17/23 read-cache.c: remove an implicit dependency on the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  78. Elijah NewrenJun 9, 2018
  79. Duy NguyenJun 9, 2018
  80. Elijah NewrenJun 9, 2018
  81. 12/23 pathspec.c: use the right index instead of the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  82. 07/23 attr: remove an implicit dependency on the_indexNguyễn Thái Ngọc Duy, Jun 6, 2018
  83. Elijah NewrenJun 7, 2018
  84. Elijah NewrenJun 9, 2018
  85. Duy NguyenJun 11, 2018
  86. Elijah NewrenJun 11, 2018
  87. Duy NguyenJun 11, 2018
  88. Elijah NewrenJun 11, 2018
  89. Duy NguyenJun 11, 2018
  90. Duy NguyenJun 14, 2018
  91. Elijah NewrenJun 14, 2018
  92. Duy NguyenJun 11, 2018

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.