1

Tag graph history isn't linear. People don't just tag baseline (master).

For example most valuable JS/CSS libraries perform release on branch from baseline to keep clean diff history. They commit release artifacts (compiled/minified JS/CSS) so users may easy grab artifacts without necessity to build. If they tag on master then master history will have huge all-on-all diffs on build artifacts.

Real example:

bash# cd js/jquery
/home/user/devel/js/jquery

bash# git remote -v
origin  https://github.com/jquery/jquery.git (fetch)

bash# git co master
Already on 'master'

bash# git describe --tags
2.1.0-beta1-590-g47ccf3d

bash# git log --graph  --decorate --simplify-by-decoration --oneline --all
* 70605c8 (origin/master, origin/HEAD) Ajax: Only form-encode requests with a body
* 47ccf3d (HEAD -> master) Attributes: do not set properties to false when removing booleans
| * 8339185 (origin/compat) Tests: Make regexes for iOS devices more rigid
| | * f9846ae (tag: 3.0.0-alpha1) 3.0.0-alpha1
| |/  
|/|   
...
* | 1185427 (tag: 2.1.0-beta1) Tagging the 2.1.0-beta1 release.

Tricks from How to get the latest tag name in current branch in Git? are useless in real world, for:

git describe --tags

I get 2.1.0-beta1 in above example, but most recent effort is 3.0.0-alpha1.

The best way I currently have is reviewing collapsed commit history manually from:

git log --graph --decorate --simplify-by-decoration --oneline --all
Community
  • 1
  • 1
gavenkoa
  • 45,285
  • 19
  • 251
  • 303
  • 1
    in [the answer](http://stackoverflow.com/a/24830212/1027800) from @ydroneaud there's a command to print tags in chronological order... isn't that precisely you want here? I think chronological order is the ideal metric given that these tags don't necessarily share a common history. – hineroptera Nov 04 '15 at 20:27
  • @hinerm Project may support old branches. As for jQuery example you may see v1.11.3 before 2.1.4 when order on date without respecting history DAG! – gavenkoa Nov 04 '15 at 21:17

1 Answers1

1

After digging to Git docs I managed to write:

$ git tag \
     | while read t; do \
         b=`git merge-base HEAD $t`; \
         echo `git log -n 1 $b --format=%ai` $t; \
       done | sort
...
2014-04-18 17:17:51 -0400 2.1.1-rc2
2014-04-30 10:43:39 -0400 2.1.1
2014-05-18 20:47:37 +0400 2.1.2
2014-05-18 20:47:37 +0400 2.1.3
2014-05-18 20:47:37 +0400 2.1.4
2015-07-13 15:01:33 -0400 3.0.0-alpha1

As I fill confident with Hg I made corresponding solution:

$ hg convert \
    $(git -C jquery/ rev-parse --branches --remotes --tags \
      | sed 's=.*=--rev &=') \
  jquery/ jquery-hg/

$ cd jquery-hg
$ hg up -r master

$ hg log -r 'tag()' --template '{node} {tags}\n' \
    | while read r t; do \
        hg log -r "ancestor($r,.)" --template "{date|isodate} {node} $t \n"; \
      done | sort

2014-06-16 03:08 +0400 f6f4d6eb708a33f714a2e0003cb7087762407348 2.1.2 
2014-06-16 03:08 +0400 f6f4d6eb708a33f714a2e0003cb7087762407348 2.1.3 
2014-06-16 03:08 +0400 f6f4d6eb708a33f714a2e0003cb7087762407348 2.1.4 
2015-07-13 15:01 -0400 4abe7e961f0e5eb0e75f03030a80a128553f34c1 3.0.0-alpha1 

I can add alias to ~/.bashrc and this code takes near 4 sec on jQuery/Hibernate/Lunix/Spring sources but some strange filling don't leave me. Are there one-liner solution?

UPDATE I wrote a long answer in https://stackoverflow.com/a/34239190/173149 Here is essential parts:

Because Git uses DAG and not linear history - it is hard to define distance metric so we can say - oh that rev is most nearest to my HEAD!

Some reasonable definition of distance between tag and revision:

  • length of shortest path from HEAD to merge base with tag (don't know who to calculate with git command)
  • date of merge base between HEAD and tag (see above script)
  • number of revs that reachable from HEAD but not reachable from tag (see below script)

Script that sort tags according to number of revs that reachable from HEAD but not reachable from tag:

$ git tag \
    | while read t; do echo `git rev-list --count $t..HEAD` $t; done \
    | sort -n

If your project history have strange dates on commits (because of rebases or another history rewriting or some moron forget to replace BIOS battery or other magics that you do on history) use that script.

Community
  • 1
  • 1
gavenkoa
  • 45,285
  • 19
  • 251
  • 303
  • git for-each-ref is better adapted for walking through the graph and select commits or tags. https://git-scm.com/docs/git-for-each-ref – Julien Carsique Apr 14 '17 at 14:11