我正在尝试删除超过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
附加到单个命令中,而不是对每个标记进行唯一删除并联系遥控器。
答案 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。