From: Catalin Marinas Date: Thu, 9 Apr 2009 20:40:59 +0000 (+0300) Subject: Add automatic git-mergetool invocation to the new infrastructure X-Git-Tag: v0.15-rc1~31 X-Git-Url: https://git.distorted.org.uk/~mdw/stgit/commitdiff_plain/1de97e5f5e62a46d69515052a860138e417f149b Add automatic git-mergetool invocation to the new infrastructure 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 Acked-by: Karl Hasselström --- 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 480266a..66f49df 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..9c530c7 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,23 @@ 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.""" + self.run(['git', 'mergetool'] + list(files)).returns([0, 1]).run() + # check for unmerged entries (prepend 'CONFLICT ' for consistency with + # merge()) + conflicts = ['CONFLICT ' + f for f in self.index.conflicts()] + if conflicts: + raise MergeConflictException(conflicts) 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 a88d289..4b5398a 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)'