git-describe

  • Follow


Discovered yet another nifty Git feature while looking through the docs.

Build scripts often try to automatically determine some kind of revision 
number to include with the version info when building a piece of software. 
With Subversion, you can use “svn info” to get a revision number that 
increments with every commit, that you can use for that.

With Git, there is no real equivalent, since it has no sequence numbers for 
anything, every object being identified by its SHA-1 hash, with no sensible 
ordering at all.

But if you have tagged some prior revision, the command “git describe --
tags” will generate a string of the form

    <tag>-<nr revisions since>-g<part of current revision hash>

For example, looking at the current dvdauthor source tree, the command 
returns this

    0.7.0-18-g6143744

which means it has been 18 commits since the one I released (and tagged) as 
“0.7.0”, and the hash for the last commit begins with 6143744.

Exercise for the reader: what happens if you don’t specify “--tags”?
0
Reply ldo (2144) 5/25/2011 10:14:29 AM

  This message is in MIME format.  The first part should be readable text,
  while the remaining parts are likely unreadable without MIME-aware tools.

--232016332-1224991537-1306429199=:19918
Content-Type: TEXT/PLAIN; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8BIT

On Wed, 25 May 2011, Lawrence D'Oliveiro wrote:

> Discovered yet another nifty Git feature while looking through the docs.
>
> Build scripts often try to automatically determine some kind of revision
> number to include with the version info when building a piece of software.
> With Subversion, you can use “svn info” to get a revision number that
> increments with every commit, that you can use for that.
>
> With Git, there is no real equivalent, since it has no sequence numbers for
> anything, every object being identified by its SHA-1 hash, with no sensible
> ordering at all.

Mercurial has a very slight edge here, in that as well as the hash-based 
changeset IDs, it also has a sequential changeset number. The output of 
'hg log' from a trivial demo repository:

changeset:   2:1af3be9856b9
tag:         tip
user:        admin@initech-dev-19
date:        Thu May 26 15:28:30 2011 +0100
summary:     keeping things up to daet

changeset:   1:d2a7ea8727e4
user:        admin@initech-dev-19
date:        Thu May 26 15:26:06 2011 +0100
summary:     update

changeset:   0:a9f4a5b5e4ca
user:        admin@initech-dev-19
date:        Thu May 26 15:25:54 2011 +0100
summary:     first commit

The 'changeset' lines have the revision number, a colon, and the first 
twelve characters of the changeset ID.

The problem with this is that the numbers record the sequence in which 
changesets were added to the current repository - which in the presence of 
commits on multiple machines (ie for any realistic development team) means 
that the numbers won't be the same in different repositories.

For example, if i create a repository and make an initial commit, the 
first changeset gets number 0. If you pull it from me, it will be 0 in 
your repository too. If i do some work and commit it, my new changeset 
will have number 1. If you do some work and commit, your new changeset 
will also have number 1. When you then pull from me, my changeset will 
have number 2.

So, numbers are useful and meaningful, but only in the context of one 
repository.

If you have a single 'golden master' repository from which you cut 
releases, then this may be good enough; you can always relate the number 
to that repository, so a higher number always means a later version.

Failing that, you could use a build number which combines the identity of 
the repository and the changeset number, but that's rather less useful.

Alternatively, you have some sort of master repository, and give it a 
post-changegroup hook that tags every push with a tag constructed from the 
local changeset number.

> But if you have tagged some prior revision, the command “git describe --
> tags” will generate a string of the form
>
>    <tag>-<nr revisions since>-g<part of current revision hash>
>
> For example, looking at the current dvdauthor source tree, the command
> returns this
>
>    0.7.0-18-g6143744
>
> which means it has been 18 commits since the one I released (and tagged) as
> “0.7.0”, and the hash for the last commit begins with 6143744.

In the absence of a master repository, that is substantially more helpful 
than what you can do with Mercurial

A bit of googling reveals that someone ported this to Mercurial as an 
extension, but it seems to have died.

> Exercise for the reader: what happens if you don’t specify “--tags”?

States it as revisions from the initial checkin?

tom

-- 
Batman always wins
--232016332-1224991537-1306429199=:19918--
0
Reply twic (2083) 5/26/2011 4:59:59 PM


In message <alpine.DEB.2.00.1105261519520.19918@urchin.earth.li>, Tom 
Anderson wrote:

> The problem with this is that the numbers record the sequence in which
> changesets were added to the current repository - which in the presence of
> commits on multiple machines (ie for any realistic development team) means
> that the numbers won't be the same in different repositories.

Sounds like it’s more equivalent to what you might get out of a “reflog” on 
Git. This is a purely personal, interim record of changes to the repository, 
which is never pushed/pulled as part of the repository itself, and can be 
purged (on demand) at any time.

> Mercurial has a very slight edge here, in that as well as the hash-based 
> changeset IDs, it also has a sequential changeset number.

As soon as I read this, I wondered what would happen to the numbering if you 
did the Git equivalent of committing something, then abandoning that commit 
(resetting that branch back to a prior commit) and making a new one. This 
can’t just arise from mistakes; it’s recommended in the Git docs as a handy 
way of saving temporary changes while working om something else.

>> Exercise for the reader: what happens if you don’t specify “--tags”?
> 
> States it as revisions from the initial checkin?

Actually, no. It turns out there are two different kinds of tags, and which 
one is used depends on this option.
0
Reply ldo (2144) 5/26/2011 11:00:38 PM

  This message is in MIME format.  The first part should be readable text,
  while the remaining parts are likely unreadable without MIME-aware tools.

--232016332-996253908-1306536687=:1610
Content-Type: TEXT/PLAIN; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8BIT

On Fri, 27 May 2011, Lawrence D'Oliveiro wrote:

> In message <alpine.DEB.2.00.1105261519520.19918@urchin.earth.li>, Tom
> Anderson wrote:
>
>> The problem with this is that the numbers record the sequence in which 
>> changesets were added to the current repository - which in the presence 
>> of commits on multiple machines (ie for any realistic development team) 
>> means that the numbers won't be the same in different repositories.
>
> Sounds like it’s more equivalent to what you might get out of a “reflog” 
> on Git. This is a purely personal, interim record of changes to the 
> repository, which is never pushed/pulled as part of the repository 
> itself, and can be purged (on demand) at any time.

Yes, it's somewhat like reflog. It's a bit more front-and-centre than 
reflog is, less of a hidden bonus feature, and it has a model that seems 
simpler to me: the numbers count the addition of changesets to the 
repository. Every changeset added, by whatever means, gets a number one 
higher than the previous one. Whereas reflog, if i've understood it right, 
numbers revisions by how recently they were the head. So the numbers 
change when you change what's head. I may have misunderstood this.

In the sense that it's personal and never pushed or pulled, though, yes, 
it's just like reflog. I wouldn't really call it interim.

>> Mercurial has a very slight edge here, in that as well as the hash-based
>> changeset IDs, it also has a sequential changeset number.
>
> As soon as I read this, I wondered what would happen to the numbering if 
> you did the Git equivalent of committing something, then abandoning that 
> commit (resetting that branch back to a prior commit) and making a new 
> one. This can’t just arise from mistakes; it’s recommended in the Git 
> docs as a handy way of saving temporary changes while working om 
> something else.

It's also the normal way of working in Mercurial (as long as 'resetting' 
doesn't mean 'throwing away'). Here's a brief session that illustrates 
what happens:

$ hg init branchy
$ cd branchy/
$ date >first
$ hg add
adding first
$ hg commit -m 'the beginning'
$ date >second
$ hg add
adding second
$ hg commit -m 'continuation'
$ # no, too boring, try again
$ hg glog
@  changeset:   1:43d273e49ff1
|  tag:         tip
|  user:        Tom Anderson <twic@urchin.earth.li>
|  date:        Fri May 27 23:44:00 2011 +0100
|  summary:     continuation
|
o  changeset:   0:be2fb6a06ade
    user:        Tom Anderson <twic@urchin.earth.li>
    date:        Fri May 27 23:43:45 2011 +0100
    summary:     the beginning

$ hg update 0
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
$ hostname >second
$ hg add
adding second
$ hg commit -m "that's more like it"
created new head
$ hg glog
@  changeset:   2:0354ae380fea
|  tag:         tip
|  parent:      0:be2fb6a06ade
|  user:        Tom Anderson <twic@urchin.earth.li>
|  date:        Fri May 27 23:44:57 2011 +0100
|  summary:     that's more like it
|
| o  changeset:   1:43d273e49ff1
|/   user:        Tom Anderson <twic@urchin.earth.li>
|    date:        Fri May 27 23:44:00 2011 +0100
|    summary:     continuation
|
o  changeset:   0:be2fb6a06ade
    user:        Tom Anderson <twic@urchin.earth.li>
    date:        Fri May 27 23:43:45 2011 +0100
    summary:     the beginning

The punchline is that, as i said, the numbers record the sequence in which 
changeset were added to the repository. Changesets 1 and 2 are on 
different branches, but they happened in a chronological order, so they 
get numbers in that order.

This is a difference from reflog, where the numbers relate to each other, 
and you can do arithmetic with them.

>>> Exercise for the reader: what happens if you don’t specify “--tags”?
>>
>> States it as revisions from the initial checkin?
>
> Actually, no. It turns out there are two different kinds of tags, and 
> which one is used depends on this option.

That's the kind of thing that's the reason i don't use git.

tom

-- 
Initial thoughts - who cares? Subsequent thoughts - omg!!! (Female, 14,
Scotland) -- 4.5 million young Brits' futures could be compromised by
their electronic footprint, Information Commissioner's Office
--232016332-996253908-1306536687=:1610--
0
Reply twic (2083) 5/27/2011 10:51:27 PM

In message <alpine.DEB.2.00.1105272251580.1610@urchin.earth.li>, Tom 
Anderson wrote:

> It's also the normal way of working in Mercurial (as long as 'resetting'
> doesn't mean 'throwing away').

In Git, “resetting” does indeed mean “throwing away”.

> Here's a brief session that illustrates what happens:
> 
> $ hg update 0

So this command has started a new branch?

In Git, every branch has a name.

>> Actually, no. It turns out there are two different kinds of tags, and
>> which one is used depends on this option.
> 
> That's the kind of thing that's the reason i don't use git.

This is why you need to understand things before trying to rubbish them.
0
Reply ldo (2144) 5/28/2011 2:34:07 AM

On 05/27/2011 10:34 PM, Lawrence D'Oliveiro wrote:
> In message<alpine.DEB.2.00.1105272251580.1610@urchin.earth.li>, Tom
> Anderson wrote:
>> $ hg update 0
>
> So this command has started a new branch?
>
> In Git, every branch has a name.

No, hg update goes to that revision. I think the git equivalent is git 
checkout (bizarrely named, if you ask me).

hg branches have names, although branch names are a property of the 
changeset and not the repository (which makes git hard for me to use, 
having used hg for 6-odd years).

-- 
Beware of bugs in the above code; I have only proved it correct, not 
tried it. -- Donald E. Knuth
0
Reply Pidgeot18 (1399) 5/28/2011 3:21:09 AM

In message <irppn6$js9$1@dont-email.me>, Joshua Cranmer wrote:

> On 05/27/2011 10:34 PM, Lawrence D'Oliveiro wrote:
>>
>> In message<alpine.DEB.2.00.1105272251580.1610@urchin.earth.li>, Tom
>> Anderson wrote:
>>>
>>> $ hg update 0
>>
>> So this command has started a new branch?
> 
> No, hg update goes to that revision.

Yes, but the next commit seemed to spawn off a new branch from there, and I 
didn’t see any name attached to it.

> I think the git equivalent is git checkout (bizarrely named, if you ask
> me).

Why? It gets a snapshot out of the tree. What else would a “checkout” do?

>> In Git, every branch has a name.
> 
> hg branches have names ...

I didn’t see any in the commit example posted earlier.

> ... although branch names are a property of the changeset and not the
> repository (which makes git hard for me to use, having used hg for 6-odd
> years).

I’m not sure how that’s different from Git. In Git, a branch head points to 
a commit/changeset, and that’s all there is to it.
0
Reply ldo (2144) 5/28/2011 4:29:49 AM

  This message is in MIME format.  The first part should be readable text,
  while the remaining parts are likely unreadable without MIME-aware tools.

--232016332-1012980313-1306625131=:28130
Content-Type: TEXT/PLAIN; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8BIT

On Sat, 28 May 2011, Lawrence D'Oliveiro wrote:

> In message <alpine.DEB.2.00.1105272251580.1610@urchin.earth.li>, Tom
> Anderson wrote:
>
>> It's also the normal way of working in Mercurial (as long as 'resetting'
>> doesn't mean 'throwing away').
>
> In Git, “resetting” does indeed mean “throwing away”.

Okay. In that case, the equivalent would actually be a little dance 
involving hg clone - Mercurial makes it much harder to throw things away - 
and the numbering would be reset, in a manner of speaking, since the clone 
would create a new numbering.

>> Here's a brief session that illustrates what happens:
>>
>> $ hg update 0
>
> So this command has started a new branch?

No, but a branch was created when i committed after that.

> In Git, every branch has a name.

Not so in Mercurial. This is, famously, one of the areas of greatest 
difference between Git and Mercurial - Mercurial can have completely 
anonymous branches, which it seems Git can't, but when it does have named 
branches, it brands the name onto each changeset in it, which Git doesn't. 
And what Git calls branches, Mercurial calls bookmarks, etc, etc.

AIUI, the reason anonymous branches don't exist in Git is because (a) 
there would be no way to get to them (apart from reflog!) and (b) they 
would get garbage collected, because names function as the rootset for 
garbage collection. Mercurial doesn't do garbage collection (er, i think), 
so you can have anonymous branches. The lack of names does obviously mean 
that their utility is rather limited in scope.

>>> Actually, no. It turns out there are two different kinds of tags, and
>>> which one is used depends on this option.
>>
>> That's the kind of thing that's the reason i don't use git.
>
> This is why you need to understand things before trying to rubbish them.

Something i am very happy to say it has never been my policy to do.

tom

-- 
The ``is'' keyword binds with the same precedence as ``.'', even when
it's not actually there. -- Larry Wall, Apocalypse 2
--232016332-1012980313-1306625131=:28130--
0
Reply twic (2083) 5/28/2011 11:25:31 PM

  This message is in MIME format.  The first part should be readable text,
  while the remaining parts are likely unreadable without MIME-aware tools.

--232016332-1595353694-1306625620=:28130
Content-Type: TEXT/PLAIN; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8BIT

On Sat, 28 May 2011, Lawrence D'Oliveiro wrote:

> In message <irppn6$js9$1@dont-email.me>, Joshua Cranmer wrote:
>
>> On 05/27/2011 10:34 PM, Lawrence D'Oliveiro wrote:
>>>
>>> In message<alpine.DEB.2.00.1105272251580.1610@urchin.earth.li>, Tom
>>> Anderson wrote:
>>>
>>>> $ hg update 0
>>>
>>> So this command has started a new branch?
>>
>> No, hg update goes to that revision. I think the git equivalent is git 
>> checkout (bizarrely named, if you ask me).
>
> Why? It gets a snapshot out of the tree. What else would a “checkout” 
> do?

Go 'beep' when you wave a packet of cornflakes at it.

'Checkout' and 'checkin' are both poor names, IMO. I appreciate that there 
is historical precedent for their use, and so their meanings are well 
understood, but as metaphors, they aren't very good. Checking out and 
checking in are about controlling exclusive access to something (eg a book 
in a library), which is something that some legacy source control systems 
do, but not something our shiny modern DVCSs do (or even something CVS dd, 
mostly).

>>> In Git, every branch has a name.
>>
>> hg branches have names ...
>
> I didn’t see any in the commit example posted earlier.

Joshua is talking about named branches. This is an anonymous branch. I 
don't know why he's talking about named branches.

>> ... although branch names are a property of the changeset and not the 
>> repository (which makes git hard for me to use, having used hg for 
>> 6-odd years).
>
> I’m not sure how that’s different from Git. In Git, a branch head points 
> to a commit/changeset, and that’s all there is to it.

Mercurial branches don't point to commits - the branch is a property of 
the changeset, it's actually recorded in the changeset's data in the 
repository. You could take a changeset, export it, fax it to someone, and 
when they imported it and looked at it, it would have the branch name on 
it. Some people recoil in horror at this; others love it. It does mean 
that Mercurial named branches are not suited for the same uses as Git 
branches; in Git, you'd use named branches for developing a few features 
locally to send to Linus, but in Mercurial, those would be anonymous 
branches, perhaps identified by bookmarks, or stored in separate 
repositories. Named branches are more for things like trunk/QA/release.

tom

-- 
The ``is'' keyword binds with the same precedence as ``.'', even when
it's not actually there. -- Larry Wall, Apocalypse 2
--232016332-1595353694-1306625620=:28130--
0
Reply twic (2083) 5/28/2011 11:33:39 PM

8 Replies
24 Views

(page loaded in 0.107 seconds)


Reply: