A Git + Drupal Primer

Now that the Drupal community's migration to Git is in full swing, it's a great time to switch your own projects as well. Curious? Perhaps you saw the Git panel in San Francisco, or maybe you've listened to Sam Boyer campaigning passionately at your local DrupalCamp. Is there a rebel in your office who keeps going on about how much better life can be with git-svn? (How ironic that Subversion is now the establishment.)

If you're just getting started, here are some tips I've collected over the last year. Or if you're already a Git ninja, here's how you can help.

GitX

Tune your environment

A few tweaks to your shell environment and Git config can make Git even more awesome.

Set up your shell

With a few lines in your ~/.bash_profile, you can get auto-completion of Git commands and branches, as well as the repository status in your command prompt.

source /opt/local/share/doc/git-core/contrib/completion/git-completion.bash
GIT_PS1_SHOWDIRTYSTATE=true
export PS1='[\u@mb \w$(__git_ps1)]\$ '

These paths are for Git installed via macports, yours may differ.

Set an editor

Your editor of choice will be used for writing commit messages, as well as some of Git's interactive features. I use TextMate, so this command does the trick:

git config --global core.editor "mate -w"

Set a merge tool

For Mac users, the XCode developer tools include a nice graphical diff utility, FileMerge. You can set this as your merge tool with this command:

git config --global merge.tool opendiff

FileMerge is also a great patch review tool, but that's a topic for another post.

Install GitX

GitX (screenshot above) is an awesome history browser for OS X. Enough said.

When disaster strikes

Inevitably, you'll make some blunders as you explore some of Git's more advanced features. Here are some ways to recover.

Undo a commit with Git revert

Unlike other VCSs I have used, git-revert actually does what you want. Simply run
git revert <commit>

and a new commit will be added that reverses the change you specified.

Start over with Git reset

If all hope has been lost, you can usually reset back to your last commit with:

git reset --hard HEAD

You can also reset to a specific commit, but note this causes commits that are forward of your reset point to be lost (assuming they don't still exist in another branch or remote).

Use local topic branches for scary changes

If you're attempting something unfamiliar (say rewriting history with an interactive rebase), I have found that doing this work in a branch makes it easy to recover if you screw up: Just checkout master again, and delete the experimental branch. If the result of your endeavor needs to eventually be the master branch, you can always delete master and re-create it as a fork of your topic branch.

Rewriting history is dangerous

Speaking of rewriting history, it's dangerous. It's just like a bad time-travel movie, where every attempt to fix the past just makes things worse, though eventually you'll probably figure it out (and win the girl). In the end, you'll learn a valuable lesson never to do that again. Of course, just like in the sequel, the power of time traveling is addictive and you'll keep coming back for more anyway.

Working with Git

Mine your history with Git pickaxe

Let say you want to trace the lineage of the mysterious $conf['page_cache_fastpath']. You could use git-blame, but that only shows the most recent change. With git log -S, you can see all commits with diffs that contain your search string. Add a -p to see the actual diffs.

Use the index

Git has an intermediate storage area between your local repo and working copy, known as the index. You'll also sometimes see this referred to as the stage, or the cache. As far as I can tell these are all the same thing (corrections are welcome if anyone can explain the subtleties of these terms).

You can selectively commit only parts of a file with git add -p or git add -i. To compare what's in the index with your latest HEAD, run git diff --cached.

Format a patch for drupal.org

When you need to export a patch for drupal.org, make sure to use the --no-prefix option. I usually have a topic branch for each issue I'm working on, so to make a patch I would run git diff master --no-prefix. If there are uncommitted changes in your working directory that you don't want in the patch, you can temporarily move them out of the way with git-stash.

Filed under:

Comments

As a note, shell autocompletion requires a couple more steps. If you're using macports you just have to select the correct variant. If you type `port variants git-core` you'll see some additional options such as bash_completion which is our happiness trigger. Something like the following should get you going on OS X:

sudo port install git-core +bash_completion +doc +svn

If you aren't on OS X and your are compiling from source there should be a script in the contrib folder which you just drop in ~/.bash_completion.d and restart your shell (or probably you can just source that file but I haven't tried it). Here's some more instructions about that: http://www.simplicidade.org/notes/archives/2008/02/git_bash_comple.html

From what I've heard, "staging area" is what the index used to be called. "cache" still refers to the same thing, but only because of the commands that operate on it with the --cached flag.

Add new comment

Restricted HTML

  • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • You can enable syntax highlighting of source code with the following tags: <code>, <blockcode>, <cpp>, <java>, <php>. The supported tag styles are: <foo>, [foo].
  • Web page addresses and email addresses turn into links automatically.
  • Lines and paragraphs break automatically.

Ready for transformation?