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

Re: [PATCH 11/15] fetch --prune: prune only based on explicit refspecs

From
Junio C Hamano <gitster@pobox.com>
Date
Oct 24, 2013, 21:11 UTC
Message-ID
<xmqqiowmml0y.fsf@gitster.dls.corp.google.com>
In-Reply-To
<1382543448-2586-12-git-send-email-mhagger@alum.mit.edu>
Michael Haggerty <mhagger@alum.mit.edu> writes:
> ...
> Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Everything in the proposed log message made sense to me.
Show 10 quoted lines
> diff --git a/Documentation/config.txt b/Documentation/config.txt
> index d4d93c9..83c1700 100644
> --- a/Documentation/config.txt
> +++ b/Documentation/config.txt
> @@ -2086,7 +2086,7 @@ remote.<name>.vcs::
>  remote.<name>.prune::
>  	When set to true, fetching from this remote by default will also
>  	remove any remote-tracking branches which no longer exist on the
> -	remote (as if the `--prune` option was give on the command line).
> +	remote (as if the `--prune` option was given on the command line).
Shouldn't we stop saying "branches" here?
Show 11 quoted lines
> diff --git a/Documentation/fetch-options.txt b/Documentation/fetch-options.txt
> index 0e6d2ac..5d12219 100644
> --- a/Documentation/fetch-options.txt
> +++ b/Documentation/fetch-options.txt
> @@ -41,8 +41,14 @@ ifndef::git-pull[]
>  
>  -p::
>  --prune::
> -	After fetching, remove any remote-tracking branches which
> -	no longer exist	on the remote.
> +	After fetching, remove any remote-tracking branches that

Likewise. This is a lot more important than the one in remote.<name>.prune documentation, as the next sentence "Tags are not subject to ..." implies that they fall into the same category as what gets pruned here, i.e. "remote-tracking branches" in the above sentence, but nobody calls refs/tags/v1.0.0 a "remote-tracking branch" even if it came from your 'origin'.

> +	no longer exist	on the remote.  Tags are not subject to
> +	pruning in the usual case that they are fetched because of the
> +	--tags option or remote.<name>.tagopt.  

We should mention the most usual case tags are fetched, before mentioning the case the unusual option "--tags" was used from the command line or .tagopt configuration was used. Namely, when the tags are automatically followed.

Show 5 quoted lines
> +     However, if tags are
> +	fetched due to an explicit refspec (either on the command line
> +	or in the remote configuration, for example if the remote was
> +	cloned with the --mirror option), then they are also subject
> +	to pruning.
Very good.
Show 9 quoted lines
> @@ -63,7 +69,10 @@ ifndef::git-pull[]
>  --tags::
>  	This is a short-hand requesting that all tags be fetched from
>  	the remote in addition to whatever else is being fetched.  It
> -	is similar to using the refspec `refs/tags/*:refs/tags/*`.
> +	is similar to using the refspec `refs/tags/*:refs/tags/*`,
> +	except that it doesn't subject tags to pruning, regardless of
> +	a --prune option or the configuration settings of fetch.prune
> +	or remote.<name>.prune.

Using --tags is not similar to using refs/tags/*:refs/tags/* after the previous patch already; "git fetch origin --tags" and "git fetch origin refs/tags/*:refs/tags/*" are vastly different and that was the whole point of the previous step. And that "calling something not so similar similar" needs to be fixed further here to clarify that they are not similar in yet another way.

We should just lose "It is similar to using" from 10/15 and start over, perhaps? Add the first paragraph of the below in 10/15 and add the rest in 11/15, or something.

	--tags::
		Request that all tags be fetched from the remote
		under the same name (i.e. `refs/tags/X` is created in
		our repository by copying their `refs/tags/X`), in
		addition to whatever is fetched by the same `git
		fetch` command without this option on the command
		line.
	+
        When `refs/tags/*` hierarchy from the remote is copied only
        because this option was given, they are not subject to be
	pruned when `--prune` option (or configuration variables
	like `fetch.prune` or `remote.<name>.prune`) is in effect.

That would make it clear that they are subject to pruning when --mirror or an explicit refspec refs/tags/*:refs/tags/* is given, as tags are not fetched "only because of --tags" in such cases.

Show 51 quoted lines
> diff --git a/builtin/fetch.c b/builtin/fetch.c
> index 7edb1ea..47b63a7 100644
> --- a/builtin/fetch.c
> +++ b/builtin/fetch.c
> @@ -829,38 +829,17 @@ static int do_fetch(struct transport *transport,
>  		goto cleanup;
>  	}
>  	if (prune) {
> -		struct refspec *prune_refspecs;
> -		int prune_refspec_count;
> -
> +		/*
> +		 * We only prune based on refspecs specified
> +		 * explicitly (via command line or configuration); we
> +		 * don't care whether --tags was specified.
> +		 */
>  		if (ref_count) {
> -			prune_refspecs = refs;
> -			prune_refspec_count = ref_count;
> -		} else {
> -			prune_refspecs = transport->remote->fetch;
> -			prune_refspec_count = transport->remote->fetch_refspec_nr;
> -		}
> -
> -		if (tags == TAGS_SET) {
> -			/*
> -			 * --tags was specified.  Pretend that the user also
> -			 * gave us the canonical tags refspec
> -			 */
> -			const char *tags_str = "refs/tags/*:refs/tags/*";
> -			struct refspec *tags_refspec, *refspec;
> -
> -			/* Copy the refspec and add the tags to it */
> -			refspec = xcalloc(prune_refspec_count + 1, sizeof(*refspec));
> -			tags_refspec = parse_fetch_refspec(1, &tags_str);
> -			memcpy(refspec, prune_refspecs, prune_refspec_count * sizeof(*refspec));
> -			memcpy(&refspec[prune_refspec_count], tags_refspec, sizeof(*refspec));
> -
> -			prune_refs(refspec, prune_refspec_count + 1, ref_map);
> -
> -			/* The rest of the strings belong to fetch_one */
> -			free_refspec(1, tags_refspec);
> -			free(refspec);
> +			prune_refs(refs, ref_count, ref_map);
>  		} else {
> -			prune_refs(prune_refspecs, prune_refspec_count, ref_map);
> +			prune_refs(transport->remote->fetch,
> +				   transport->remote->fetch_refspec_nr,
> +				   ref_map);
>  		}
>  	}
Nice.
Previous: Michael HaggertyNext: Michael Haggerty
Message 26 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.