如果我已经开始变基,如何将两个提交合并为一个?
我试图将 2 个提交合并为 1 个,所以我遵循 “使用 rebase 压缩提交”来自 git read。
我
git rebase --interactive HEAD~2
在生成的编辑器中运行,将 pick
更改为 squash
,然后保存退出,但变基失败并出现错误
没有先前的提交就无法“挤压”
现在我的工作树已达到此状态,我在恢复时遇到了困难。
命令 git rebase --interactive HEAD~2 失败并显示:
交互式变基已开始
,git rebase --continue
失败并显示
没有先前的提交就无法“挤压”
I am trying to merge 2 commits into 1, so I followed “squashing commits with rebase” from git ready.
I ran
git rebase --interactive HEAD~2
In the resulting editor, I change pick
to squash
and then save-quit, but the rebase fails with the error
Cannot 'squash' without a previous commit
Now that my work tree has reached this state, I’m having trouble recovering.
The command git rebase --interactive HEAD~2
fails with:
Interactive rebase already started
and git rebase --continue
fails with
Cannot 'squash' without a previous commit
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(15)
摘要
错误信息
意味着您可能试图“向下挤压”。 Git 总是将较新的提交压缩到较旧的提交 或“向上”(如交互式变基待办事项列表中所示),即压缩到上一行的提交中。将待办事项列表第一行上的命令更改为
squash
总是会产生此错误,因为第一次提交没有任何内容可以压缩。修复
首先回到您开始的位置
假设您的历史记录是
也就是说,a 是第一次提交,然后是 b,最后是 c。提交 c 后,我们决定将 b 和 c 压缩在一起:
(注意:运行
git log
将其输出传输到分页器中,less
。要退出寻呼机并返回命令提示符,请按q
key。)运行 git rebase --interactive HEAD~2 会为您提供一个编辑器
(请注意,与 git log 的输出相比,此待办事项列表的顺序相反。)
将 b 的
pick
更改为squash
将导致您看到的错误,但如果您将 c 压缩到 b (较新的提交到较旧的或“压缩向上”)通过将待办事项列表更改为并保存退出编辑器,您将得到另一个编辑器,其内容为
当您保存并退出时,编辑文件的内容将成为新组合提交的提交消息:
关于重写历史记录的注意事项
交互式变基重写历史。尝试推送到包含旧历史记录的远程将会失败,因为它不是快进。
如果您重新建立的分支是您自己工作的主题或功能分支,那么没什么大不了的。推送到另一个存储库将需要
--force
选项,或者您也可以根据远程存储库的权限,首先删除旧分支,然后推送重新设置基础的版本。这些可能会破坏工作的命令的示例超出了本答案的范围。在您与其他人合作的分支上重写已发布的历史记录,而没有充分的理由(例如泄露密码或其他敏感详细信息)会迫使您的合作者承担工作,这是反社会的,并且会惹恼其他开发人员。
git rebase
文档中的 “从上游 Rebase 恢复”部分 解释道,并强调了这一点。Summary
The error message
means you likely attempted to “squash downward.” Git always squashes a newer commit into an older commit or “upward” as viewed on the interactive rebase todo list, that is into a commit on a previous line. Changing the command on your todo list’s very first line to
squash
will always produce this error as there is nothing for the first commit to squash into.The Fix
First get back to where you started with
Say your history is
That is, a was the first commit, then b, and finally c. After committing c we decide to squash b and c together:
(Note: Running
git log
pipes its output into a pager,less
by default on most platforms. To quit the pager and return to your command prompt, press theq
key.)Running
git rebase --interactive HEAD~2
gives you an editor with(Notice that this todo list is in the reverse order as compared with the output of
git log
.)Changing b’s
pick
tosquash
will result in the error you saw, but if instead you squash c into b (newer commit into the older or “squashing upward”) by changing the todo list toand save-quitting your editor, you'll get another editor whose contents are
When you save and quit, the contents of the edited file become commit message of the new combined commit:
Note About Rewriting History
Interactive rebase rewrites history. Attempting to push to a remote that contains the old history will fail because it is not a fast-forward.
If the branch you rebased is a topic or feature branch in which you are working by yourself, no big deal. Pushing to another repository will require the
--force
option, or alternatively you may be able, depending on the remote repository’s permissions, to first delete the old branch and then push the rebased version. Examples of those commands that will potentially destroy work is outside the scope of this answer.Rewriting already-published history on a branch in which you are working with other people without very good reason such as leaking a password or other sensitive details forces work onto your collaborators and is antisocial and will annoy other developers. The “Recovering From an Upstream Rebase” section in the
git rebase
documentation explains, with added emphasis.如果有多个提交,您可以使用 git rebase -i 将两个提交压缩为一个。
如果您只想合并两个提交,并且它们是“最近的两个”,则可以使用以下命令将两个提交合并为一个:
If there are multiple commits, you can use
git rebase -i
to squash two commits into one.If there are only two commits you want to merge, and they are the "most recent two", the following commands can be used to combine the two commits into one:
Rebase:你不需要它:
针对最常见场景的更简单的方法。
在大多数情况下:
实际上,如果您想要的只是简单地将最近的几个提交合并为一个,但不需要
drop
、reword
和其他rebase工作。您可以简单地执行以下操作:
~n
是软取消提交的提交次数(即~1
、~2
,...)然后,使用以下命令修改提交消息。
这与大范围的
squash
和一个pick
几乎相同。它适用于 n 次提交,但不仅仅适用于上面答案提示的两次提交。
Rebase: You Ain't Gonna Need It:
A simpler way for most frequent scenario.
In most cases:
Actually if all you want is just simply combine several recent commits into one but do not need
drop
,reword
and other rebase work.you can simply do:
~n
is number of commits to softly un-commit (i.e.~1
,~2
,...)Then, use following command to modify the commit message.
which is pretty much the same as a long range of
squash
and onepick
.And it works for n commits but not just two commits as above answer prompted.
首先你应该检查你有多少次提交:
有两种状态:
一种是只有两次提交:
例如:(
在这种情况下,你不能使用 git rebase 来做)你需要执行以下操作。
另一个是有两次以上的提交;你想合并提交C和D。
例如:(
在这种情况下,你可以使用git rebase)
而不是使用“squash”来做。剩下的瘦身就很容易了。如果你还不知道,请阅读 http://zerodie.github.io /博客/2012/01/19/git-rebase-i/
First you should check how many commits you have:
There are two status:
One is that there are only two commits:
For example:
(In this case, you can't use git rebase to do) you need to do following.
Another is that there are more than two commits; you want to merge commit C and D.
For example:
(under this condition, you can use git rebase)
And than use "squash" to do. The rest thins is very easy. If you still don't know, please read http://zerodie.github.io/blog/2012/01/19/git-rebase-i/
假设您在自己的主题分支中。如果您想将最后 2 个提交合并为一个并看起来像个英雄,请在进行最后两个提交之前分支该提交(使用相对提交名称 HEAD~2 指定)。
然后压缩提交这个新分支中的另一个分支:
这将引入更改但不提交它们。因此,只需提交它们即可。
现在您可以将此新主题分支合并回主分支。
Assuming you were in your own topic branch. If you want to merge the last 2 commits into one and look like a hero, branch off the commit just before you made the last two commits (specified with the relative commit name HEAD~2).
Then squash commit the other branch in this new branch:
That will bring in the changes but not commit them. So just commit them and you're done.
Now you can merge this new topic branch back into your main branch.
取消变基
您可以使用'squash; ,并且当您再次运行交互式变基命令时提交必须位于列表中选择提交的下方
you can cancel the rebase with
and when you run the interactive rebase command again the 'squash; commit must be below the pick commit in the list
$ git rebase --abort
如果您想撤消 git rebase,请随时运行此代码
$ git rebase -i HEAD~2
重新应用最后两次提交。上面的命令将打开一个代码编辑器
致力于壁球。因为挤压将与之前的提交合并。
在 :wq 之后,您将处于活动变基模式
注意:您将得到另一个编辑器如果没有警告/错误消息,如果有错误或警告另一个编辑器不会显示,您可以通过运行中止
$ git rebase --abort
如果您看到错误或警告,否则只需运行$ git rebase --continue
即可继续,您将看到您的 2 次提交消息。选择一个或编写您自己的提交消息,保存并退出 [:wq]
注释 2: 如果运行 rebase 命令,您可能需要将更改强制推送到远程存储库
$ git Push -f
$ git Push -f origin master
$ git rebase --abort
Run this code at any time if you want to undo the git rebase
$ git rebase -i HEAD~2
To reapply last two commits. The above command will open a code editor
commit to squash(s). Since squash will meld with previous commit.
After :wq you will be in active rebase mode
Note: You'll get another editor if no warning/error messages, If there is an error or warning another editor will not show, you may abort by runnning
$ git rebase --abort
if you see an error or warning else just continue by running$ git rebase --continue
You will see your 2 commit message. Choose one or write your own commit message, save and quit [:wq]
Note 2: You may need to force push your changes to the remote repo if you run rebase command
$ git push -f
$ git push -f origin master
我经常使用 git reset --mixed 在您想要合并的多个提交之前恢复基本版本,然后我进行一个新的提交,这样可以让您的提交最新,确保您的版本是 HEAD 之后你推送到服务器。
如果我想将两个提交合并为一个,首先我使用:
“249cf9392da197573a17c8426c282”是第三个版本,也是合并之前的基本版本,之后,我进行一个新的提交:
就这样了,希望对每个人来说都是另一种方式。
仅供参考,来自
git reset --help
:I often use git reset --mixed to revert a base version before multiple commits which you want to merge, then I make a new commit, that way could let your commit newest, assure your version is HEAD after you push to server.
If I want to merge head two commits into one, first I use :
"249cf9392da197573a17c8426c282" was third version, also is your base version before you merge, after that, I make a new commit :
It's all, hope is another way for everybody.
FYI, from
git reset --help
:如果您想将多个提交压缩在一起,则可以使用交互式变基方法来实现。 (感谢 Mads 教我这一点!)
git rebase origin/develop -i
在 git rebase-interactive 模式 (vim) 下的专业提示:
ciw
- (更改内部单词)将更改光标下的整个单词。s
表示挤压wq
写得很安静,您就完成了。然后
git push -f
If you have several commits you'd like to squash together, you can do so using the interactive rebase method. (Thanks Mads for teaching me about this!)
git rebase origin/develop -i
Pro-tip when in git rebase-interactive mode (vim):
ciw
- (change inner word) will change the whole word under the cursor.s
for squashingwq
write quite, you are done.then
git push -f
由于我几乎所有事情都使用 gitcherry-pick ,所以对我来说,即使在这里这样做也是很自然的。
鉴于我已签出
branchX
,并且在其顶端有两个提交,其中我想创建一个结合其内容的提交,我会这样做:如果我想更新
branchX
(我想这是这个方法的缺点)我还必须:Since I use
git cherry-pick
for just about everything, to me it comes natural to do so even here.Given that I have
branchX
checked out and there are two commits at the tip of it, of which I want to create one commit combining their content, I do this:If i want to update
branchX
as well (and I suppose this is the down side of this method) I also have to:如果您的主分支 git log 看起来如下所示:
并且您想要合并前两个提交,只需执行以下简单步骤:
git checkout 77df2a40e53136c7a2d58fd847372 -b merged-commits
gitcherry-pick -n -x ac72a4308ba70cc42aace47509a5e
。 (如果出现任何冲突,请解决)就是这样。如果您愿意,您可以将这个合并版本推送到分支“merged-commits”中。
另外,您现在可以放弃主分支中连续的两次提交。只需将您的主分支更新为:
If your master branch
git log
looks something like following:and you want to merge the top two commits just do following easy steps:
git checkout 77df2a40e53136c7a2d58fd847372 -b merged-commits
git cherry-pick -n -x ac72a4308ba70cc42aace47509a5e
. (Resolve conflicts if arise any)git commit --amend
.That's it. You may push this merged version in branch "merged-commits" if you like.
Also, you can discard the back-to-back two commits in your master branch now. Just update your master branch as:
要在完成所有操作(即压缩提交)后添加@greg的答案,如果您执行 git push (原始提交将保留在分支中),而如果您执行 git push -f origin 则提交将被删除。
例如,如果您执行 git push,您将合并提交 B 和提交 C,您将拥有提交 B、提交 C 和提交 BC,但如果您执行 git push -f origin,您将只有提交 BC
To add to @greg's answer after you are done with everything i.e. squashing the commits, if you do git push (the original commits will remain in the branch) whereas if you do git push -f origin the commits will be deleted.
Eg- you combined commit B and commit C if you do git push you will have commit B, commit C and commit BC, but if you do git push -f origin you will only have commit BC
好的,
Okay, So
如果您想合并两个最近的提交并仅使用较旧的提交消息,您可以使用 < 自动化该过程代码>期望。
我假设:
我使用 git version 2.14.3 (Apple Git-98) 进行了测试。
If you want to combine the two most recent commits and just use the older commit's message, you can automate the process using
expect
.I assume:
I tested with
git version 2.14.3 (Apple Git-98)
.让我建议您一个更简单的方法,
您可以执行以下操作,而不是深入了解 GIT 的深层概念并为编辑的螃蟹烦恼;
假设您从 master 创建了一个名为 bug1 的分支。对 bug1 进行了 2 次提交。您仅通过这些更改修改了 2 个文件。
将这两个文件复制到文本编辑器中。结账师傅。粘贴文件。犯罪。
就这么简单。
Let me suggest you an easier approach,
Instead of divind into GIT's deep consepts and bothering with the editor's crab, you could do the following;
Lets suppose you created a branch named bug1 from master. Made 2 commits to bug1. You only modified 2 files with these changes.
Copy these two files into a text editor. Checkout master. Paste the files. Commit.
That simple.