| Something people don't get about commits is they have multiple purposes. A lot of this is due to still entrenched assumptions and practices from older, inferior version control systems. There are at least two types of commit in git: a savepoint and a version. A savepoint is what happens during development on a branch. Git makes it super easy to make many, many savepoints throughout the day. These help you as a developer because it gives you something to fall back on if you make a mistake. But most of them should never be exposed to anyone not directly working on the branch. A version is what you share with others. A version is a fully working version of the software that can be reasonably checked out and put through a release process at any time. Usually a version will be unit tested but not subject to the same rigorous tests as a release. There is a direct analogy here with database transactions. Just replace version with transaction. Often while working you will find it's possible to write the version commit right away. This is usually for more trivial fixes or in some cases when a commit is required for something like a database migration (when things need to be deployed in stages). Other times you will need to make several savepoints before you get to a new version. This is what rebase is for. Many of those savepoints don't belong on the master branch as they are often fixing stuff you haven't even committed to master yet. Git has a few tools to help you defer rebasing until later. In particular you can make fixup and squash commits. These will be normal savepoint commits, but they will be labelled in a way that later you can issue an "autosquash" command to automatically rebase these into version commits. |
Git provides a DAG and you can use a --no-ff merge to build your "version commit" from the sub history of its "savepoints". You can follow one parent of the merge to the next "version commit" or you can follow the other parent through the intermediate "savepoints" that built it step by step.
You can use --first-parent today for most git operations to get "clean views" no matter how complex the DAG web is beyond it. I think a lot of these debates would "go away" if more people and user interfaces defaulted to --first-parent and "drill down" navigation rather than firehose of the complete graph and confusing (but pretty) "subway diagrams".