How to squash commits properly
- 5 minsGit
The most popular version control system is git
developed originally by Linus Torvalds. It is widely used by almost every developer around the world and probably a very few can use it properly, neither do I.
Rebasing/squashing commits
In a big project when you develop a on your own branch, committing regularly with small changes each time. This is useful and a good pattern to follow. Create some code, commit, push, repeat. Finally, when you finished and the feature is done, you can start thinking about merging your bracnh into master. But you’ve gathered 10+ commits and you don’t want those to be added to master. One commit stating that the feature was created would be sufficient enough. Using it on an example project:
git log --graph --pretty=oneline --abbrev-commit
* 55c3586 (HEAD -> master, origin/master, origin/HEAD) Merge pull request #2 from hollasch/hollasch/cmake-edit
|\
| * 2cc9046 Add navigation links from top-level readme
| * 7468866 Final edits of CMake lessons
| * a2ab07e Add nav links to CMake lessons
| * 8f443a7 Fix typo in directory name - dependencies
| * fe6960a Add CMake lesson links
| * 0dc4926 Light edit of lesson 0 README
| * d464769 Fix URL to CMake logo
| * 108a0b7 Wrap lines at 100 characters
|/
* 715c578 Fixed fix of fix
* be84121 Fixed bug in thread launch range slicing.
* 085f29f Fixed bug in thread launch iterator slicing.
* 734af80 Link to Threads::Threads
* 021475b Added C++14 requirement to C++ samples
* fd37cb5 Merge branch 'master' of https://github.com/Wigner-GPU-Lab/Teaching
|\
| * 229dc55 Added Matrix Multiplication benchmark sample code
| * 0a38219 Update AlgorithmDemo
| * dbcb762 AlgorithmDemo.cpp
| * 08a193a Fixed a copy-paste error in ode2.cu
* | cc150b7 C++ samples added, some cleanups
* | 26888ef Iniital File IO sample stub
|/
* b3224f1 Minor update
* 521c1a2 Added state monad demo
* 6b93148 Minor cleanup
* 2e2fb7c Minor change
-
First of all, you need to check the number of commits on your branch before starting the squashing process. I usually check this on
GitLab
since my company uses that butGitHub
and probabylBitBucket
is also capable of doing so. As a last resort, you can always count your commits from agit --log
-
Now start a reabase with assuming 12 commits counted:
git rebase -i HEAD~12
- This pops up a window such as this one:
pick f7f3f6d changed my name a bit
pick 310154e updated README formatting and added blame
pick a5f4a0d added cat-file
# Rebase 710f0f8..a5f4a0d onto 710f0f8
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out
- Update each
pick
statement tos
orsquash
in order to squash those into one commit. Make sure to leave out one of these commits and let it have the valuepick
.
pick f7f3f6d changed my name a bit
s 310154e updated README formatting and added blame
s a5f4a0d added cat-file
# Rebase 710f0f8..a5f4a0d onto 710f0f8
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out
- Save and exit your editor. I use ubuntu, so by default
nano
pops up in my terminal window.
-
After this you will need to edit the commit message. I usually comment out everything (
#
) and just leave a message insige that reperesent what the point of the branching was, e.g.: implementing feature-X or something like that. Save and exit. -
You will need to force push to your branch now to ‘rewrite history’. By some this is considered anti-pattern.
git push origin +branch-name
- Enjoy. Now you can merge.