git - 带分支的同名标签

时间:2015-09-16 12:54:02

标签: git tags branch

我有点吓坏了为什么地球git diff branch1 branch2显示无关紧要的事情(就像它将branch1与一个OLDER版本的branch2进行比较)

直到我发现我们有一些带有分支的同名标签!

除了差异之外,这会导致拉/推(模糊的引用名称错误......)以及可能结帐的问题......

所以我想找到所有这些标签,以便我可以删除它们

3 个答案:

答案 0 :(得分:7)

首先,我们提取所有标签:

git tag | sort > tags

分支机构,如果你想用本地分支机构检查一下:

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

或特定遥控器的分支,例如origin

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

在提取标签和分支(按排序顺序)后,我们在这两个文件中找到公共行:

comm -1 -2 tags branches > bad-tags

查看文件bad-tags
然后我们可以删除所有这些:

cat bad-tags | xargs git tag -d

答案 1 :(得分:1)

saeedgnuanswer处在正确的位置,但是使用了许多其他Shell命令。

git taggit branch都使用| sort选项,而不是使用--sort=<key>,而<key>基于git for-each-ref field names和{{3 }}。

默认情况下,分支机构和标签的默认排序顺序已经是 refname

而且自Git 2.19(2018年第三季度)以来,git branch支持配置branch.sort,就像git tag已经具有配置tag.sort
请参见using a patterncommit 560ae1c(2018年8月16日)。
(由Samuel Maftoul (``)Junio C Hamano -- gitster --中合并,2018年8月27日)

所以:

  • 无需对git tag进行排序:默认情况下,它们已经由refname进行了排序,除非设置了tag.sort配置。
    但是为了安全起见,请至少使用git tag --sort="refname"(无需使用| sort
  • 无需grep originsedsort(除非已设置branch.sort配置):使用模式和格式:

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

该格式将remotes/origin/aBranchName转换为aBranchName
模式'origin/*确保我们选择了正确的远程仓库的远程分支。

这为您提供了纯git命令:

git tag --sort="refname" > tags
git branch -r --list 'origin/*' --format="%(refname:lstrip=3)"
comm -1 -2 tags branches > bad-tags

答案 2 :(得分:0)

除了脚本(使用纯git命令)之外,不良标签的数量也有所增加,Git 2.20(2018年第四季度)为 avoid 提供了一种替代方法,即必须通过分支获取具有相同名称的标签。< / p>

git push”和“ git fetch”使用的确定引用是否可以更新的规则不一致;具体来说,即使标签被认为无法移动锚点,也允许进行提取以更新现有标签。
教“ git fetch”禁止在没有“ --force”选项的情况下更新现有标签。

请参见commit 0bc8d71commit ae6a470commit fe802bdcommit 8da6128commit d931455commit 6b0b067commit 253b3d4,{{3} },commit f08fb8d(2018年8月31日)由commit 8cd4b7c
(由Ævar Arnfjörð Bjarmason (avar)Junio C Hamano -- gitster --中合并,2018年9月17日)

获取:不使用--force即可停止破坏现有标签

将refspecs中的“ fetch”更改为“ +”(也称为--force)表示我们 应该破坏同名的本地标签。

  

这改变了commit d39cab3中添加的“ fetch”的长期行为(“ [PATCH]多头读取。”,2005-08-20,Git 0.99.5)。 br />   在进行此更改之前,所有标签提取均已有效启用--force
  参见853a369

     
    

标签不必指向提交,因此没有办法     无论如何都要保证“快进”。

  
     

该提交和“ fetch”历史记录的其余部分表明,refpecs的“ +”(--force)部分仅被设计用于分支更新,而标签已被接受来自上游的任何更改都会无条件地破坏本地标签对象。更改此行为git-fetch-script code in fast_forward_local() with the comment

     

当前的行为对我来说没有意义,很容易导致本地标签意外被破坏。
  我们可以为每个远程标记添加名称空间,而不是在本地填充refs/tags/*,但可以像我的has been discussed as early as 2011(“ fetch:添加--prune-tags选项和fetch.pruneTags   config”,2018-02-09,Git 2.17),解决当前问题更容易   实施比解​​决根本原因。

(请参见“ 97716d2”)

  

因此,此更改实现了In Git, how do I sync my tags against a remote server?,“ fetch”现在仅在提供“ +”作为refspec的一部分或“ --force ”在命令行上提供。

     

这也使得它在“ tag”本身工作时具有很好的对称性   创建标签。
  即除非提供“ --force”,否则我们将拒绝发布任何现有标签。
  现在我们可以拒绝所有这样的破坏,无论是通过破坏带有“ tag”的本地标签,还是通过使用“ fetch”从远程获取它都可以。

     

refs/{tags,heads/*之外的引用更新仍然与suggestion #1 from Jeff's 2011 E-Mail的工作原理不对称,
  这一变化使两种不同的行为更加相互吻合。我不认为“获取”不能完全与“ git push”所使用的行为完全融合,但这是另一个更改的主题。

相关问题