From d3cf7d862f3ef6e3d6994714163a847e2ecba8e5 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Fri, 16 Sep 2005 21:35:20 +0200 Subject: [PATCH] Implement fast-forward when only tree (but not From: Paolo 'Blaisorblade' Giarrusso When the "bottom" commit and the HEAD don't match, but they refer to the same tree (for instance after a refresh where only the description changed), we can still fast-forward, by keeping the same top tree and calling git-commit-tree (which only requires the tree object) with the new parent. I've altered git.commit to allow this. Btw, I've also avoided the use of .commitmsg and switched to piping the description. Signed-off-by: Paolo 'Blaisorblade' Giarrusso --- stgit/git.py | 30 ++++++++++++++++-------------- stgit/stack.py | 35 +++++++++++++++++++++++++++++++---- 2 files changed, 47 insertions(+), 18 deletions(-) diff --git a/stgit/git.py b/stgit/git.py index 2661622..9ad6f0d 100644 --- a/stgit/git.py +++ b/stgit/git.py @@ -126,8 +126,12 @@ def _output(cmd): raise GitException, '%s failed' % str(cmd) return string -def _output_one_line(cmd): +def _output_one_line(cmd, file_desc = None): p=popen2.Popen3(cmd) + if file_desc != None: + for line in file_desc: + p.tochild.write(line) + p.tochild.close() string = p.fromchild.readline().strip() if p.wait(): raise GitException, '%s failed' % str(cmd) @@ -297,7 +301,7 @@ def update_cache(files = [], force = False): return True def commit(message, files = [], parents = [], allowempty = False, - cache_update = True, + cache_update = True, tree_id = None, author_name = None, author_email = None, author_date = None, committer_name = None, committer_email = None): """Commit the current tree to repository @@ -309,15 +313,15 @@ def commit(message, files = [], parents = [], allowempty = False, raise GitException, 'No changes to commit' # get the commit message - f = file('.commitmsg', 'w+') - if message[-1:] == '\n': - f.write(message) - else: - print >> f, message - f.close() + if message[-1:] != '\n': + message += '\n' + must_switch = True # write the index to repository - tree_id = _output_one_line('git-write-tree') + if tree_id == None: + tree_id = _output_one_line('git-write-tree') + else: + must_switch = False # the commit cmd = '' @@ -337,11 +341,9 @@ def commit(message, files = [], parents = [], allowempty = False, for p in parents: cmd += ' -p %s' % p - cmd += ' < .commitmsg' - - commit_id = _output_one_line(cmd) - __set_head(commit_id) - os.remove('.commitmsg') + commit_id = _output_one_line(cmd, message) + if must_switch: + __set_head(commit_id) return commit_id diff --git a/stgit/stack.py b/stgit/stack.py index 55c49a8..7109186 100644 --- a/stgit/stack.py +++ b/stgit/stack.py @@ -517,13 +517,40 @@ class Series: # top != bottom always since we have a commit for each patch if head == bottom: # reset the backup information - patch.set_bottom(bottom, backup = True) + patch.set_bottom(head, backup = True) patch.set_top(top, backup = True) else: - top = head - # stop the fast-forwarding, must do a real merge - break + head_tree = git.get_commit(head).get_tree() + bottom_tree = git.get_commit(bottom).get_tree() + if head_tree == bottom_tree: + # We must just reparent this patch and create a new commit + # for it + descr = patch.get_description() + author_name = patch.get_authname() + author_email = patch.get_authemail() + author_date = patch.get_authdate() + committer_name = patch.get_commname() + committer_email = patch.get_commemail() + + top_tree = git.get_commit(top).get_tree() + + top = git.commit(message = descr, parents = [head], + cache_update = False, + tree_id = top_tree, + allowempty = True, + author_name = author_name, + author_email = author_email, + author_date = author_date, + committer_name = committer_name, + committer_email = committer_email) + + patch.set_bottom(head, backup = True) + patch.set_top(top, backup = True) + else: + top = head + # stop the fast-forwarding, must do a real merge + break forwarded+=1 unapplied.remove(name) -- 2.11.0