Fix "stg resolved" to work with new conflict representation
authorKarl Hasselström <kha@treskal.com>
Wed, 19 Dec 2007 18:00:13 +0000 (18:00 +0000)
committerCatalin Marinas <catalin.marinas@gmail.com>
Wed, 19 Dec 2007 23:13:30 +0000 (23:13 +0000)
The actual resolving is done by calling the same subroutine as "git
add".

Instead of using existing *.{ancestor,current,patches} files, the
interactive merge has to create them from the index contents, and
delete them afterwards.

Signed-off-by: Karl Hasselström <kha@treskal.com>
stgit/commands/common.py
stgit/commands/resolved.py
stgit/gitmergeonefile.py
t/t0002-status.sh

index 1426aca..d040ee9 100644 (file)
@@ -147,20 +147,11 @@ def print_crt_patch(crt_series, branch = None):
 
 def resolved(filename, reset = None):
     if reset:
 
 def resolved(filename, reset = None):
     if reset:
-        reset_file = filename + file_extensions()[reset]
-        if os.path.isfile(reset_file):
-            if os.path.isfile(filename):
-                os.remove(filename)
-            os.rename(reset_file, filename)
-            # update the access and modificatied times
-            os.utime(filename, None)
-
-    git.update_cache([filename], force = True)
-
-    for ext in file_extensions().values():
-        fn = filename + ext
-        if os.path.isfile(fn):
-            os.remove(fn)
+        stage = {'ancestor': 1, 'current': 2, 'patched': 3}[reset]
+        Run('git', 'checkout-index', '--no-create', '--stage=%d' % stage, '--',
+            filename).no_output()
+    git.add([filename])
+    os.utime(filename, None) # update the access and modificatied times
 
 def resolved_all(reset = None):
     conflicts = git.get_conflicts()
 
 def resolved_all(reset = None):
     conflicts = git.get_conflicts()
index 011db91..845eca0 100644 (file)
@@ -77,18 +77,7 @@ def func(parser, options, args):
                 raise CmdException, 'No conflicts for "%s"' % filename
 
     # resolved
                 raise CmdException, 'No conflicts for "%s"' % filename
 
     # resolved
-    try:
-        for filename in files:
-            if options.interactive:
-                interactive_merge(filename)
-            resolved(filename, options.reset)
-            del conflicts[conflicts.index(filename)]
-    finally:
-        # save or remove the conflicts file. Needs a finally clause to
-        # ensure that already solved conflicts are marked
-        if conflicts == []:
-            os.remove(os.path.join(basedir.get(), 'conflicts'))
-        else:
-            f = file(os.path.join(basedir.get(), 'conflicts'), 'w+')
-            f.writelines([line + '\n' for line in conflicts])
-            f.close()
+    for filename in files:
+        if options.interactive:
+            interactive_merge(filename)
+        resolved(filename, options.reset)
index 4c90e1a..c85e347 100644 (file)
@@ -97,51 +97,60 @@ def __conflict(path):
 
 
 def interactive_merge(filename):
 
 
 def interactive_merge(filename):
-    """Run the interactive merger on the given file. Note that the
-    index should not have any conflicts.
-    """
-    extensions = file_extensions()
-
-    ancestor = filename + extensions['ancestor']
-    current = filename + extensions['current']
-    patched = filename + extensions['patched']
-
-    if os.path.isfile(ancestor):
-        three_way = True
-        files_dict = {'branch1': current,
-                      'ancestor': ancestor,
-                      'branch2': patched,
-                      'output': filename}
-        imerger = config.get('stgit.i3merge')
-    else:
-        three_way = False
-        files_dict = {'branch1': current,
-                      'branch2': patched,
-                      'output': filename}
-        imerger = config.get('stgit.i2merge')
-
-    if not imerger:
-        raise GitMergeException, 'No interactive merge command configured'
-
-    # check whether we have all the files for the merge
-    for fn in [filename, current, patched]:
-        if not os.path.isfile(fn):
-            raise GitMergeException, \
-                  'Cannot run the interactive merge: "%s" missing' % fn
-
-    mtime = os.path.getmtime(filename)
-
-    out.info('Trying the interactive %s merge'
-             % (three_way and 'three-way' or 'two-way'))
-
-    err = os.system(imerger % files_dict)
-    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
-
+    """Run the interactive merger on the given file."""
+    try:
+        extensions = file_extensions()
+        line = MRun('git', 'checkout-index', '--stage=all', '--', filename
+                    ).output_one_line()
+        stages, path = line.split('\t')
+        stages = dict(zip(['ancestor', 'current', 'patched'],
+                          stages.split(' ')))
+        for stage, fn in stages.iteritems():
+            if stages[stage] == '.':
+                stages[stage] = None
+            else:
+                newname = filename + extensions[stage]
+                if not os.path.exists(newname):
+                    os.rename(stages[stage], newname)
+                    stages[stage] = newname
+
+        # Check whether we have all the files for the merge.
+        if not (stages['current'] and stages['patched']):
+            raise GitMergeException('Cannot run the interactive merge')
+
+        if stages['ancestor']:
+            three_way = True
+            files_dict = {'branch1': stages['current'],
+                          'ancestor': stages['ancestor'],
+                          'branch2': stages['patched'],
+                          'output': filename}
+            imerger = config.get('stgit.i3merge')
+        else:
+            three_way = False
+            files_dict = {'branch1': stages['current'],
+                          'branch2': stages['patched'],
+                          'output': filename}
+            imerger = config.get('stgit.i2merge')
+
+        if not imerger:
+            raise GitMergeException, 'No interactive merge command configured'
+
+        mtime = os.path.getmtime(filename)
+
+        out.start('Trying the interactive %s merge'
+                  % (three_way and 'three-way' or 'two-way'))
+        err = os.system(imerger % files_dict)
+        out.done()
+        if err != 0:
+            raise GitMergeException, 'The interactive merge failed'
+        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
+    finally:
+        for fn in stages.itervalues():
+            if os.path.isfile(fn):
+                os.remove(fn)
 
 #
 # Main algorithm
 
 #
 # Main algorithm
index 32c01d0..9a5a285 100755 (executable)
@@ -144,7 +144,7 @@ cat > expected.txt <<EOF
 A fie
 M foo/bar
 EOF
 A fie
 M foo/bar
 EOF
-test_expect_failure 'Status after resolving the push' '
+test_expect_success 'Status after resolving the push' '
     stg resolved -a &&
     stg status > output.txt &&
     diff -u expected.txt output.txt
     stg resolved -a &&
     stg status > output.txt &&
     diff -u expected.txt output.txt
@@ -154,7 +154,7 @@ cat > expected.txt <<EOF
 A fie
 D foo/bar
 EOF
 A fie
 D foo/bar
 EOF
-test_expect_failure 'Status after deleting a file' '
+test_expect_success 'Status after deleting a file' '
     rm foo/bar &&
     stg status > output.txt &&
     diff -u expected.txt output.txt
     rm foo/bar &&
     stg status > output.txt &&
     diff -u expected.txt output.txt
@@ -163,7 +163,7 @@ test_expect_failure 'Status after deleting a file' '
 cat > expected.txt <<EOF
 D foo/bar
 EOF
 cat > expected.txt <<EOF
 D foo/bar
 EOF
-test_expect_failure 'Status of disappeared newborn' '
+test_expect_success 'Status of disappeared newborn' '
     stg refresh &&
     touch foo/bar &&
     stg add foo/bar &&
     stg refresh &&
     touch foo/bar &&
     stg add foo/bar &&