有没有一种方法可以让本地git标签与远程的标签保持同步? 也就是说,不仅在创建新标签时(通常在fetch
/pull
)获取新标签,而且还能够清除不再存在于远程的标签,并在其他人使用git push -f
推送标签时删除现有标签。
我知道我可以通过git fetch remotename
和git remote prune remotename
来实现类似分支的行为。
...还可以修剪不再存在于远程的标签
git fetch
在Git 2.17(2018年第二季度)中提供了一个方便的简写,用于清除本地保留的陈旧标签。
avar
)提交。gitster
--于commit c1a7902合并,2018年3月6日)
--prune-tags
选项和fetch.pruneTags
配置Add a
--prune-tags
option togit-fetch
, along withfetch.pruneTags
config option and a-P
shorthand (-p
is--prune
).
This allows for doing any of:git fetch -p -P git fetch --prune --prune-tags git fetch -p -P origin git fetch --prune --prune-tags origin
Or simply:
git config fetch.prune true && git config fetch.pruneTags true && git fetch
Instead of the much more verbose:
git fetch --prune origin 'refs/tags/*:refs/tags/*' '+refs/heads/*:refs/remotes/origin/*'
Before this feature it was painful to support the use-case of pulling from a repo which is having both its branches and tags deleted regularly, and have our local references to reflect upstream.
At work we create deployment tags in the repo for each rollout, and there's lots of those, so they're archived within weeks for performance reasons.
Without this change it's hard to centrally configure such repos in
/etc/gitconfig
(on servers that are only used for working with them). You need to setfetch.prune=true
globally, and then for each repo:git -C {} config --replace-all remote.origin.fetch "refs/tags/*:refs/tags/*" "^\+*refs/tags/\*:refs/tags/\*$"
Now I can simply set
fetch.pruneTags=true
in/etc/gitconfig
as well, and users running "git pull
" will automatically get the pruning semantics I want.
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 Desktop 中点击 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
和 git remote prune remotename
之外)。
无论哪种方式都是一种黑客行为,“正确”的答案是停止经常更改标签。
git tag -d
命令,因此 git tag | xargs git tag -d && git fetch --tags
对我而言是有效的。 - solstice333另一个实际可行的解决方案:
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
![rejected] 7.34 -> 7.34 (would clobber existing tag)
,尝试了很多方法都没有用。谢谢! - Intervaliagit push --tags会将您本地的标签推送到服务器。默认情况下,git fetch(git pull或git pull --rebase的前半部分)将拉取标签,但您可以指定-t或--tags来拉取所有标签。
我不确定如何修剪远程删除的标签,但fetch应该会拉取任何强制更新的标签。
注意事项: 这里使用的是 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 --prune
在获取之前,删除任何在远程不存在的远程跟踪引用。如果标签仅因默认标签自动跟随或由于--tags选项而被获取,则不会对其进行修剪。但是,如果标签由于显式refspec(无论是在命令行上还是在远程配置中,例如如果使用--mirror选项克隆了远程),则它们也会受到修剪的影响。
git config fetch.pruneTags true
,就可以使您的git fetch
达到您想要的效果!请参见下面的答案。 - VonC