#!/usr/bin/python
+#
+# Copyright (C) 2005 Fredrik Kuivinen
+#
-import sys, math, random, os, re, signal, tempfile, stat, errno, traceback
+import sys
+sys.path.append('''@@GIT_PYTHON_PATH@@''')
+
+import math, random, os, re, signal, tempfile, stat, errno, traceback
from heapq import heappush, heappop
from sets import Set
-sys.path.append('''@@GIT_PYTHON_PATH@@''')
from gitMergeCommon import *
outputIndent = 0
def getFilesAndDirs(tree):
files = Set()
dirs = Set()
- out = runProgram(['git-ls-tree', '-r', '-z', tree])
+ out = runProgram(['git-ls-tree', '-r', '-z', '-t', tree])
for l in out.split('\0'):
m = getFilesRE.match(l)
if m:
try:
createDir = not stat.S_ISDIR(os.lstat(p).st_mode)
- except:
+ except OSError:
createDir = True
if createDir:
runProgram(['git-update-index', '--add', '--cacheinfo',
'0%o' % mode, sha, path])
+def setIndexStages(path,
+ oSHA1, oMode,
+ aSHA1, aMode,
+ bSHA1, bMode):
+ 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))
+
def removeFile(clean, path):
updateCache = cacheOnly or clean
updateWd = not cacheOnly
except OSError, e:
if e.errno != errno.ENOENT and e.errno != errno.EISDIR:
raise
+ try:
+ os.removedirs(os.path.dirname(path))
+ except OSError:
+ pass
def uniquePath(path, branch):
def fileExists(path):
raise
branch = branch.replace('/', '_')
- newPath = path + '_' + branch
+ newPath = path + '~' + branch
suffix = 0
while newPath in currentFileSet or \
newPath in currentDirectorySet or \
fileExists(newPath):
suffix += 1
- newPath = path + '_' + branch + '_' + str(suffix)
+ newPath = path + '~' + branch + '_' + str(suffix)
currentFileSet.add(newPath)
return newPath
else:
dstName2 = ren1.dstName
+ # 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:
cleanMerge = False
if not cacheOnly:
- updateFileExt(ren1.dstSha, ren1.dstMode, ren1.dstName,
- updateCache=True, updateWd=False)
+ setIndexStages(ren1.dstName,
+ ren1.srcSha, ren1.srcMode,
+ ren1.dstSha, ren1.dstMode,
+ ren2.dstSha, ren2.dstMode)
+
updateFile(clean, resSha, resMode, ren1.dstName)
else:
# Renamed in 1, maybe changed in 2
tryMerge = True
if tryMerge:
+
+ oName, oSHA1, oMode = ren1.srcName, ren1.srcSha, ren1.srcMode
+ aName, bName = ren1.dstName, ren1.srcName
+ aSHA1, bSHA1 = ren1.dstSha, srcShaOtherBranch
+ aMode, bMode = ren1.dstMode, srcModeOtherBranch
+ aBranch, bBranch = branchName1, branchName2
+
+ if renamesA != renames1:
+ aName, bName = bName, aName
+ aSHA1, bSHA1 = bSHA1, aSHA1
+ aMode, bMode = bMode, aMode
+ aBranch, bBranch = bBranch, aBranch
+
[resSha, resMode, clean, merge] = \
- mergeFile(ren1.srcName, ren1.srcSha, ren1.srcMode,
- ren1.dstName, ren1.dstSha, ren1.dstMode,
- ren1.srcName, srcShaOtherBranch, srcModeOtherBranch,
- branchName1, branchName2)
+ mergeFile(oName, oSHA1, oMode,
+ aName, aSHA1, aMode,
+ bName, bSHA1, bMode,
+ aBranch, bBranch);
if merge or not clean:
output('Renaming', fmtRename(ren1.srcName, ren1.dstName))
cleanMerge = False
if not cacheOnly:
- updateFileExt(ren1.dstSha, ren1.dstMode, ren1.dstName,
- updateCache=True, updateWd=False)
+ setIndexStages(ren1.dstName,
+ oSHA1, oMode,
+ aSHA1, aMode,
+ bSHA1, bMode)
+
updateFile(clean, resSha, resMode, ren1.dstName)
return cleanMerge
if cacheOnly:
updateFile(False, sha, mode, path)
else:
- updateFileExt(aSha, aMode, path,
- updateCache=True, updateWd=False)
updateFileExt(sha, mode, path, updateCache=False, updateWd=True)
else:
die("ERROR: Fatal merge failure, shouldn't happen.")