chiark / gitweb /
Failed recursive merging can silently lose date in StGIT
authorCatalin Marinas <catalin.marinas@gmail.com>
Tue, 17 Apr 2007 16:29:32 +0000 (17:29 +0100)
committerCatalin Marinas <catalin.marinas@gmail.com>
Tue, 17 Apr 2007 23:58:14 +0000 (00:58 +0100)
The logic in git.merge(recursive = True) is that if
git-merge-recursive fails, deal with the unmerged entries via diff3
and interactive merge (if 'autoimerge' is set to 'yes' in
config). There is a situation, however, when git-merge-recursive fails
because of an untracked file that would be overwritten by the
merge. In this case, git-merge-recursive aborts the operation but
without any unmerged entries in the index. StGIT considers that the
merge lead to an empty patch without reporting any error.

This commit makes it a bit safer by detecting whether there are
unmerged index entries and, if not, further raises an error informing
the user of the problem. The patch is still pushed as empty but the
user is informed of the failure and the possibility of running 'push
--undo'.

A better solution, but which require a bit more work, is to
distinguish between the merge failures and, in this specific case,
abort the push completely and revert the patch to its original state
(and popped from the stack).

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

index f6d6b43e5daa682ced028c84acf206569310ac08..d7eb48e1023110ee52628514409bd07892b84592 100644 (file)
@@ -672,13 +672,15 @@ def merge(base, head1, head2, recursive = False):
     """
     refresh_index()
 
+    err_output = None
     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:
+        except GitException, ex:
+            err_output = str(ex)
             pass
     else:
         # the fast case where we don't track renames (used when the
@@ -706,6 +708,11 @@ def merge(base, head1, head2, recursive = False):
 
         files[path][stage] = (mode, hash)
 
+    if err_output and not files:
+        # if no unmerged files, there was probably a different type of
+        # error and we have to abort the merge
+        raise GitException, err_output
+
     # merge the unmerged files
     errors = False
     for path in files:
index a726cb5ec8287688d704957f39495680e035773d..b0a01dd76ab7742d213ba689a579ef61eb221523 100644 (file)
@@ -1046,7 +1046,8 @@ class Series(StgitObject):
                 except git.GitException, ex:
                     print >> sys.stderr, \
                           'The merge failed during "push". ' \
-                          'Use "refresh" after fixing the conflicts'
+                          'Use "refresh" after fixing the conflicts or ' \
+                          'revert the operation with "push --undo".'
 
         append_string(self.__applied_file, name)