[PATCH 3 of 3] merge: delay writing the mergestate during applyupdates

Peter Arrenbrecht peter.arrenbrecht at gmail.com
Fri Jun 18 02:36:47 CDT 2010


# HG changeset patch
# User Peter Arrenbrecht <peter.arrenbrecht at gmail.com>
# Date 1276845982 -7200
merge: delay writing the mergestate during applyupdates

This speeds up merges of lots of files considerably.

diff --git a/mercurial/merge.py b/mercurial/merge.py
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -35,17 +35,18 @@
         except IOError, err:
             if err.errno != errno.ENOENT:
                 raise
-    def _write(self):
+    def commit(self):
         f = self._repo.opener("merge/state", "w")
         f.write(hex(self._local) + "\n")
         for d, v in self._state.iteritems():
             f.write("\0".join([d] + v) + "\n")
-    def add(self, fcl, fco, fca, fd, flags):
+    def add(self, fcl, fco, fca, fd, flags, commit=True):
         hash = util.sha1(fcl.path()).hexdigest()
         self._repo.opener("merge/" + hash, "w").write(fcl.data())
         self._state[fd] = ['u', hash, fcl.path(), fca.path(),
                            hex(fca.filenode()), fco.path(), flags]
-        self._write()
+        if commit:
+            self.commit()
     def __contains__(self, dfile):
         return dfile in self._state
     def __getitem__(self, dfile):
@@ -55,10 +56,11 @@
         l.sort()
         for f in l:
             yield f
-    def mark(self, dfile, state):
+    def mark(self, dfile, state, commit=True):
         self._state[dfile][0] = state
-        self._write()
-    def resolve(self, dfile, wctx, octx):
+        if commit:
+            self.commit()
+    def resolve(self, dfile, wctx, octx, commit=True):
         if self[dfile] == 'r':
             return 0
         state, hash, lfile, afile, anode, ofile, flags = self._state[dfile]
@@ -69,7 +71,7 @@
         fca = self._repo.filectx(afile, fileid=anode)
         r = filemerge.filemerge(self._repo, self._local, lfile, fcd, fco, fca)
         if not r:
-            self.mark(dfile, 'r')
+            self.mark(dfile, 'r', commit=commit)
         return r
 
 def _checkunknown(wctx, mctx):
@@ -271,7 +273,7 @@
             fcl = wctx[f]
             fco = mctx[f2]
             fca = fcl.ancestor(fco, actx) or repo.filectx(f, fileid=nullrev)
-            ms.add(fcl, fco, fca, fd, flags)
+            ms.add(fcl, fco, fca, fd, flags, commit=False)
             if f != fd and move:
                 moves.append(f)
 
@@ -306,7 +308,7 @@
                 subrepo.submerge(repo, wctx, mctx, wctx.ancestor(mctx))
                 continue
             f2, fd, flags, move = a[2:]
-            r = ms.resolve(fd, wctx, mctx)
+            r = ms.resolve(fd, wctx, mctx, commit=False)
             if r is not None and r > 0:
                 unresolved += 1
             else:
@@ -346,6 +348,7 @@
         elif m == "e": # exec
             flags = a[2]
             util.set_flags(repo.wjoin(f), 'l' in flags, 'x' in flags)
+    ms.commit()
     u.progress('update', None, total=numupdates, unit='files')
 
     return updated, merged, removed, unresolved


More information about the Mercurial-devel mailing list