git.pretty_commit() re-implemented with "git show" (bug #10018)
[stgit] / stgit / git.py
index b5551de..27d2595 100644 (file)
@@ -230,15 +230,27 @@ def tree_status(files = None, tree_id = 'HEAD', unknown = False,
         conflicts = []
     cache_files += [('C', filename) for filename in conflicts
                     if not files or filename in files]
+    reported_files = set(conflicts)
 
-    # the rest
+    # files in the index
     args = diff_flags + [tree_id]
     if files:
         args += ['--'] + files
     for line in GRun('diff-index', *args).output_lines():
         fs = tuple(line.rstrip().split(' ',4)[-1].split('\t',1))
-        if fs[1] not in conflicts:
+        if fs[1] not in reported_files:
             cache_files.append(fs)
+            reported_files.add(fs[1])
+
+    # files in the index but changed on (or removed from) disk
+    args = list(diff_flags)
+    if files:
+        args += ['--'] + files
+    for line in GRun('diff-files', *args).output_lines():
+        fs = tuple(line.rstrip().split(' ',4)[-1].split('\t',1))
+        if fs[1] not in reported_files:
+            cache_files.append(fs)
+            reported_files.add(fs[1])
 
     if verbose:
         out.done()
@@ -354,13 +366,20 @@ def create_branch(new_branch, tree_id = None):
     if branch_exists(new_branch):
         raise GitException, 'Branch "%s" already exists' % new_branch
 
+    current_head_file = get_head_file()
     current_head = get_head()
     set_head_file(new_branch)
     __set_head(current_head)
 
     # a checkout isn't needed if new branch points to the current head
     if tree_id:
-        switch(tree_id)
+        try:
+            switch(tree_id)
+        except GitException:
+            # Tree switching failed. Revert the head file
+            set_head_file(current_head_file)
+            delete_branch(new_branch)
+            raise
 
     if os.path.isfile(os.path.join(basedir.get(), 'MERGE_HEAD')):
         os.remove(os.path.join(basedir.get(), 'MERGE_HEAD'))
@@ -796,13 +815,10 @@ def barefiles(rev1, rev2):
 
     return '\n'.join(result)
 
-def pretty_commit(commit_id = 'HEAD', diff_flags = []):
+def pretty_commit(commit_id = 'HEAD', flags = []):
     """Return a given commit (log + diff)
     """
-    return GRun('diff-tree',
-                *(diff_flags
-                  + ['--cc', '--always', '--pretty', '-r', commit_id])
-                ).raw_output()
+    return GRun('show', *(flags + [commit_id])).raw_output()
 
 def checkout(files = None, tree_id = None, force = False):
     """Check out the given or all files