From f7ed76a9b6158888e8efe2faef9c095802fd93fe Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Wed, 10 Jan 2007 19:38:26 +0000 Subject: [PATCH] Add option to automatically invoke the interactive merger The 'autoimerge' option was added (defaulting to 'no') to automatically invoke the interactive merging tool when a conflict occurs. Signed-off-by: Catalin Marinas --- examples/gitconfig | 3 +++ stgit/commands/resolved.py | 35 +------------------------ stgit/config.py | 1 + stgit/gitmergeonefile.py | 64 +++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 65 insertions(+), 38 deletions(-) diff --git a/examples/gitconfig b/examples/gitconfig index 0c0555a..5e7b240 100644 --- a/examples/gitconfig +++ b/examples/gitconfig @@ -50,6 +50,9 @@ #imerger = emacs --eval '(ediff-merge-files-with-ancestor \ # "%(branch1)s" "%(branch2)s" "%(ancestor)s" nil "%(output)s")' + # Automatically invoke the interactive merger in case of conflicts + #autoimerge = no + # Leave the original files in the working tree in case of a # merge conflict #keeporig = yes diff --git a/stgit/commands/resolved.py b/stgit/commands/resolved.py index ae85f2b..1130641 100644 --- a/stgit/commands/resolved.py +++ b/stgit/commands/resolved.py @@ -23,6 +23,7 @@ from stgit.commands.common import * from stgit.utils import * from stgit import stack, git, basedir from stgit.config import config, file_extensions +from stgit.gitmergeonefile import interactive_merge help = 'mark a file conflict as solved' @@ -42,40 +43,6 @@ options = [make_option('-a', '--all', help = 'run the interactive merging tool', action = 'store_true')] -def interactive_merge(filename): - """Run the interactive merger on the given file - """ - try: - imerger = config.get('stgit', 'imerger') - except Exception, err: - raise CmdException, 'Configuration error: %s' % err - - extensions = file_extensions() - - ancestor = filename + extensions['ancestor'] - current = filename + extensions['current'] - patched = filename + extensions['patched'] - - # check whether we have all the files for a three-way merge - for fn in [filename, ancestor, current, patched]: - if not os.path.isfile(fn): - raise CmdException, \ - 'Cannot run the interactive merger: "%s" missing' % fn - - mtime = os.path.getmtime(filename) - - err = os.system(imerger % {'branch1': current, - 'ancestor': ancestor, - 'branch2': patched, - 'output': filename}) - - if err != 0: - raise CmdException, 'The interactive merger failed: %d' % err - if not os.path.isfile(filename): - raise CmdException, 'The "%s" file is missing' % filename - if mtime == os.path.getmtime(filename): - raise CmdException, 'The "%s" file was not modified' % filename - def func(parser, options, args): """Mark the conflict as resolved """ diff --git a/stgit/config.py b/stgit/config.py index 2174f09..f5fbdab 100644 --- a/stgit/config.py +++ b/stgit/config.py @@ -69,6 +69,7 @@ def config_setup(): config.set('stgit', 'merger', 'diff3 -L current -L ancestor -L patched -m -E ' \ '"%(branch1)s" "%(ancestor)s" "%(branch2)s" > "%(output)s"') + config.set('stgit', 'autoimerge', 'no') config.set('stgit', 'keeporig', 'yes') config.set('stgit', 'keepoptimized', 'no') config.set('stgit', 'extensions', '.ancestor .current .patched') diff --git a/stgit/gitmergeonefile.py b/stgit/gitmergeonefile.py index a8dc2a8..200448b 100644 --- a/stgit/gitmergeonefile.py +++ b/stgit/gitmergeonefile.py @@ -20,7 +20,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA import sys, os from stgit import basedir -from stgit.config import file_extensions, ConfigOption +from stgit.config import config, file_extensions, ConfigOption from stgit.utils import append_string @@ -98,6 +98,42 @@ def __conflict(path): append_string(os.path.join(basedir.get(), 'conflicts'), path) +def interactive_merge(filename): + """Run the interactive merger on the given file. Note that the + index should not have any conflicts. + """ + try: + imerger = config.get('stgit', 'imerger') + except Exception, err: + raise GitMergeException, 'Configuration error: %s' % err + + extensions = file_extensions() + + ancestor = filename + extensions['ancestor'] + current = filename + extensions['current'] + patched = filename + extensions['patched'] + + # check whether we have all the files for a three-way merge + for fn in [filename, ancestor, current, patched]: + if not os.path.isfile(fn): + raise GitMergeException, \ + 'Cannot run the interactive merger: "%s" missing' % fn + + mtime = os.path.getmtime(filename) + + err = os.system(imerger % {'branch1': current, + 'ancestor': ancestor, + 'branch2': patched, + 'output': filename}) + + if err != 0: + raise GitMergeException, 'The interactive merge failed: %d' % err + if not os.path.isfile(filename): + raise GitMergeException, 'The "%s" file is missing' % filename + if mtime == os.path.getmtime(filename): + raise GitMergeException, 'The "%s" file was not modified' % filename + + # # Main algorithm # @@ -148,10 +184,30 @@ def merge(orig_hash, file1_hash, file2_hash, # reset the cache to the first branch os.system('git-update-index --cacheinfo %s %s %s' % (file1_mode, file1_hash, path)) - if str(keeporig) != 'yes': + + if config.get('stgit', 'autoimerge') == 'yes': + print >> sys.stderr, \ + 'Trying the interactive merge' + try: + interactive_merge(path) + except GitMergeException, ex: + # interactive merge failed + print >> sys.stderr, str(ex) + if str(keeporig) != 'yes': + __remove_files(orig_hash, file1_hash, + file2_hash) + __conflict(path) + return 1 + # successful interactive merge __remove_files(orig_hash, file1_hash, file2_hash) - __conflict(path) - return 1 + return 0 + else: + # no interactive merge, just mark it as conflict + if str(keeporig) != 'yes': + __remove_files(orig_hash, file1_hash, file2_hash) + __conflict(path) + return 1 + # file deleted in both or deleted in one and unchanged in the other elif not (file1_hash or file2_hash) \ or file1_hash == orig_hash or file2_hash == orig_hash: -- 2.11.0