[PATCH 3 of 6 resolve-ux] merge: implement mergestate.__len__ and mergestate.__nonzero__

Gregory Szorc gregory.szorc at gmail.com
Fri May 2 00:47:38 CDT 2014


# HG changeset patch
# User Gregory Szorc <gregory.szorc at gmail.com>
# Date 1397872888 25200
#      Fri Apr 18 19:01:28 2014 -0700
# Branch stable
# Node ID b4d95342be6de3e3a229e1536720d22d6de6eb13
# Parent  812bb7bf59e8ff0e2e60c1d73857206c6efd8b32
merge: implement mergestate.__len__ and mergestate.__nonzero__

An upcoming patch will test if mergestate is present. Until this patch,
there was no easy way to do this without looking at files on disk (which
are part of mergestate's implementation details).

This patch allows consumers to differentiate between no mergestate,
empty mergestate, and mergestate with entries. It does this by
implementing __nonzero__ and __len__. |if ms| will now be true if the
mergestate has entries or it has records on disk. |if len(ms)| will now
be true iff mergestate has entries.

diff --git a/mercurial/merge.py b/mercurial/merge.py
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -46,16 +46,17 @@ class mergestate(object):
     F: a file to be merged entry
     '''
     statepathv1 = "merge/state"
     statepathv2 = "merge/state2"
 
     def __init__(self, repo):
         self._repo = repo
         self._dirty = False
+        self._recordpresent = 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)
@@ -136,16 +137,17 @@ class mergestate(object):
         try:
             f = self._repo.opener(self.statepathv1)
             for i, l in enumerate(f):
                 if i == 0:
                     records.append(('L', l[:-1]))
                 else:
                     records.append(('F', l[:-1]))
             f.close()
+            self._recordpresent = True
         except IOError, err:
             if err.errno != errno.ENOENT:
                 raise
         return records
 
     def _readrecordsv2(self):
         """read on disk merge state for version 2 file
 
@@ -161,16 +163,17 @@ class mergestate(object):
                 rtype = data[off]
                 off += 1
                 length = _unpack('>I', data[off:(off + 4)])[0]
                 off += 4
                 record = data[off:(off + length)]
                 off += length
                 records.append((rtype, record))
             f.close()
+            self._recordpresent = True
         except IOError, err:
             if err.errno != errno.ENOENT:
                 raise
         return records
 
     def commit(self):
         """Write current state on disk (if necessary)"""
         if self._dirty:
@@ -181,16 +184,17 @@ class mergestate(object):
                 records.append(("F", "\0".join([d] + v)))
             self._writerecords(records)
             self._dirty = False
 
     def _writerecords(self, records):
         """Write current state on disk (both v1 and v2)"""
         self._writerecordsv1(records)
         self._writerecordsv2(records)
+        self._recordpresent = True
 
     def _writerecordsv1(self, records):
         """Write current state on disk in a version 1 file"""
         f = self._repo.opener(self.statepathv1, "w")
         irecords = iter(records)
         lrecords = irecords.next()
         assert lrecords[0] == 'L'
         f.write(hex(self._local) + "\n")
@@ -220,16 +224,22 @@ class mergestate(object):
         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 __nonzero__(self):
+        return self._recordpresent or bool(self._state)
+
+    def __len__(self):
+        return len(self._state)
+
     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()


More information about the Mercurial-devel mailing list