git-describe

Discussion in 'Java' started by Lawrence D'Oliveiro, May 25, 2011.

  1. 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�
     
    Lawrence D'Oliveiro, May 25, 2011
    #1
    1. Advertising

  2. Lawrence D'Oliveiro

    Tom Anderson Guest

    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
     
    Tom Anderson, May 26, 2011
    #2
    1. Advertising

  3. In message <>, 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.
     
    Lawrence D'Oliveiro, May 27, 2011
    #3
  4. Lawrence D'Oliveiro

    Tom Anderson Guest

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

    > In message <>, 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 <>
    | date: Fri May 27 23:44:00 2011 +0100
    | summary: continuation
    |
    o changeset: 0:be2fb6a06ade
    user: Tom Anderson <>
    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 <>
    | date: Fri May 27 23:44:57 2011 +0100
    | summary: that's more like it
    |
    | o changeset: 1:43d273e49ff1
    |/ user: Tom Anderson <>
    | date: Fri May 27 23:44:00 2011 +0100
    | summary: continuation
    |
    o changeset: 0:be2fb6a06ade
    user: Tom Anderson <>
    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
     
    Tom Anderson, May 27, 2011
    #4
  5. In message <>, 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.
     
    Lawrence D'Oliveiro, May 28, 2011
    #5
  6. On 05/27/2011 10:34 PM, Lawrence D'Oliveiro wrote:
    > In message<>, 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
     
    Joshua Cranmer, May 28, 2011
    #6
  7. In message <irppn6$js9$>, Joshua Cranmer wrote:

    > On 05/27/2011 10:34 PM, Lawrence D'Oliveiro wrote:
    >>
    >> In message<>, 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.
     
    Lawrence D'Oliveiro, May 28, 2011
    #7
  8. Lawrence D'Oliveiro

    Tom Anderson Guest

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

    > In message <>, 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
     
    Tom Anderson, May 29, 2011
    #8
  9. Lawrence D'Oliveiro

    Tom Anderson Guest

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

    > In message <irppn6$js9$>, Joshua Cranmer wrote:
    >
    >> On 05/27/2011 10:34 PM, Lawrence D'Oliveiro wrote:
    >>>
    >>> In message<>, 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
     
    Tom Anderson, May 29, 2011
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ingmar Seifert
    Replies:
    10
    Views:
    17,355
    swatig29
    Nov 4, 2009
  2. Eric DELAGE
    Replies:
    2
    Views:
    708
  3. f
    Replies:
    3
    Views:
    401
    GIMME
    Dec 1, 2003
  4. Cram TeXeD
    Replies:
    0
    Views:
    370
    Cram TeXeD
    Jun 12, 2004
  5. luk
    Replies:
    5
    Views:
    392
    Guy Lépine
    Aug 28, 2003
Loading...

Share This Page