删除超过X个月的远程git标记

时间:2018-02-05 18:46:17

标签: git gitlab

我正在尝试删除超过X个月的git标记

我们有需要保留的发布代码,它们都标记为release-* * = date

我知道如何删除单个标记git push origin :refs/tags/<tagName>

所以我推断得到所有的远程标签来删除它们

git ls-remote --tags origin | xargs git push origin :$1

要跳过发布标记,我计划使用egrep -v发出命令

git ls-remote --tags origin | egrep -v "(^\*|release*)" | xargs git push origin :$1

但我仍然没有想出如何按日期去做。

在本地,我可以像git for-each-ref --sort=taggerdate --format '%(refname)' refs/tags | egrep -v "(^\*|release*)"一样按日期订购,但这对我的远程标签没有帮助。

如果有帮助我不介意删除或不删除本地标签以删除远程标签。

最后我们使用gitlab,如果它提供了更好的清理方法吗?

无论如何,这需要通过Jenkins像脚本一样运行,以帮助满足我们的git清理需求。

更新

由于我们有数千个git标签,我意识到xargs会变得相当慢。

我相信删除的方式更像是

git push origin $(< git tag | <sorting_by_date + exclude release> \ | sed -e 's/^/:/' | paste -sd " ")

这样命令基本上会将:refs/tags/tag1 :refs/tags/tag2附加到单个命令中,而不是对每个标记进行唯一删除并联系遥控器。

2 个答案:

答案 0 :(得分:3)

在过去几天的工作之后,我找到了一个效果很好的解决方案。

首先按时间顺序收集所有git标记,我排除了release*标记

git for-each-ref --sort=taggerdate --format '%(refname:short) %(taggerdate:short)' refs/tags | egrep -v "(^\*|release*)"

这将提供以下输出

master_7 2017-12-05
master_8 2017-12-05
master_9 2017-12-07
master_10 2017-12-08
master_11 2017-12-08
update_framework_1 2017-12-12
master_12 2017-12-12
master_13 2017-12-13

所以它是由空格分隔的标签名称,然后是YYYY-MM-DD格式的日期。如果您想要一个完整的日期或某些特定的更新taggerdate:short与适当的东西。

然后我拿出输出并逐行处理,查看日期并将其与截止日期进行比较。

这允许我生成要删除的标签列表。

然后我通过循环标记列表并执行以下命令来运行删除

git push origin :refs/tags/<tag1> :refs/tags/<tag2>

我安全地播放它并且每50个标签运行一次命令,但git似乎没有任何问题。

最后,在所有删除完成后,我运行 git fetch --prune origin +refs/tags/*:refs/tags/*删除遥控器中不存在的所有本地标记。

并且你已经清理了所有标签。

答案 1 :(得分:0)

您需要对日期戳的来源非常具体,因为有多个候选人:

  • 标签名称本身,或
  • 带注释的标记对象,如果标记是带注释的标记,或
  • 标签最终指向的提交,可能通过中间对象(带注释的标签)。

其中,只有第一个可以通过git ls-remote立即获得:为了得到其余部分,您必须在本地提供对象,以便您可以读取它们并提取其嵌入的(通过文本编码)日期邮票。

您可以使用git fetch --tags origin获取标签及其目标对象,这与运行大致相同,例如,`git fetch origin'+ refs / tags / :refs / tags / ”。但是,如果您想确保您的存储库没有将其标记作为标记,那么您可能希望将这些标记提取到一个单独的名称空间中,例如:

git fetch origin '+refs/tags/*:refs/rtags/origin/*'

因此,无论他们(来源)的存储库标记为refs/tags/v12.34,现在都会以名称refs/rtags/origin/v12.34显示在您的存储库中。您现在可以在v12.34空格下阅读名称refs/rtags/origin/

然后,您可以使用全名来读取标记的Git对象。如果标记的对象是带注释的标记,则可以提取其元数据,包括其日期。如果标记对象是提交,则可以读取其元数据。

如果标记对象是带注释的标记,则可以读取其object元数据并继续读取对象(“剥离”标记),直到找到最终对象为止。或者您可以让Git使用name^{commit}name^{}语法为您执行此操作。请注意,name^{commit}语法指示Git剥离标记,直到它到达提交,否则退出并显示错误,这样如果带注释的标记最终指向其他内容 - 例如blob对象 - 你抓住了这个错误。 name^{}语法指示Git剥离标记,直到它到达任何非注释标记对象,即提交,树或blob。