On Mon, Jan 15 2018, Michael Giuffrida jotted: > `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/c5a84e92a2fe9e8748e32341c344d7a6c0f52a50 These 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.