In the previous blog post I explained my preferred way of commit messages, closely related to this is the way of how to actually commit these changes. In the end you want the changes to be available on the main branch, but there are may possible ways to get there. In this blog post I will explain some possibilities and which I prefer.
The easiest way is obviously to just using a single master branch and directly commit everything on there. The downsides of this approach are that you can’t do any peer review before the code is merged and collaborating becomes harder in general. Merging changes will also becomes more cumbersome as the master branch changes a lot and often, meaning you constantly have to keep merging the changes into your local branch. Having a separate branch for your changes is the solution to all of these problems.
Just like my commit messages, I choose the branch name according to the issue the changes are for. While this usually isn’t strictly necessary because tools like Jira will use commit messages rather than branch names, it still allows humans to more easily track and trace changes.
A branch should always start from the latest master version to avoid unnecessary merge conflicts in the end. For the same reason, it is essential that a branch does not live too long, but frequent merges into the master branch take place. This should also make code review, if any is done, a lot easier. Even if the issue that is being worked on is quite large, and completing it will take several days, small frequent merges are essential. After each merge work can start again from the latest master version. It is however critical that all the small changes still compile and do not break anything else, they should form a whole.
Even if you don’t want to bother others with many code reviews as work is still in progress you should do small frequent commits with expressive commit messages. When trying to merge these commits you can either merge as is, or you can squash all of these commits. Squashing commits keeps your history on the main branch cleaner, as it removes intermediate states of the code. These intermediate states however can sometimes be useful, and therefore I don’t have a strict view on this. Either you keep it, or you squash it.
Another approach is to avoid merging and doing cherry picks, this avoids having merge commits but still contains the possible problems of conflicts. I don’t see why anyone would be choosing a cherry pick over a merge to merge into the master branch. Cherry picks are good if you need a single commit to be moved or copied to a different branch, I would only advise this for release branches that need to be supported. Cherry picks still cause potential conflicts and overdoing it, like everything in Git will make it a lot harder to maintain everything.