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

[PATCH 00/15] Change semantics of "fetch --tags"

From
Michael Haggerty <mhagger@alum.mit.edu>
Date
Oct 23, 2013, 15:50 UTC
Message-ID
<1382543448-2586-1-git-send-email-mhagger@alum.mit.edu>
In-Reply-To
<52327E62.2040301@alum.mit.edu>

This is my proposed fix for the "local tag killer" problem that I reported recently [1].

There are three main things changed by this patch series:
1. "git fetch --tags" causes tags to be fetched *in addition to* any
   other refspecs that are configured for the remote, rather than
   *instead of*.  I believe this is more useful behavior.  It is also
   consistent with the documentation as it was written before it was
   disambiguated in 1.8.0.3.
2. "git fetch --prune" only prunes references that match an explicit
   refspec (either from the command line or from the
   remote.<name>.fetch configuration.  In particular, using "--prune"
   and "--tag" together do *not* make tags subject to pruning.  (Tags
   can still be pruned if the user specifies an explicit refspec
   "refs/tags/*:refs/tags/*".)
3. Previously, if the user invoked one of the following commands with
   --no-prune, the --no-prune option was not passed to the "git fetch"
   subprocesses that they invoked to do their work:
       git fetch --all
       git fetch --multiple
       git fetch --recurse-submodules
       git remote update
   If fetch.prune or remote.<name>.prune were set to true, this could
   result in unwanted reference pruning.  The last commit in the
   series fixes this bug and should not be controversial.

I had originally planned to solve the "local tag killer" problem by adding a new configuration option to define which reference namespaces were subject to pruning (e.g., remote.<name>.pruneRef="refs/remotes/*"). I may yet submit that patch series as a separate feature. But while working on it I hit on the present solution, which I think is simpler and more elegant (albeit a bit less flexible).

Changes (1) and (2) introduce behavior changes, but I think that they are improvements and that the resulting backwards-incompatibility is acceptable:

Change (1) means that "git fetch --tags <remote>" without any additional refspec arguments will fetch more references than it did before. But I don't think it is very useful to want to fetch tags without fetching other configured references, so I think it is OK [2].

Change (2) means that using "git fetch --tags --prune" will *not* prune tags. (This is the whole point of the change!) As discussed in the mailing list, it is usually bad policy to prune tags, because tags for the local repository and for all remote repositories currently share a single namespace, "refs/tags/*". Therefore, pruning tags based on information from a single remote risks pruning local tags or tags that have been obtained from another remote. The main exception, when one probably *does* want to prune tags, is when fetching into a mirror clone. But mirror clones have "remote.<name>.fetch=+refs/*:refs/*", and so even after this change tags will be subject to pruning when fetching into a mirror clone.

The only other place I can find that does reference pruning is "git remote prune", but that codepath didn't respect remote.<name>.tagopt anyway and therefore it *didn't* prune tags unless they were part of an explicit refspec; i.e., this codepath already behaved the "new" way that other pruning codepaths now behave.

Patches 1-9 are just preliminary cleanup and documentation improvements.

Patch 10 implements change (1) described above.
Patch 11 implements change (2).
Patches 12-14 are some more minor cleanups.
Patch 15 implements change (3).
[1] http://article.gmane.org/gmane.comp.version-control.git/234723
[2] Indeed, I bet that most scripts that invoke "git fetch --tags
    <remote>" also invoke a plain "git fetch" immediately before or
    after to get the rest of the references.
Michael Haggerty (15):
  t5510: use the correct tag name in test
  t5510: prepare test refs more straightforwardly
  t5510: check that "git fetch --prune --tags" does not prune branches
  api-remote.txt: correct section "struct refspect"
  get_ref_map(): rename local variables
  ref_remove_duplicates(): avoid redundant bisection
  ref_remove_duplicates(): simplify function
  ref_remove_duplicates(): improve documentation comment
  builtin/fetch.c: reorder function definitions
  fetch --tags: fetch tags *in addition to* other stuff
  fetch --prune: prune only based on explicit refspecs
  query_refspecs(): move some constants out of the loop
  builtin/remote.c: reorder function definitions
  builtin/remote.c:update(): use struct argv_array
  fetch, remote: properly convey --no-prune options to subprocesses
 Documentation/config.txt                 |   2 +-
 Documentation/fetch-options.txt          |  21 ++-
 Documentation/technical/api-remote.txt   |  20 +--
 builtin/fetch.c                          | 253 +++++++++++++++----------------
 builtin/remote.c                         | 196 ++++++++++++------------
 git-pull.sh                              |   2 +-
 remote.c                                 |  44 +++---
 remote.h                                 |   9 +-
 t/t5510-fetch.sh                         |  36 ++++-
 t/t5515/fetch.br-unconfig_--tags_.._.git |   1 +
 t/t5515/fetch.master_--tags_.._.git      |   1 +
 t/t5525-fetch-tagopt.sh                  |  23 ++-
 12 files changed, 322 insertions(+), 286 deletions(-)
-- 
1.8.4
Next: Michael Haggerty
Message 1 of 34 in “Change semantics of "fetch --tags"”
  1. 00/15 Change semantics of "fetch --tags"Michael Haggerty, Oct 23, 2013
  2. 01/15 t5510: use the correct tag name in testMichael Haggerty, Oct 23, 2013
  3. 02/15 t5510: prepare test refs more straightforwardlyMichael Haggerty, Oct 23, 2013
  4. Junio C HamanoOct 23, 2013
  5. Michael HaggertyOct 24, 2013
  6. Junio C HamanoOct 24, 2013
  7. 03/15 t5510: check that "git fetch --prune --tags" does not prune branchesMichael Haggerty, Oct 23, 2013
  8. 04/15 api-remote.txt: correct section "struct refspect"Michael Haggerty, Oct 23, 2013
  9. Junio C HamanoOct 23, 2013
  10. Michael HaggertyOct 24, 2013
  11. 05/15 get_ref_map(): rename local variablesMichael Haggerty, Oct 23, 2013
  12. Junio C HamanoOct 23, 2013
  13. Michael HaggertyOct 24, 2013
  14. 06/15 ref_remove_duplicates(): avoid redundant bisectionMichael Haggerty, Oct 23, 2013
  15. 07/15 ref_remove_duplicates(): simplify functionMichael Haggerty, Oct 23, 2013
  16. 08/15 ref_remove_duplicates(): improve documentation commentMichael Haggerty, Oct 23, 2013
  17. Junio C HamanoOct 23, 2013
  18. 09/15 builtin/fetch.c: reorder function definitionsMichael Haggerty, Oct 23, 2013
  19. 10/15 fetch --tags: fetch tags *in addition to* other stuffMichael Haggerty, Oct 23, 2013
  20. Junio C HamanoOct 24, 2013
  21. Michael HaggertyOct 25, 2013
  22. Junio C HamanoOct 28, 2013
  23. Michael HaggertyOct 30, 2013
  24. Michael HaggertyOct 26, 2013
  25. 11/15 fetch --prune: prune only based on explicit refspecsMichael Haggerty, Oct 23, 2013
  26. Junio C HamanoOct 24, 2013
  27. Michael HaggertyOct 26, 2013
  28. Junio C HamanoOct 28, 2013
  29. 12/15 query_refspecs(): move some constants out of the loopMichael Haggerty, Oct 23, 2013
  30. 13/15 builtin/remote.c: reorder function definitionsMichael Haggerty, Oct 23, 2013
  31. 14/15 builtin/remote.c:update(): use struct argv_arrayMichael Haggerty, Oct 23, 2013
  32. 15/15 fetch, remote: properly convey --no-prune options to subprocessesMichael Haggerty, Oct 23, 2013
  33. Junio C HamanoOct 24, 2013
  34. Junio C HamanoOct 23, 2013

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.