Git:重写历史记录:重新排序和合并提交

25

当前情况:

origin/mybranch --- A1 --- B1 --- A2 --- B2 --- A3 --- B3   mybranch

我想要清除那段历史记录(从A1到B3),特别是因为我还没有将它推送到任何地方,而且我想准备一个仅包含那些B * 的补丁。

我的目标是:

origin/mybranch --- A1+A2+A3 --- B1+B2+B3   mybranch

我可能根本不会推送这个(或者如果我推送,只会推送总和B*,我必须完全删除A*提交),而当我进一步开发时,我可能会有额外的类似提交,就像这样:

origin/mybranch --- A1+A2+A3 --- B1+B2+B3 --- A4 --- B4   mybranch

我想再次像上面那样重写。

我不仅想知道任何一种做法(因为我可以用某种有些繁琐的方式得到它),我特别在这里询问正确/最佳/最清洁/最简单的方法。


我正在做的是:我正在工作于官方xorg-xserver-1.7分支,并想准备一个补丁(B*)。由于我想能够替换自己编译的xserver以进行简单的测试,我已经应用了一堆Debian/Ubuntu的补丁(A*)。但是,当我要在其他地方发布该补丁时,我希望将其排除在外。


1
这个来自Git Pro书籍的参考资料将会很有用(重写Git历史记录)。http://git-scm.com/book/ch6-4.html - Rimian
1个回答

30

你想进行一个交互式变基

在尝试使用git命令之前,我喜欢先备份我的分支:

$ git branch my-backup-branch

假设您的A1提交哈希值为152274b。尝试以下操作:

$ git rebase -i 152274b^

该命令将使用类似以下内容的文本编辑器(通常为vim)呈现:

pick 152274b A1
pick 14b0838 B1
pick 661b993 A2
pick a6510db B2
pick 557e171 A3
pick 85da0e4 B3

# Rebase 39a47e4..85da0e4 onto 39a47e4
#
# Commands:
#  p, pick = use commit
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#

从这里开始,您可以更改提交的顺序,完全删除它们,甚至压缩它们。 在这个例子中,您可能想要像这样移动和压缩:

pick 152274b A1
squash 661b993 A2
squash 557e171 A3
pick 14b0838 B1
squash a6510db B2
squash 85da0e4 B3

试一试吧。如果你最终进入了一个不想要的状态,你可以回到你在备份分支中保存的状态:

$ git reset --hard my-backup-branch

2
哇,那真的很容易! :) 如此自然、优雅和完美。 - Albert

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接