70

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)
Machavity
  • 30,841
  • 27
  • 92
  • 100
soerface
  • 6,417
  • 6
  • 29
  • 50
  • 1
    seems duplicate of [this thread](http://stackoverflow.com/questions/6269927/how-can-i-list-all-tags-in-my-git-repository-by-the-date-they-were-created) – Mali Sep 06 '13 at 14:21
  • 2
    “annotated tags” are new for me, thats a good word to search for. But the question there asked for the order of the tags when they were created, I would like to order them accordingly to the dates of the commits they are assigned to, I will make this more clear in the question, thanks. In the comments of the question you have linked it also refers to another question, which is also similiar: http://stackoverflow.com/questions/6900328/git-command-to-show-all-lightweight-tags-creation-dates – soerface Sep 06 '13 at 14:27
  • Also check out http://stackoverflow.com/a/22634649/6309 – VonC Aug 09 '14 at 19:56
  • @Mali not of duplicate of that one because that is about the annotated tag date. But duplicate of: http://stackoverflow.com/questions/6900328/git-command-to-show-all-lightweight-tags-creation-dates (mentioned by @wegenerd) since that it is the only sensible interpretation for lightweight tags. – Ciro Santilli OurBigBook.com Apr 27 '15 at 06:54
  • 1
    Possible duplicate of [git command to show all (lightweight) tags creation dates](https://stackoverflow.com/questions/6900328/git-command-to-show-all-lightweight-tags-creation-dates) – Trevor Boyd Smith Feb 21 '18 at 13:15

10 Answers10

71

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.

rraval
  • 1,007
  • 1
  • 9
  • 11
  • 24
    This is the best way, IMO. Except that you need to specify `taggerdate` instead of `commiterdate` if you want to get the chronological order of tags. – Alexander Amelkin May 24 '17 at 08:43
  • 1
    taggerdate works fine in Git 2.11.0 Is it possible to sort in inverted order though ? – CLOVIS Jan 12 '19 at 15:33
  • If you want just the first say 3, you can always pipe it into head: `git tag --sort=committerdate | head -3` – luckydonald Feb 01 '19 at 18:05
  • this doesn't work if you have several tags pointed to the same commit – Ezh Mar 13 '19 at 15:14
  • 4
    If you want to sort in descending order: _Prefix - to sort in descending order of the value_ (from link in answer). So i.e. `git tag --sort=-committerdate` – KJdev Mar 06 '20 at 23:22
  • 2
    This works only for lightweight tags. Unfortunately it does not work with annotated tags. – jakun May 08 '21 at 07:58
  • Thanks @jakun that was doing my head in. I asked a separate question specifically about annotated tags here: https://stackoverflow.com/questions/71670977/list-all-annotated-tags-with-annotation-and-commit-date-sorted-by-commit-date – naught101 Mar 30 '22 at 03:01
  • Thanks @naught101. I have asked another question for a mixture of annotated tags and lightweight tags: https://stackoverflow.com/q/71689439/2828064 – jakun Mar 31 '22 at 08:44
  • It 100% printed wrong for me. I added a tag today, added another one right after, printed with that command and my two tags are intermingled with al tags created yesterday... what in the world!!! git version 2.32.1 (Apple Git-133) – Dean Hiller Sep 08 '22 at 04:43
29

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

Community
  • 1
  • 1
opsidao
  • 1,441
  • 16
  • 23
  • 12
    This does **not** lists them sorted by date. In my repo a tag `testBranch-4` was listed after `master-10` even though testbranch is older – sydd Aug 12 '15 at 12:40
  • Well, it is supposed to do it @sydd... but it seems, there are some [known bugs with it](http://thread.gmane.org/gmane.comp.version-control.git/242392/focus=242822), but what they describe there doesn't seem to apply to your branch names... no idea, it works on my machine :P (just kidding, it sounds like a bug in git itself, have you tried with git 2.5?) – opsidao Aug 12 '15 at 15:54
  • 4
    Surely this only works for because the chrono ordering happens to match your alpha ordering? Isn't taggerdate what is wanted? – Neil Gatenby Feb 08 '17 at 13:20
  • 4
    the only thing that actually worked for me is `git tag --sort=taggerdate` as per [this answer](https://stackoverflow.com/a/39839178/777285) – Arnaud P Jul 24 '17 at 15:23
  • 2
    This does **not** list by date, but annotation: https://git-scm.com/docs/git-for-each-ref#Documentation/git-for-each-ref.txt-refname – Brandt Oct 06 '19 at 16:18
20
git tag | xargs -I@ git log --format=format:"%ai @%n" -1 @ | sort | awk '{print $4}'
soerface
  • 6,417
  • 6
  • 29
  • 50
  • 7
    Impressive, though hard to remember for casual typing. What would be nice: `git tag --sort=date` or something like that. – Craig McQueen Jan 10 '14 at 01:08
  • 1
    The solution in [the thread](http://stackoverflow.com/questions/6269927/how-can-i-list-all-tags-in-my-git-repository-by-the-date-they-were-created) @Mali mentioned is better. `git for-each-ref --sort=-committerdate --format=%\(refname:short\) refs/tag` – richsoni Oct 15 '14 at 13:31
  • This will use commit date for sorting not the time of creation of the tag. As a result you may not get the latest tag if it was created from older commit. – Dmitri Mar 01 '15 at 23:48
  • @Dmitri, "lightweight" tag is simply a name for an object so it doesn't contain any other info – stevemao Aug 20 '15 at 10:57
  • Great, have a lot of old ubuntu 14.04 containers with git 1.9.1 and they do not support --sort – MortenB Feb 20 '17 at 10:07
  • 3
    mate your answer would be 10x better if you could explain what that magic pipe of commands does, it is awesome. – alexserver Jun 14 '17 at 22:20
  • `git log --no-walk --tags` in whatever format you like. – jthill Aug 25 '23 at 16:47
18

For information, to get it in reverse order, prefix it with "-"

git tag --sort=-taggerdate
rfrerebe
  • 409
  • 4
  • 4
10

As far as I can tell, even with git 2.37+, there is no single git command to sort tags by date of the commits they point to, because the available sort options are:

It should be

git tag --sort=*committerdate

for correct commit chronological order for only annotated tags.

(iff you're interested in the date the tags where pushed, use taggerdatehere.)

and

git tag --sort=committerdate

for only lightweight tags.

git supports a special field, creatordate:

For commit and tag objects, the special creatordate ... will correspond to the appropriate date ... from the committer or tagger fields depending on the object type. These are intended for working on a mix of annotated and lightweight tags.

This field will collapse the committerdate of lightweight tags and the taggerdate of annotated tags.

You can use

git tag --sort=creatordate

for a mix of tag types, but this will not sort by commit date, because it will sort the annotated tags by their creation("tagger") date, which is not the date of the commit they point to.

To my knowledge, you need to use:

git tag -l --format="%(refname:short) :: %(committerdate:iso) :: %(*committerdate:iso) ::"

and then sort that output with the date that is set (committerdate and *committerdate are mutually exclusive here, AFAICT).

You can also collapse the two values directly in the format expression:

git tag -l --format="%(refname:short) :: %(if)%(committerdate:iso)%(then)%(committerdate:iso)%(else)%(*committerdate:iso)%(end)"
Martin Ba
  • 37,187
  • 33
  • 183
  • 337
mwallner
  • 985
  • 11
  • 23
  • I've found that some tags have no `taggerdate`, but they always have a `committerdate`. For `git tag --sort=-taggerdate --format "%(refname:short) %(taggerdate:short)"` I get the tags with taggerdates at the top, and none of the rest show any dates. `committerdate` always sorts and shows dates. – theory Oct 04 '21 at 16:01
9
git log --date-order --tags --simplify-by-decoration --pretty=format:"%ci %d"
seacoder
  • 514
  • 5
  • 11
4

Another way:

git log --no-walk --tags --decorate --oneline

Example:

$ 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:

dentarg
  • 1,694
  • 2
  • 12
  • 20
3

Try this:

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

It works perfectly and very fast for me.

Refer to How can I list all tags in my Git repository by the date they were created?

Community
  • 1
  • 1
John Zhang
  • 1,043
  • 2
  • 13
  • 22
2

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.

theory
  • 9,178
  • 10
  • 59
  • 129
-1

You may want to use --topo-order.


If you are trying to make CHANGELOG.md, you can use output of this command:

git log --pretty=format:"Commit: %an: %B %d" --tags  --topo-order > changelog.log
TylerH
  • 20,799
  • 66
  • 75
  • 101
ADR
  • 1,255
  • 9
  • 20
  • ChatGPT content is not allowed on Stack Overflow. – TylerH Aug 25 '23 at 14:33
  • This is NOT ChatGPT content! This is a manual on how to USE ChatGPT to make CHANGELOG.md. It was tested on my case, and I wanted to share it. Now, after my answer was edited, it doesn't make much sense. – ADR Aug 30 '23 at 23:30