Git and Revisionist Histories

24 Apr 2023 - Estimated reading time: 5 min

Most Hymans Robertson software delivery teams started using git for version control approximately five years ago. We migrated all our many applications, libraries, and services from TFS and said goodbye to waiting ten minutes for a branch to be created. But what did we say hello to? Here’s my personal reflection on what stands out now with five years of hindsight.

Git is hard! I don’t remember ever reading extensively about any source control system before I started using git. Having made the move, I found myself reading (more than once) the book Pro Git (available free online; a hefty 440 pages). Even after many years of using various source control systems (RCS, CVS, Subversion, Perforce, TFS, and on and on) there was git terminology that meant nothing to me.  I’d overhear colleagues talking a language that was alien to my ear: “You’ve got a detached head, so find the SHA of the commit you want; check that out and then do a fast-forward merge with a Triple Salchow to finish”. What?!

The past is immutable. Or, at least, that’s how I liked my source control history to be. I wanted complete fidelity with regard to what changes were made and when. Did it take you fifteen commits to resolve that PowerShell script error? Fine, we should see fifteen commits in the history. Were there seven features being worked on concurrently? Fine, we should see the interleaved commits of those seven features in the history.

Git, however, has turned me into a revisionist historian. The directed acyclic graph of commits that form the history in git can easily become too complicated for a human to parse. Given that, I have now ditched my attachment to immutable and full-fidelity history in favour of the cleaner, linear fiction made possible by rebasing and squash commits (although don’t, for the love of Torvalds, squash commit between two long-lived branches!).

There is a commonly held belief in software engineering that real engineers use the command line. I don’t share that belief, but I do favour the command line for interacting with git.

David Boyle - Hymans Robertson

And this is because git is like the Lloyd’s of London building. All the ducting, pipework, wiring, and other internals are visible. If you’re using a tool that forms a layer of abstraction over git (such as the source control operations within an IDE) then often these git internals pop up in dialog boxes in ways that are more confusing than if it were the direct consequence of a git command issued at the command line. I also find myself using git fetch followed by a merge, rather than a pull, just to remind myself that you have not two but three branches in play when pushing and pulling changes between repos.

The greatest irony of my five years with git, given that its killer feature is fast branch creation, is that it has confirmed in me the sense that branches are a necessary evil. Tools can be put to many uses, sure, but what is easy and what is difficult, given a particular tool, will influence our behaviour. Branching is so quick in git (because a git branch is just a tiny bit of metadata; a reference to a node in a commit graph) that it tends to encourage more branching rather than less. Maybe those ten-minute branch operations in TFS were saving me from myself!

Subscribe to our news and insights

0 comments on this post