git: list dangling tags
Asked Answered
T

3

7

Context:

  • assume you have some rather tricky CI/CD workflow which relies on git tags
  • the feature branches are built and generate some short-lived tags to signify commits which yield the deployable artifacts
  • when the feature branch gets squash-merged, usually it's deleted, but the tags, unsurprisingly, survive
  • after, say, several months of development the tag listing predictably becomes hairy

Hence, the question:

how would I, using git command line and, optionally, basic bash tooling

  1. list all the branches which have given tag reachable (the dual to that is git tag -l --merged ${BRANCH_COMMITTISH}, but I need not tags for the given branch but branches for a given tag)
  2. list all the tags which have empty output from point 1 above (obviously this is doable with a for loop (given any terminating implementation for 1), but maybe there's some neat magical git one-liner)?
Turgot answered 31/7, 2018 at 13:45 Comment(0)
S
6
git log --simplify-by-decoration --tags --not --branches --remotes --pretty=%d

--simplify-by-decoration says only show the bare minimum needed to reveal the ancestry (usually you use this with --graph). --tags --not --branches --remotes says, well, what it says: list the tag history that's not in the branches or remotes history, i.e. tags unreachable from any branch or remote-tracking branch. --pretty=%d says just show the refs.

Splenomegaly answered 31/7, 2018 at 14:27 Comment(1)
that I won't have found/figured myself, ever, thanks a lot!Turgot
R
3
  1. git branch --contains ${TAG}

https://git-scm.com/docs/git-branch#git-branch---containsltcommitgt.

Retard answered 31/7, 2018 at 14:12 Comment(1)
oh well, I had to read the flaming manual for just a tad longer, thanks!Turgot
T
0

Just to illustrate all solutions I've seen so far:

~$ git init dangling_tags
Initialized empty Git repository in ~/dangling_tags/.git/
$ cd dangling_tags/
~/dangling_tags$ touch a.txt && git add a.txt && git commit -m a
[master (root-commit) f1b1070] a
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 a.txt
~/dangling_tags$ git tag a
~/dangling_tags$ git checkout -b feature/add_some_tags
Switched to a new branch 'feature/add_some_tags'
~/dangling_tags$ touch b.txt && git add b.txt && git commit -m b 
[feature/add_some_tags 1871cde] b
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 b.txt
~/dangling_tags$ git tag b
~/dangling_tags$ touch c.txt && git add c.txt && git commit -m c 
[feature/add_some_tags 26f6611] c
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 c.txt
~/dangling_tags$ git tag c
~/dangling_tags$ git checkout master
Switched to branch 'master'
~/dangling_tags$ git merge --squash feature/add_some_tags 
Updating f1b1070..26f6611
Fast-forward
Squash commit -- not updating HEAD
 b.txt | 0
 c.txt | 0
 2 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 b.txt
 create mode 100644 c.txt
~/dangling_tags$ git commit
[master 99b33ae] Squashed commit of the following:
 2 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 b.txt
 create mode 100644 c.txt
~/dangling_tags$ git branch --contains a
* master
~/dangling_tags$ git branch --contains b
  feature/add_some_tags 
~/dangling_tags$ git branch -D feature/add_some_tags 
Deleted branch feature/add_some_tags (was 26f6611).
~/dangling_tags$ git tag
a
b
c
~/dangling_tags$ git branch --contains a
* master
~/dangling_tags$ git branch --contains b
~/dangling_tags$ for t in $(git tag); do if test "$(git branch --contains $t | wc -l)" == "0" ; then echo $t; fi done
b
c
~/dangling_tags$ git log --simplify-by-decoration --tags --not --branches --remotes --pretty=%d
 (tag: c)
 (tag: b)
Turgot answered 31/7, 2018 at 14:40 Comment(1)
In the command before the last one for t in $(git tag); do if test "$(git branch --contains $t | wc -l)" == "0" ; then echo $t; fi done, there's a missing semicolon just before done. I can't edit the answer to add it because only 6-char change is a valid edit.Ramer

© 2022 - 2024 — McMap. All rights reserved.