我试图合并2个提交为1,所以我遵循“压缩提交与rebase”从git就绪。

我跑

git rebase --interactive HEAD~2

在结果编辑器中,我将pick更改为squash,然后save-quit,但由于出现错误,重基操作失败

没有之前的提交就不能“squash”

现在我的工作树已经达到了这个状态,我很难恢复。

命令git rebase——interactive HEAD~2失败:

交互式改基已经开始

git rebase -continue失败

没有之前的提交就不能“squash”


当前回答

总结

错误消息

没有之前的提交就不能“squash”

意味着你可能试图“向下挤压”。Git总是将一个新的提交压缩到一个旧的提交中,或者在交互的rebase todo列表中看到的“向上”,即压缩到前一行的提交中。将待办事项列表的第一行命令更改为“压缩”总是会产生这个错误,因为没有任何东西可以让第一个提交进行压缩。

修复

先回到你开始的地方

$ git rebase --abort

说你的历史

$ git log --pretty=oneline
a931ac7c808e2471b22b5bd20f0cad046b1c5d0d c
b76d157d507e819d7511132bdb5a80dd421d854f b
df239176e1a2ffac927d8b496ea00d5488481db5 a

也就是说,a是第一次提交,然后是b,最后是c。在提交c之后,我们决定将b和c合并在一起:

(注意:运行git日志将其输出输送到分页器,在大多数平台上默认情况较少。要退出寻呼机并返回命令提示符,请按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.
#

(请注意,此todo列表与git log的输出顺序相反。)

将b的选择更改为squash将导致您看到的错误,但如果相反,通过将todo列表更改为将c压缩到b(新的提交到旧的或“向上压缩”)

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

如果你的主分支git日志看起来像下面这样:

commit ac72a4308ba70cc42aace47509a5e
Author: <me@me.com>
Date:   Tue Jun 11 10:23:07 2013 +0500

    Added algorithms for Cosine-similarity

commit 77df2a40e53136c7a2d58fd847372
Author: <me@me.com>
Date:   Tue Jun 11 13:02:14 2013 -0700

    Set stage for similar objects

commit 249cf9392da197573a17c8426c282
Author: Ralph <ralph@me.com>
Date:   Thu Jun 13 16:44:12 2013 -0700

    Fixed a bug in space world automation

你想合并前两个提交,只需执行以下简单的步骤:

首先,为了安全起见,在一个单独的分支签出第二个最后提交。你可以给分支起任何名字。Git checkout 77df2a40e53136c7a2d58fd847372 -b合并提交 现在,只需要从上次提交到这个新分支的更改中选择:git cherry-pick -n -x ac72a4308ba70cc42aace47509a5e。(如有冲突,应及时解决) 你在上次提交中的改变在第二次提交中。但是你仍然需要提交,所以首先添加你刚刚选择的更改,然后执行git commit—amend。

就是这样。如果你愿意,你可以在分支“merge -commits”中推送这个合并的版本。

此外,您现在可以在主分支中丢弃连续两次提交。只需将你的主分支更新为:

git checkout master
git reset --hard origin/master (CAUTION: This command will remove any local changes to your master branch)
git pull

假设你在自己的主题分支里。如果你想把最后两个提交合并成一个,看起来像一个英雄,就在你做最后两个提交之前分支提交(使用相对提交名称HEAD~2指定)。

git checkout -b temp_branch HEAD~2

然后在这个新分支中挤压提交另一个分支:

git merge branch_with_two_commits --squash

这将带来改变,但不会导致改变。所以只要承诺就行了。

git commit -m "my message"

现在您可以将这个新的主题分支合并回您的主分支。

添加到@greg的答案后,你完成了所有的事情,即压缩提交,如果你做git push(原始提交将保留在分支),而如果你做git push -f origin提交将被删除。 例如,你合并了提交B和提交C,如果你使用git push,你将有提交B,提交C和提交BC,但如果你使用git push -f origin,你将只有提交BC

首先你应该检查你有多少提交:

git log

有两种状态:

一是只有两次提交:

例如:

commit A
commit B

(在这种情况下,你不能使用git rebase来做)你需要做下面的事情。

$ git reset --soft HEAD^1

$ git commit --amend

另一种情况是提交次数超过两次;你想合并提交C和D。

例如:

commit A
commit B
commit C
commit D

(在这种情况下,你可以使用git rebase)

git rebase -i B

而不是用“壁球”来做。剩下的就很简单了。如果你还不知道,请阅读http://zerodie.github.io/blog/2012/01/19/git-rebase-i/