Re: [BUG] git remote prune removes local tags, depending on fetch config
From: Michael Giuffrida <hidden>
Date: 2018-01-16 02:15:10
Just to confirm, you're talking about the behavior of removing *all* tags that aren't found on the remote? (Not just tags that used to be on some remote, but have since been removed from that remote.) So, with your proposed workflow, you would never create your own tags locally, without pushing them to the remote before running `git fetch` -- otherwise they would simply be deleted. It doesn't seem like a useful feature -- you wouldn't expect `git fetch --prune` to remove your local branches that you were developing on, right? On Mon, Jan 15, 2018 at 4:38 PM, Ævar Arnfjörð Bjarmason [off-list ref] wrote:
On Mon, Jan 15 2018, Michael Giuffrida jotted:quoted
`git remote prune <name>` should "delete all stale remote-tracking branches under <name>". I was surprised to discover, after some troubleshooting, that it also deletes *all* local tags that don't exist on the remote, if the following refspec is included in the remote's fetch config: +refs/tags/*:refs/tags/* So, if `remote.origin.fetch` is configured to fetch all tags from the remote, any tags I create locally will be deleted when running `git remote prune origin`. This is not intuitive [1], nor is is it explained in the docs [2]. Is this behavior obvious to someone with a better understanding of Git internals? I did find a better way to automatically fetch tags (using tagopt instead of adding the fetch refspec). However, the refspec doesn't seem "wrong" in itself; in particular, `git fetch --tags` used to be considered equivalent to specifying the refspec "refs/tags/*:refs/tags/*" -- implying that this is a sensible refspec [3]. So I wouldn't expect it to "break" the behavior of another command. [1] https://stackoverflow.com/q/34687657/1327867 [2] https://git-scm.com/docs/git-remote.html#git-remote-empruneem [3] https://github.com/git/git/commit/c5a84e92a2fe9e8748e32341c344d7a6c0f52a50These docs are really confusing, but it is working as intended, and really should be re-documented. The `git remote prune` subcommand just ends up piggy-backing on git-fetch, whose behavior is explained here: https://git-scm.com/docs/git-fetch.html#git-fetch---prune It's worked this way since at least v1.8.5.6, maybe at some distant point in the past it only did this for branches when invoked via git-remote as the documentation says. RELATED: I've actually had the reverse problem with this. I want some way to turn this behavior on without explicitly hacking the refspec, so I can do it globally in /etc/gitconfig or in ~/.gitconfig without screwing with the config of each checkout on certain machines. You can set fetch.prune=true, but that only prunes the branches, you need to inject remote.origin.fetch into each checkout, unless I've missed some way of doing this. I wanted to add fetch.pruneTags that would make it as if you had refs/tags/*:refs/tags/* in the fetch spec, but I haven't hacked that up yet, if anyone can see any inherent issue with that plan I'd like to know about it.