我正在尝试将 2 个提交合并为 1 个,因此我遵循了来自 git ready 的“使用 rebase 取消提交”。
我跑了
git rebase --interactive HEAD~2
在生成的编辑器中,我更改pick为squash然后保存退出,但变基失败并出现错误
pick
squash
没有先前的提交就不能“挤压”
现在我的工作树已经达到这个状态,我很难恢复。
该命令git rebase --interactive HEAD~2失败并显示:
交互式变基已经开始
并git rebase --continue失败了
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 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。)
更改 b pick-tosquash将导致您看到的错误,但如果您通过将待办事项列表更改为
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
交互式变基重写历史。尝试推送到包含旧历史的远程会失败,因为它不是快进。
如果您重新定位的分支是 您自己工作的主题或功能分支,那 没什么大不了的。推送到另一个存储库将需要该--force选项,或者您可以根据远程存储库的权限,首先删除旧分支,然后推送重新定位的版本。那些可能会破坏工作的命令示例不在此答案的范围内。
--force
在没有 充分理由(例如泄露密码或其他敏感细节)的情况下,在您与其他人合作的分支上重写已经发布的历史记录会迫使您的合作者工作,并且是反社会的,并且会惹恼其他开发人员。文档中的“从上游变基中恢复”部分进行了git rebase解释,并特别强调了这一点。
git rebase
Rebase(或任何其他形式的重写)其他人基于其工作的分支是一个坏主意:它下游的任何人都被迫手动修复他们的历史记录。本节说明如何从下游的角度进行修复。 然而,真正的解决办法是首先避免重新定位上游。 ‘’