为什么 git remote prune origin 会删除我的本地标签?

Why does git remote prune origin remove my local tags?

我有几个标签引用来自本地分支和远程跟踪分支的提交,或者这些提交的祖先。

在 运行 git fetch:

之后,我想删除对 origin 上的分支和标签的引用

git remote prune origin --dry-run

但输出表明它会 p运行e 我的本地标签,即使是我手动创建的标签,而不是从任何远程 fetched:

 * [would prune] origin/git-svn
 * [would prune] origin/ignore/some_branch
 * [would prune] refs/tags/MyLocalTag
 * [would prune] refs/tags/MyLocalTag2

为什么 git 试图 p运行e 我的本地标签(即使是那些指向我本地分支但没有上游的标签)?

因为 Git 2.17 (Q2 2018)git config fetch.pruneTags false 可以提供帮助。

参见:

默认应该是false:

Git has a default disposition of keeping data unless it’s explicitly thrown away; this extends to holding onto local references to branches on remotes that have themselves deleted those branches.


改用 (2016)

  • pushing your tags

    git push --tags
    
  • 通过修剪获取:

    git fetch --prune --tags origin
    

git fetch man page 提及:

Before fetching, remove any remote-tracking references that no longer exist on the remote.
Tags are not subject to pruning if they are fetched only because of the default tag auto-following or due to a --tags option.

如果出现任何问题,请记住 git reflog 恢复任何错误删除的标签。


OP 添加:

Unfortunately I don't have the ability to push to the repo. But I don't need the tags to be associated with the upstream (origin);

然后您可以将其推送到分叉或原始存储库的任何克隆 --mirror 副本。我的意思是将它们推到一些回购协议中。

why can't I just have a tag pointing to a local branch that doesn't get removed on git remote prune origin?

它们确实不应该被删除(见下一点)

Makes me think somehow I'm creating the tags wrong (git tag foo MyLocalBranch).

就是这样!您已经创建了 lightweight tags, which linked to the branch, as opposed to annotated tags,它将引用分支 HEAD 提交。

尝试创建标签为:

git tag -m "old MyLocalBranch" foo MyLocalBranch

添加评论足以创建一个带注释的标签,与分支分开:它们不会被 git remote prune origin(首先检查 --dry-run)或 git fetch --prune --tags(但前提是首先推送这些标签)。

我能够再次重现此问题并将问题缩小到 remote.origin.fetch 配置。我添加了一个 refspec 以确保 git fetch 从远程获取所有标签:

[remote "origin"]
    url = https://<path-to-repo>.git
    fetch = +refs/heads/*:refs/remotes/origin/*
    fetch = +refs/tags/*:refs/tags/*

据我所知,这很像设置 tagopt = --tags,因为 运行 git fetch origin 会将所有标签复制到 .git/refs/tags。但是,在配置文件中包含此 refspec 会产生意想不到的副作用,导致 git remote prune origin 修剪所有本地标签

我提交了 a bug report,它已经遇到了一系列补丁,以便在文档中更好地解释这一点,以及(具有讽刺意味的)新标志来专门启用这种删除标签的行为,而无需额外的 refspec在遥控器的获取配置中。

从 git 2.17 开始,有一个 fetch.pruneTags config setting。我的设置为 true,将其设置为 false 修复了我的本地标签丢失问题。