使用git rebase——interactive <commit>,你可以把任意数量的提交压缩成一个单独的提交。
这一切都很好,除非您想将提交压缩到初始提交中。这似乎是不可能的。
有什么方法可以实现吗?
适度相关:
在一个相关的问题中,我设法提出了一种不同的方法来满足压缩第一次提交的需要,也就是将其作为第二次提交。
如果你感兴趣:git:如何插入一个提交作为第一个,转移所有其他?
使用git rebase——interactive <commit>,你可以把任意数量的提交压缩成一个单独的提交。
这一切都很好,除非您想将提交压缩到初始提交中。这似乎是不可能的。
有什么方法可以实现吗?
适度相关:
在一个相关的问题中,我设法提出了一种不同的方法来满足压缩第一次提交的需要,也就是将其作为第二次提交。
如果你感兴趣:git:如何插入一个提交作为第一个,转移所有其他?
当前回答
你可以使用git filter-branch。如。
git filter-branch --parent-filter \
'if test $GIT_COMMIT != <sha1ofB>; then cat; fi'
这将导致AB-C丢弃A的提交日志。
其他回答
你可以使用git filter-branch。如。
git filter-branch --parent-filter \
'if test $GIT_COMMIT != <sha1ofB>; then cat; fi'
这将导致AB-C丢弃A的提交日志。
2012年7月更新(git 1.7.12+)
现在,您可以将所有提交重置为root,并选择第二个提交Y与第一个X压缩。
git rebase -i --root master
pick sha1 X
squash sha1 Y
pick sha1 Z
Git rebase [-i]——root $tip 这个命令现在可以用来重写从“$tip”到根提交的所有历史记录。
参见Chris Webb (arachsys)在GitHub上提交df5df20c13 (rebase -i: support——root without——onto, 2012-06-26)。
正如评论中提到的,在任何重基操作之后,如果你需要在远程存储库中发布重做,都需要git push——force- withlease(比——force更安全,Mikko Mantalainen提醒我们)。
原答案(2009年2月)
我相信您会在SO问题“如何组合git存储库的前两次提交?”中找到不同的解决方法。
Charles Bailey在那里提供了最详细的答案,提醒我们一个提交是一个完整的树(不仅仅是与以前的状态不同)。 这里旧的提交(“初始提交”)和新提交(压缩的结果)将没有共同的祖先。 这意味着你不能“提交-修改”最初的提交到一个新的,然后在新的初始提交上重新建立先前初始提交的历史(很多冲突)
(git rebase -i——root < branch >)
相反(A是原始的“初始提交”,B是后续提交,需要压缩到初始提交中):
Go back to the last commit that we want to form the initial commit (detach HEAD): git checkout <sha1_for_B> Reset the branch pointer to the initial commit, but leaving the index and working tree intact: git reset --soft <sha1_for_A> Amend the initial tree using the tree from 'B': git commit --amend Temporarily tag this new initial commit (or you could remember the new commit sha1 manually): git tag tmp Go back to the original branch (assume master for this example): git checkout master Replay all the commits after B onto the new initial commit: git rebase --onto tmp <sha1_for_B> Remove the temporary tag: git tag -d tmp
这样,“rebase—onto”就不会在合并过程中引入冲突,因为它将上一次提交(B)之后的历史记录重新压缩到初始提交(即A)到tmp(表示压缩的新初始提交):只是简单的快进合并。
这句话适用于“A- b”,但也适用于“A-…-…-…-B"(任何数量的提交都可以被压缩到初始提交中)
这将把第二次提交压缩到第一次提交中:
a - b - c -…- > AB-C -…
git filter-branch --commit-filter '
if [ "$GIT_COMMIT" = <sha1ofA> ];
then
skip_commit "$@";
else
git commit-tree "$@";
fi
' HEAD
AB的提交消息将从B获取(尽管我更喜欢从A)。
与Uwe Kleine-König的答案具有相同的效果,但也适用于非首字母A。
有一种更简单的方法。假设您在主分支上
创建一个新的孤立分支,它将删除所有的提交历史:
$ git checkout --orphan new_branch
添加你的初始提交消息:
$ git commit -a
摆脱旧的未合并的主分支:
$ git branch -D master
将当前分支new_branch重命名为master:
$ git branch -m master
在最后两次提交被推送到远程服务器之前,可以使用rebase交互来修改它们
git rebase HEAD^^ -i