Joel
Joel

Reputation: 1486

How to show git commit using number of commits since a tag

With git describe you can get the number of commits since the last tag. If you only had the tag and the number of commits what is the best way to show the commit that was described?

I know you could use git log tag.. and pipe it to a a script that does the counting but I was hoping for a more elegant solution similar to git show tag~n.

To add more context, we are planning using git describe to create release numbers, for example with

$ git describe
v1.5-39-g5ede964

we would use foo_1.5.39. What we would like to do is knowing 1.5.39 means the 39th commit after the v1.5 tag, find that commit, i.e. find g5ede964. As pointed out in a comment, the 39th commit after v1.5 may not be unique. So perhaps a better way to ask this is what is the best way to find all commits X such that if HEAD was pointing to X git describe would return v1.5-39-*****.

Upvotes: 31

Views: 26618

Answers (9)

Salvioner
Salvioner

Reputation: 333

You can now do so using

git show v1.5-39-g5ede964

and it will print the info about the commit, e.g.

commit 335ceedde1a2d61e48eb891b9f51a344705ee5af
Merge: 57628284 3b7eef9e
Author: John Doe <[email protected]>
Date:   Wed Dec 20 18:00:56 2023 +0200

Upvotes: 0

m19v
m19v

Reputation: 2192

Try the following, if you want to get the number of commits since last tag.

git rev-list $(git describe --abbrev=0)..HEAD --count

Upvotes: 5

ctech 2030
ctech 2030

Reputation: 1

This will give you the number of commits between these two commit.

$ git log --oneline 8a32722def6b80e343...e817c082323e65bb1053

Upvotes: 0

jthill
jthill

Reputation: 60275

what is the best way to find all commits X such that if HEAD was pointing to X git describe would return v1.5-39-*****

is still the wrong question. The right question is

how to find all commits X such that if HEAD was pointing to X an ordinary git describe could ever have returned v1.5-39-*****

and it's not all that easy to answer that. Still, absent enemy action this procedure will list the right commit maybe among some other possibilities:

ancestor=v1.5 n=39
git rev-list --all --reverse --topo-order --parents --ancestry-path ^$ancestor \
| awk ' function minmore(       i) {
                for ( i=2; i <= NF; ++i )
                        if ( gen[$i] > gen[$1] ) 
                                gen[$1]=gen[$i]
                return ++gen[$1]
        }
        minmore()<=n {
                print "[[ $(git rev-list --count "ancestor".."$1") == "n" ]] &&"
                print "         git describe --match="ancestor" "$1 }
      ' ancestor=$ancestor n=$n \
# | sh    # lose the first `#` here to actually run the generated checks

The reason for the uncertainty and complexity is that git describe is just trying to get a reasonable base, so (see its docs) it'll pick the most recent of the closest current tags it can see, and count how many additional commits there are in the described history, and generate a moniker that way. For examples, new tags can change its preferred base such that a bare git describe would no longer generate that moniker; and while SHA's are immutable, references can be rewritten.

Upvotes: 0

PhilLab
PhilLab

Reputation: 5007

As Kevin's answer explained, this is generally not possible. To solve the problem for special cases he mentioned:

That said, if you don't have a bunch of parallel branches going on at once, then you may be able to resolve a given commit number back to a single commit, but if you have even a single active side branch at the time of your tag then this may not work.

you can use the following command (with n being the number of commits since the tag)

git rev-list tag..HEAD --reverse | awk NR==n

Upvotes: 1

Justin Ohms
Justin Ohms

Reputation: 3523

If you are looking for the number of commits since the last tag, the following worked for me

git rev-list  `git rev-list --tags --no-walk --max-count=1`..HEAD --count

Upvotes: 16

Sam
Sam

Reputation: 431

Try

git rev-list tag..HEAD --count

OR

git rev-list tag.. --count

They mean the same thing.

Upvotes: 43

Lily Ballard
Lily Ballard

Reputation: 185681

What you're asking for is impossible in the general case. The number of commits alone can't tell you anything if there are any merges in your history.

For example, given the following repo structure:

a - b - c - d - h
  \           /
    e - f - g

With a tag put on a, the outputs of git describe d and git describe g are identical save for the SHA1:

> git describe d
tag-3-ge8dca33
> git describe g
tag-3-g4fecc2e

That said, if you don't have a bunch of parallel branches going on at once, then you may be able to resolve a given commit number back to a single commit, but if you have even a single active side branch at the time of your tag then this may not work.

If you need reliable release numbers, you should stick to explicit tags.

Upvotes: 8

fge
fge

Reputation: 121710

You can:

git log --oneline tag.. | wc -l

this will give you the number of commits

Upvotes: 5

Related Questions