有没有办法让我的本地 git 标签与远程标签保持同步?也就是说 - 不仅在创建时获取新标签(像往常一样,当fetch
-ing/ pull
-ing 时),而且修剪不再在遥控器上的标签,并在其他人git push -f
的标签时删除现有标签。我知道我可以git fetch remotename
随后git remote prune remotename
为分支实现类似的行为。
8 回答
...还修剪不再在遥控器上的标签
git fetch
使用 Git 2.17(2018 年第二季度)是摆脱本地持有的陈旧标签的方便快捷方式。
See commit 6317972 , commit 97716d2 , commit e249ce0 , commit 627a129 , commit d0e0747 , commit 2c72ed7 , commit e1790f9 , commit 59caf52 , commit 82f34e0 , commit 6fb23f5 , commit ca3065e , commit bf16ab7 , commit eca142d , commit 750d0da , commit 0711883 , commit ce3ab21 , commit aa59e0e(2018 年 2 月 9 日)作者:Ævar Arnfjörð Bjarmason(avar
)。
(合并于Junio C Hamano -- gitster
--在提交 c1a7902中,2018 年 3 月 6 日)
fetch : 添加
--prune-tags
选项和fetch.pruneTags
配置
添加一个
--prune-tags
选项到git-fetch
,以及fetch.pruneTags
配置选项和-P
简写(-p
is--prune
)。
这允许执行以下任何操作:git fetch -p -P git fetch --prune --prune-tags git fetch -p -P origin git fetch --prune --prune-tags origin
或者简单地说:
git config fetch.prune true && git config fetch.pruneTags true && git fetch
而不是更冗长:
git fetch --prune origin 'refs/tags/*:refs/tags/*' '+refs/heads/*:refs/remotes/origin/*'
在此功能之前,支持从定期删除其分支和标签的 repo 中提取用例是很痛苦的,并让我们的本地引用反映上游。
在工作中,我们在 repo 中为每次推出创建部署标签,并且有很多这样的标签,因此出于性能原因,它们会在几周内存档。
如果没有此更改,很难集中配置此类存储库
/etc/gitconfig
(在仅用于处理它们的服务器上)。您需要fetch.prune=true
全局设置,然后为每个 repo:git -C {} config --replace-all remote.origin.fetch "refs/tags/*:refs/tags/*" "^\+*refs/tags/\*:refs/tags/\*$"
现在我也可以简单地设置
fetch.pruneTags=true
,/etc/gitconfig
运行“git pull
”的用户将自动获得我想要的修剪语义。
2021 年 4 月更新,Git for Windows 2.30.1 和GitHub Desktop 2.8
如果您有设置prune
和 pruneTags
选项,它会起作用:
cd C:\path\to\local\repo
git config fetch.prune true
git config fetch.pruneTags true
然后在 GitHub Deskop 中单击 Fetch origin:日志将显示:
2021-04-28T20:25:21.244Z - info: [ui] Executing fetch:
git -c credential.helper= -c protocol.version=2 fetch --progress --prune origin (took 2.986s)
...并且遥控器中不存在的任何本地标签都将消失!
以下对我有用:
git fetch --prune --tags
一些研究表明,git无法区分本地或外部标签(所有标签都转到 .git/refs/tags/)。因此,无法确定本地创建的标签和可修剪的远程标签之间的区别。然后选项被简化为:拥有不断增长的标签集,或者只有服务器上的标签。
git push --tags origin && \
git tag | xargs -n1 git tag -d && \
git fetch --tags
删除后一种行为的第一行,并且可能是 git 别名以供频繁使用。
另一种方法是在标签点创建一个分支(因为它们可以被识别为本地/远程),并且永远不会再写入它。然后使用 remotename/branchname 作为结帐的标签将使标签保持同步(除了git fetch
and git remote prune remotename
)。
无论哪种方式都是一种技巧,“正确”的答案是始终停止更改标签。
另一个实际上对我有用的解决方案:
git tag -l | xargs git tag -d && git fetch -t
使用这些命令同步标签(删除所有本地然后获取所有远程)
git tag -d $(git tag) # delete all local tags
git fetch --all # fetch all remote to local
git push --tags 会将您的本地标签推送到服务器。默认情况下,git fetch(git pull 或 git pull --rebase 的前半部分)会拉取标签,但您可以指定 -t 或 --tags 来拉取所有标签。
我不确定如何修剪远程删除的标签,但提取应该拉下任何强制更新的标签。
免责声明这使用了 git 内部(有些人可能会争辩说文件系统是一个 git 接口,但那是另一天:D)
# Blow away all local tags, this will remove any that are tagged locally
# but are not on the remote
rm .git/refs/tags/*
# Download all the tags from the remote
git fetch --tags
这是一个替代解决方案:
git fetch -p +refs/tags/*:refs/tags/*
从git fetch文档:
-p --修剪
在获取之前,删除远程上不再存在的任何远程跟踪引用。如果仅由于默认标签自动跟踪或由于 --tags 选项而获取标签,则不会对其进行修剪。但是,如果由于显式 refspec(在命令行或远程配置中,例如,如果远程是使用 --mirror 选项克隆的)而获取标签,那么它们也会受到 pruning 的影响。