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