Why git squash merges are bad
von Felix Mößbauer
It's been a long time since my last block entry. Studying and being part of a research project at the same time does not leave much space for writing. However what I discovered during some years of daily software development is that many - even senior - software developers are not familiar with the workflow of git.
Disclaimer: If you are not familiar with git at all, read this article first:
So, back to topic:
Using Github's squash merge feature seems to be perfect to transform a wast amount of commits made during development of a feature into one single and tidy one. However this only holds in theory due to the following show-stoppers:
- all changes are owned by the member who merges
- complete loss of history
The first point is especially problematic if multiple authors committed to the
same branch. Later on it is very useful to check who implemented a line of code by
git blame. With squash merges this is not possible anymore!
squeezing code through CI
A common pro argument for squash merges arises from the antipattern of having
many small commits which countermand each other. This often happens if
developers try to get their changes through an online CI provider registered
as a post-commit hook on Github. However this problem can easily be lessened by
using a different test-branch (which can be safely deleted afterwards). There,
you can play around and use the CI to verify your implementation. If CI passes,
simply go to your feature branch and use
git checkout <test-branch> -- path/to/file
to copy the changes to your feature branch. Then, commit and push the feature branch.
Hopefully CI will pass now.
If you are the only developer on this branch, you can safely use
git reset --soft
to reset the commit log to a previous version, while keeping the changes in your
working copy. After committing them, you have to use
git push -f to force update
the remote branch. NEVER do this if anyone else has pulled your branch.
However I do not recommend this workflow!
clean commit history
So if you are really interested in a nice and clean commit history (which I desire), follow this recommendations:
- think before committing
- test before committing
- use a combination of
git checkoutto combine multiple commits on another branch
It's not the job ob Github to cleanup a ugly commit history. When implementing new features, do your work, but never "own" commits of other developers. After you have finished your the implementation, make a pull request, assign a reviewer which you think is capable of validating your changes and assign yourself as "assignee".