My biggest issue with squashing everything is that every non-trivial development necessarily composes of three types of changes:
- functional changes (changes functionality as visible from outside),
- refactorings (changes how application works internally)
- reformatting (does not change the compiled paths but improves readability).
Now, there is very good case for keeping these types of changes separate.
For example, when I want to change something I may want to first refactor it (to bring the code to a state where the functional change can be done easier and is more clearly correct), then I will make separate commit/commits to modify the code functionally, then I will possibly follow with more changes to "clean up" -- refactor the code using my newly acquired knowledge.
I always mark refactorings / reformat by starting the commit message with the word 'refactoring' or 'reformatting' so that any reviewer can easily see that these commit are not allowed any functional changes (and if I made one it means I made a mistake).
What this means is that the functional changes are as light and to the point as possible, not burdened with unrelated changes. It makes it much easier to review and ensure they are correct when I "tell" the reviewer which parts of the change are intended to modify functionality and which are just housekeeping.
That information obviously vanishes if you squash everything together.
**
Another big problem with squashing commits is that they become very large.
I find it makes much more sense to compose a large change from smaller, simple, logical, understandable changes that each produces (hopefully) working application.
If you find a problem with the commit (for example as a result of bisecting to find where something was introduced) it is much easier to understand what the change intended and compare this with the actual code modification to figure out where I failed.
Obviously, when you squash it the information is gone.
- functional changes (changes functionality as visible from outside),
- refactorings (changes how application works internally)
- reformatting (does not change the compiled paths but improves readability).
Now, there is very good case for keeping these types of changes separate.
For example, when I want to change something I may want to first refactor it (to bring the code to a state where the functional change can be done easier and is more clearly correct), then I will make separate commit/commits to modify the code functionally, then I will possibly follow with more changes to "clean up" -- refactor the code using my newly acquired knowledge.
I always mark refactorings / reformat by starting the commit message with the word 'refactoring' or 'reformatting' so that any reviewer can easily see that these commit are not allowed any functional changes (and if I made one it means I made a mistake).
What this means is that the functional changes are as light and to the point as possible, not burdened with unrelated changes. It makes it much easier to review and ensure they are correct when I "tell" the reviewer which parts of the change are intended to modify functionality and which are just housekeeping.
That information obviously vanishes if you squash everything together.
**
Another big problem with squashing commits is that they become very large.
I find it makes much more sense to compose a large change from smaller, simple, logical, understandable changes that each produces (hopefully) working application.
If you find a problem with the commit (for example as a result of bisecting to find where something was introduced) it is much easier to understand what the change intended and compare this with the actual code modification to figure out where I failed.
Obviously, when you squash it the information is gone.