views:

4161

answers:

9

I read through a bunch of questions asking about simple source code control tools and git seemed like a reasonable choice. I have it up and running and it works well so far. One aspect that I like about CVS is the automatic incrementation of a version number.

I understand that this makes less sense in a distributed repository, but as a developer I want/need something like this. Let me explain why:

I use Emacs. Periodically I go through and look for new versions of the lisp source files for 3rd-party packages. Say I've got a file foo.el which according to the header is version 1.3; if I look up the latest version and see it's 1.143 or 2.6 or whatever, I know I'm pretty far behind. If instead I see a couple of 40-character hashes, I won't know which is later or get any idea of how much later it is. I would absolutely hate it if I had to manually check ChangeLogs just to get an idea of how out of date I am.

As a developer, I want to extend this courtesy, as I see it, to the people that use my output (and maybe I'm kidding myself that anyone is, but let's leave that aside for a moment). I don't want to have to remember to increment the damn number myself every time, or a timestamp or something like that. That's a real PITA, and I know that from experience.

So what alternatives do I have? If I can't get an $Id:$ equivalent, how else can I provide what I'm looking for? Thanks for the help!

EDIT: I should mention that my expectation is that the end user will NOT have git installed and even if they do, will not have a local repository (indeed, I expect not to make it available that way). Thanks for the answers so far!

+7  A: 

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.

orip
Yeah, I read part of that long string of emails about keyword expansions. Linus' attitude was almost enough to put me off git completely.
Joe Casadonte
Yeah, sometimes he’s lacking politeness but he’s usually correct, and he definitely is on the topic of keyword expansion.
Bombe
+3  A: 

If I understand correctly, essentially, you want to know how many commits have happened on a given file since you last updated.

First get the changes in the remote origin, but don't merge them into your master branch:

% git fetch

Then get a log of the changes that have happened on a given file between your master branch and the remote origin/master.

% git log master..origin/master foo.el

This gives you the log messages of all the commits that have happened in the remote repository since you last merged origin/master into your master.

If you just want a count of the changes, pipe it to wc. Say, like this:

% git rev-list master..origin/master foo.el | wc -l
Otto
So, don't use log: git rev-list master..origin/master | wc -l
Dustin
Updated the answer.
Otto
+2  A: 

If you're just wanting people to be able to get an idea how far out of date they are, git can inform them of that in several fairly easy ways. They compare the dates of the last commit on their trunk and your trunk, for example. They can use git cherry to see how many commits have occurred in your trunk that are not present in theirs.

If that's all you want this for, I'd look for a way to provide it without a version number.

Also, I wouldn't bother extending the courtesy to anyone unless you're sure they want it. :)

skiphoppy
+3  A: 

Something that is done with git repositories is to use the tag object. This can be used to tag a commit with any kind of string and can be used to mark versions. You can see that tags in a repo with the git tag command, which returns all the tags.

It's easy to check out a tag. For example, if there is a tag v1.1 you can check that tag out to a branch like this:

git checkout -b v1.1

As it's a top level object, you'll see the whole history to that commit, as well as be able to run diffs, make changes, and merges.

Not only that, but a tag persists, even if the branch that it was on has been deleted without being merged back into the main line.

Abizern
Is there, then, a way to get this tag inserted into the file automatically by git? Thanks!
Joe Casadonte
If you mean by keyword expansion? Not as far as I know. if you are building products you can get the information as part of your build script and insert it somewhere into your built product. Try man git-describe which gives the latest tag, the number of commits since this tag, and the current hash.
Abizern
+3  A: 

If having $Keywords$ is essential for you, then maybe you could try to look at Mercurial instead? It has a hgkeyword extension that implement what you want. Mercurial is interesting as a DVCS anyway.

Keltia
Thanks, Olivier, I'll check it out. I'm not a huge Python fan, which is why I avoided it initially, but if it has what I'm looking for.....
Joe Casadonte
+4  A: 

As I’ve written before:

Having automatically generated Id tags that show a sensible version number is impossible to do with DSCM tools like Bazaar because everybody’s line of development can be different from all others. So somebody could refer to version “1.41” of a file but your version “1.41” of that file is different.

Basically, $Id$ does not make any sense with Bazaar, Git, and other distributed source code management tools.

Bombe
Right, I read that before posting, and that's why I asked for a more general solution to the underlying problem. I think the desire for an individual file to have a version # is legitimate, as is git's inability to provide a solution.
Joe Casadonte
It’s not an inability of Git, it’s an inability of all distributed SCMs. If you really want meaningful version numbers, use Subversion, or CVS, or some other centralized system.
Bombe
You're right, I should have said "as is DSCM's inability to provide a solution".
Joe Casadonte
+1  A: 

You've put so many constraints on the problem that you're left with custom scripting as your only solution.

Otto
+17  A: 

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.
Dustin
Excellent write-up. Thanks
Paul
A: 

Since you use emacs, you might be lucky :)

I've came across this question by coincidence, and also by coincidence I've came by Lively few days ago, an emacs package which allows having lively pieces of emacs lisp in your document. I've not tried it to be honest, but it came to my mind when reading this.

Amr Mostafa