From fab69eacedd180b5c67812336bfdb5f52f6a4ae5 Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20K=C3=A5gedal?= Date: Wed, 19 Dec 2007 18:00:11 +0000 Subject: [PATCH] Split git.merge into two functions MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This only prepares for later simplifications. Signed-off-by: David Kågedal Signed-off-by: Karl Hasselström --- stgit/commands/pick.py | 2 +- stgit/git.py | 91 +++++++++++++++++++++++++++++++++++++++----------- stgit/stack.py | 2 +- 3 files changed, 73 insertions(+), 22 deletions(-) diff --git a/stgit/commands/pick.py b/stgit/commands/pick.py index 5b45434..e011a84 100644 --- a/stgit/commands/pick.py +++ b/stgit/commands/pick.py @@ -100,7 +100,7 @@ def func(parser, options, args): # try a direct git-apply first if not git.apply_diff(bottom, top): - git.merge(bottom, git.get_head(), top, recursive = True) + git.merge_recursive(bottom, git.get_head(), top) out.done() elif options.update: diff --git a/stgit/git.py b/stgit/git.py index deb5efc..70c2d91 100644 --- a/stgit/git.py +++ b/stgit/git.py @@ -695,32 +695,83 @@ def apply_diff(rev1, rev2, check_index = True, files = None): return True -def merge(base, head1, head2, recursive = False): +stages_re = re.compile('^([0-7]+) ([0-9a-f]{40}) ([1-3])\t(.*)$', re.S) + +def merge_recursive(base, head1, head2): """Perform a 3-way merge between base, head1 and head2 into the local tree """ refresh_index() err_output = None - if recursive: - # this operation tracks renames but it is slower (used in - # general when pushing or picking patches) - try: - # discard output to mask the verbose prints of the tool - GRun('merge-recursive', base, '--', head1, head2 - ).discard_output() - except GitRunException, ex: - err_output = str(ex) - pass - else: - # the fast case where we don't track renames (used when the - # distance between base and heads is small, i.e. folding or - # synchronising patches) - try: - GRun('read-tree', '-u', '-m', '--aggressive', - base, head1, head2).run() - except GitRunException: - raise GitException, 'read-tree failed (local changes maybe?)' + # this operation tracks renames but it is slower (used in + # general when pushing or picking patches) + try: + # discard output to mask the verbose prints of the tool + GRun('merge-recursive', base, '--', head1, head2).discard_output() + except GitRunException, ex: + err_output = str(ex) + pass + + # check the index for unmerged entries + files = {} + + for line in GRun('ls-files', '--unmerged', '--stage', '-z' + ).raw_output().split('\0'): + if not line: + continue + + mode, hash, stage, path = stages_re.findall(line)[0] + + if not path in files: + files[path] = {} + files[path]['1'] = ('', '') + files[path]['2'] = ('', '') + files[path]['3'] = ('', '') + + 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: + # remove additional files that might be generated for some + # newer versions of GIT + for suffix in [base, head1, head2]: + if not suffix: + continue + fname = path + '~' + suffix + if os.path.exists(fname): + os.remove(fname) + + stages = files[path] + if gitmergeonefile.merge(stages['1'][1], stages['2'][1], + stages['3'][1], path, stages['1'][0], + stages['2'][0], stages['3'][0]) != 0: + errors = True + + if errors: + raise GitException, 'GIT index merging failed (possible conflicts)' + +def merge(base, head1, head2): + """Perform a 3-way merge between base, head1 and head2 into the + local tree + """ + refresh_index() + + err_output = None + # the fast case where we don't track renames (used when the + # distance between base and heads is small, i.e. folding or + # synchronising patches) + try: + GRun('read-tree', '-u', '-m', '--aggressive', base, head1, head2 + ).run() + except GitRunException: + raise GitException, 'read-tree failed (local changes maybe?)' # check the index for unmerged entries files = {} diff --git a/stgit/stack.py b/stgit/stack.py index 6db789a..26a2b58 100644 --- a/stgit/stack.py +++ b/stgit/stack.py @@ -1096,7 +1096,7 @@ class Series(PatchSet): # merge can fail but the patch needs to be pushed try: - git.merge(bottom, head, top, recursive = True) + git.merge_recursive(bottom, head, top) except git.GitException, ex: out.error('The merge failed during "push".', 'Use "refresh" after fixing the conflicts or' -- 2.11.0