Git 如何挤压两个不连续的提交?
我对git中的整个重定基调功能有点陌生。假设我做出了以下承诺:Git 如何挤压两个不连续的提交?,git,git-rebase,Git,Git Rebase,我对git中的整个重定基调功能有点陌生。假设我做出了以下承诺: A -> B -> C -> D 之后,我意识到D包含一个修复,该修复依赖于a中添加的一些新代码,并且这些提交属于一个整体。如何将A和D挤压在一起,而将B和C单独留在一起?您可以运行git rebase--interactive并在B之前重新排序D,然后将D挤压到A中 Git将打开一个编辑器,您会看到这样一个文件,例如:Git rebase——interactive HEAD~4 pick aaaaaaa Com
A -> B -> C -> D
之后,我意识到
D
包含一个修复,该修复依赖于a
中添加的一些新代码,并且这些提交属于一个整体。如何将A
和D
挤压在一起,而将B
和C
单独留在一起?您可以运行git rebase--interactive
并在B之前重新排序D,然后将D挤压到A中
Git将打开一个编辑器,您会看到这样一个文件,例如:Git rebase——interactive HEAD~4
pick aaaaaaa Commit A
pick bbbbbbb Commit B
pick ccccccc Commit C
pick ddddddd Commit D
# Rebase aaaaaaa..ddddddd onto 1234567 (4 command(s))
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out
现在更改文件,使其看起来像这样:
pick aaaaaaa Commit A
squash ddddddd Commit D
pick bbbbbbb Commit B
pick ccccccc Commit C
git现在将A和D的更改合并到一个提交中,然后将B和C放在一起。当您不想保留D的提交消息时,可以使用fixup
关键字,而不是squash
。有关fixup
的更多信息,您可以咨询,或查看有一些好答案的。$git checkout master
$git日志--一行
$git rebase--在头部^^^头部^
$git日志--一行
注意:除非您知道原因,否则您不应以任何方式更改已推送到另一回购协议的提交
git日志--oneline-4
D commit_message_for_D
C commit_message_for_C
B commit_message_for_B
A commit_message_for_A
E new_commit_message_for_A_and_D
C commit_message_for_C
B commit_message_for_B
git-rebase——交互式
pick D commit_message_for_D
pick C commit_message_for_C
pick B commit_message_for_B
pick A commit_message_for_A
输入i
(将VIM置于插入模式)
将列表更改为如下所示(您不必删除或包含提交消息)。不要拼错squash
!:
然后键入EscZZ
(保存并退出VIM)
类型i
将文本更改为新提交消息的外观。我建议这是对提交a
和D
中的更改的描述:
new_commit_message_for_A_and_D
然后键入EscZZ
git日志--oneline-4
D commit_message_for_D
C commit_message_for_C
B commit_message_for_B
A commit_message_for_A
E new_commit_message_for_A_and_D
C commit_message_for_C
B commit_message_for_B
git show E
(You should see a diff showing a combination of changes from A and D)
您现在已经创建了一个新的提交E
。提交A
和D
不再出现在您的历史记录中,但不会消失。此时,您仍然可以通过git-rebase--hard D D
恢复它们(git-rebase--hard
将破坏任何本地更改!)。对于那些使用:
确保您尚未推送提交
Squash与上一个
交互式重基工作得很好,直到你有了20-30次提交的大功能分支和/或来自master的几次合并,或者/和修复在分支中提交时的冲突。即使通过历史记录查找我的提交,并将
pick
替换为squash
在这里也不起作用。所以我在寻找另一种方法,找到了这个。
我在单独的分支上进行了更改:
git checkout master
git fetch
git pull
git merge branch-name
git reset origin/master
git branch -D branch-name
git checkout -b branch-name
git add --all
#Do some commit
git push -f --set-upstream origin branch-name
在此之前,我收到了来自master的约30次提交和2-3次合并的pull请求,并修复了冲突。在这之后,我通过一次承诺获得了清晰的公共关系
这里是bash在自动模式下执行这些步骤。我想你的意思是
--oneline
?看起来你已经放弃了C
和B
,这不是OP的意图。对我来说不起作用。它将我的头和主机都移动到A,但没有将D合并到A(git show A
),并且D、C和B在我的ref日志中丢失。必须git-rebase-D
才能返回。最初,我将其理解为“将D重基到A上,将D挤压到A上,然后将B重基到DA上”。答案中不清楚这是否可以通过在文本编辑器中重新排序行来完成。如果您的分支是本地分支,则在重定基址时,您将获得当前分支的无跟踪信息。在这种情况下,您需要指定要处理的提交数量,如下所示:git-rebase-i HEAD~4
。看,我使用交互模式(git rebase-I)多年了,我刚刚意识到它可以重新排序。感谢大家用粗体告诉所有刚接触git的人。没有人告诉我在rebase中重新排序会产生奇迹。文章中的第一个解决方案非常好,谢谢链接
(You should see a diff showing a combination of changes from A and D)
git checkout master
git fetch
git pull
git merge branch-name
git reset origin/master
git branch -D branch-name
git checkout -b branch-name
git add --all
#Do some commit
git push -f --set-upstream origin branch-name