[PATCH 2 of 2] merge: adds documentation to the mergestate class

pierre-yves.david at ens-lyon.org pierre-yves.david at ens-lyon.org
Wed Mar 5 13:05:08 CST 2014


# HG changeset patch
# User Pierre-Yves David <pierre-yves.david at fb.com>
# Date 1394045383 28800
#      Wed Mar 05 10:49:43 2014 -0800
# Node ID 7760e02d58f2f00dd944ce585af63b8e05cfc69f
# Parent  37d4c6705c2470d788ad9ed4af3d1d6f27400032
merge: adds documentation to the mergestate class

Document most the new function involved in the new serialisation process (and a
few others).

diff --git a/mercurial/merge.py b/mercurial/merge.py
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -60,10 +60,15 @@ class mergestate(object):
             self._other = other
         shutil.rmtree(self._repo.join("merge"), True)
         self._dirty = False
 
     def _read(self):
+        """Analyse each record content to restore a serialized state from disk
+
+        This function process "record" entry produced by the de-serialization
+        of on disk file.
+        """
         self._state = {}
         records = self._readrecords()
         for rtype, record in records:
             if rtype == 'L':
                 self._local = bin(record)
@@ -76,10 +81,23 @@ class mergestate(object):
                 raise util.Abort(_('unsupported merge state record:'
                                    % rtype))
         self._dirty = False
 
     def _readrecords(self):
+        """Read merge state from disk and return a list of record (TYPE, data)
+
+        We read data from both V1 and Ve files decide which on to use.
+
+        V1 have been used by version prior to 2.9.1 and contains less data than
+        v2. We read both version and check if no data in v2 contradict one in
+        v1. If there is not contradiction we can safely assume that both v1
+        and v2 were written at the same time and use the extract data in v2. If
+        there is contradiction we ignore v2 content as we assume an old version
+        of Mercurial have over written the mergstate file and left an old v2
+        file around.
+
+        returns list of record [(TYPE, data), …]"""
         v1records = self._readrecordsv1()
         v2records = self._readrecordsv2()
         oldv2 = set() # old format version of v2 record
         for rec in v2records:
             if rec[0] == 'L':
@@ -105,10 +123,17 @@ class mergestate(object):
                 return v1records
         else:
             return v2records
 
     def _readrecordsv1(self):
+        """read on disk merge state for version 1 file
+
+        returns list of record [(TYPE, data), …]
+
+        Note: the "F" data from this file are one entry short
+              (no "other file node" entry)
+        """
         records = []
         try:
             f = self._repo.opener(self.statepathv1)
             for i, l in enumerate(f):
                 if i == 0:
@@ -120,10 +145,14 @@ class mergestate(object):
             if err.errno != errno.ENOENT:
                 raise
         return records
 
     def _readrecordsv2(self):
+        """read on disk merge state for version 2 file
+
+        returns list of record [(TYPE, data), …]
+        """
         records = []
         try:
             f = self._repo.opener(self.statepathv2)
             data = f.read()
             off = 0
@@ -141,24 +170,27 @@ class mergestate(object):
             if err.errno != errno.ENOENT:
                 raise
         return records
 
     def commit(self):
+        """Write current state on disk (if necessary)"""
         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):
+        """Write current state on disk (both v1 and v2)"""
         self._writerecordsv1(records)
         self._writerecordsv2(records)
 
     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")
@@ -166,18 +198,27 @@ class mergestate(object):
             if rtype == "F":
                 f.write("%s\n" % _droponode(data))
         f.close()
 
     def _writerecordsv2(self, records):
+        """Write current state on disk in a version 2 file"""
         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):
+        """add a new (potentially?) conflicting file the merge state
+        fcl: file context for local,
+        fco: file context for remote,
+        fca: file context for ancestors,
+        fd:  file path of the resulting merge.
+
+        note: also write the local version to the `.hg/merge` directory.
+        """
         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()),
@@ -202,10 +243,11 @@ class mergestate(object):
     def mark(self, dfile, state):
         self._state[dfile][0] = state
         self._dirty = True
 
     def resolve(self, dfile, wctx):
+        """rerun merge process for file path `dfile`"""
         if self[dfile] == 'r':
             return 0
         stateentry = self._state[dfile]
         state, hash, lfile, afile, anode, ofile, onode, flags = stateentry
         octx = self._repo[self._other]


More information about the Mercurial-devel mailing list