Add import -p option
[stgit] / stgit / git.py
index 0955be7..012e282 100644 (file)
@@ -18,7 +18,7 @@ along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 """
 
-import sys, os, re, gitmergeonefile
+import sys, os, re
 from shutil import copyfile
 
 from stgit.exception import *
@@ -191,6 +191,9 @@ def ls_files(files, tree = 'HEAD', full_name = True):
     return list(fileset)
 
 def parse_git_ls(output):
+    """Parse the output of git diff-index, diff-files, etc. Doesn't handle
+    rename/copy output, so don't feed it output generated with the -M
+    or -C flags."""
     t = None
     for line in output.split('\0'):
         if not line:
@@ -204,7 +207,7 @@ def parse_git_ls(output):
             t = None
 
 def tree_status(files = None, tree_id = 'HEAD', unknown = False,
-                  noexclude = True, verbose = False, diff_flags = []):
+                  noexclude = True, verbose = False):
     """Get the status of all changed files, or of a selected set of
     files. Returns a list of pairs - (status, filename).
 
@@ -249,7 +252,7 @@ def tree_status(files = None, tree_id = 'HEAD', unknown = False,
     # specified when calling the function (i.e. report all files) or
     # files were specified but already found in the previous step
     if not files or files_left:
-        args = diff_flags + [tree_id]
+        args = [tree_id]
         if files_left:
             args += ['--'] + files_left
         for t, fn in parse_git_ls(GRun('diff-index', '-z', *args).raw_output()):
@@ -265,7 +268,7 @@ def tree_status(files = None, tree_id = 'HEAD', unknown = False,
     # function (i.e. report all files) or files were specified but
     # already found in the previous step
     if not files or files_left:
-        args = list(diff_flags)
+        args = []
         if files_left:
             args += ['--'] + files_left
         for t, fn in parse_git_ls(GRun('diff-files', '-z', *args).raw_output()):
@@ -629,19 +632,23 @@ def merge_recursive(base, head1, head2):
     output = p.output_lines()
     if p.exitcode:
         # There were conflicts
-        conflicts = [l.strip() for l in output if l.startswith('CONFLICT')]
+        if config.get('stgit.autoimerge') == 'yes':
+            mergetool()
+        else:
+            conflicts = [l for l in output if l.startswith('CONFLICT')]
+            out.info(*conflicts)
+            raise GitException, "%d conflict(s)" % len(conflicts)
+
+def mergetool(files = ()):
+    """Invoke 'git mergetool' to resolve any outstanding conflicts. If 'not
+    files', all the files in an unmerged state will be processed."""
+    GRun('mergetool', *list(files)).returns([0, 1]).run()
+    # check for unmerged entries (prepend 'CONFLICT ' for consistency with
+    # merge_recursive())
+    conflicts = ['CONFLICT ' + f for f in get_conflicts()]
+    if conflicts:
         out.info(*conflicts)
-
-        # try the interactive merge or stage checkout (if enabled)
-        for filename in get_conflicts():
-            if (gitmergeonefile.merge(filename)):
-                # interactive merge succeeded
-                resolved([filename])
-
-        # any conflicts left unsolved?
-        cn = len(get_conflicts())
-        if cn:
-            raise GitException, "%d conflict(s)" % cn
+        raise GitException, "%d conflict(s)" % len(conflicts)
 
 def diff(files = None, rev1 = 'HEAD', rev2 = None, diff_flags = [],
          binary = True):
@@ -666,10 +673,6 @@ def diff(files = None, rev1 = 'HEAD', rev2 = None, diff_flags = [],
     else:
         return ''
 
-def diffstat(diff):
-    """Return the diffstat of the supplied diff."""
-    return GRun('apply', '--stat', '--summary').raw_input(diff).raw_output()
-
 def files(rev1, rev2, diff_flags = []):
     """Return the files modified between rev1 and rev2
     """
@@ -755,7 +758,6 @@ def resolved(filenames, reset = None):
              '--stdin', '-z').input_nulterm(filenames).no_output()
     GRun('update-index', '--add', '--').xargs(filenames)
     for filename in filenames:
-        gitmergeonefile.clean_up(filename)
         # update the access and modificatied times
         os.utime(filename, None)
 
@@ -816,7 +818,7 @@ def repack():
     GRun('repack', '-a', '-d', '-f').run()
 
 def apply_patch(filename = None, diff = None, base = None,
-                fail_dump = True):
+                fail_dump = True, reject = False, strip = None):
     """Apply a patch onto the current or given index. There must not
     be any local changes in the tree, otherwise the command fails
     """
@@ -835,8 +837,13 @@ def apply_patch(filename = None, diff = None, base = None,
     else:
         refresh_index()
 
+    cmd = ['apply', '--index']
+    if reject:
+        cmd += ['--reject']
+    if strip != None:
+        cmd += ['-p', str(strip)]
     try:
-        GRun('apply', '--index').raw_input(diff).no_output()
+        GRun(*cmd).raw_input(diff).no_output()
     except GitRunException:
         if base:
             switch(orig_head)