merge-recursive: add a bunch of FIXME comments documenting known bugs

The plan is to just delete merge-recursive, but not until everyone is comfortable with merge-ort as a replacement. Given that I haven't switched all callers of merge-recursive over yet (e.g. git-am still uses merge-recursive), maybe there's some value documenting known bugs in the algorithm in case we end up keeping it or someone wants to dig it up in the future. Signed-off-by: Elijah Newren <newren@gmail.com> Reviewed-by: Derrick Stolee <dstolee@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Elijah Newren committed Mar 20, 2021 at 00:03 UTC 816147e7bab0c7e9c3a578ce166c55d5f7a64a8a
1 file changed +37
merge-recursive.c
+37
@@ -1075,6 +1075,11 @@ static int merge_3way(struct merge_options *opt,
1075 read_mmblob(&src1, &a->oid);
1076 read_mmblob(&src2, &b->oid);
1077
1078 + /*
1079 + * FIXME: Using a->path for normalization rules in ll_merge could be
1080 + * wrong if we renamed from a->path to b->path. We should use the
1081 + * target path for where the file will be written.
1082 + */
1083 merge_status = ll_merge(result_buf, a->path, &orig, base,
1084 &src1, name1, &src2, name2,
1085 opt->repo->index, &ll_opts);
@@ -1154,6 +1159,8 @@ static void print_commit(struct commit *commit)
1159 struct strbuf sb = STRBUF_INIT;
1160 struct pretty_print_context ctx = {0};
1161 ctx.date_mode.type = DATE_NORMAL;
1162 + /* FIXME: Merge this with output_commit_title() */
1163 + assert(!merge_remote_util(commit));
1164 format_commit_message(commit, " %h: %m %s", &sb, &ctx);
1165 fprintf(stderr, "%s\n", sb.buf);
1166 strbuf_release(&sb);
@@ -1177,6 +1184,11 @@ static int merge_submodule(struct merge_options *opt,
1184 int search = !opt->priv->call_depth;
1185
1186 /* store a in result in case we fail */
1187 + /* FIXME: This is the WRONG resolution for the recursive case when
1188 + * we need to be careful to avoid accidentally matching either side.
1189 + * Should probably use o instead there, much like we do for merging
1190 + * binaries.
1191 + */
1192 oidcpy(result, a);
1193
1194 /* we can not handle deletion conflicts */
@@ -1301,6 +1313,13 @@ static int merge_mode_and_contents(struct merge_options *opt,
1313
1314 if ((S_IFMT & a->mode) != (S_IFMT & b->mode)) {
1315 result->clean = 0;
1316 + /*
1317 + * FIXME: This is a bad resolution for recursive case; for
1318 + * the recursive case we want something that is unlikely to
1319 + * accidentally match either side. Also, while it makes
1320 + * sense to prefer regular files over symlinks, it doesn't
1321 + * make sense to prefer regular files over submodules.
1322 + */
1323 if (S_ISREG(a->mode)) {
1324 result->blob.mode = a->mode;
1325 oidcpy(&result->blob.oid, &a->oid);
@@ -1349,6 +1368,7 @@ static int merge_mode_and_contents(struct merge_options *opt,
1368 free(result_buf.ptr);
1369 if (ret)
1370 return ret;
1371 + /* FIXME: bug, what if modes didn't match? */
1372 result->clean = (merge_status == 0);
1373 } else if (S_ISGITLINK(a->mode)) {
1374 result->clean = merge_submodule(opt, &result->blob.oid,
@@ -2664,6 +2684,14 @@ static int process_renames(struct merge_options *opt,
2684 struct string_list b_by_dst = STRING_LIST_INIT_NODUP;
2685 const struct rename *sre;
2686
2687 + /*
2688 + * FIXME: As string-list.h notes, it's O(n^2) to build a sorted
2689 + * string_list one-by-one, but O(n log n) to build it unsorted and
2690 + * then sort it. Note that as we build the list, we do not need to
2691 + * check if the existing destination path is already in the list,
2692 + * because the structure of diffcore_rename guarantees we won't
2693 + * have duplicates.
2694 + */
2695 for (i = 0; i < a_renames->nr; i++) {
2696 sre = a_renames->items[i].util;
2697 string_list_insert(&a_by_dst, sre->pair->two->path)->util
@@ -3602,6 +3630,15 @@ static int merge_recursive_internal(struct merge_options *opt,
3630 return err(opt, _("merge returned no commit"));
3631 }
3632
3633 + /*
3634 + * FIXME: Since merge_recursive_internal() is only ever called by
3635 + * places that ensure the index is loaded first
3636 + * (e.g. builtin/merge.c, rebase/sequencer, etc.), in the common
3637 + * case where the merge base was unique that means when we get here
3638 + * we immediately discard the index and re-read it, which is a
3639 + * complete waste of time. We should only be discarding and
3640 + * re-reading if we were forced to recurse.
3641 + */
3642 discard_index(opt->repo->index);
3643 if (!opt->priv->call_depth)
3644 repo_read_index(opt->repo);