Advertisement
Advertisement


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


Question

This gives a good explanation of squashing multiple commits:

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
# 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. 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?

2014/09/10
1
583
9/10/2014 12:06:13 AM

Accepted Answer

Squash commits locally with

git rebase -i origin/master~4 master

and then force push with

git push origin +master

Difference between --force and +

From the documentation of 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). To force a push to only one branch, use a + in front of the refspec to push (e.g git push origin +master to force a push to the master branch).

2019/10/11
827
10/11/2019 9:34:37 PM

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

git checkout my_branch
git reset --soft HEAD~4
git commit
git push --force origin my_branch
2015/09/16

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.
  • Save and close the editor through esc --> :wq

Push to the remote using:

$ git push origin branch-name --force
2017/12/22

A lot of problems can be avoided by only creating a branch to work on & not working on master:

git checkout -b mybranch

The following works for remote commits already pushed & a mixture of remote pushed commits / local only commits:

# 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.

2016/09/05

git rebase -i master

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

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).

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.

2017/09/26

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.

2018/10/23

Source: https://stackoverflow.com/questions/5667884
Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Email: [email protected]