From e4394e12db7cccd1b5bf905d364763221d65f534 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Tue, 17 Apr 2007 17:29:32 +0100 Subject: [PATCH] Failed recursive merging can silently lose date in StGIT 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 --- stgit/git.py | 9 ++++++++- stgit/stack.py | 3 ++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/stgit/git.py b/stgit/git.py index 46ba5c8..81f6501 100644 --- a/stgit/git.py +++ b/stgit/git.py @@ -606,13 +606,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 @@ -640,6 +642,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: diff --git a/stgit/stack.py b/stgit/stack.py index 0f5d868..b21cc30 100644 --- a/stgit/stack.py +++ b/stgit/stack.py @@ -1030,7 +1030,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) -- 2.11.0