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

我跑

git rebase --interactive HEAD~2

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

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

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

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

交互式改基已经开始

git rebase -continue失败

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


当前回答

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

其他回答

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

git checkout -b temp_branch HEAD~2

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

git merge branch_with_two_commits --squash

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

git commit -m "my message"

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

如果你想把几个提交压缩在一起,你可以使用交互式的rebase方法。(谢谢小麦教我这些!)

Git rebase origin/develop -i 然后你只需在你想要压缩的提交前写一个's',让它们卷到主提交中

在git rebase交互模式(vim)下的提示:

导航到要修改的提交行 (ESC) ciw -(改变内部单词)将改变光标下的整个单词。 输入你想做的,例如s表示压扁 (ESC) wq写得挺,你就搞定了。

然后git push -f

总结

错误消息

没有之前的提交就不能“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 reset -mixed在你想合并的多次提交之前恢复一个基本版本,然后我做一个新的提交,这样可以让你提交最新的版本,确保你推送到服务器后你的版本是HEAD。

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 reset --mixed 249cf9392da197573a17c8426c282

“249cf9392da197573a17c8426c282”是第三个版本,也是你合并之前的基础版本,在那之后,我做了一个新的提交:

git add .
git commit -m 'some commit message'

希望对每个人来说都是另一种方式。

供参考,从git重置——帮助:

 --mixed
     Resets the index but not the working tree (i.e., the changed files are
     preserved but not marked for commit) and reports what has not been
     updated. This is the default action.

Rebase:你不需要它:

对于最常见的场景,这是一种更简单的方法。

在大多数情况下:

实际上,如果你想要的只是简单地将最近的几次提交合并成一个,而不需要删除,重写和其他rebase工作。

你可以简单地做:

git reset --soft "HEAD~n"

假设~n是软取消提交的提交数(即~1,~2,…)

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

git commit --amend

这和长范围的壁球和单挑是差不多的。

它适用于n次提交,而不是像上面提示的那样只适用于两次提交。