Add file renaming support
[stgit] / stgit / git.py
index 025d15d..20cac61 100644 (file)
@@ -22,6 +22,7 @@ import sys, os, popen2, re, gitmergeonefile
 
 from stgit import basedir
 from stgit.utils import *
+from stgit.config import config
 
 # git exception class
 class GitException(Exception):
@@ -78,6 +79,9 @@ class Commit:
     def get_log(self):
         return self.__log
 
+    def __str__(self):
+        return self.get_id_hash()
+
 # dictionary of Commit objects, used to avoid multiple calls to git
 __commits = dict()
 
@@ -178,9 +182,13 @@ def __run(cmd, args=None):
     return 0
 
 def __tree_status(files = None, tree_id = 'HEAD', unknown = False,
-                  noexclude = True):
+                  noexclude = True, verbose = False):
     """Returns a list of pairs - [status, filename]
     """
+    if verbose:
+        print 'Checking for changes in the working directory...',
+        sys.stdout.flush()
+
     refresh_index()
 
     if not files:
@@ -217,12 +225,15 @@ def __tree_status(files = None, tree_id = 'HEAD', unknown = False,
         if fs[1] not in conflicts:
             cache_files.append(fs)
 
+    if verbose:
+        print 'done'
+
     return cache_files
 
 def local_changes():
     """Return true if there are local changes in the tree
     """
-    return len(__tree_status()) != 0
+    return len(__tree_status(verbose = True)) != 0
 
 # HEAD value cached
 __head = None
@@ -397,7 +408,7 @@ def update_cache(files = None, force = False):
     if not files:
         files = []
 
-    cache_files = __tree_status(files)
+    cache_files = __tree_status(files, verbose = False)
 
     # everything is up-to-date
     if len(cache_files) == 0:
@@ -504,8 +515,12 @@ def merge(base, head1, head2):
     local tree
     """
     refresh_index()
-    if __run('git-read-tree -u -m --aggressive', [base, head1, head2]) != 0:
-        raise GitException, 'git-read-tree failed (local changes maybe?)'
+
+    try:
+        # use _output() to mask the verbose prints of the tool
+        _output('git-merge-recursive %s -- %s %s' % (base, head1, head2))
+    except GitException:
+        pass
 
     # check the index for unmerged entries
     files = {}
@@ -691,34 +706,48 @@ def pull(repository = 'origin', refspec = None):
     if refspec:
         args.append(refspec)
 
-    if __run('git-pull', args) != 0:
+    if __run(config.get('stgit', 'pullcmd'), args) != 0:
         raise GitException, 'Failed "git-pull %s"' % repository
 
-def apply_patch(filename = None, base = None):
+def repack():
+    """Repack all objects into a single pack
+    """
+    __run('git-repack -a -d -f')
+
+def apply_patch(filename = None, diff = None, base = None,
+                fail_dump = True):
     """Apply a patch onto the current or given index. There must not
     be any local changes in the tree, otherwise the command fails
     """
-    def __apply_patch():
-        if filename:
-            return __run('git-apply --index', [filename]) == 0
-        else:
-            try:
-                _input('git-apply --index', sys.stdin)
-            except GitException:
-                return False
-            return True
-
     if base:
         orig_head = get_head()
         switch(base)
     else:
-        refresh_index()         # needed since __apply_patch() doesn't do it
+        refresh_index()
+
+    if diff is None:
+        if filename:
+            f = file(filename)
+        else:
+            f = sys.stdin
+        diff = f.read()
+        if filename:
+            f.close()
 
-    if not __apply_patch():
+    try:
+        _input_str('git-apply --index', diff)
+    except GitException:
         if base:
             switch(orig_head)
-        raise GitException, 'Patch does not apply cleanly'
-    elif base:
+        if fail_dump:
+            # write the failed diff to a file
+            f = file('.stgit-failed.patch', 'w+')
+            f.write(diff)
+            f.close()
+
+        raise
+
+    if base:
         top = commit(message = 'temporary commit used for applying a patch',
                      parents = [base])
         switch(orig_head)