As you embark on a new project, be it to build something new or to make incremental changes to something existing, make differences between each set of changes really small. Make small diffs, in other words.
It's easy to say but can be hard to do. Sometimes it's very difficult to express a large change as a series of small steps. It takes discipline to keep a checkpoint of each set of small changes that result in a much bigger change. But it's that discipline we should strive for.
As I work on a large change, say a fundamental redesign of architecture or
refactoring a library, I think of the final outcome first. Then I imagine what
git diff would look like from when I start to when I am done. I break down
that diff into logical pieces. Recursively, I break down each subsequent
diff into even smaller pieces. Eventually I get a lot of small pieces to
implement one after the other.
The strategy of breaking down the largest diff into many smaller diffs does not always go to plan. As I implement the first small diff I learn more about the flaws in my understanding or my design. I correct course and the next small diff represents this course correction. The final result is still intact in this progression but each step allows me to reverse or correct previous changes with the smallest of risk. I feel easy throwing away, say a couple hours of work, knowing I may have saved myself days of work later.
Sometimes I go three or four steps forward before taking a checkpoint. For
example, I might implement a small diff, then build on it, and build some
more, and so on. At the end of these series of small diffs, I take stock of
my status. I then
git commit the first small diff, then the next, and you
get the idea. It allows me to more easily group changes into logical
collections and/or steps. This means that you don't have to commit after every
few hours or after every few whatever. Commit when you're good and ready. But
make each commit as small and as narrow as possible.
The key to my successful use of this strategy is to seldom end my work day
without committing all diffs made that day. I like to end each day with an
git diff and an empty browser. I document things while they are
fresh in my mind. I bookmark useful pages in the browser. I Slack my friends
interesting findings during the course of the day. I close all applications and
all windows before letting my machine go to sleep. The next day I am ready to
start making more small diffs with a fresh mind and a clean workspace.