5

Getting latest tag on git repository

 2 months ago
source link: https://gist.github.com/rponte/fdc0724dd984088606b0
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Getting latest tag on git repository · GitHub

Instantly share code, notes, and snippets.

Getting latest tag on git repository

this did it better.

git tag | sort -V | tail -1

This does not work

0.1.9 should come before 0.1.10

The sort just sorts alphabetically

This does not work for me either. I have a list of tags like the one below

$git tag
v1.1.1
v1.1.2
v1.1.3
v1.2.0-rc.1
v1.2.0-rc.2
v1.2.0-rc.3
v1.2.0-rc.4
v1.2.0-rc.5
v1.2.0-rc.6
v1.2.0-rc.7

The tags RC are generated automatically, then I am tagging manually for the release version -> git tag v1.2.0 and doing a git describe I am expecting the v1.2.0 since it is the tag I just added. However, I am getting the v1.2.0-rc.7

Any idea why?

$git describe
v1.2.0-rc.7

$git tag
v0.1.0-rc.1
v0.1.0-rc.2
v0.1.0-rc.3
v1.0.0
v1.1.0
v1.1.0-rc.1
v1.1.1
v1.1.2
v1.1.3
v1.2.0           <- here is the lastest tag I added. As per the git documentation it lists the tags in alphabetical order which makes senses
v1.2.0-rc.1
v1.2.0-rc.2
v1.2.0-rc.3
v1.2.0-rc.4
v1.2.0-rc.5
v1.2.0-rc.6
v1.2.0-rc.7

The tag v1.2.0-rc.7 and v1.2.0 are on the same commit

@tavo-sanchez
That's exactly because both tags are on the same commit.
git rev-list --tags --max-count=1 gets the commit ID for the latest tag, and then git describe --tags [COMMIT_ID] displays the tags on this commit.

Yeah, this is tricky. To get the “latest,” you really have to define what you actually mean by “latest,” for example:

  • Most recent in time? Add --sort=committerdate flag.
  • Largest version number? Pipe through | sort -V (for version friendly sorting)

This is important, because in some repositories, depending on the branching structure and amount of concurrent supported major versions, you may easily have a version tag like 1.2.3 added chronologically after version 2.3.4. By default, git will simply sort tags lexicographically (er, alphabetical) and that can even be changed based on your user settings.

Ideally, you just wanna sort consistently, across machines and developers for a consistent experience (e.g. like for tagging and shipping builds). For example:

# Most recent by date
git tag --sort=committerdate | tail -1

# Largest version number (assuming ALL your tags are numbered... see below)
git tag | sort -V

In my case, I prefer to filter out tags that start with a number (my system is 1.2.3, but your system could be v1.2.3) because I will often work in repositories that may contain non-numbered/non-version tags (which will become clutter for versioning). So depending on your needs, that would just become:

# Pure number, e.g. 1.2.3
git tag --sort=committerdate | grep -E '^[0-9]' | tail -1
git tag  | grep -E '^[0-9]' | sort -V | tail -1

# Or with v-prefix, e.g. v1.2.3
git tag --sort=committerdate | grep -E '^v[0-9]' | tail -1
git tag  | grep -E '^v[0-9]' | sort -V | tail -1

# Don’t forget: You can even use -v flag in grep to exclude! E.g.
git tag  | grep -E '^v[0-9]' | grep -v '-rc' | sort -V | tail -1

Hopefully this helps someone else. I know I studied and wrote most of this up for my own reference too! sunglasses

@patricknelson beautiful, thanks! ok_hand

nfantone commented on Dec 26, 2019

edited

Adding on top of @patricknelson excellent response, you can omit grep entirely by providing a pattern to git tag.

# Equivalent to grep -E '^[0-9]'
git tag --sort=committerdate --list '[0-9]*'

Additionally, if you are on PowerShell, you may want to replace tail -1 with Select-Object -Last 1 to fetch that last item.

# Equivalent to tail -1
git tag --sort=v:refname | Select-Object -Last 1

@patricknelson great explanation, thanks!

@nfantone nice! Thank you!

This is how you get the latest tagged version, but remove the v...

git tag --sort=committerdate | grep -E '[0-9]' | tail -1 | cut -b 2-7

I had more accurate results with taggerdate as a sort key instead of committerdate
git tag --sort=taggerdate | tail -1

I had more accurate results with taggerdate as a sort key instead of committerdate
git tag --sort=taggerdate | tail -1

Yes or the creatordate, the committerdate doesn't work for me.
And don't forget that you can add - (e.g. --sort=-taggerdate) before to sort it as newer -> older

the-glima commented on Apr 8, 2020

edited

For the latest tag on remote I'm doing this:

$ git ls-remote --tags --sort=committerdate | grep -o 'v.*' | sort -r

v1.2.3
v1.2.2
v1.2.1
v1.2.0
v1.1.0

Or, what I wanted, just the single latest one:

 $ git ls-remote --tags --sort=committerdate | grep -o 'v.*' | sort -r | head -1

v1.2.3

bodia-uz commented on Apr 9, 2020

edited

Faced with problem after using taggerdate and old git version on CI:

git tag --list "RC;*" --sort=taggerdate | tail -1
error: unsupported sort specification ‘taggerdate’

Found a better way to do it (git describe and --abbrev=0 argument):

git describe --abbrev=0
git describe --abbrev=0 --match "RC;*"

You can find a same example on https://git-scm.com/docs/git-describe page:

image

The difference is, that git will take the latest tag for this branch (not for all branches).

A similar approach uses lerna for getting the last tag:
https://github.com/lerna/lerna/blob/f2c3a92fe41b6fdc5d11269f0f2c3e27761b4c85/utils/collect-updates/collect-updates.js#L31
https://github.com/lerna/lerna/blob/f2c3a92fe41b6fdc5d11269f0f2c3e27761b4c85/utils/describe-ref/lib/describe-ref.js#L36

joseluisq commented on Apr 23, 2020

edited

In my case (Git v2.25), the command git describe --tags $(git rev-list --tags --max-count=1) returns the latest tag.

What's wrong with a simple git tag -l | tail -1?

It's sorted alphabetically...

Just in case anyone is looking for how to update package.json's version with the latest tag:

let fs = require('fs');
const { exec, execSync } = require('child_process');

if (fs.existsSync('./package.json')) {
  var package = require('./package.json');
  let currentVersion = package.version;

  exec('git tag --sort=committerdate | tail -1', (error, stdout) => {
    if (error) {
      console.error(`exec error: ${error}`);
      return;
    }

    let newVersion = stdout.trim();
    package.version = newVersion;
    fs.writeFileSync('./package.json', JSON.stringify(package, null, 2));

    execSync("git commit -am 'Bump version '" + newVersion);

    console.log('Version updated', currentVersion, '=>', newVersion);
  });
}

Not working with gitlab, got the usage information.

$ git rev-list --tags --max-count=1
usage: git rev-list [OPTION] <commit-id>... [ -- paths... ]
  limiting output:
    --max-count=<n>
    --max-age=<epoch>
    --min-age=<epoch>
    --sparse
    --no-merges
    --min-parents=<n>
    --no-min-parents
    --max-parents=<n>
    --no-max-parents
    --remove-empty
    --all
    --branches
    --tags
    --remotes
    --stdin
    --quiet
  ordering output:
    --topo-order
    --date-order
    --reverse
  formatting output:
    --parents
    --children
    --objects | --objects-edge
    --unpacked
    --header | --pretty
    --abbrev=<n> | --no-abbrev
    --abbrev-commit
    --left-right
  special purpose:
    --bisect
    --bisect-vars
    --bisect-all

cawa-93 commented on Dec 11, 2020

edited

Maybe someone will tell me how to get the last tag, or if there are no tags in the branch - the initial commit?

I would like to know how the last tag that was tagged before a specific tag. Meaning lets say I have.

2.0.0
1.5.10
1.5.8
1.0.1

I like to say git --last-tag-b4="1.5.10" and it should give me 1.5.8. When 1.5.9 was never created or deleted.

@cawa-93 why not just git tag | sort -V | tail -1? i.e. Sort tags by version and just take the last one (tail -1). If that's empty, then git tag returned nothing.

@nextgenthemes The best (hacky) way I can think of quickly is to use version sort and then use grep to to find an exact match for the version you know already exists (a possible shortcoming if that exact version you're looking for isn't already present).

# 1. Pull out tags
# 2. Use version sort
# 3. Use grep to find the known version, ensuring we also output the line before
# 4. Just take the first line (the line before the match)

git tag | sort -V | grep -B 1 1.5.8 | head -1

Alternative, you could probably use awk to use a comparison operator (e.g. awk '$1 < NUMBER { print }') but I don't know how to do that when the number has multiple dots in it, nor in a way that would be version safe... disappointed

@patricknelson Thanks. I was thinking about some pipe thing. This actually reads and works quite nice. Not sure why I am obsessing trying to do it with more git and less gnu right now. Tell me to stop ;)

dimisjim commented on Mar 16, 2021

edited

One could also do, without using git: curl -s GET https://api.github.com/repos/aws/aws-cli/tags | jq -r '.[].name' | head -n1

One could also do, without using git: curl -s GET https://api.github.com/repos/aws/aws-cli/tags | jq -r '.[].name' | head -n1

add per_page params curl -s GET https://api.github.com/repos/cloudreve/Cloudreve/tags\?per_page\=1 | jq -r '.[].name'

Ran into an issue where we accidentally made two tags on the same commit, in that case this method returns the first tag it encounters, which is the earliest tag, not the latest.

You can get the most recent commit by doing git tag --sort=committerdate | tail -1

The commit date sort way is unreliable, because you don't know if someone create a wrong tag.

Using:

git describe --tags git rev-list --tags --max-count=1

returns me the last tag with a commit.

but if I create a new tag from an older commit (without a new commit), it will return the wrong tag: the last tag with a commit!

Using:

git tag --sort=committerdate | tail -1

returns me a tag created 1 year ago, I dont know why...

git-tag1

My real last tag:

git-tag2

can someone help me to return the last tag created?

patricknelson commented on Mar 15

edited

@MarcusPetri found this on StackOverflow: https://stackoverflow.com/a/6270112/899075

git for-each-ref --sort=creatordate --format '%(refname) %(creatordate)' refs/tags

But are you interested in when the tag itself was actually created, or, are you really just interested in seeing the semantically largest tag number (see number sorting below)? The reason I ask is because it's technically possible for you to currently be on v2 but then at a later date create the tag v1.1 (which is obviously smaller) well after both v1 and v2 already existed. That command would sort it as v1, v2, v1.1 instead of the semantic ordering of v1, v1.1, v2 and etc.

Example of naïve sort vs. version sorting:

# Naïve sort
$ sort test/test.txt
0
1.01
10.1
2
# Version sort
$ sort -V test/test.txt
0
1.01
2
10.1

@MarcusPetri found this on StackOverflow: https://stackoverflow.com/a/6270112/899075

git for-each-ref --sort=creatordate --format '%(refname) %(creatordate)' refs/tags

But are you interested in when the tag itself was actually created, or, are you really just interested in seeing the semantically largest tag number (see number sorting below)? The reason I ask is because it's technically possible for you to currently be on v2 but then at a later date create the tag v1.1 (which is obviously smaller) well after both v1 and v2 already existed. That command would sort it as v1, v2, v1.1 instead of the semantic ordering of v1, v1.1, v2 and etc.

Example of naïve sort vs. version sorting:

# Naïve sort
$ sort test/test.txt
0
1.01
10.1
2
# Version sort
$ sort -V test/test.txt
0
1.01
2
10.1

Thanks for the answer.

I just really need the last tag created, I don't care if it has v1, v2...

git tag | sort -g | tail -1


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK