I find it challenging to keep commits consistent and perfectly segmented. My original reasoning was a lack of discipline on my end. But over time, I discovered that I am the majority. My new conclusion is it's not me. It's git's fault.
Human brains function in vastly different ways among the population. Some are logical; some are sensitive, and some are more organised than others.
Astrology can explain it all. The two forms of thinking that are related to this topic is divergent thinking and convergent thinking. If you are more of a divergent thinker, you might find ideas popping up in your head constantly (which is pretty annoying sometimes). That's because your brain works by association more. Input from the world, in the case of writing code, is mostly the existing codebase, combined with your past experiences with previous projects, which will generate ideas of how to solve your current tasks. And ideas will trigger more thoughts in a chaining fashion. That's why I often find myself ending up in a place that's nothing to do with the original task. And it's often too late when I realised that (i.e. progress has been made, but not finished). Sometimes there were multiple jumps. When I finish all the bits I started, that's when the biggest problem of the whole work comes in: writing a commit message. Here is an example of a very common commit message in my works.
fix issue #45 - add [aaa] support - improve ergonomics of API [bbb] - refactor [ccc] to [ddd] so that it fits in the eco-system - oh, package X just became multiple sub packages, we have an eco-system now
Solutions and Their Problems
I have made numerous attempts to improve the situation. Most of the ideas are from "industry best practices".
create branches for everything
This idea came early. Branching makes sense when you work with other people because you are working in parallel. Merging code and resolve conflicts is worth the effort in that scenario. You get the cost back easily from the progress gain due to parallelisation of your work. But it falls apart when the scope is about you and your thoughts. Yes, you are generating more ideas then you physically can keep up with your code, but you are still single-threaded processor. Merging old branches is not a fun activity.
I mean like very often! It's always a good idea to follow the first principle in any engineering problems. Breaking things down into atomic pieces and commit frequently is a sound solution. You also have the benefit of being able to revert specific changes quickly since they are small(er) and (more) atomic. I tried this for a while. The trick is to build up a habit of recognising boundaries and commit without procrastination. In practice, though, I find myself, more often than I would like to, going back changing the git history just to align with the principle. Maybe I should just accept that nobody is perfect, it's okay to mess things up from time to time. But that really demotivate me to keep doing it. Also, I have to constantly be aware of the situation at hand. That's extra brain energy I don't want to waste during heavy works.
My Current Solution
It's not a solution per se; it's more of a compromise. (Well, isn't that the nature of life 😉?) Or you can say I don't have a solution yet, and I am getting by with it.
breaking things down (or I try to)
I try to break things down to manageable size and commit as soon as the progress is granular. Sometimes it might be an entirely different task I was set out to do because of my divergent thinking nature.
keep track of everthing going on in my brain efficiently
I use one org-mode file (it's a plain text format for keeping notes and todo lists, you can use whatever works for you, even multiple apps) per project to document my thoughts, ideas, review them regularly, transform them into tasks, and document the progress. I try to keep the file with the repo, but sometimes I don't necessarily want to share my thought process with others, say a work-related repo, or an open-source one. Then it goes into my own knowledge base.
be stingy about branching
I know one of the biggest selling points of git is: branching is cheap. It depends on the reason for branching, as I described above. It is definitely not cheap in solo scenarios. So I only create branches when:
- It's the start of a new era. E.g. orgajs v1.0 -> v2.0. The whole thing will be gutted and refactored to death and brought back to life stronger.
- work with other people, of course. But when it's only me left in the conversation, I keep only one branch at a time. Context switching between multiple branches cost energy. Unless something urgent comes up, I normally don't do time-sharing based multitasking.
Hopefully, my story can help you optimise your productivity. Even if it doesn't work for you, I hope you can at least have one take away from it: don't try too hard to fit yourself into squares that others created, or feel bad when the "best practice" doesn't work for you, as long it gets the job done, your way is the best way.