Skip to content

Commit 890fca8

Browse files
committed
rerere: adjust 'forget' to multi-variant world order
Because conflicts with the same contents inside conflict blocks enclosed by "<<<<<<<" and ">>>>>>>" can now have multiple variants to help three-way merge to adjust to the differences outside the conflict blocks, "rerere forget $path" needs to be taught that there may be multiple recorded resolutions that share the same conflict hash (which groups the conflicts with "the same contents inside conflict blocks"), among which there are some that would not be relevant to the conflict we are looking at. These "other variants" that happen to share the same conflict hash should not be cleared, and the variant that would apply to the current conflict may not be the zero-th one (which is the only one that is cleared by the current code). After finding the conflict hash, iterate over the existing variants and try to resolve the conflict using each of them to find the one that "cleanly" resolves the current conflict. That is the one we want to forget and record the preimage for, so that the user can record the corrected resolution. Signed-off-by: Junio C Hamano <[email protected]>
1 parent 0ce02b3 commit 890fca8

File tree

2 files changed

+37
-1
lines changed

2 files changed

+37
-1
lines changed

rerere.c

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1038,7 +1038,33 @@ static int rerere_forget_one_path(const char *path, struct string_list *rr)
10381038

10391039
/* Nuke the recorded resolution for the conflict */
10401040
id = new_rerere_id(sha1);
1041-
id->variant = 0; /* for now */
1041+
1042+
for (id->variant = 0;
1043+
id->variant < id->collection->status_nr;
1044+
id->variant++) {
1045+
mmfile_t cur = { NULL, 0 };
1046+
mmbuffer_t result = {NULL, 0};
1047+
int cleanly_resolved;
1048+
1049+
if (!has_rerere_resolution(id))
1050+
continue;
1051+
1052+
handle_cache(path, sha1, rerere_path(id, "thisimage"));
1053+
if (read_mmfile(&cur, rerere_path(id, "thisimage"))) {
1054+
free(cur.ptr);
1055+
return error("Failed to update conflicted state in '%s'",
1056+
path);
1057+
}
1058+
cleanly_resolved = !try_merge(id, path, &cur, &result);
1059+
free(result.ptr);
1060+
free(cur.ptr);
1061+
if (cleanly_resolved)
1062+
break;
1063+
}
1064+
1065+
if (id->collection->status_nr <= id->variant)
1066+
return error("no remembered resolution for '%s'", path);
1067+
10421068
filename = rerere_path(id, "postimage");
10431069
if (unlink(filename))
10441070
return (errno == ENOENT

t/t4200-rerere.sh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,16 @@ test_expect_success 'multiple identical conflicts' '
536536
test_cmp file1.expect file1 &&
537537
test_cmp file2.expect file2 &&
538538
539+
# Forget resolution for file2
540+
git rerere forget file2 &&
541+
echo file2 >expect &&
542+
git rerere status >actual &&
543+
test_cmp expect actual &&
544+
count_pre_post 2 1 &&
545+
546+
# file2 already has correct resolution, so record it again
547+
git rerere &&
548+
539549
# Pretend that the resolutions are old again
540550
find .git/rr-cache/ -type f | xargs test-chmtime -172800 &&
541551

0 commit comments

Comments
 (0)