Git Storytelling – Part 1
Since the dawn of humanity, we have helped each other understand the world by telling stories. In software projects, our primary medium for stories is the version control commit log.
In today’s episode, guest chef Brooke Kuhlmann joins us to demonstrate how the interactive rebase feature in Git can help us tell better stories about our code changes. Along the way, he’ll show off some handy git command aliases for a more productive git workflow. Enjoy!
Video transcript & code
Today, I want to explore dealing with Git repositories that are hard to read, understand, and, maintain. We'll begin by studying an existing repository that exhibits a common pattern I see within software development teams, open source projects, etc. Granted, the repository that we'll be working with today is a fabricated version of what I've seen in the wild, but I think it'll help drive home the point better.
OK, let's dig in!
As you can see from the directory listing, this is a simple project with a single Ruby
add.rb script. The other files and directories we'll ignore.
OK, so the Ruby script takes two arguments:
These arguments are destructured from the ARGV constant in order to print a friendly sentence of two numbers being added together followed by the resulting sum.
Let's see what this looks like in practice:
ruby add.rb 2 5
Now we understand how the script works.
By the way, implementation details of this Ruby script are not important. The purpose of today's lesson is not to focus on the Ruby code but the Git commits. We need to understand the story of how this was architected and implemented.
With that in mind, let's study the Git history to learn more.
git log --graph --pretty=format:"%C(yellow)%h%C(reset) %G? %C(bold blue)%an%C(reset) %s%C(bold cyan)%d%C(reset) %C(green)%cr.%C(reset)"
Due to the above Git log command being a lot to type, I want to pause for a moment and explain the Bash aliases I'll be using today. To start, I'll be use my
gl alias from this point forward to speed things up:
gl alias is doing is formatting our Git logs so they are easier to read. If you don't have an alias like this as part of your workflow, I highly recommend adding one as it'll save yourself a lot of typing and speed up your debugging process.
Before we continue, there is another command I'll be using a lot which is
git show. Here is how I like to use it with enhanced formatting and color coding:
git show --stat --pretty=format:"%C(yellow)%h%C(reset) %G? %C(bold blue)%an%C(reset) %s%C(bold cyan)%d%C(reset) %C(green)%cr.%C(reset) %n%n%b%n%N%-%n"
Again, that is a lot to type, so I'll use my
ghow alias from this point forward to reduce typing:
ghow (short for Git show), allows me to view the details of the last commit made or a specific commit.
OK, enough about aliases, let's return to studying the Git log:
Unfortunately, these commits are difficult to read because they fail to explain what has been implemented or how it was designed. There is no compelling story for how the Ruby script was architected. So we are forced to dig deeper into the Git History to learn more. Let's start by studying the first commit on this
tutorial feature branch.
ghow git diff ^
So the first commit is where we see the initial implementation added to the project. Let's pretend this project hasn't been shared with anyone and we were the original developer instead. How could we make these commit messages easier to understand?
This is where one of my favorite tools comes into play which is: Git Interactive Rebase.
Let's start with the first commit on this feature branch:
git rebase --interactive
Added initial implementation for adding two numbers Provides a handy Ruby script for adding two numbers. Usage: ruby add.rb 5 2 # => Yields: 7
Look at how much better that first commit message is! From the Git Log we understand what the commit is. ...and, by using Git Show to inspect, we understand why the commit was made.
This is worth taking a moment to emphasis as each commit message should accomplish the following two principals: - One: Each commit should explain what you are committing via the commit subject. - Two: Each commit should explain why the commit is important via the body of the commit.
OK, with that in mind, let's continue applying the same technique to the last two commits.
gl ghow git diff ^ git rebase --interactive
Added frozen string literal pragma Ensures all strings are frozen by default to improve performance and prevent mutation of strings.
Again, look at how much more descriptive that commit message is. OK, one more to go. Let's reword the last commit message on this feature branch as well.
ghow git diff ^ git rebase --interactive
Fixed adding of values by ensuring they are cast to integers Ensures the arguments given to the script are converted to integers before adding them to ensure we can calculate sums properly.
I don't know about you but those last three commit messages are a lot easier to read and understand. This is a project I would enjoy working in.
In the next episode we'll discuss how we can improve upon this even further.
That's all for today.