[StGit PATCH 3/5] Add automatic git-mergetool invocation to the new infrastructure

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch adds the IndexAndWorktree.mergetool() function responsible
for calling 'git mergetool' to interactively solve conflicts. The
function may also be called from IndexAndWorktree.merge() if the
standard 'git merge-recursive' fails and 'interactive == True'. The
'allow_interactive' parameter is passed to Transaction.push_patch() from
the functions allowing interactive merging.

Signed-off-by: Catalin Marinas <catalin.marinas@xxxxxxxxx>
---
 stgit/commands/edit.py   |    2 +-
 stgit/commands/goto.py   |    2 +-
 stgit/lib/git.py         |   21 ++++++++++++++++++---
 stgit/lib/transaction.py |    7 +++++--
 4 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/stgit/commands/edit.py b/stgit/commands/edit.py
index ed785aa..42eb792 100644
--- a/stgit/commands/edit.py
+++ b/stgit/commands/edit.py
@@ -128,7 +128,7 @@ def func(parser, options, args):
     trans.patches[patchname] = stack.repository.commit(cd)
     try:
         for pn in popped:
-            trans.push_patch(pn, iw)
+            trans.push_patch(pn, iw, allow_interactive = True)
     except transaction.TransactionHalted:
         pass
     try:
diff --git a/stgit/commands/goto.py b/stgit/commands/goto.py
index 0f67314..56c09da 100644
--- a/stgit/commands/goto.py
+++ b/stgit/commands/goto.py
@@ -48,7 +48,7 @@ def func(parser, options, args):
     elif patch in trans.unapplied:
         try:
             for pn in trans.unapplied[:trans.unapplied.index(patch)+1]:
-                trans.push_patch(pn, iw)
+                trans.push_patch(pn, iw, allow_interactive = True)
         except transaction.TransactionHalted:
             pass
     elif patch in trans.hidden:
diff --git a/stgit/lib/git.py b/stgit/lib/git.py
index 07079b8..d83b475 100644
--- a/stgit/lib/git.py
+++ b/stgit/lib/git.py
@@ -824,7 +824,7 @@ class IndexAndWorktree(RunWithEnvCwd):
                      ).discard_output()
         except run.RunException:
             raise CheckoutException('Index/workdir dirty')
-    def merge(self, base, ours, theirs):
+    def merge(self, base, ours, theirs, interactive = False):
         assert isinstance(base, Tree)
         assert isinstance(ours, Tree)
         assert isinstance(theirs, Tree)
@@ -838,10 +838,25 @@ class IndexAndWorktree(RunWithEnvCwd):
             output = r.output_lines()
             if r.exitcode:
                 # There were conflicts
-                conflicts = [l for l in output if l.startswith('CONFLICT')]
-                raise MergeConflictException(conflicts)
+                if interactive:
+                    self.mergetool()
+                else:
+                    conflicts = [l for l in output if l.startswith('CONFLICT')]
+                    raise MergeConflictException(conflicts)
         except run.RunException, e:
             raise MergeException('Index/worktree dirty')
+    def mergetool(self, files = ()):
+        """Invoke 'git mergetool' on the current IndexAndWorktree to resolve
+        any outstanding conflicts. If 'not files', all the files in an
+        unmerged state will be processed."""
+        err = os.system('git mergetool %s' % ' '.join(files))
+        # check for unmerged entries (prepend 'CONFLICT ' for consistency with
+        # merge())
+        conflicts = ['CONFLICT ' + f for f in self.index.conflicts()]
+        if conflicts:
+            raise MergeConflictException(conflicts)
+        elif err:
+            raise MergeException('"git mergetool" failed, exit code: %d' % err)
     def changed_files(self, tree, pathlimits = []):
         """Return the set of files in the worktree that have changed with
         respect to C{tree}. The listing is optionally restricted to
diff --git a/stgit/lib/transaction.py b/stgit/lib/transaction.py
index 5a81f9d..a918a66 100644
--- a/stgit/lib/transaction.py
+++ b/stgit/lib/transaction.py
@@ -8,6 +8,7 @@ from stgit import exception, utils
 from stgit.utils import any, all
 from stgit.out import *
 from stgit.lib import git, log
+from stgit.config import config
 
 class TransactionException(exception.StgException):
     """Exception raised when something goes wrong with a
@@ -296,7 +297,7 @@ class StackTransaction(object):
                     out.info('Deleted %s%s' % (pn, s))
         return popped
 
-    def push_patch(self, pn, iw = None):
+    def push_patch(self, pn, iw = None, allow_interactive = False):
         """Attempt to push the named patch. If this results in conflicts,
         halts the transaction. If index+worktree are given, spill any
         conflicts to them."""
@@ -319,7 +320,9 @@ class StackTransaction(object):
             except git.CheckoutException:
                 self.__halt('Index/worktree dirty')
             try:
-                iw.merge(base, ours, theirs)
+                interactive = allow_interactive and \
+                        config.get('stgit.autoimerge') == 'yes'
+                iw.merge(base, ours, theirs, interactive = interactive)
                 tree = iw.index.write_tree()
                 self.__current_tree = tree
                 s = ' (modified)'

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux