协慌网

登录 贡献 社区

如果我已经开始使用 rebase,如何将两个提交合并为一个?

我试图将 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

Rebase:你不需要它:

对于最常见的情况,更简单的方法。

在多数情况下:

实际上,如果你想要的只是简单地将几个最近的提交合并为一个,但不需要dropreword和其他 rebase 工作。

你可以简单地做:

git reset --soft "HEAD~n"
  • 假设~n是轻微取消提交的提交数(即~1~2 ,...)

然后,使用以下命令修改提交消息。

git commit --amend

这与一系列squash和一个pick

并且它适用于 n 次提交但不仅仅是两次提交,如上面的答案提示。