Skip to content

Git: Squash commits

When merging your work into another branch, it may be useful to regroup all the commits into one and indicate a clear commit message that says what has been done.

Initial Setup

Working on a new feature while develop continued evolving.

* a78d2b1 (HEAD -> develop) feat: other god feature
* 7a5c8fb feat: hell of a feature
| * ca5ee3c (feature/awesome-feature) found solution for config
| * aff1a6c fucked up config
| * 24aaa34 do some other shit
| * bc471b9 do some shit
|/  
* 9a6b2f1 feat: bar
* 3a74cdc (main) initial commit

Merge?

Even after a rebase, this will become messy:

* ca5ee3c (HEAD -> develop) found solution for config
* aff1a6c fucked up config
* 24aaa34 do some other shit
* bc471b9 do some shit
* a78d2b1 feat: other god feature
* 7a5c8fb feat: hell of a feature
* 9a6b2f1 feat: bar
* 3a74cdc (main) initial commit

Very ugly, not efficient!

Squash it baby!

1. git reset --soft

git checkout feature/awesome-feature
git reset --soft 9a6b2f1    # where 9a6b2f1 is the point you diverted from develop
git add .
git commit -m 'feat: awesome feature with good commit message'

Result:

* 51a726c (HEAD -> feature/awesome-feature) feat: awesome feature with good commit message
| * 2abdf42 (develop) feat: other god feature
| * 7a5c8fb feat: hell of a feature
|/  
* 9a6b2f1 feat: bar
* 3a74cdc (main) initial commit

2. git rebase

git checkout develop
git pull    # make sure develop is up to date
git checkout feature/awesome-feature
git rebase develop

Result:

* de09afd (HEAD -> feature/awesome-feature) feat: awesome feature with good commit message
* a78d2b1 (develop) feat: other god feature
* 7a5c8fb feat: hell of a feature
* 9a6b2f1 feat: bar
* 3a74cdc (main) initial commit

Note

Rebasing will also become much easier as there will only be ONE commit to replay
And not the WHOLE history

3. git merge

git checkout develop
git merge feature/awesome-feature   # and use the same good commit message as above

Result:

* de09afd (HEAD -> develop, feature/awesome-feature) feat: awesome feature with good commit message
* a78d2b1 feat: other god feature
* 7a5c8fb feat: hell of a feature
* 9a6b2f1 feat: bar
* 3a74cdc (main) initial commit

4. Cleanup

git branch -d feature/awesome-feature

Result:

* de09afd (HEAD -> develop) feat: awesome feature with good commit message
* a78d2b1 feat: other god feature
* 7a5c8fb feat: hell of a feature
* 9a6b2f1 feat: bar
* 3a74cdc (main) initial commit

In short

# squash
git checkout __feature/branch__
git reset --soft __latest_common_parent__
git add .
git commit -m '__good_commit_message__'

# rebase
git checkout __base/branch__
git pull
git checkout __feature/branch__
git rebase __base/branch__

# merge
git checkout __base/branch__
git merge __feature/branch__

# cleanup
git branch -d __feature/branch__

And don't forget to push your commit !

Note

You can use git-merge-base to find the latest common commit of two branches.
See Git: Find latest common ancestor of two branches

Comments