When you go bugfixing, the quick, obvious change isn’t always the best one. And the code in front of you is never the whole story. To go beyond the easy fix, you have to know why certain decisions were made. You have to understand the history behind the code. And there are three great ways to learn what you need to know to confidently change code.
With the help of
git blame, you can trace through every version of every line of code in a project, all the way back to when it was written.
For example, say you were looking at ActiveJob’s
queue_name.rb file, and you wanted to know what this
queue_name_delimiter attribute was all about:
You could run
git blame on it:
And for each line, in order, you’ll see:
- The revision that changed that line most recently (
11ab04b1, for example),
- The name of the author of that commit,
- And the date the change was made.
To learn more about that line of code, you’ll need the revision number. Pass the id (that
11ab04b1 part) to
git show or
Cool! You get to learn a little more about the change, why it’s useful, and see the part of the Rails Guide about it that you might have missed before.
Here, we got pretty lucky. We found the information we were looking for right away. But
git blame only shows you the most recent time that line changed. And sometimes, you won’t find what you’re looking for until you go two or three commits back.
To see earlier commits, you can call
git blame again. But this time, pass the revision before the commit
git blame found. (In git, you can say “the commit before this other commit” by putting a
^ after the revision, like
That’s pretty mind-numbing, though.
Instead, explore your text editor. Most editors make tracing through history with
git blame easy. For example, in Emacs, after
git blame-ing your code, place your cursor on a line. Then, you can press
a to step back through each change that affected that line, and use
D to see more detail about a commit.
Does your team refer to issue numbers and pull requests in your commit messages? If so,
git blame can easily take you from a line of code, to a commit, to the discussion about that commit. And that discussion is where you’ll find all the really good stuff.
A little while ago, I noticed that Rails 4.2 removed
respond_with. In the docs, it’s clear that it was removed, but I didn’t understand why.
There’s a ton of great knowledge hidden behind GitHub’s issue search box. If you want to know why a feature was removed, there’s no better place to learn than the discussion the team had while they decided to remove it.
So, if you search Rails’ GitHub repo for
respond_with, you’ll find some interesting threads about
respond_with. If you’re trying to find out why it was removed, you’ll probably land on this thread. Unfortunately, it describes how it was removed, but not why.
Later on in that thread, though, you’ll find a comment that points to the actual discussion about removing
respond_with. That’s where the good stuff is!
git blame, you might not find exactly what you’re looking for right away. You’ll have to follow references, read comments, and click on links. But GitHub’s issue search will get you started in the right place. And with a little curiosity and a sense of exploration, you’ll learn what you came for.
Unfortunately, not all knowledge about a project can be found in its history, issues, and pull requests. Not everything is written down.
So if you can find the person that originally wrote the code, ask about it. You’ll discover the dev culture and ideas that led to a decision. You’ll learn some history about the project that might never have been recorded. And you’ll hear about paths that were never taken, which might actually make sense to try now.
The easy way can be dangerous
Sometimes, a fix just seems so easy. All you have to do is rescue this one exception in this one place, and then you can go home!
But it’s dangerous to change code you don’t understand.
So when a line of code seems off, or a decision seems weird, or a call seems useless, put on your archeologist’s hat. Learn as much as you can, however you can, about that code. That’s how you’ll make your code change intentionally, and fix the problem at its root.