git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] git fetch one tag only
@ 2012-06-07  1:40 cheng renquan
  2012-06-07  4:37 ` Junio C Hamano
  0 siblings, 1 reply; 9+ messages in thread
From: cheng renquan @ 2012-06-07  1:40 UTC (permalink / raw)
  To: git

Someone maybe like me is working in the way of following one central
git repository
while sometimes need to fetch some code or tags from a 3rd git repo,
but unfortunately the 3rd repo may contain a lot of tags not all I want
to fetch to mess up my local repo, at this time I want to fetch only one tag
from the 3rd repo, but the syntax of
  `git fetch 3rd-repo the-tag-name`

really fetched the code of the-tag-name from 3rd-repo, but forgot the
tag itself;
this patch enhanced the above syntax to create the tag itself;


 builtin/fetch.c |    8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/builtin/fetch.c b/builtin/fetch.c
index bb9a074..9a3ec4a 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -439,6 +439,14 @@ static int store_updated_refs(const char
*raw_url, const char *remote_name,
 			else if (!prefixcmp(rm->name, "refs/tags/")) {
 				kind = "tag";
 				what = rm->name + 10;
+				if (!ref) {
+					unsigned char sha1[20];
+					ref = alloc_ref(rm->name);
+					hashcpy(ref->new_sha1, rm->old_sha1);
+					if (!get_sha1(rm->name, sha1))
+						hashcpy(ref->old_sha1, sha1);
+				}
 			}
 			else if (!prefixcmp(rm->name, "refs/remotes/")) {
 				kind = "remote-tracking branch";

-- 
cheng renquan (程任全)

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

* Re: [PATCH] git fetch one tag only
  2012-06-07  1:40 [PATCH] git fetch one tag only cheng renquan
@ 2012-06-07  4:37 ` Junio C Hamano
  2012-06-07  5:17   ` cheng renquan
  0 siblings, 1 reply; 9+ messages in thread
From: Junio C Hamano @ 2012-06-07  4:37 UTC (permalink / raw)
  To: cheng renquan; +Cc: git

On Wed, Jun 6, 2012 at 6:40 PM, cheng renquan <crquan@gmail.com> wrote:
>
> Someone maybe like me is working in the way of following one central
> git repository
> while sometimes need to fetch some code or tags from a 3rd git repo,
> but unfortunately the 3rd repo may contain a lot of tags not all I want
> to fetch to mess up my local repo, at this time I want to fetch only one tag
> from the 3rd repo, but the syntax of
>  `git fetch 3rd-repo the-tag-name`
>
> really fetched the code of the-tag-name from 3rd-repo, but forgot the
> tag itself;


The subject of "forgot" in that sentence is you, not "git fetch".
You told "git fetch" to grab it but not store it locally in your
refs/tags namespace.

There is a convenience short-hand "tag <tagname>", i.e.

  git fetch 3rd-repo tag the-tag-name

that is equivalent to

  git fetch 3rd-repo refs/tags/the-tag-name:refs/tags/the-tag-name

So I do not think your patch is necessary for your use case, and
obviously it will
break other people's use case where they just want to fetch (and inspect what is
left in FETCH_HEAD) but do not want to store.

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

* Re: [PATCH] git fetch one tag only
  2012-06-07  4:37 ` Junio C Hamano
@ 2012-06-07  5:17   ` cheng renquan
  2012-06-07  5:33     ` Junio C Hamano
  0 siblings, 1 reply; 9+ messages in thread
From: cheng renquan @ 2012-06-07  5:17 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

On Wed, Jun 6, 2012 at 9:37 PM, Junio C Hamano <gitster-vger@pobox.com> wrote:
> On Wed, Jun 6, 2012 at 6:40 PM, cheng renquan <crquan@gmail.com> wrote:
>>
>> Someone maybe like me is working in the way of following one central
>> git repository
>> while sometimes need to fetch some code or tags from a 3rd git repo,
>> but unfortunately the 3rd repo may contain a lot of tags not all I want
>> to fetch to mess up my local repo, at this time I want to fetch only one tag
>> from the 3rd repo, but the syntax of
>>  `git fetch 3rd-repo the-tag-name`
>>
>> really fetched the code of the-tag-name from 3rd-repo, but forgot the
>> tag itself;
>
>
> The subject of "forgot" in that sentence is you, not "git fetch".
> You told "git fetch" to grab it but not store it locally in your
> refs/tags namespace.
>
> There is a convenience short-hand "tag <tagname>", i.e.
>
>   git fetch 3rd-repo tag the-tag-name
>
> that is equivalent to
>
>   git fetch 3rd-repo refs/tags/the-tag-name:refs/tags/the-tag-name
>
> So I do not think your patch is necessary for your use case, and
> obviously it will
> break other people's use case where they just want to fetch (and inspect what is
> left in FETCH_HEAD) but do not want to store.

No, I tried what you said but it doesn't work as expected:

  git fetch linux-stable tag v3.4.1

My [linus-git] is following torvalds' tree and now I want to fetch
just one tag v3.4.1 from
linux-stable tree, but the above command would fetch all tags from linux-stable

linus-git	git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
(fetch)
linux-stable	git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git
(fetch)


[linus-git] $ git fetch -v --dry-run linux-stable tag v3.4.1 |& head
From git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable
 = [up to date]      v3.4.1     -> v3.4.1
 * [new tag]         latest     -> latest
 * [new tag]         v2.6.12.1  -> v2.6.12.1
 * [new tag]         v2.6.12.2  -> v2.6.12.2
[...]


I didn't know this syntax before, but Yes, this syntax should serve
the one-tag-only goal better,
  `git fetch 3rd-repo tag the-tag-name`
maybe I'd better to fix that?

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

* Re: [PATCH] git fetch one tag only
  2012-06-07  5:17   ` cheng renquan
@ 2012-06-07  5:33     ` Junio C Hamano
  2012-06-07  5:47       ` cheng renquan
  2012-06-07 17:08       ` Junio C Hamano
  0 siblings, 2 replies; 9+ messages in thread
From: Junio C Hamano @ 2012-06-07  5:33 UTC (permalink / raw)
  To: cheng renquan; +Cc: git

cheng renquan <crquan@gmail.com> writes:

>> There is a convenience short-hand "tag <tagname>", i.e.
>>
>>  git fetch 3rd-repo tag the-tag-name
>>
>> that is equivalent to
>>
>>  git fetch 3rd-repo refs/tags/the-tag-name:refs/tags/the-tag-name
>>
>> So I do not think your patch is necessary for your use case, and
>> obviously it will break other people's use case where they just
>> want to fetch (and inspect what is left in FETCH_HEAD) but do not
>> want to store.
>
> No, I tried what you said but it doesn't work as expected:
> ...
> [linus-git] $ git fetch -v --dry-run linux-stable tag v3.4.1 |& head
> From git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable
>  = [up to date]      v3.4.1     -> v3.4.1
>  * [new tag]         latest     -> latest
>  * [new tag]         v2.6.12.1  -> v2.6.12.1
>  * [new tag]         v2.6.12.2  -> v2.6.12.2
> [...]
> maybe I'd better to fix that?

Ahh, that is auto-following of tags.  Read up on that in "git fetch"
manual page, and there is an option to decline auto-following also
described.

The (current) rule is to grab all tags that reference commits you
are fetching *IF* you are storing any refs resulting from the fetch
in your refs/ namespace, and "tag v3.4.1" obviously asks for storing
that tag at refs/tags/v3.4.1 in your repository, so it is expected
that the auto-following kicks in.

It is a separate matter if we should add some special case to further
reduce the cases where auto-following happens. I personally do not
think any change is needed.

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

* Re: [PATCH] git fetch one tag only
  2012-06-07  5:33     ` Junio C Hamano
@ 2012-06-07  5:47       ` cheng renquan
  2012-06-07 16:11         ` cheng renquan
  2012-06-07 17:08       ` Junio C Hamano
  1 sibling, 1 reply; 9+ messages in thread
From: cheng renquan @ 2012-06-07  5:47 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

ok, got it:

$ git fetch -v --no-tags linux-stable tag v3.4.1
From git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable
 = [up to date]      v3.4.1     -> v3.4.1

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

* Re: [PATCH] git fetch one tag only
  2012-06-07  5:47       ` cheng renquan
@ 2012-06-07 16:11         ` cheng renquan
  0 siblings, 0 replies; 9+ messages in thread
From: cheng renquan @ 2012-06-07 16:11 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

On Wed, Jun 6, 2012 at 10:47 PM, cheng renquan <crquan@gmail.com> wrote:
> ok, got it:
>
> $ git fetch -v --no-tags linux-stable tag v3.4.1
> From git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable
>  = [up to date]      v3.4.1     -> v3.4.1

Here I still think the logic is wrong:

$ git fetch linux-stable tag
fatal: You need to specify a tag name.

$ git fetch linux-stable tag v3.4.1
[this would actually fetch all tags]


from `git help fetch`:

           Some short-cut notations are also supported.

           ·    tag <tag> means the same as
refs/tags/<tag>:refs/tags/<tag>; it requests fetching everything up to
the given tag.


Here the documentation is saying "everything up to the given tag.",
but other tags can never be all belonging to that path, for above
example, in the path up to given tag v3.4.1, I'm sure other tags like
v3.3.1 are not in the path;

So the `git fetch linux-stable tag v3.4.1` fetched other tags is a
WRONG behavior,
and why can't we fix that by disabling auto-following automatically if
use tag syntax? Why to the user "--no-tags" is explicitly required?

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

* Re: [PATCH] git fetch one tag only
  2012-06-07  5:33     ` Junio C Hamano
  2012-06-07  5:47       ` cheng renquan
@ 2012-06-07 17:08       ` Junio C Hamano
  2012-06-08 21:46         ` cheng renquan
  1 sibling, 1 reply; 9+ messages in thread
From: Junio C Hamano @ 2012-06-07 17:08 UTC (permalink / raw)
  To: git; +Cc: cheng renquan

Junio C Hamano <gitster@pobox.com> writes:

> It is a separate matter if we should add some special case to further
> reduce the cases where auto-following happens. I personally do not
> think any change is needed.

I do not care too deeply either way, but after doing

	$ git init blank && cd blank

and in an empty repository:

        $ git fetch $over_there v1.0.0

will grab the named tag and drop it in FETCH_HEAD, without adding
anything to your local refs, while

	$ git fetch $over_there tag v1.0.0

will grab the named tag and copy it to your refs/tags/v1.0.0, and
auto-follow all the tags that point at commits that are reachable.

To grab and store _only_ v1.0.0 in the local refs, you need to say
"do not auto-follow" with

	$ git fetch $over_there --no-tags tag v1.0.0

While it may be workable, the user experience could be better in a
couple of different ways.

 * It is not fair to expect anybody to guess that "--no-tags" means
   "--no-auto-follow-tags" without reading documentation.

	$ git fetch $over_there --no-auto-follow-tags tag v1.0.0

   might be an improvement, but of course, it is a bit longer to
   spell ;-).

 * The auto-follow kicks in whenever you tell "fetch" to update some
   refs locally.  Maybe if we tweak the rule and auto-follow kick in
   only when you tell "fetch" to update some refs outside refs/tags
   locally,

	$ git fetch $over_there tag v1.0.0

   will fetch and store _only_ the v1.0.0 tag.

   Of course, any behaviour change is a regression, and if done
   without an escape hatch, such a change robs people one useful
   feature: grab tag v1.0.0 and others older than that tag in one
   go.

I won't be coding any of the above; just thinking aloud. 

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

* Re: [PATCH] git fetch one tag only
  2012-06-07 17:08       ` Junio C Hamano
@ 2012-06-08 21:46         ` cheng renquan
  2012-06-08 22:22           ` Junio C Hamano
  0 siblings, 1 reply; 9+ messages in thread
From: cheng renquan @ 2012-06-08 21:46 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

On Thu, Jun 7, 2012 at 10:08 AM, Junio C Hamano <gitster@pobox.com> wrote:
>  * The auto-follow kicks in whenever you tell "fetch" to update some
>   refs locally.  Maybe if we tweak the rule and auto-follow kick in
>   only when you tell "fetch" to update some refs outside refs/tags
>   locally,
>
>        $ git fetch $over_there tag v1.0.0
>
>   will fetch and store _only_ the v1.0.0 tag.
>
>   Of course, any behaviour change is a regression, and if done
>   without an escape hatch, such a change robs people one useful
>   feature: grab tag v1.0.0 and others older than that tag in one
>   go.
>
> I won't be coding any of the above; just thinking aloud.

Here is the code to implement your 2nd approach,
and I don't think this behaviour change is a regression,
because if someone is really relying this fetch one tag actually fetch
all tags feature
he is relying on a broken feature, and should be corrected:
if one really need to fetch all tags, that's what explicit "--tags"
designed and documented for


diff --git a/builtin/fetch.c b/builtin/fetch.c
index bb9a074..b6d7ef3 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -158,7 +158,8 @@ static struct ref *get_ref_map(struct transport *transport,
 	if (ref_count || tags == TAGS_SET) {
 		for (i = 0; i < ref_count; i++) {
 			get_fetch_map(remote_refs, &refs[i], &tail, 0);
-			if (refs[i].dst && refs[i].dst[0])
+			if (refs[i].dst && refs[i].dst[0]
+			    && prefixcmp(refs[i].dst, "refs/tags/"))
 				*autotags = 1;
 		}
 		/* Merge everything on the command line, but not --tags */

-- 
cheng renquan (程任全)

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

* Re: [PATCH] git fetch one tag only
  2012-06-08 21:46         ` cheng renquan
@ 2012-06-08 22:22           ` Junio C Hamano
  0 siblings, 0 replies; 9+ messages in thread
From: Junio C Hamano @ 2012-06-08 22:22 UTC (permalink / raw)
  To: cheng renquan; +Cc: git

cheng renquan <crquan@gmail.com> writes:

> On Thu, Jun 7, 2012 at 10:08 AM, Junio C Hamano <gitster@pobox.com> wrote:
>>  * The auto-follow kicks in whenever you tell "fetch" to update some
>>   refs locally.  Maybe if we tweak the rule and auto-follow kick in
>>   only when you tell "fetch" to update some refs outside refs/tags
>>   locally,
>>
>>        $ git fetch $over_there tag v1.0.0
>>
>>   will fetch and store _only_ the v1.0.0 tag.
>>
>>   Of course, any behaviour change is a regression, and if done
>>   without an escape hatch, such a change robs people one useful
>>   feature: grab tag v1.0.0 and others older than that tag in one
>>   go.
>>
>> I won't be coding any of the above; just thinking aloud.
>
> Here is the code to implement your 2nd approach,

The patch is obviously and trivially correct ;-)

> and I don't think this behaviour change is a regression,
> because if someone is really relying this fetch one tag actually fetch
> all tags feature
> he is relying on a broken feature,

I do not think the old behaviour is broken. "tag v1.0.0" asks for
refs/tags/v1.0.0 at the remote and store it at refs/tags/v1.0.0
locally.  And when you ask "git fetch" to store something in refs/
hierarchy like that, without --no-tags, you are also asking tags on
commits reachable from v1.0.0 (e.g. v0.99, but not v1.1.0).

	Side note: I just double-checked this.

	$ git init junk && cd junk
        $ git fetch ../git.git tag v1.0.0

	Of course, I get v1.0.0, many tags in v0.99 series and
	v1.0rc tags, but nothing newer.

I would grant you that "asking for only tags v1.0.0 and everything
before" is not a very common thing to do, but I do not think it is a
wrong feature in any way.

In any case, when we discuss regression, "I think the old behaviour
is broken" does not matter.  Change in behaviour is change in
behaviour, even if the new one is superiour than the old one (and I
tend to think that if I were doing Git from scratch, I probably
would have coded the auto-follow part to ignore refs/tags hierarchy).

The problem of introducing such a change _today_ is that it robs a
way to ask for tags v1.0.0 and all tags before it, which people can
do with Git without the patch.  A new --auto-follow-tags option that
undoes what the patch does could remedy it, but without such an
escape hatch, the change will be a true regression as it not just
changes behaviour but it loses capability.

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

end of thread, other threads:[~2012-06-08 22:22 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-06-07  1:40 [PATCH] git fetch one tag only cheng renquan
2012-06-07  4:37 ` Junio C Hamano
2012-06-07  5:17   ` cheng renquan
2012-06-07  5:33     ` Junio C Hamano
2012-06-07  5:47       ` cheng renquan
2012-06-07 16:11         ` cheng renquan
2012-06-07 17:08       ` Junio C Hamano
2012-06-08 21:46         ` cheng renquan
2012-06-08 22:22           ` Junio C Hamano

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).