Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

git - Tags with the same name with a branch

Tags:

git

branch

tags

I was kind of freaking out why on earth git diff branch1 branch2 is showing irrelevant things (it was like it's comparing branch1 with an OLDER version of branch2)

Until I found out we have some tags with the same name with a branch!

Other than diff, that makes problems on pull/push (ambiguous ref name error...), and possibly checkout...

So I want to find all these tags so that I can delete them

like image 483
saeedgnu Avatar asked Sep 16 '15 12:09

saeedgnu


2 Answers

First, we extract all the tags:

git tag | sort > tags

And branches, if you want to check this with local branches:

git branch | sed -e 's/^[ \t]*//' | sort > branches

Or branches of a specific remote, like origin

git branch -r | grep origin/  | sed -e 's:^[ \t]*origin/::' | sort > branches

After extracting tags and branches (in sorted order), we find the common lines in these 2 files:

comm -1 -2 tags branches > bad-tags

And view the file bad-tags
Then we can delete all of them:

cat bad-tags | xargs git tag -d
like image 184
saeedgnu Avatar answered Oct 15 '22 02:10

saeedgnu


saeedgnu's answer is on the right track, but uses many additional shell commands.

Instead of using | sort, both git tag and git branch have a --sort=<key> option, with <key> based on git for-each-ref field names and using a pattern.

By default, the default sort order, both for branches and tags, is already by refname.

And since Git 2.19 (Q3 2018), git branch supports a config branch.sort, like git tag already had a config tag.sort.
See commit 560ae1c (16 Aug 2018) by Samuel Maftoul (``).
(Merged by Junio C Hamano -- gitster -- in commit d89db6f, 27 Aug 2018)

So:

  • no need to sort git tag: they are already sorted by default by refname, unless a tag.sort config had been set.
    But to be on the safe side, use at least git tag --sort="refname" (no | sort needed)
  • no need to grep origin, sed or sort (unless a branch.sort config had been set): use a pattern and a format:

    git branch -r --list 'origin/*' --format="%(refname:lstrip=3)"
    

The format transforms a remotes/origin/aBranchName into aBranchName.
The pattern 'origin/*' makes sure we are selecting the remote branches of the right remote repo.

That gives you pure git commands:

git tag --sort="refname" > tags
git branch -r --list 'origin/*' --format="%(refname:lstrip=3)"
comm -1 -2 tags branches > bad-tags
like image 33
VonC Avatar answered Oct 15 '22 04:10

VonC