我试图将 2 个提交合并为 1,所以我从 git 准备好跟随“压缩提交与 rebase” 。
我跑了
git rebase --interactive HEAD~2
在生成的编辑器中,我将pick
更改为squash
然后 save-quit,但是 rebase 因错误而失败
没有先前的提交,不能 '挤压'
既然我的工作树已达到这种状态,我就无法恢复了。命令git rebase --interactive HEAD~2
失败了
交互式 rebase 已经开始
和git rebase --continue
失败
没有先前的提交,不能 '挤压'
错误消息
没有先前的提交,不能 '挤压'
意味着你可能试图 “向下压缩 。” Git 总是把一个较新的提交压缩到一个较旧的提交或者在交互式 rebase 待办事项列表中查看的 “向上”,即在前一行的提交中。将你的待办事项列表的第一行命令更改为squash
将始终产生此错误,因为第一次提交没有任何东西可以压缩。
首先回到你开始的地方
$ git rebase --abort
说你的历史是
$ git log --pretty=oneline
a931ac7c808e2471b22b5bd20f0cad046b1c5d0d c
b76d157d507e819d7511132bdb5a80dd421d854f b
df239176e1a2ffac927d8b496ea00d5488481db5 a
也就是说,a 是第一次提交,然后是 b,最后是 c。在提交 c 之后,我们决定将 b 和 c 压缩在一起:
(注意:运行git log
会将其输出管道传输到寻呼机,在大多数平台上默认为less
。要退出寻呼机并返回到命令提示符,请按q
键。)
运行git rebase --interactive HEAD~2
为你提供了一个编辑器
pick b76d157 b
pick a931ac7 c
# Rebase df23917..a931ac7 onto df23917
#
# 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
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#
(请注意,与git log
的输出相比,此 todo 列表的顺序相反。)
将 b 的pick
更改为squash
将导致您看到的错误,但是如果您将 c 压缩到 b(较旧的提交到较旧的或 “向上挤压”)通过将 todo 列表更改为
pick b76d157 b
squash a931ac7 c
并保存退出您的编辑器,您将获得其内容的另一个编辑器
# This is a combination of 2 commits.
# The first commit's message is:
b
# This is the 2nd commit message:
c
保存并退出时,已编辑文件的内容将成为新组合提交的提交消息:
$ git log --pretty=oneline
18fd73d3ce748f2a58d1b566c03dd9dafe0b6b4f b and c
df239176e1a2ffac927d8b496ea00d5488481db5 a
交互式 rebase 重写历史记录。尝试推送到包含旧历史记录的遥控器将失败,因为它不是快进的。
如果您重新分支的分支是您自己工作的主题或功能分支,那么没什么大不了的。推送到另一个存储库将需要--force
选项,或者您可以根据远程存储库的权限首先删除旧分支,然后推送已更新的版本。可能会破坏工作的那些命令的示例超出了本答案的范围。
重写一个分支,它是你与其他人的工作没有很好的理由,如泄露密码或其他敏感信息的工作力量到你的合作者,是反社会和会惹恼其他开发商已经发布的历史。 git rebase
文档中的“从上游 Rebase 中恢复” 部分进行了解释,并进一步强调了这一点。
重新定位(或任何其他形式的重写)其他人基于其工作的分支是一个坏主意:它下游的任何人都被迫手动修复其历史记录。本节介绍如何从下游的角度进行修复。 然而,真正的解决方法是首先避免重新定位上游。 ...
如果有多个提交,您可以使用git rebase -i
将两个提交压缩为一个。
如果您只想合并两个提交,并且它们是 “最近的两个”,则可以使用以下命令将两个提交合并为一个:
git reset --soft "HEAD^"
git commit --amend
对于最常见的情况,更简单的方法。
实际上,如果你想要的只是简单地将几个最近的提交合并为一个,但不需要drop
, reword
和其他 rebase 工作。
git reset --soft "HEAD~n"
~n
是轻微取消提交的提交数(即~1
, ~2
,...) 然后,使用以下命令修改提交消息。
git commit --amend
这与一系列squash
和一个pick
。
并且它适用于 n 次提交但不仅仅是两次提交,如上面的答案提示。