简体   繁体   English

推送后如何压缩 git 中的提交?

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

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?如何压缩本地和远程存储库中最近的几次提交?

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 cx cc 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 pick commit.其中 2f40 是pick提交。 And now none of the 4 commits appear in git log .现在,4 个提交都没有出现在git log中。 I expected my editor to be restarted so that I could enter a commit message.我希望我的编辑器会重新启动,以便我可以输入提交消息。 What am I doing wrong?我究竟做错了什么?

Squash commits locally with壁球在本地提交

git rebase -i origin/master~4 master

and then force push with然后用力推

git push origin +master

Difference between --force and + --force+之间的区别

From the documentation of git push :git push的文档中:

Note that --force applies to all the refs that are pushed, hence using it with push.default set to matching or with multiple push destinations configured with remote.*.push may overwrite refs other than the current branch (including local refs that are strictly behind their remote counterpart).请注意, --force适用于所有被推送的引用,因此将它与push.default设置为matching或配置为remote.*.push的多个推送目标一起使用可能会覆盖当前分支以外的引用(包括本地引用严格落后于他们的远程对手)。 To force a push to only one branch, use a + in front of the refspec to push (eg git push origin +master to force a push to the master branch).要强制只推送到一个分支,请在 refspec 前使用+来推送(例如git push origin +master强制推送到master分支)。

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

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 pick with squash at the top for all the commits that you want to squash.在打开的交互式屏幕上,将顶部的pick替换为squash以获取您想要压缩的所有提交。
  • Save and close the editor保存并关闭编辑器

Push to the remote using:使用以下命令推送到远程:

$ git push origin branch-name --force

A lot of problems can be avoided by only creating a branch to work on & not working on master :很多问题可以通过只创建一个branch来工作而不是master上工作来避免:

git checkout -b mybranch

The following works for remote commits already pushed & a mixture of remote pushed commits / local only 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 notes which may be helpful.我也有一些可能会有所帮助的拉取请求说明

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

this will fixup all the commits to one commit and will remove all the other commits .这会将所有提交修复为一个提交,并将删除所有其他提交。 I did this and it helped me.我这样做了,它帮助了我。

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; HEAD~4 表示压缩最近的四个提交; interactive mode (-i)交互模式 (-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)

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.默认情况下,这将包括最新提交的提交消息作为对旧提交的评论。

When you are working with a Gitlab or Github you can run in trouble in this way.当您使用 Gitlab 或 Github 时,您可能会以这种方式遇到麻烦。 You squash your commits with one of the above method.您使用上述方法之一压缩您的提交。 My preferite one is:我最喜欢的是:

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

select squash or fixup for yours commit.为您的提交选择 squash 或 fixup。 At this point you would check with git status.此时,您将使用 git status 进行检查。 And the message could be:消息可能是:

    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 THAT or 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. + 允许强制推送到一个分支。

Sqush Changes in remote Sqush 远程更改

  • First ensure your local master is at par with remote首先确保您的本地主机与远程主机相同
  • Then reset your local feature branch to be at par with master: git reset --soft master然后将您的本地功能分支重置为与 master 相同: git reset --soft master
  • then add all your modifications and changes (that you made on your local feature branch you just reset to master) to staging area: git add .然后将所有修改和更改(您在刚刚重置为 master 的本地功能分支上所做的)添加到暂存区域: git add .
  • then commit these changes: git commit -m "this is the final commit message"然后提交这些更改: git commit -m "this is the final commit message"
  • then force push to remote branch: git push RemoteBranch --force然后强制推送到远程分支: git push RemoteBranch --force

In my case requirement was to squash all the feature branch commits into one, to have a clean commit history.在我的情况下,要求是将所有功能分支提交压缩为一个,以拥有干净的提交历史记录。 Utilized the GitHub UI to do so.利用 GitHub UI 来做到这一点。

Problem:问题:

  • Feature branch (eg:featureBranch) has been created from master (a month ago).功能分支(例如:featureBranch)已从 master(一个月前)创建。
  • Committed all my changes to the featureBranch (~12 commits, a month of work).提交我对 featureBranch 的所有更改(约 12 次提交,一个月的工作)。 And has been pushed to remote regularly.并定期被推送到远程。

Requirement:要求:

  • To Get the feature branch updated with the master and to have a single commit in a featureBranch使用 master 更新功能分支并在 featureBranch 中进行一次提交

Steps followed:后续步骤:

  • Create a new branch (eg: featureBranchLatest) from master in GitHub UI.在 GitHub UI 中从 master 创建一个新分支(例如:featureBranchLatest)。
  • Create a PR from featureBranch to featureBranchLatest.创建一个从 featureBranch 到 featureBranchLatest 的 PR。
  • Resolve conflicts if any.如果有冲突,请解决。 Merge the PR with the squash commit option in GitHub UI.将 PR 与 GitHub UI 中的 squash 提交选项合并。 (Alter the commit message to have a cleaner message). (更改提交消息以获得更清晰的消息)。

Now the featureBranchLatest will have a single commit of all the changes needed in a single commit, along with the latest changes from the master.现在,featureBranchLatest 将在单个提交中包含所有所需更改的单个提交,以及来自 master 的最新更改。 Delete the old branch featureBranch if not required for reference.如果不需要参考,请删除旧分支 featureBranch。

For whom might be interested, this is how it looks like when you squash commits in GitHub PR.对于谁可能感兴趣,这就是您在 GitHub PR 中压缩提交时的样子。

Before:前: 在此处输入图像描述

After:后:

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM