78

有没有办法让我的本地 git 标签与远程标签保持同步?也就是说 - 不仅在创建时获取新标签(像往常一样,当fetch-ing/ pull-ing 时),而且修剪不再在遥控器上的标签,并在其他人git push -f的标签时删除现有标签。我知道我可以git fetch remotename随后git remote prune remotename为分支实现类似的行为。

4

8 回答 8

68

...还修剪不再在遥控器上的标签

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简写(-pis --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)

...并且遥控器中不存在的任何本地标签都将消失!

于 2018-03-10T23:46:37.707 回答
50

以下对我有用:

git fetch --prune --tags
于 2013-05-22T15:05:57.297 回答
21

一些研究表明,git无法区分本地或外部标签(所有标签都转到 .git/refs/tags/)。因此,无法确定本地创建的标签和可修剪的远程标签之间的区别。然后选项被简化为:拥有不断增长的标签集,或者只有服务器上的标签。

git push --tags origin && \
git tag | xargs -n1 git tag -d && \
git fetch --tags

删除后一种行为的第一行,并且可能是 git 别名以供频繁使用。

另一种方法是在标签点创建一个分支(因为它们可以被识别为本地/远程),并且永远不会再写入它。然后使用 remotename/branchname 作为结帐的标签将使标签保持同步(除了git fetchand git remote prune remotename)。

无论哪种方式都是一种技巧,“正确”的答案是始终停止更改标签。

于 2012-05-17T22:11:30.757 回答
10

另一个实际上对我有用的解决方案:

git tag -l | xargs git tag -d && git fetch -t
于 2017-12-01T11:05:46.883 回答
8

使用这些命令同步标签(删除所有本地然后获取所有远程)

git tag -d $(git tag) # delete all local tags
git fetch --all # fetch all remote to local
于 2019-05-08T01:28:23.490 回答
7

git push --tags 会将您的本地标签推送到服务器。默认情况下,git fetch(git pull 或 git pull --rebase 的前半部分)会拉取标签,但您可以指定 -t 或 --tags 来拉取所有标签。

我不确定如何修剪远程删除的标签,但提取应该拉下任何强制更新的标签。

于 2012-05-08T01:26:25.033 回答
5

免责声明这使用了 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
于 2016-11-14T23:45:26.080 回答
0

这是一个替代解决方案:

git fetch -p +refs/tags/*:refs/tags/*

git fetch文档:

-p --修剪

在获取之前,删除远程上不再存在的任何远程跟踪引用。如果仅由于默认标签自动跟踪或由于 --tags 选项而获取标签,则不会对其进行修剪。但是,如果由于显式 refspec(在命令行或远程配置中,例如,如果远程是使用 --mirror 选项克隆的)而获取标签,那么它们也会受到 pruning 的影响

于 2017-01-19T20:11:15.263 回答