Git is the C of Version Control Tools
I've been working lately on a major revision of Source Control HOWTO.
The plan is to publish an expanded version of this material as a book later
The original series of chapters was written almost five
years ago, and the content is looking rather dated here in 2009. One of the
biggest problems is that no book on this topic can be truly credible these days
without covering distributed version control tools like Git and Mercurial.
These tools aren't mainstream yet, but their popularity is growing very fast.
So as I overhaul the content for book publication, I am
including lots of new stuff on distributed version control and how it's
And that means I am spending a fair amount of time using
Bazaar and Git and Darcs and their ilk. Broadly speaking, I think these tools
But I keep stumbling across little things that surprise me.
git add -p
Some folks say that Git's killer feature is its index. That's
like saying that C's killer feature is the ability to cast an int to a pointer.
Git's index is neato, but it allows you to do things that may
be unsafe. At first I didn't get this. Whenever I was reading about the
index, I thought it was equivalent to a pending changeset, a simple list of
changes in the working copy that are waiting to be committed to the repo.
But Git's index isn't just metadata. It doesn't just point
to things in the working copy. It actually contains its own copies of things.
And this is where Git's index is both cool and not cool.
One of the best practices I suggest in Source Control HOWTO is to never use a
version control feature which encourages you to checkin code which you have
never been allowed to compile and test. This is exactly what Git's index
allows the developer to do.
- By using "git add --p", you can choose which patches from a
file you want to include for checkin.
- The result is that the index contains a version of the
file which is not in your working copy.
- If you fire up your build tool, it will compile the
version of the file that is sitting in your working copy, not the one
tucked away in Git's index.
- If you run your unit tests, they are not testing the
contents of the file that are about to be committed.
- So when you type "git commit", your repository will
contain something that has never been compiled or tested.
- This is not a Best Practice.
That doesn't mean Git or its index are bad. I'll agree that
"git add --p" is a very powerful feature that has its place. But in this
respect, Git is a bit like C.
- C is fast, hard-to-learn and it allows the developer to do
things that are probably a bad idea.
- Git could be described in exactly the same way.
Not that there's anything wrong with that. :-) I
could actually see myself using "git add --p", but that doesn't mean it would be
a smart thing to do.
And I would adopt the same mindset I use when I'm coding in
C. Whether you're using C or Git or a 12-gauge shotgun, you need to act
differently than you do when you're in an environment that attempts to protect
you from your own mistakes.