git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [BUG] git remote prune removes local tags, depending on fetch config

From
Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Date
Jan 16, 2018, 11:14 UTC
Message-ID
<87po6ahx87.fsf@evledraar.gmail.com>
In-Reply-To
<CACi5S_33F7VVRYiBOQsxgg_ZPOg9ZvhLZ26bStYWiq7n96aeug@mail.gmail.com>
On Tue, Jan 16 2018, Michael Giuffrida jotted:
Show 10 quoted lines
> 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?

Yes, I realize this isn't everyone's cup of tea, but it's very useful in our in-house use-case for git.

We have repos that have tags pushed to them on every deployment, thus the cumulative set of tags is in the hundreds of thousands.

There's a pruning script that prunes both branches and tags from the server (and archives them to an archive repo that has every ref ever).

Then we need to push these deletions back to client checkouts. For branches that's easy, just set fetch.prune=true. For tags I need to chase down checkouts and do:

    git -C {} config --replace-all remote.origin.fetch "refs/tags/*:refs/tags/*" "^refs/tags/*:refs/tags/*$"

It would be easier to just set fetch.{prune,pruneTags}=true in /etc/gitconfig, this is on e.g. shared development staging boxes where you might have a manually cloned checkout in your ~.

Of course it'll wipe away any manually created tag you have, *ideally* we'd have something like the refs/remotes/ namespace for tags, but that ship has sailed.

But meanwhile tag pruning is an OK compromise, 99% of our users will never even think to create a tag (and if they created one manually they couldn't push it), the advanced users that would know what sort of repo they're editing and can out-out of the behavior by editing their local config.

Show 57 quoted lines
> On Mon, Jan 15, 2018 at 4:38 PM, Ævar Arnfjörð Bjarmason
> <avarab@gmail.com> wrote:
>>
>> 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.
Previous: Michael GiuffridaNext: Ævar Arnfjörð Bjarmason
Message 4 of 118 in “[BUG] git remote prune removes local tags, depending on fetch config”
  1. Michael GiuffridaJan 15, 2018
  2. Ævar Arnfjörð BjarmasonJan 16, 2018
  3. Michael GiuffridaJan 16, 2018
  4. Ævar Arnfjörð BjarmasonJan 16, 2018
  5. 00/11 document & test fetch pruning + WIP fetch.pruneTagsÆvar Arnfjörð Bjarmason, Jan 19, 2018
  6. 01/11 fetch tests: refactor in preparation for testing tag pruningÆvar Arnfjörð Bjarmason, Jan 19, 2018
  7. 02/11 fetch tests: arrange arguments for future readabilityÆvar Arnfjörð Bjarmason, Jan 19, 2018
  8. 03/11 fetch tests: add a tag to be deleted to the pruning testsÆvar Arnfjörð Bjarmason, Jan 19, 2018
  9. 04/11 fetch tests: double quote a variable for interpolationÆvar Arnfjörð Bjarmason, Jan 19, 2018
  10. 05/11 fetch tests: test --prune and refspec interactionÆvar Arnfjörð Bjarmason, Jan 19, 2018
  11. 06/11 git fetch doc: add a new section to explain the ins & outs of pruningÆvar Arnfjörð Bjarmason, Jan 19, 2018
  12. Eric SunshineJan 19, 2018
  13. 07/11 git remote doc: correct dangerous lies about what prune doesÆvar Arnfjörð Bjarmason, Jan 19, 2018
  14. 08/11 git-fetch & config doc: link to the new PRUNING sectionÆvar Arnfjörð Bjarmason, Jan 19, 2018
  15. 09/11 fetch: don't redundantly null something calloc() gave usÆvar Arnfjörð Bjarmason, Jan 19, 2018
  16. 10/11 fetch tests: add scaffolding for the new fetch.pruneTagsÆvar Arnfjörð Bjarmason, Jan 19, 2018
  17. 11/11 WIP fetch: add a --fetch-prune option and fetch.pruneTags configÆvar Arnfjörð Bjarmason, Jan 19, 2018
  18. 00/12 document & test fetch pruning & add fetch.pruneTagsÆvar Arnfjörð Bjarmason, Jan 21, 2018
  19. 01/12 fetch tests: refactor in preparation for testing tag pruningÆvar Arnfjörð Bjarmason, Jan 21, 2018
  20. 02/12 fetch tests: arrange arguments for future readabilityÆvar Arnfjörð Bjarmason, Jan 21, 2018
  21. 03/12 fetch tests: add a tag to be deleted to the pruning testsÆvar Arnfjörð Bjarmason, Jan 21, 2018
  22. 04/12 fetch tests: double quote a variable for interpolationÆvar Arnfjörð Bjarmason, Jan 21, 2018
  23. Junio C HamanoJan 22, 2018
  24. Ævar Arnfjörð BjarmasonJan 22, 2018
  25. 05/12 fetch tests: test --prune and refspec interactionÆvar Arnfjörð Bjarmason, Jan 21, 2018
  26. 06/12 git fetch doc: add a new section to explain the ins & outs of pruningÆvar Arnfjörð Bjarmason, Jan 21, 2018
  27. 07/12 git remote doc: correct dangerous lies about what prune doesÆvar Arnfjörð Bjarmason, Jan 21, 2018
  28. Junio C HamanoJan 22, 2018
  29. Ævar Arnfjörð BjarmasonJan 22, 2018
  30. 08/12 git-fetch & config doc: link to the new PRUNING sectionÆvar Arnfjörð Bjarmason, Jan 21, 2018
  31. 09/12 fetch: don't redundantly NULL something calloc() gave usÆvar Arnfjörð Bjarmason, Jan 21, 2018
  32. Ævar Arnfjörð BjarmasonJan 21, 2018
  33. 10/12 fetch: stop accessing "remote" variable indirectlyÆvar Arnfjörð Bjarmason, Jan 21, 2018
  34. 11/12 fetch tests: add scaffolding for the new fetch.pruneTagsÆvar Arnfjörð Bjarmason, Jan 21, 2018
  35. 12/12 fetch: add a --fetch-prune option and fetch.pruneTags configÆvar Arnfjörð Bjarmason, Jan 21, 2018
  36. Junio C HamanoJan 22, 2018
  37. Ævar Arnfjörð BjarmasonJan 22, 2018
  38. 00/11 document & test fetch pruning & add fetch.pruneTagsÆvar Arnfjörð Bjarmason, Jan 23, 2018
  39. 01/11 fetch: don't redundantly NULL something calloc() gave usÆvar Arnfjörð Bjarmason, Jan 23, 2018
  40. 03/11 fetch tests: refactor in preparation for testing tag pruningÆvar Arnfjörð Bjarmason, Jan 23, 2018
  41. 02/11 fetch: stop accessing "remote" variable indirectlyÆvar Arnfjörð Bjarmason, Jan 23, 2018
  42. Junio C HamanoJan 24, 2018
  43. 06/11 fetch tests: test --prune and refspec interactionÆvar Arnfjörð Bjarmason, Jan 23, 2018
  44. 07/11 git fetch doc: add a new section to explain the ins & outs of pruningÆvar Arnfjörð Bjarmason, Jan 23, 2018
  45. 09/11 git-fetch & config doc: link to the new PRUNING sectionÆvar Arnfjörð Bjarmason, Jan 23, 2018
  46. 10/11 fetch tests: add scaffolding for the new fetch.pruneTagsÆvar Arnfjörð Bjarmason, Jan 23, 2018
  47. 11/11 fetch: add a --fetch-prune option and fetch.pruneTags configÆvar Arnfjörð Bjarmason, Jan 23, 2018
  48. Junio C HamanoJan 24, 2018
  49. Ævar Arnfjörð BjarmasonJan 24, 2018
  50. Junio C HamanoJan 24, 2018
  51. 05/11 fetch tests: add a tag to be deleted to the pruning testsÆvar Arnfjörð Bjarmason, Jan 23, 2018
  52. 08/11 git remote doc: correct dangerous lies about what prune doesÆvar Arnfjörð Bjarmason, Jan 23, 2018
  53. 04/11 fetch tests: re-arrange arguments for future readabilityÆvar Arnfjörð Bjarmason, Jan 23, 2018
  54. Junio C HamanoJan 24, 2018
  55. Ævar Arnfjörð BjarmasonJan 24, 2018
  56. Ævar Arnfjörð BjarmasonFeb 6, 2018
  57. 00/17 document & test fetch pruning & add fetch.pruneTagsÆvar Arnfjörð Bjarmason, Feb 8, 2018
  58. 01/17 fetch: don't redundantly NULL something calloc() gave usÆvar Arnfjörð Bjarmason, Feb 8, 2018
  59. Eric SunshineFeb 9, 2018
  60. Ævar Arnfjörð BjarmasonFeb 9, 2018
  61. 02/17 fetch: trivially refactor assignment to ref_nrÆvar Arnfjörð Bjarmason, Feb 8, 2018
  62. Eric SunshineFeb 9, 2018
  63. 03/17 fetch: stop accessing "remote" variable indirectlyÆvar Arnfjörð Bjarmason, Feb 8, 2018
  64. 05/17 fetch tests: refactor in preparation for testing tag pruningÆvar Arnfjörð Bjarmason, Feb 8, 2018
  65. 07/17 fetch tests: add a tag to be deleted to the pruning testsÆvar Arnfjörð Bjarmason, Feb 8, 2018
  66. 11/17 fetch tests: fetch <url> <spec> as well as fetch [<remote>]Ævar Arnfjörð Bjarmason, Feb 8, 2018
  67. Eric SunshineFeb 9, 2018
  68. Ævar Arnfjörð BjarmasonFeb 9, 2018
  69. Jeff KingFeb 9, 2018
  70. Eric SunshineFeb 9, 2018
  71. Junio C HamanoFeb 9, 2018
  72. Junio C HamanoFeb 9, 2018
  73. 12/17 git fetch doc: add a new section to explain the ins & outs of pruningÆvar Arnfjörð Bjarmason, Feb 8, 2018
  74. Eric SunshineFeb 9, 2018
  75. 13/17 git remote doc: correct dangerous lies about what prune doesÆvar Arnfjörð Bjarmason, Feb 8, 2018
  76. Eric SunshineFeb 9, 2018
  77. 16/17 fetch: add a --fetch-prune option and fetch.pruneTags configÆvar Arnfjörð Bjarmason, Feb 8, 2018
  78. Eric SunshineFeb 9, 2018
  79. Ævar Arnfjörð BjarmasonFeb 9, 2018
  80. 15/17 fetch tests: add scaffolding for the new fetch.pruneTagsÆvar Arnfjörð Bjarmason, Feb 8, 2018
  81. 14/17 git-fetch & config doc: link to the new PRUNING sectionÆvar Arnfjörð Bjarmason, Feb 8, 2018
  82. 17/17 fetch: make the --fetch-prune work with <url>Ævar Arnfjörð Bjarmason, Feb 8, 2018
  83. Eric SunshineFeb 9, 2018
  84. Ævar Arnfjörð BjarmasonFeb 9, 2018
  85. 10/17 fetch tests: expand case/esac for later changeÆvar Arnfjörð Bjarmason, Feb 8, 2018
  86. 09/17 fetch tests: double quote a variable for interpolationÆvar Arnfjörð Bjarmason, Feb 8, 2018
  87. 06/17 fetch tests: re-arrange arguments for future readabilityÆvar Arnfjörð Bjarmason, Feb 8, 2018
  88. 08/17 fetch tests: test --prune and refspec interactionÆvar Arnfjörð Bjarmason, Feb 8, 2018
  89. 04/17 remote: add a macro for "refs/tags/*:refs/tags/*"Ævar Arnfjörð Bjarmason, Feb 8, 2018
  90. Ævar Arnfjörð BjarmasonFeb 8, 2018
  91. Junio C HamanoFeb 8, 2018
  92. Ævar Arnfjörð BjarmasonFeb 9, 2018
  93. 00/17 document & test fetch pruning & add fetch.pruneTagsÆvar Arnfjörð Bjarmason, Feb 9, 2018
  94. 01/17 fetch: don't redundantly NULL something calloc() gave usÆvar Arnfjörð Bjarmason, Feb 9, 2018
  95. 02/17 fetch: trivially refactor assignment to ref_nrÆvar Arnfjörð Bjarmason, Feb 9, 2018
  96. 03/17 fetch: stop accessing "remote" variable indirectlyÆvar Arnfjörð Bjarmason, Feb 9, 2018
  97. 04/17 remote: add a macro for "refs/tags/*:refs/tags/*"Ævar Arnfjörð Bjarmason, Feb 9, 2018
  98. 05/17 fetch tests: refactor in preparation for testing tag pruningÆvar Arnfjörð Bjarmason, Feb 9, 2018
  99. 08/17 fetch tests: test --prune and refspec interactionÆvar Arnfjörð Bjarmason, Feb 9, 2018
  100. 09/17 fetch tests: double quote a variable for interpolationÆvar Arnfjörð Bjarmason, Feb 9, 2018
  101. 10/17 fetch tests: expand case/esac for later changeÆvar Arnfjörð Bjarmason, Feb 9, 2018
  102. 11/17 fetch tests: fetch <url> <spec> as well as fetch [<remote>]Ævar Arnfjörð Bjarmason, Feb 9, 2018
  103. 13/17 git remote doc: correct dangerous lies about what prune doesÆvar Arnfjörð Bjarmason, Feb 9, 2018
  104. 12/17 git fetch doc: add a new section to explain the ins & outs of pruningÆvar Arnfjörð Bjarmason, Feb 9, 2018
  105. 06/17 fetch tests: re-arrange arguments for future readabilityÆvar Arnfjörð Bjarmason, Feb 9, 2018
  106. 07/17 fetch tests: add a tag to be deleted to the pruning testsÆvar Arnfjörð Bjarmason, Feb 9, 2018
  107. 14/17 git-fetch & config doc: link to the new PRUNING sectionÆvar Arnfjörð Bjarmason, Feb 9, 2018
  108. 15/17 fetch tests: add scaffolding for the new fetch.pruneTagsÆvar Arnfjörð Bjarmason, Feb 9, 2018
  109. 16/17 fetch: add a --prune-tags option and fetch.pruneTags configÆvar Arnfjörð Bjarmason, Feb 9, 2018
  110. 17/17 fetch: make the --prune-tags work with <url>Ævar Arnfjörð Bjarmason, Feb 9, 2018
  111. Junio C HamanoFeb 22, 2018
  112. Ævar Arnfjörð BjarmasonFeb 22, 2018
  113. Junio C HamanoFeb 22, 2018
  114. Ævar Arnfjörð BjarmasonFeb 23, 2018
  115. Junio C HamanoFeb 23, 2018
  116. Ævar Arnfjörð BjarmasonFeb 24, 2018
  117. Andreas SchwabJan 16, 2018
  118. Kevin DaudtJan 18, 2018

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.