Moving from CVS to Git: $Id$ equivalent?

This isn't an unreasonable request from the OP.

My use-case is:

  1. I use Git for my own personal code, therefore no collaboration with others.
  2. I keep system Bash scripts in there which might go into /usr/local/bin when they are ready.

I use three separate machines with the same Git repository on it. It would be nice to know what "version" of the file I have currently in /usr/local/bin without having to do a manual "diff -u <repo version> <version in /usr/local/bin>".

To those of you being negative, remember there are other use cases out there. Not everyone uses Git for collaborative work with the files in the Git repository being their "final" location.

Anyway, the way I did it was to create an attributes file in the repository like this:

cat .git/info/attributes
# see man gitattributes
*.sh ident
*.pl ident
*.cgi ident

Then put $Id$ somewhere in the file (I like to put it after the shebang).

The commit. Note that this doesn't automatically do the expansion like I expected. You have to re-co the file, for example,

git commit foo.sh
rm foo.sh
git co foo.sh

And then you will see the expansion, for example:

$ head foo.sh
#!/bin/sh

# $Id: e184834e6757aac77fd0f71344934b1cd774e6d4 $

Some good information is in How do I enable the ident string for a Git repository?.


By now there is support for $Id:$ in Git. To enable it for file README you would put "README ident" into .gitattributes. Wildcards on file names are supported. See man gitattributes for details.


Not sure this will ever be in Git. To quote Linus:

"The whole notion of keyword substitution is just totally idiotic. It's trivial to do "outside" of the actual content tracking, if you want to have it when doing release trees as tar-balls etc."

It's pretty easy to check the log, though - if you're tracking foo.el's stable branch, you can see what new commits are in the stable branch's log that aren't in your local copy. If you want to simulate CVS's internal version number, you can compare the timestamp of the last commit.

Edit: you should write or use someone else's scripts for this, of course, not do this manually.


The SHA is just one representation of a version (albeit canonical). The git describe command offers others and does so quite well.

For example, when I run git describe in my master branch of my Java memcached client source, I get this:

2.2-16-gc0cd61a

That says two important things:

  1. There have been exactly 16 commits in this tree since 2.2
  2. The exact source tree can be displayed on anyone else's clone.

Let's say, for example, you packaged a version file with the source (or even rewrote all the content for distribution) to show that number. Let's say that packaged version was 2.2-12-g6c4ae7a (not a release, but a valid version).

You can now see exactly how far behind you are (4 commits), and you can see exactly which 4 commits:

# The RHS of the .. can be origin/master or empty, or whatever you want.
% git log --pretty=format:"%h %an %s" 2.2-12-g6c4ae7a..2.2-16-gc0cd61a
c0cd61a Dustin Sallings More tries to get a timeout.
8c489ff Dustin Sallings Made the timeout test run on every protocol on every bui
fb326d5 Dustin Sallings Added a test for bug 35.
fba04e9 Valeri Felberg Support passing an expiration date into CAS operations.