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