`git tag` sorted in chronological order of the date of the commit pointed to
GitSortingGit Problem Overview
The output from git tag
is ordered alphabetically. I would like it to be ordered chronological (the date of the commits they are assigned to, not the date on which they were created), otherwise the output should stay the same.
I’ve tried the suggestion from http://networkadmin20.blogspot.de/2010/08/howto-list-git-tags-by-date.html, but the order is still the same.
To make sure it is not an error with my repository, I tried the following with a clean repository:
soeren@ubuntu ~/Projects/sandbox % mkdir chronogit
soeren@ubuntu ~/Projects/sandbox % cd chronogit
soeren@ubuntu ~/Projects/sandbox/chronogit % git init
Initialized empty Git repository in /home/soeren/Projects/sandbox/chronogit/.git/
soeren@ubuntu ~/Projects/sandbox/chronogit (git)-[master] % touch a
soeren@ubuntu ~/Projects/sandbox/chronogit (git)-[master] % git add a
soeren@ubuntu ~/Projects/sandbox/chronogit (git)-[master] % git commit -m 'a'
[master (root-commit) f88e0e9] a
0 files changed
create mode 100644 a
soeren@ubuntu ~/Projects/sandbox/chronogit (git)-[master] % git tag 'A-first'
soeren@ubuntu ~/Projects/sandbox/chronogit (git)-[master] % git mv a b
soeren@ubuntu ~/Projects/sandbox/chronogit (git)-[master] % git commit -m 'c'
[master ecc0c08] c
1 file changed, 0 insertions(+), 0 deletions(-)
rename a => b (100%)
soeren@ubuntu ~/Projects/sandbox/chronogit (git)-[master] % git tag 'C-second'
soeren@ubuntu ~/Projects/sandbox/chronogit (git)-[master] % git mv b c
soeren@ubuntu ~/Projects/sandbox/chronogit (git)-[master] % git commit -m 'b'
[master e72682d] b
1 file changed, 0 insertions(+), 0 deletions(-)
rename b => c (100%)
soeren@ubuntu ~/Projects/sandbox/chronogit (git)-[master] % git tag 'B-third'
soeren@ubuntu ~/Projects/sandbox/chronogit (git)-[master] % git tag
A-first
B-third
C-second
soeren@ubuntu ~/Projects/sandbox/chronogit (git)-[master] % git for-each-ref refs/tags --sort=taggerdate --format="%(refname:short)"
A-first
B-third
C-second
The desired output is:
A-first
C-second
B-third
or, since inverting it shouldn’t be too hard:
B-third
C-second
A-first
Edit: As pointed out in the comments, this question is pretty similiar, so I tried the following:
soeren@ubuntu ~/Projects/sandbox/chronogit (git)-[master] % git log --tags --simplify-by-decoration --pretty="format:%ai %d"
2013-09-06 16:08:43 +0200 (HEAD, B-third, master)
2013-09-06 16:08:21 +0200 (C-second)
2013-09-06 16:07:42 +0200 (A-first)
The order is fine, but now I’m fighting with the formatting…
soeren@ubuntu ~/Projects/sandbox/chronogit (git)-[master] % git log --tags --simplify-by-decoration --pretty="format:%(refname:short)"
%(refname:short)
%(refname:short)
%(refname:short)
soeren@ubuntu ~/Projects/sandbox/chronogit (git)-[master] % git log --tags --simplify-by-decoration --format="%(refname:short)"
%(refname:short)
%(refname:short)
%(refname:short)
Git Solutions
Solution 1 - Git
Just tested with git 2.8.0:
git tag --sort=committerdate
For a full list of field names you can use, see https://git-scm.com/docs/git-for-each-ref#_field_names
> For commit and tag objects, the special creatordate
and creator
fields will correspond to the appropriate date or name-email-date tuple from the committer or tagger fields depending on the object type. These are intended for working on a mix of annotated and lightweight tags.
>
> Fields that have name-email-date tuple as its value (author
, committer
, and tagger
) can be suffixed with name
, email
, and date
to extract the named component.
Solution 2 - Git
In git 2.3.3 I can just do this to get them sorted by date:
git tag --sort version:refname
PS: For the record, I also answered the same thing on a duplicate question
Solution 3 - Git
git tag | xargs -I@ git log --format=format:"%ai @%n" -1 @ | sort | awk '{print $4}'
Solution 4 - Git
For information, to get it in reverse order, prefix it with "-"
git tag --sort=-taggerdate
Solution 5 - Git
git log --date-order --tags --simplify-by-decoration --pretty=format:"%ci %d"
Solution 6 - Git
As Alexander pointed out it should be
git tag --sort=taggerdate
for correct chronological order.
edit:
- iff you're interested in the date the tags where pushed, if you're interested in the date of the commits, it should be "commiterdate"
Solution 7 - Git
Try this:
git for-each-ref --sort=taggerdate --format '%(refname) %(taggerdate)' refs/tags
It works perfectly and very fast for me.
Solution 8 - Git
Another way:
git log --no-walk --tags --decorate --oneline
$ git log --no-walk --tags --decorate --oneline | head -n5
e214a28f (tag: v4.20.0, origin/4-stable) Release 4.20.0
519512ae (tag: v4.19.0) Release 4.19.0
a201a5ca (tag: v4.18.0) Release 4.18.0
c5037e4a (tag: v4.17.0) Release 4.17.0
9f19351d (tag: v4.16.0) Release 4.16.0
References:
-
https://git-scm.com/docs/git-log#Documentation/git-log.txt---no-walksortedunsorted
-
https://git-scm.com/docs/git-log#Documentation/git-log.txt---tagsltpatterngt
-
https://git-scm.com/docs/git-log#Documentation/git-log.txt---decorateshortfullautono
-
https://git-scm.com/docs/git-log#Documentation/git-log.txt---oneline
Solution 9 - Git
I want to use taggerdate
, but it does not always have a value:
git tag --sort=-taggerdate --format "%(refname:short) %(taggerdate:short)" | head -5
v41 2018-11-05
v40 2018-11-05
v1
v10
v100
To support the scenario in which taggerdate
is not set, fall back on the creatordate
and use sort
to sort the generated field specifically:
$ git tag --format '%(refname:short) %(if)%(taggerdate)%(then)%(taggerdate:short)%(else)%(creatordate:short)%(end)' | sort -k2,2 -t$'\t' | head -5
v1 2018-05-15
v2 2018-05-15
v3 2018-05-15
v4 2018-05-24
v5 2018-06-12
Here's the alias:
[alias]
tags = ! git tag --format '%(refname:short)\t%(if)%(taggerdate)%(then)%(taggerdate:short)%(else)%(creatordate:short)%(end)' | sort -k2,2 -t$'\t'
Thanks to @thomas-sibley for the solution in this thread.