I recently read Git Organized: A Better Git Flow, and I find myself disagreeing strongly with its philosophy. Now, I am not hating on this article, but it does nicely sum up what I see as a systemic problem when it comes to developers in general. So, while I am going to be responding to its points directly, please do not read this as an individual attack, but rather as a response to that mindset.
Now, I take issue with two concepts brought up in the article and I would like to discuss them here. These are the shifting of effort around without any real savings, and discipline (or lack thereof).
The problem the author discusses is of a commit that contains changes (usually bugfixes) unrelated to the topic of the branch. Their suggestion breaks a few fundamentals tenets of programming, namely that commits should be as small as possible (small, logical units of work), and that a branch should stick to its topic. Now, you would not work on two tickets in the same branch, or if you had to switch between tickets, you would also switch branches. This same discipline should be applied if you come across an unrelated bug.
Let us try a thought experiment: You are using this system and, during your development, come across a dozen unrelated bugs, spanning multiple files. You work on these within your branch and, while consolidating at the end, you forget about one of them (or worse, you forget about part of one of them). Humans are fallible and it is possible to simple overlook one of these fixes. If you had isolated the fix immediately, you would not have to remember all the bugfixes you made. Branches in Git are cheap, but if you do not want to stash your work and switch to a new branch, you could clone the repository to a different directory and do the work there. There is just less overall cognitive load fixing the problem in-place than retaining all the changes you made so you can separate them out at the end. And if you thought ‘I’ll just make a note’, well that is even more effort than fixing it in place.
Quite simply, a PR should not contain any code unrelated to its topic, even if that code is isolated to its own commit. If I come across such unrelated code in a PR, I reject it.
It is true that development can be messy, and it can sometimes be difficult to make clean, clear commits. Of course, it is much easier if you are doing TDD (you are doing TDD right?). But even if you are not, most of your commits should be logical units of work. Just because some of them cannot be, does not mean you should throw away the idea altogether.
Every profession requires some amount of discipline and programming is no exception. Stop inventing systems that undercut that discipline. I am all for systems that guard against the fallibility of programmers, but not ones that make us lazier and, in the case of this system, undermine those safeguards and ultimately make more work.
The article frames a programmer as an artist, furiously applying paint to a canvas before the muse abandons them. It then suggests the programmer take another pass at the work to ‘sort it all out’. That system may work for you if your changes are small, but it fails when they span disparate parts of a file (or worse, multiple files). And what if you made multiple changes to the same line? Plus, it can be difficult to recall what you meant during that ‘frenzied’ process, especially for a long-lived branch.
The article also mentions using some advanced Git (reflog, mixing commits and, most likely, interactive commits). Why? While there is nothing wrong with knowing how to use these features, it simple is not necessary if you apply some discipline. Besides, I find interactive commits unpleasant, and something best avoided unless absolutely necessary. The article recommends creating non-broken commits and using stash in this second pass, so why not just use these while you do your initial work? Why work twice?
Coming up with some system to deal with a lack of personal discipline is never going to work. I can understand systems that exist to guard against mistakes and the inevitable fallibility of being human, but when a little discipline is a viable solution, I argue that it is the right solution.
As a developer you should take an active interest in your career. Wherever an opportunity for self-improvement presents itself, do it. No matter how many systems you employ, you ultimately must still do the thinking and problem-solving. All these systems do is reduce your self-discipline.
A disciplined mind is a sharper mind.