Don't always use git-merge-recursive because of speed
authorCatalin Marinas <catalin.marinas@gmail.com>
Fri, 8 Dec 2006 22:31:52 +0000 (22:31 +0000)
committerCatalin Marinas <catalin.marinas@gmail.com>
Fri, 8 Dec 2006 22:31:52 +0000 (22:31 +0000)
There are situations like picking patches, folding a patch onto a base
or synchronising patches where the distance between base and heads is
in general small. In this case, git-read-tree --aggressive is much
faster. We currently use the recursive merge when picking or pushing a
patch (the base change might involve some renames).

Signed-off-by: Catalin Marinas <catalin.marinas@gmail.com>
stgit/commands/pick.py
stgit/git.py
stgit/stack.py

index 996e789..400e4eb 100644 (file)
@@ -91,7 +91,7 @@ def func(parser, options, args):
 
         # try a direct git-apply first
         if not git.apply_diff(bottom, top):
-            git.merge(bottom, git.get_head(), top)
+            git.merge(bottom, git.get_head(), top, recursive = True)
 
         print 'done'
     elif options.update:
index eb8da4e..cdf15fd 100644 (file)
@@ -596,17 +596,27 @@ def apply_diff(rev1, rev2, check_index = True, files = None):
 
     return True
 
-def merge(base, head1, head2):
+def merge(base, head1, head2, recursive = False):
     """Perform a 3-way merge between base, head1 and head2 into the
     local tree
     """
     refresh_index()
 
-    try:
-        # use _output() to mask the verbose prints of the tool
-        _output('git-merge-recursive %s -- %s %s' % (base, head1, head2))
-    except GitException:
-        pass
+    if recursive:
+        # this operation tracks renames but it is slower (used in
+        # general when pushing or picking patches)
+        try:
+            # use _output() to mask the verbose prints of the tool
+            _output('git-merge-recursive %s -- %s %s' % (base, head1, head2))
+        except GitException:
+            pass
+    else:
+        # the fast case where we don't track renames (used when the
+        # distance between base and heads is small, i.e. folding or
+        # synchronising patches)
+        if __run('git-read-tree -u -m --aggressive',
+                 [base, head1, head2]) != 0:
+            raise GitException, 'git-read-tree failed (local changes maybe?)'
 
     # check the index for unmerged entries
     files = {}
index e650713..33010d9 100644 (file)
@@ -933,7 +933,7 @@ class Series(StgitObject):
 
                 # merge can fail but the patch needs to be pushed
                 try:
-                    git.merge(bottom, head, top)
+                    git.merge(bottom, head, top, recursive = True)
                 except git.GitException, ex:
                     print >> sys.stderr, \
                           'The merge failed during "push". ' \