@@ -45,21 +45,24 @@ class mergestate(object):
O: the node of the "other" part of the merge (hexified version)
F: a file to be merged entry
'''
statepathv1 = "merge/state"
statepathv2 = "merge/state2"
+
def __init__(self, repo):
self._repo = repo
self._dirty = False
self._read()
+
def reset(self, node=None, other=None):
self._state = {}
if node:
self._local = node
self._other = other
shutil.rmtree(self._repo.join("merge"), True)
self._dirty = False
+
def _read(self):
self._state = {}
records = self._readrecords()
for rtype, record in records:
if rtype == 'L':
@@ -71,10 +74,11 @@ class mergestate(object):
self._state[bits[0]] = bits[1:]
elif not rtype.islower():
raise util.Abort(_('unsupported merge state record:'
% rtype))
self._dirty = False
+
def _readrecords(self):
v1records = self._readrecordsv1()
v2records = self._readrecordsv2()
oldv2 = set() # old format version of v2 record
for rec in v2records:
@@ -99,10 +103,11 @@ class mergestate(object):
bits.insert(-2, '')
v1records[idx] = (r[0], "\0".join(bits))
return v1records
else:
return v2records
+
def _readrecordsv1(self):
records = []
try:
f = self._repo.opener(self.statepathv1)
for i, l in enumerate(f):
@@ -113,10 +118,11 @@ class mergestate(object):
f.close()
except IOError, err:
if err.errno != errno.ENOENT:
raise
return records
+
def _readrecordsv2(self):
records = []
try:
f = self._repo.opener(self.statepathv2)
data = f.read()
@@ -133,61 +139,72 @@ class mergestate(object):
f.close()
except IOError, err:
if err.errno != errno.ENOENT:
raise
return records
+
def commit(self):
if self._dirty:
records = []
records.append(("L", hex(self._local)))
records.append(("O", hex(self._other)))
for d, v in self._state.iteritems():
records.append(("F", "\0".join([d] + v)))
self._writerecords(records)
self._dirty = False
+
def _writerecords(self, records):
self._writerecordsv1(records)
self._writerecordsv2(records)
+
def _writerecordsv1(self, records):
f = self._repo.opener(self.statepathv1, "w")
irecords = iter(records)
lrecords = irecords.next()
assert lrecords[0] == 'L'
f.write(hex(self._local) + "\n")
for rtype, data in irecords:
if rtype == "F":
f.write("%s\n" % _droponode(data))
f.close()
+
def _writerecordsv2(self, records):
f = self._repo.opener(self.statepathv2, "w")
for key, data in records:
assert len(key) == 1
format = ">sI%is" % len(data)
f.write(_pack(format, key, len(data), data))
f.close()
+
def add(self, fcl, fco, fca, fd):
hash = util.sha1(fcl.path()).hexdigest()
self._repo.opener.write("merge/" + hash, fcl.data())
self._state[fd] = ['u', hash, fcl.path(),
fca.path(), hex(fca.filenode()),
fco.path(), hex(fco.filenode()),
fcl.flags()]
self._dirty = True
+
def __contains__(self, dfile):
return dfile in self._state
+
def __getitem__(self, dfile):
return self._state[dfile][0]
+
def __iter__(self):
l = self._state.keys()
l.sort()
for f in l:
yield f
+
def files(self):
return self._state.keys()
+
def mark(self, dfile, state):
self._state[dfile][0] = state
self._dirty = True
+
def resolve(self, dfile, wctx):
if self[dfile] == 'r':
return 0
stateentry = self._state[dfile]
state, hash, lfile, afile, anode, ofile, onode, flags = stateentry