public inbox for git@vger.kernel.org
 help / color / mirror / Atom feed
* Tags auto fetched by "git fetch origin" but not "git fetch origin main"
@ 2024-08-28 23:23 Yukai Chou
  2024-08-29 21:32 ` brian m. carlson
  0 siblings, 1 reply; 6+ messages in thread
From: Yukai Chou @ 2024-08-28 23:23 UTC (permalink / raw)
  To: git

In using `git fetch [<options>] [<repository> [<refspec>…]]`,
- when a branch is specified as <refspec>, no tags are fetched automatically;
- when no <refspec>s are specified, tags are fetched automatically.

This reproduces with both glob (`+refs/heads/*:refs/remotes/origin/*`)
or restricted (`+refs/heads/main:refs/remotes/origin/main`)
`remote.<name>.fetch`.

From the git-fetch doc in Git v2.46.0 [1], I don't understand why they
behave differently.

> DESCRIPTION
> [...]
> By default, any tag that points into the histories being fetched is
> also fetched; the effect is to fetch tags that
> point at branches that you are interested in.

> <refspec>
> [...] Since
> Git version 2.20, fetching to update `refs/tags/*` works the same way
> as when pushing. I.e. any updates will be rejected without `+` in the
> refspec (or `--force`).

> CONFIGURED REMOTE-TRACKING BRANCHES
> [...]
> This configuration is used in two ways:
>
> * When `git fetch` is run without specifying what branches
> and/or tags to fetch on the command line, e.g. `git fetch origin`
> or `git fetch`, `remote.<repository>.fetch` values are used as
> the refspecs ...
>
> * When `git fetch` is run with explicit branches and/or tags
> to fetch on the command line, e.g. `git fetch origin master`, the
> <refspec>s given on the command line determine what are to be
> fetched (...). The `remote.<repository>.fetch` values determine
> which remote-tracking branch, if any, is updated.


Steps to reproduce

```shell
# prepare a local upstream and fork it
git init local-upstream && cd local-upstream
for i in 1 2 3; do git commit --allow-empty -m "commit $i"; done
git tag v0.3
cd ..
git clone file://$(pwd)/local-upstream local-fork
# now local-fork has all three commits and a tag v0.3

# add more commits and a new tag to upstream
cd local-upstream
for i in 4 5; do git commit --allow-empty -m "commit $i"; done
git tag v0.5
cd ..

# try to fetch new commits and the new tag v0.5
cd local-fork
# this fetches commits only
git fetch origin main
# this finally fetches the tag new v0.5, but why?
git fetch origin
cd ..
```

[1] https://git-scm.com/docs/git-fetch/2.46.0

Yukai

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Tags auto fetched by "git fetch origin" but not "git fetch origin main"
  2024-08-28 23:23 Tags auto fetched by "git fetch origin" but not "git fetch origin main" Yukai Chou
@ 2024-08-29 21:32 ` brian m. carlson
  2024-08-29 21:44   ` Junio C Hamano
  2024-08-29 23:16   ` Yukai Chou
  0 siblings, 2 replies; 6+ messages in thread
From: brian m. carlson @ 2024-08-29 21:32 UTC (permalink / raw)
  To: Yukai Chou; +Cc: git

[-- Attachment #1: Type: text/plain, Size: 994 bytes --]

On 2024-08-28 at 23:23:57, Yukai Chou wrote:
> In using `git fetch [<options>] [<repository> [<refspec>…]]`,
> - when a branch is specified as <refspec>, no tags are fetched automatically;
> - when no <refspec>s are specified, tags are fetched automatically.

Yes, this is expected.  Tags are refs, and when you specify no refspec,
you're asking for the default behaviour, which usually involves fetching
tags.  But when you specify a refspec, you are saying, "I want you to
fetch this, and only this; don't fetch anything else."

For example, if I say, `git fetch origin
refs/heads/main:refs/heads/main`, it would be very unexpected for it to
fetch tags as well; I only wanted it to fetch the main branch.  In fact,
I might be explicitly relying on it not affecting any other refs.

If you want tags nonetheless, you can use the `--tags` option, which
should fetch tags in addition to the refspec provided.
-- 
brian m. carlson (they/them or he/him)
Toronto, Ontario, CA

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 262 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Tags auto fetched by "git fetch origin" but not "git fetch origin main"
  2024-08-29 21:32 ` brian m. carlson
@ 2024-08-29 21:44   ` Junio C Hamano
  2024-08-29 22:22     ` brian m. carlson
  2024-08-29 23:16   ` Yukai Chou
  1 sibling, 1 reply; 6+ messages in thread
From: Junio C Hamano @ 2024-08-29 21:44 UTC (permalink / raw)
  To: brian m. carlson; +Cc: Yukai Chou, git

"brian m. carlson" <sandals@crustytoothpaste.net> writes:

> If you want tags nonetheless, you can use the `--tags` option, which
> should fetch tags in addition to the refspec provided.

But doesn't that grab _all_ tags, not only the relevant tags that
point into the history leading to the commits being fetched?

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Tags auto fetched by "git fetch origin" but not "git fetch origin main"
  2024-08-29 21:44   ` Junio C Hamano
@ 2024-08-29 22:22     ` brian m. carlson
  2024-08-29 22:38       ` Junio C Hamano
  0 siblings, 1 reply; 6+ messages in thread
From: brian m. carlson @ 2024-08-29 22:22 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Yukai Chou, git

[-- Attachment #1: Type: text/plain, Size: 1995 bytes --]

On 2024-08-29 at 21:44:02, Junio C Hamano wrote:
> "brian m. carlson" <sandals@crustytoothpaste.net> writes:
> 
> > If you want tags nonetheless, you can use the `--tags` option, which
> > should fetch tags in addition to the refspec provided.
> 
> But doesn't that grab _all_ tags, not only the relevant tags that
> point into the history leading to the commits being fetched?

It's not clear to me.  The description says this:

  By default, any tag that points into the histories being fetched is
  also fetched; the effect is to fetch tags that point at branches that
  you are interested in. This default behavior can be changed by using
  the --tags or --no-tags options or by configuring
  remote.<name>.tagOpt. By using a refspec that fetches tags explicitly,
  you can fetch tags that do not point into branches you are interested
  in as well.

That implies that `--tags` or `--no-tags` simply changes whether that
limited set of tags is fetched.

But the `--tags` option says this:

  Fetch all tags from the remote (i.e., fetch remote tags refs/tags/* into
  local tags with the same name), in addition to whatever else would
  otherwise be fetched. Using this option alone does not subject tags to
  pruning, even if --prune is used (though tags may be pruned anyway if
  they are also the destination of an explicit refspec; see --prune).

That implies that all tags are fetched.

I think we need somebody to test things and clarify the documentation.
(I'm not volunteering because I have a lot of things on my plate right
now.)

In addition, it might be useful to add a `--relevant-tags` option or
some such that simply fetches the relevant tags when arbitrary refspecs
are specified.  If someone felt super interested, they could even make
an additional generic option over other refspecs (I can imagine
something like GitHub's refs/pull might be interesting for users).
-- 
brian m. carlson (they/them or he/him)
Toronto, Ontario, CA

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 262 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Tags auto fetched by "git fetch origin" but not "git fetch origin main"
  2024-08-29 22:22     ` brian m. carlson
@ 2024-08-29 22:38       ` Junio C Hamano
  0 siblings, 0 replies; 6+ messages in thread
From: Junio C Hamano @ 2024-08-29 22:38 UTC (permalink / raw)
  To: brian m. carlson; +Cc: Yukai Chou, git

"brian m. carlson" <sandals@crustytoothpaste.net> writes:

> But the `--tags` option says this:
>
>   Fetch all tags from the remote (i.e., fetch remote tags refs/tags/* into
>   local tags with the same name), in addition to whatever else would
>   otherwise be fetched. Using this option alone does not subject tags to
>   pruning, even if --prune is used (though tags may be pruned anyway if
>   they are also the destination of an explicit refspec; see --prune).
>
> That implies that all tags are fetched.

That is stronger than "implies", I would think.  Indeed I know from
the code inspection that the auto-following only triggers when neither
--tags or --no-tags option is given, i.e. builtin/fetch.c has this:

	if (tags == TAGS_DEFAULT && autotags)
		transport_set_option(transport, TRANS_OPT_FOLLOWTAGS, "1");

where the variable tags is initialized to TAGS_DEFAULT,
--tags/--no-tags sets it to TAGS_SET or TAGS_UNSET, and autotags is
incremented only if a refspec we use has right hand side after the
colon, i.e. stores what we fetched in our refs/ namespace.

> I think we need somebody to test things and clarify the documentation.

Done ;-)

> In addition, it might be useful to add a `--relevant-tags` option or

A similar option is called "--follow-tags" on the "git push" side.
I _think_ it is just the matter of adding the option and have it set
the tags variable back to TAGS_DEFAULT, i.e.


diff --git c/builtin/fetch.c w/builtin/fetch.c
index c297569a47..f22c00a39d 100644
--- c/builtin/fetch.c
+++ w/builtin/fetch.c
@@ -2186,6 +2186,8 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
 			    N_("fetch all tags and associated objects"), TAGS_SET),
 		OPT_SET_INT('n', NULL, &tags,
 			    N_("do not fetch all tags (--no-tags)"), TAGS_UNSET),
+		OPT_SET_INT(0, "follow-tags", &tags,
+			    N_("auto-follow tags"), TAGS_DEFAULT)),
 		OPT_INTEGER('j', "jobs", &max_jobs,
 			    N_("number of submodules fetched in parallel")),
 		OPT_BOOL(0, "prefetch", &prefetch,


but I didn't look too deeply into it.  It needs compile testing,
documentation updates and new teststo cover the behaviour.

Thanks.

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: Tags auto fetched by "git fetch origin" but not "git fetch origin main"
  2024-08-29 21:32 ` brian m. carlson
  2024-08-29 21:44   ` Junio C Hamano
@ 2024-08-29 23:16   ` Yukai Chou
  1 sibling, 0 replies; 6+ messages in thread
From: Yukai Chou @ 2024-08-29 23:16 UTC (permalink / raw)
  To: brian m. carlson, Yukai Chou, git

brian m. carlson <sandals@crustytoothpaste.net> 于2024年8月30日周五 05:32写道:
>
> On 2024-08-28 at 23:23:57, Yukai Chou wrote:
> > In using `git fetch [<options>] [<repository> [<refspec>…]]`,
> > - when a branch is specified as <refspec>, no tags are fetched automatically;
> > - when no <refspec>s are specified, tags are fetched automatically.
>
> Yes, this is expected.  Tags are refs, and when you specify no refspec,
> you're asking for the default behaviour, which usually involves fetching
> tags.

According to the doc section CONFIGURED REMOTE-TRACKING BRANCHES [1],
when no refspec is specified,

  remote.<repository>.fetch values are used as the refspecs

Then according to doc of <refspec> [2],

  Since Git version 2.20, fetching to update refs/tags/* works the same
  way as when pushing. I.e. any updates will be rejected without + in
  the refspec (or --force).

So the tags are fetched due to the + in the remote.<repository>.fetch
values, are they?

> For example, if I say, `git fetch origin
> refs/heads/main:refs/heads/main`, it would be very unexpected for it to
> fetch tags as well; ... .

Actually,

  git fetch --update-head-ok origin refs/heads/main:refs/heads/main

does fetch tags "that points into the histories being fetched".

This time the refspec is given on the command line, without +.

According to the doc of CONFIGURED REMOTE-TRACKING BRANCHES [1],

  When used in this way, the remote.<repository>.fetch values do not
  have any effect in deciding what gets fetched (i.e. the values are
  not used as refspecs when the command-line lists refspecs); they
  are only used to decide where the refs that are fetched are stored
  by acting as a mapping.

[1] https://git-scm.com/docs/git-fetch#_configured_remote_tracking_branches
[2] https://git-scm.com/docs/git-fetch#Documentation/git-fetch.txt-ltrefspecgt

Yukai

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2024-08-29 23:16 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-08-28 23:23 Tags auto fetched by "git fetch origin" but not "git fetch origin main" Yukai Chou
2024-08-29 21:32 ` brian m. carlson
2024-08-29 21:44   ` Junio C Hamano
2024-08-29 22:22     ` brian m. carlson
2024-08-29 22:38       ` Junio C Hamano
2024-08-29 23:16   ` Yukai Chou

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox