Streamline Drupal Development with Effective Git Practices

Possibly the nerdiest thing that's ever escaped my mind is a reimagining of the lyrics to 1983 pop hit The Safety Dance by Men Without Hats in tribute to my favorite distributed version control system, Git, contra CVS:

"We can branch if we want to. We can leave your friends behind. 'Cause your friends don't branch, and if they don't branch, well they're no friends of mine!"

You may think that's a little over the top, but even if your appreciation for Git hasn't advanced to the point of putting anachronistic praise into the mouths of Canadian synth pop bands of yore, I probably don't have to persuade you that it's pretty awesome. It's been a few years since Drupal.org made the switch to Git, and by now most folks in the community are using it if they're using anything. But not all of us have learned to use it effectively yet. My goal in this article is to provide a roadmap to help everyone get there.

Master the Fundamentals

Of course, if you want to be effective with anything, you have to master the fundamentals first. [Insert tired sports cliche here.] A great place to do so with Git is the official documentation. Here are the highlights, if you ask me (which, incidentally, I'm pretending you did):

  • The Videos will get you basically oriented if you're completely new to the topic. For a more extensive overview, including Git's genesis and design principles, I like Linus Torvalds' Google Tech Talk on Git.
  • The Reference Manual helpfully organizes all Git commands into categories. Spend some quality time there—you're sure to learn a few new tricks. Don't believe me? Allow me to blow your mind: `git checkout -` checks out the previous branch, just like `cd -` in bash changes to the previous directory. You stand corrected.
  • The Book, Pro Git by Scott Chacon, is not only excellent but free. It covers all the fundamentals with some advanced topics and pro tips to boot! You can read the whole thing online, if that's your cup of tea, but don't overlook the PDF, mobi, and ePub formats in the sidebar.
  • There are more tutorials, books, and videos in the External Links section..

Acquaint Yourself with Advanced Features

If you read the Git Book you'll learn about a number of advanced features, but a few are worth calling out here:

Rewriting History

The whole point of version control is that you never lose a committed change. But we all make mistakes: We let a password or other sensitive information slip into an open source repository. We create an ugly tangle of commits that are hard to review or merge. Git helps you recover from such errors by rewriting history with `git commit --amend`, `git rebase` / `git rebase -i`, and family.

Rebasing in particular seems to confuse newbies, but once you learn to use it properly you'll appreciate its power. Of course, as with any power tool, you need to be careful. It's all fun and games until somebody loses an eye a commit. This is probably a good time to learn about the recovery plan.

Debugging

Speaking of making mistakes, at some point you're going to commit a change that breaks your application, and you're going to want to be familiar with Git's debugging tools when that happens:

If you don't notice a regression right away, it can be hard to isolate the problem code. `git bisect` is designed precisely for figuring out where brokenness was introduced. It takes a little practice to become proficient, but if you break stuff a lot you'll get the hang of it. [wink] If your build script takes a long time or your test suite is adequately complex, you can even automate the process.

Coming from the other direction, when you've identified some code and you want to know where it came from, `git blame` is the tool for the job. Point it at a file, and it will tell you, line by line, who added the code at what time in what commit. Of course, it can be more complicated than that. For example, if the line you're interested in has been non-meaningfully changed since it was first introduced (such as by changing its indentation), it will be identified with the later, irrelevant commit. Git still has you covered. You'll just need to sophisticate your approach a little.

Show-branch... -ing

A brief excursus at this point to give disproportionate attention to a feature of Git that doesn't get the love it deserves: `git show-branch` is like a network graph for the command line. It shows branches in parallel up to a common ancestor. I use it all day long, but I've scarcely met anyone else that knew about it. To get a sense of what you may be missing, try a few of these out:

  • You want to see how all branches in your current repo relate to each other: `git show-branch`
  • You want to see the same thing but with commit hashes: `git show-branch --sha1-name`
  • You want to compare two specific branches: `git show-branch first-branch second-branch`
  • You want to see the state of a given branch across all remotes: `git show-branch */branch-name`
  • You want to spam your terminal and regret taking the last bullet seriously: `git show-branch \*/\*`

Optimize Your Environment

Now that we know how to use our tools, lets talk about tuning them.

  • Customize your configuration. If you do nothing else, `git config --global color.ui auto`, because life in grayscale is for the dogs. Then, as long as you're picking low-hanging fruit, set up a global .gitignore file and banish .swp, .DS_Store, and other garbage files from your repos once and for all.
  • Install auto-completion. You know what auto-completion is, right? If not, suffice it to say, install it and you'll miss it when it's gone #meme. (Depending on how you installed Git, you may already have it.)
  • Set up some aliases. Use them to shorten common commands, correct oft-repeated typos, or make "macros" of sorts. Gitready.com recommends a good baseline of common ones, and Open Sourcery has some more advanced examples you won't regret trying. (I defy you to restrain a little smile the first time you run `lp` for `log --graph --pretty=format:'%C(yellow)%h%C(cyan)%d%Creset %s %C(white)- %an, %ar%Creset'`!)
  • Add the current branch/state to your bash prompt. Slow the inexorable march to carpal tunnel syndrome and trade in a thousand `git status`-es for a glance at your command prompt. Use Drush's example prompt for a twofer!
  • Enable git rerere. Your time is valuable—don't waste it resolving the same merge conflicts over and over.
  • Be sure to keep an eye on the size of your repository, if you include files or other assets, or items pulled in during build it could get quite large.
  • Install IDE integration. Most modern IDE's have Git integration of some kind. Many come with it enabled out-of-the-box. Even if you still prefer to issue commands from the terminal like I do, it's very valuable to get change indicators in the code editor. (See PhpStorm, for example.)

Look at You!

Well, we went over quite a bit here. If you followed along, you have a good understanding of Git concepts and commands and you have a well-optimized environment. If you've mastered everything discussed, there's probably a job for you at Github—or better yet, here at Acquia!