问题
I have several tags that reference commits from local branches and remote tracking branches, or ancestors of those commits.
I want to remove references to branches and tags on origin
after having run git fetch
:
git remote prune origin --dry-run
But the output indicates it would prune my local tags, even ones that were created manually by me instead of being fetch
ed from any remote:
* [would prune] origin/git-svn
* [would prune] origin/ignore/some_branch
* [would prune] refs/tags/MyLocalTag
* [would prune] refs/tags/MyLocalTag2
Why is git trying to prune my local tags (even those that point to my local branches with no upstream)?
回答1:
I was able to reproduce this again and narrowed the problem down to the remote.origin.fetch
config. I had added a refspec to ensure that git fetch
fetched all tags from the remote:
[remote "origin"]
url = https://<path-to-repo>.git
fetch = +refs/heads/*:refs/remotes/origin/*
fetch = +refs/tags/*:refs/tags/*
As far as I can tell, this works much like setting tagopt = --tags
, in that running git fetch origin
will copy all tags into .git/refs/tags
. However, including this refspec in the config file has the unexpected side effect of causing git remote prune origin
to prune all local tags.
I submitted a bug report which has been met with a series of patches to better explain this in the documentation, as well as (ironically) new flags to specifically enable this behavior of removing tags without needing the extra refspec in the remote's fetch config.
回答2:
Since Git 2.17 (Q2 2018), git config fetch.pruneTags false
can help.
See:
- git config fetch.pruneTags
- git fetch # pruning
It should be false by default:
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.
Try instead (2016)
pushing your tags
git push --tags
fetching with prune:
git fetch --prune --tags origin
git fetch man page mentions:
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.
If anything goes wrong, remember git reflog to recover any tag incorrectly removed.
The OP adds:
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);
You could push then to a fork or any clone --mirror copy of the original repo. My point is to push them to some back repo.
why can't I just have a tag pointing to a local branch that doesn't get removed on git remote prune origin?
They should not be removed indeed (see next point)
Makes me think somehow I'm creating the tags wrong (
git tag foo MyLocalBranch
).
That is it! You have created lightweight tags, which linked to the branch, as opposed to annotated tags, which would reference the branch HEAD commit.
Try creating tags as:
git tag -m "old MyLocalBranch" foo MyLocalBranch
Adding a comment is enough to create an annotated tag, separate from the branch: they won't be removed by a git remote prune origin
(check with --dry-run
first), or with git fetch --prune --tags
(but only if those tags were pushed first).
回答3:
As of git 2.17, there is a fetch.pruneTags config setting. Mine was set to true
, and setting it to false
fixes my local tag loss issues.
来源:https://stackoverflow.com/questions/34687657/why-does-git-remote-prune-origin-remove-my-local-tags