From: Junio C Hamano Date: Mon, 12 Dec 2005 00:44:05 +0000 (-0800) Subject: merge-recursive: conflicting rename case. X-Git-Tag: v1.1.0~38 X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=724b511d4fb363ebee828ba3992c831ba006444c;p=git.git merge-recursive: conflicting rename case. This changes the way the case two branches rename the same path to different paths is handled. Earlier, the code removed the original path and added both destinations to the index at stage0. This commit changes it to leave the original path at stage1, and two destination paths at stage2 and stage3, respectively. [jc: I am not really sure if this makes much difference in the real life merge situations. What should happen when our branch renames A to B and M to N, while their branch renames A to M? That is, M remains in our tree as is.] Signed-off-by: Junio C Hamano --- diff --git a/git-merge-recursive.py b/git-merge-recursive.py index f1320a695..56c3641ab 100755 --- a/git-merge-recursive.py +++ b/git-merge-recursive.py @@ -283,12 +283,20 @@ def updateFileExt(sha, mode, path, updateCache, updateWd): def setIndexStages(path, oSHA1, oMode, aSHA1, aMode, - bSHA1, bMode): + bSHA1, bMode, + clear=True): + istring = [] + if clear: + istring.append("0 " + ("0" * 40) + "\t" + path + "\0") + if oMode: + istring.append("%o %s %d\t%s\0" % (oMode, oSHA1, 1, path)) + if aMode: + istring.append("%o %s %d\t%s\0" % (aMode, aSHA1, 2, path)) + if bMode: + istring.append("%o %s %d\t%s\0" % (bMode, bSHA1, 3, path)) + runProgram(['git-update-index', '-z', '--index-info'], - input="0 " + ("0" * 40) + "\t" + path + "\0" + \ - "%o %s %d\t%s\0" % (oMode, oSHA1, 1, path) + \ - "%o %s %d\t%s\0" % (aMode, aSHA1, 2, path) + \ - "%o %s %d\t%s\0" % (bMode, bSHA1, 3, path)) + input="".join(istring)) def removeFile(clean, path): updateCache = cacheOnly or clean @@ -570,7 +578,7 @@ def processRenames(renamesA, renamesB, branchNameA, branchNameB): continue ren1.processed = True - removeFile(True, ren1.srcName) + if ren2: # Renamed in 1 and renamed in 2 assert(ren1.srcName == ren2.srcName) @@ -598,13 +606,19 @@ def processRenames(renamesA, renamesB, branchNameA, branchNameB): 'adding as', dstName2, 'instead.') removeFile(False, ren2.dstName) else: - dstName2 = ren1.dstName + dstName2 = ren2.dstName + setIndexStages(dstName1, + None, None, + ren1.dstSha, ren1.dstMode, + None, None) + setIndexStages(dstName2, + None, None, + None, None, + ren2.dstSha, ren2.dstMode) - # NEEDSWORK: place dstNameA at stage 2 and dstNameB at stage 3 - # What about other stages??? - updateFile(False, ren1.dstSha, ren1.dstMode, dstName1) - updateFile(False, ren2.dstSha, ren2.dstMode, dstName2) else: + removeFile(True, ren1.srcName) + [resSha, resMode, clean, merge] = \ mergeFile(ren1.srcName, ren1.srcSha, ren1.srcMode, ren1.dstName, ren1.dstSha, ren1.dstMode, @@ -630,6 +644,8 @@ def processRenames(renamesA, renamesB, branchNameA, branchNameB): updateFile(clean, resSha, resMode, ren1.dstName) else: + removeFile(True, ren1.srcName) + # Renamed in 1, maybe changed in 2 if renamesA == renames1: stage = 3 diff --git a/t/t6022-merge-rename.sh b/t/t6022-merge-rename.sh index 153b9e49f..1292cafd7 100755 --- a/t/t6022-merge-rename.sh +++ b/t/t6022-merge-rename.sh @@ -161,4 +161,41 @@ test_expect_success 'pull unrenaming branch into renaming one' \ } ' +test_expect_success 'pull conflicting renames' \ +' + git reset --hard + git show-branch + git pull . blue && { + echo "BAD: should have conflicted" + exit 1 + } + test "$(git ls-files -u A | wc -l)" -eq 1 || { + echo "BAD: should have left a stage" + exit 1 + } + test "$(git ls-files -u B | wc -l)" -eq 1 || { + echo "BAD: should have left a stage" + exit 1 + } + test "$(git ls-files -u C | wc -l)" -eq 1 || { + echo "BAD: should have left a stage" + exit 1 + } + test "$(git ls-files -s N | wc -l)" -eq 1 || { + echo "BAD: should have merged N" + exit 1 + } + sed -ne "/^g/{ + p + q + }" B | grep red || { + echo "BAD: should have listed our change first" + exit 1 + } + test "$(git diff white N | wc -l)" -eq 0 || { + echo "BAD: should have taken colored branch" + exit 1 + } +' + test_done