Fix the displaying of unknown files for 'stg status'
[stgit] / stgit / git.py
index 13f7b87..7d99338 100644 (file)
@@ -262,10 +262,10 @@ def __tree_status(files = None, tree_id = 'HEAD', unknown = False,
 
     return cache_files
 
-def local_changes():
+def local_changes(verbose = True):
     """Return true if there are local changes in the tree
     """
-    return len(__tree_status(verbose = True)) != 0
+    return len(__tree_status(verbose = verbose)) != 0
 
 # HEAD value cached
 __head = None
@@ -397,6 +397,11 @@ def rename_branch(from_name, to_name):
     rename(os.path.join(basedir.get(), 'refs', 'heads'),
            from_name, to_name)
 
+    reflog_dir = os.path.join(basedir.get(), 'logs', 'refs', 'heads')
+    if os.path.exists(reflog_dir) \
+           and os.path.exists(os.path.join(reflog_dir, from_name)):
+        rename(reflog_dir, from_name, to_name)
+
 def add(names):
     """Add the files or recursively add the directory contents
     """
@@ -596,17 +601,27 @@ def apply_diff(rev1, rev2, check_index = True, files = None):
 
     return True
 
-def merge(base, head1, head2):
+def merge(base, head1, head2, recursive = False):
     """Perform a 3-way merge between base, head1 and head2 into the
     local tree
     """
     refresh_index()
 
-    try:
-        # use _output() to mask the verbose prints of the tool
-        _output('git-merge-recursive %s -- %s %s' % (base, head1, head2))
-    except GitException:
-        pass
+    if recursive:
+        # this operation tracks renames but it is slower (used in
+        # general when pushing or picking patches)
+        try:
+            # use _output() to mask the verbose prints of the tool
+            _output('git-merge-recursive %s -- %s %s' % (base, head1, head2))
+        except GitException:
+            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)
+        if __run('git-read-tree -u -m --aggressive',
+                 [base, head1, head2]) != 0:
+            raise GitException, 'git-read-tree failed (local changes maybe?)'
 
     # check the index for unmerged entries
     files = {}
@@ -629,6 +644,15 @@ def merge(base, head1, head2):
     # 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],
@@ -664,6 +688,8 @@ def status(files = None, modified = False, new = False, deleted = False,
         cache_files = [x for x in cache_files if x[0] in filestat]
 
     for fs in cache_files:
+        if files and not fs[1] in files:
+            continue
         if all:
             print '%s %s' % (fs[0], fs[1])
         else:
@@ -805,12 +831,6 @@ def apply_patch(filename = None, diff = None, base = None,
     """Apply a patch onto the current or given index. There must not
     be any local changes in the tree, otherwise the command fails
     """
-    if base:
-        orig_head = get_head()
-        switch(base)
-    else:
-        refresh_index()
-
     if diff is None:
         if filename:
             f = file(filename)
@@ -820,6 +840,12 @@ def apply_patch(filename = None, diff = None, base = None,
         if filename:
             f.close()
 
+    if base:
+        orig_head = get_head()
+        switch(base)
+    else:
+        refresh_index()
+
     try:
         _input_str('git-apply --index', diff)
     except GitException:
@@ -830,6 +856,7 @@ def apply_patch(filename = None, diff = None, base = None,
             f = file('.stgit-failed.patch', 'w+')
             f.write(diff)
             f.close()
+            print >> sys.stderr, 'Diff written to the .stgit-failed.patch file'
 
         raise