提交后如何在 git 中压缩提交?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5667884/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 10:37:32  来源:igfitidea点击:

How to squash commits in git after they have been pushed?

gitsquash

提问by Loren

This gives a good explanation of squashing multiple commits:

这很好地解释了压缩多个提交:

http://git-scm.com/book/en/Git-Branching-Rebasing

http://git-scm.com/book/en/Git-Branching-Rebasing

but it does not work for commits that have already been pushed. How do I squash the most recent few commits both in my local and remote repos?

但它不适用于已经推送的提交。如何压缩本地和远程存储库中最近的几次提交?

EDIT:When I do git rebase -i origin/master~4 master, keep the first one as pick, set the other three as squash, and then exit (via c-x c-c in emacs), I get:

编辑:当我这样做时git rebase -i origin/master~4 master,将第一个保留为pick,将其他三个设置为squash,然后退出(通过 emacs 中的 cx cc),我得到:

$ git rebase -i origin/master~4 master
# Not currently on any branch.
nothing to commit (working directory clean)

Could not apply 2f40e2c... Revert "issue 4427: bpf device permission change option added"
$ git rebase -i origin/master~4 master
Interactive rebase already started

where 2f40 is the pickcommit. And now none of the 4 commits appear in git log. I expected my editor to be restarted so that I could enter a commit message. What am I doing wrong?

其中 2f40 是pick提交。现在 4 个提交都没有出现在git log. 我希望我的编辑器能够重新启动,以便我可以输入提交消息。我究竟做错了什么?

回答by Alan Haggai Alavi

Squash commits locally with

壁球在本地提交

git rebase -i origin/master~4 master

and then force push with

然后用力推

git push origin +master


Difference between --forceand +

--force和之间的区别+

From the documentation of git push:

从文档git push

Note that --forceapplies to all the refs that are pushed, hence using it with push.defaultset to matchingor with multiple push destinations configured with remote.*.pushmay overwrite refs other than the current branch (including local refs that are strictly behind their remote counterpart). To force a push to only one branch, use a +in front of the refspec to push (e.g git push origin +masterto force a push to the masterbranch).

请注意,这--force适用于所有被推送的引用,因此将它与push.defaultset tomatching或多个推送目标配置一起使用remote.*.push可能会覆盖当前分支以外的引用(包括严格落后于远程副本的本地引用)。要强制只推送到一个分支,请+在 refspec 前面使用 a进行推送(例如git push origin +master,强制推送到master分支)。

回答by jakob-r

On a branch I was able to do it like this (for the last 4 commits)

在一个分支上,我可以这样做(对于最后 4 次提交)

git checkout my_branch
git reset --soft HEAD~4
git commit
git push --force origin my_branch

回答by BLRBoy

Minor difference to accepted answer, but I was having a lot of difficulty squashing and finally got it.

与接受的答案略有不同,但我在挤压时遇到了很多困难,最终得到了它。

$ git rebase -i HEAD~4
  • At the interactive screen that opens up, replace pickwith squashat the top for all the commits that you want to squash.
  • Save and close the editor through esc --> :wq
  • 在打开的交互式屏幕上,将 顶部的pick替换为squash,用于您要压缩的所有提交。
  • 保存并关闭编辑器 esc --> :wq

Push to the remote using:

使用以下方法推送到遥控器:

$ git push origin branch-name --force

回答by Stuart Cardall

A lot of problems can be avoided by only creating a branchto work on & notworking on master:

很多问题可以通过只创建一个branch工作和工作来避免master

git checkout -b mybranch

git checkout -b mybranch

The following works for remotecommits already pushed & a mixture of remotepushed commits / localonly commits:

以下适用于remote已经推送的提交和remote推送提交/local仅提交的混合:

# example merging 4 commits

git checkout mybranch
git rebase -i mybranch~4 mybranch

# at the interactive screen
# choose fixup for commit: 2 / 3 / 4

git push -u origin +mybranch

I also have some pull request noteswhich may be helpful.

我还有一些拉取请求说明可能会有所帮助。

回答by Nupur

git rebase -i master

git rebase -i master

you will get the editor vm open and msgs something like this

您将打开编辑器 vm 并发送类似这样的消息

Pick 2994283490 commit msg1
f 7994283490 commit msg2
f 4654283490 commit msg3
f 5694283490 commit msg4
#Some message 
#
#some more

Here I have changed pick for all the other commits to "f" (Stands for fixup).

在这里,我已将所有其他提交的选择更改为“f”(代表修复)。

git push -f origin feature/feature-branch-name-xyz

git push -f origin feature/feature-branch-name-xyz

this will fixup all the commits to one commit and will remove all the other commits . I did this and it helped me.

这将修复一个提交的所有提交,并将删除所有其他提交。我这样做了,它帮助了我。

回答by Alex

When you are working with a Gitlab or Github you can run in trouble in this way. You squash your commits with one of the above method. My preferite one is:

当您使用 Gitlab 或 Github 时,您可能会以这种方式遇到麻烦。您可以使用上述方法之一压缩您的提交。我最喜欢的是:

git rebase -i HEAD~4
or
git rebase -i origin/master

select squash or fixup for yours commit. At this point you would check with git status. And the message could be:

为您的提交选择壁球或修复。此时,您将检查 git status。消息可能是:

    On branch ABC-1916-remote
    Your branch and 'origin/ABC-1916' have diverged,
    and have 1 and 7 different commits each, respectively.
      (use "git pull" to merge the remote branch into yours)

And you can be tempted to pull it. DO NOT DO THATor you will be in the same situation as before.

你可能会想拉它。不要这样做,否则您将处于与以前相同的情况。

Instead push to your origin with:

而是通过以下方式推送到您的原点:

git push origin +ABC-1916-remote:ABC-1916

The + allow to force push only to one branch.

+ 允许只强制推送到一个分支。

回答by lobsterhands

For squashing two commits, one of which was already pushed, on a single branch the following worked:

为了压缩两个提交,其中一个已经被推送,在单个分支上执行以下操作:

git rebase -i HEAD~2
    [ pick     older-commit  ]
    [ squash   newest-commit ]
git push --force

By default, this will include the commit message of the newest commit as a comment on the older commit.

默认情况下,这将包括最新提交的提交消息作为对旧提交的评论。

回答by terwxqian

1) git rebase -i HEAD~4

1) git rebase -i HEAD~4

To elaborate: It works on the current branch; the HEAD~4 means squashing the latest four commits; interactive mode (-i)

详细说明:它适用于当前分支;HEAD~4 表示压缩最近的四次提交;交互模式 (-i)

2) At this point, the editor opened, with the list of commits, to change the second and following commits, replacing pick with squash then save it.

2)此时,编辑器打开了提交列表,更改第二次及后续提交,将pick替换为squash然后保存。

output: Successfully rebased and updated refs/heads/branch-name.

输出:成功地重新定位和更新 refs/heads/branch-name。

3) git push origin refs/heads/branch-name --force

3) git push origin refs/heads/branch-name --force

output:

输出:

remote:
remote: To create a merge request for branch-name, visit:
remote: http://xxx/sc/server/merge_requests/new?merge_request%5Bsource_branch%5D=sss
remote:To ip:sc/server.git
 + 84b4b60...5045693 branch-name -> branch-name (forced update)