{"thread":{"id":"24706","subject":"[PATCH] rerere: demonstrate a weakness with identical conflicts in different files","startedAt":"2010-08-11T12:16:21Z","lastAt":"2010-08-12T07:28:18Z","messageCount":4,"participants":["Johannes Sixt","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"147758","messageId":"4C629495.60105@viscovery.net","threadId":"24706","inReplyTo":null,"subject":"[PATCH] rerere: demonstrate a weakness with identical conflicts in different files","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2010-08-11T12:16:21Z","receivedAt":"2010-08-11T12:16:21Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"From: Johannes Sixt <j6t@kdbg.org>\n\nWhen code sections are duplicated in different files and identical\nconflicts arise simultaneously in these sections, then rerere resolves only\nthe first one and leaves the others unresolved.\n\nSigned-off-by: Johannes Sixt <j6t@kdbg.org>\n---\n I encounter this situation several times a year, and every now and then\n it is particularly annoying because the conflicts are extensive.\n\n I would appreciate if you could have a look whether this is fixed\n easily. I tried myself, but I can't find the point where the\n subsequent conflicts are ignored.\n\n -- Hannes\n\n t/t4208-rerere-dup.sh |   77 +++++++++++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 77 insertions(+), 0 deletions(-)\n create mode 100755 t/t4208-rerere-dup.sh\n\ndiff --git a/t/t4208-rerere-dup.sh b/t/t4208-rerere-dup.sh\nnew file mode 100755\nindex 0000000..34c182a\n--- /dev/null\n+++ b/t/t4208-rerere-dup.sh\n@@ -0,0 +1,77 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2010 Johannes Sixt\n+#\n+\n+test_description='test git rerere when sections of files are duplicated,\n+and identical conflicts arise in these sections simultaneously.\n+'\n+\n+. ./test-lib.sh\n+\n+test_expect_success 'setup' '\n+\tcat > a1 <<- EOF &&\n+\talpha\n+\tbeta\n+\tgamma\n+\tEOF\n+\tsed -e s/alpha/ALPHA/ <a1 >a2 &&\n+\n+\tgit add a1 a2 &&\n+\tgit commit -q -a -m initial &&\n+\n+\tgit checkout -b first &&\n+\tcat > a1 <<- EOF &&\n+\talpha\n+\tBETA\n+\tgamma\n+\tEOF\n+\tsed -e s/alpha/ALPHA/ <a1 >a2 &&\n+\tgit commit -q -a -m first &&\n+\n+\tgit checkout master &&\n+\tcat > a1 <<- EOF &&\n+\talpha\n+\t----\n+\tgamma\n+\tEOF\n+\tsed -e s/alpha/ALPHA/ <a1 >a2 &&\n+\tgit commit -q -a -m master &&\n+\tgit config rerere.enabled true\n+'\n+\n+test_expect_success 'merge records only one conflict' '\n+\ttest_must_fail git merge first &&\n+\tsha1=$(ls .git/rr-cache) &&\n+\ttest $(echo $sha1 | wc -w) = 1\n+'\n+\n+test_expect_success 'record a resolution' '\n+\tcat > a1 <<- EOF &&\n+\talpha\n+\t--beta--\n+\tgamma\n+\tEOF\n+\tsed -e s/alpha/ALPHA/ <a1 >a2 &&\n+\tgit rerere 2>actual\n+'\n+\n+test_expect_success 'postimage must exist' '\n+\ttest -f .git/rr-cache/$sha1/postimage\n+'\n+\n+test_expect_success 'same resolution recorded twice' '\n+\ttest $(grep \"Recorded resolution\" actual | wc -l) = 2 &&\n+\ttest $(ls .git/rr-cache | wc -w) = 1\n+'\n+\n+test_expect_success 'repeat merge' '\n+\tgit reset --hard &&\n+\ttest_must_fail git merge first\n+'\n+\n+test_expect_failure 'both files are resolved' '\n+\t! grep ===== a1 a2\n+'\n+\n+test_done\n-- \n1.7.2.63.g079547\n"},{"id":"147842","messageId":"7vmxssvi2t.fsf@alter.siamese.dyndns.org","threadId":"24706","inReplyTo":"4C629495.60105@viscovery.net","subject":"Re: [PATCH] rerere: demonstrate a weakness with identical conflicts in different files","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-08-11T23:35:22Z","receivedAt":"2010-08-11T23:35:22Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Hmm, my knee-jerk reaction was that something may be keying off of the\nconflict ids to keep track of which ones are dealt with and which ones are\nyet to be resolved, but I don't recall any part of the implementation that\nwould do something like that offhand.  Sorry.\n\nWill try to find/make time to take a look at it later.\n"},{"id":"147857","messageId":"7vfwykv92a.fsf@alter.siamese.dyndns.org","threadId":"24706","inReplyTo":"7vmxssvi2t.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] rerere: demonstrate a weakness with identical conflicts in different files","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-08-12T02:50:05Z","receivedAt":"2010-08-12T02:50:05Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Hmm, my knee-jerk reaction was that something may be keying off of the\n> conflict ids to keep track of which ones are dealt with and which ones are\n> yet to be resolved, but I don't recall any part of the implementation that\n> would do something like that offhand.  Sorry.\n\nHeh, what was I thinking.  Yes, rr-cache/ database keys off of the\nconflict id, so if your repository has more than one contents that produce\nexactly the same conflict, say F and G, then, most likely:\n\n * You see one of them first, say F, record preimage.F and record its\n   resolution as postimage.F\n\n * You encounter conflict G; record it in thisimage, try three-way merge\n   between postimage.F and that using preimage.F as the common ancestor.\n   If this doesn't work (and it likely doesn't), rerere punts.\n\nNote that this issue can happen even when the trees you are currently\nmerging have only content derived from G and nothing related to F, as\ntheir resolutions share the same conflict id.\n\nI vaguely recall discussing this with you here and bringing up a possibile\nsolution for a situation like this; keep sets of <preimage, postimage>\n(starting from the current {pre,post}image adding {pre,post}image.1,\n{pre,post}image.2 and so on).  When we see a new conflict (after a mergy\noperation before \"rerere\" resolves it), try to run the three-way merge\nwith it and each pair, and if we don't find anything that successfully\nmerges, record it as a new half of the pre-post pair, incrementing the\ncounter, and record a new resolution to complete the new pair for later\nuse.\n\nWe also need to split \"thisimage\" into multiple ones in case this happens\nin a single tree (i.e. contents derived from F and from G are both present\nand produce the conflict in the same merge).\n"},{"id":"147878","messageId":"4C63A292.4010604@viscovery.net","threadId":"24706","inReplyTo":"7vfwykv92a.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] rerere: demonstrate a weakness with identical conflicts in different files","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2010-08-12T07:28:18Z","receivedAt":"2010-08-12T07:28:18Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 8/12/2010 4:50, schrieb Junio C Hamano:\n> Yes, rr-cache/ database keys off of the\n> conflict id, so if your repository has more than one contents that produce\n> exactly the same conflict, say F and G, then, most likely:\n> \n>  * You see one of them first, say F, record preimage.F and record its\n>    resolution as postimage.F\n> \n>  * You encounter conflict G; record it in thisimage, try three-way merge\n>    between postimage.F and that using preimage.F as the common ancestor.\n>    If this doesn't work (and it likely doesn't), rerere punts.\n\nAha! Since the files differ in the immediate neighborhood of the context\nmarkers, the merge that applies the resolution fails.\n\nSquash in this and the test passes:\n\ndiff --git a/t/t4208-rerere-dup.sh b/t/t4208-rerere-dup.sh\nindex 34c182a..2afa0ef 100755\n--- a/t/t4208-rerere-dup.sh\n+++ b/t/t4208-rerere-dup.sh\n@@ -12,6 +12,7 @@\n test_expect_success 'setup' '\n \tcat > a1 <<- EOF &&\n \talpha\n+\tdelta\n \tbeta\n \tgamma\n \tEOF\n@@ -23,6 +24,7 @@ test_expect_success 'setup' '\n \tgit checkout -b first &&\n \tcat > a1 <<- EOF &&\n \talpha\n+\tdelta\n \tBETA\n \tgamma\n \tEOF\n@@ -32,6 +34,7 @@ test_expect_success 'setup' '\n \tgit checkout master &&\n \tcat > a1 <<- EOF &&\n \talpha\n+\tdelta\n \t----\n \tgamma\n \tEOF\n@@ -49,6 +52,7 @@ test_expect_success 'merge records\n test_expect_success 'record a resolution' '\n \tcat > a1 <<- EOF &&\n \talpha\n+\tdelta\n \t--beta--\n \tgamma\n \tEOF\n@@ -61,7 +65,7 @@ test_expect_success 'postimage must\n '\n\n test_expect_success 'same resolution recorded twice' '\n-\ttest $(grep \"Recorded resolution\" actual | wc -l) = 2 &&\n+#\ttest $(grep \"Recorded resolution\" actual | wc -l) = 2 &&\n \ttest $(ls .git/rr-cache | wc -w) = 1\n '\n\n\nThe last hunk is necessary because the output of rerere is now:\n\nRecorded resolution for 'a1'.\nResolved 'a2' using previous resolution.\n\nwhere the second statement is slightly misleading because the resolution\nwas not \"used\". But already present in the file (the resolution-merge\nstill succeeded, hence, rerere thought it had \"used\" the resolution).\n\nI assumed that in my case I had identical text immediately outside the\nconflict markers, and so I also assumed that the resolution-merge would\nsucceed, but it seems I was wrong. I'll go back and investigate closer as\ntime permits.\n\nThanks for your help so far.\n\n-- Hannes\n"}]}