git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [BUG] "fetch $there +refs/*:refs/*" fails if there is a stash
@ 2012-05-01 22:19 Junio C Hamano
  2012-05-02  9:15 ` Michael Haggerty
  2012-05-04 22:30 ` [PATCH] fetch/push: allow refs/*:refs/* Junio C Hamano
  0 siblings, 2 replies; 10+ messages in thread
From: Junio C Hamano @ 2012-05-01 22:19 UTC (permalink / raw)
  To: git; +Cc: Michael Haggerty

This ought to work:

    $ git checkout HEAD^0 ;# make sure we are on detached HEAD
    $ git fetch $somewhere +refs/*:refs/*

if you want to pull down all the branches from somewhere, potentially
nuking the refs we currently have.

However, if $somewhere has a stash, i.e. refs/stash, even though our
"fetch" sees it in the "ls-remote $somewhere" output and tries to make
sure that the object comes over the wire, we never show "want" line for
refs/stash, because we silently drop it with check_ref_format().

I have run out concentration before digging this through, but the attached
single liner patch fixes it.  The thing is, this function is given a list
of refs and drops refs/stash (which is not what I want in the context of
the above +refs/*:refs/*), and modifies the caller's list of refs, and
then the caller (i.e. do_fetch_pack() that called everything_local()) then
uses updated list (i.e. without refs/stash) to run find_common() and
get_pack(), but the layer higher above (namely, do_fetch() that calls
fetch_refs() that in turn calls store_updated_refs(), all in
builtin/fetch.c) is _not_ aware of this filtering and expects that the
code at this layer *must* have asked for and obtained all the objects
reachable from what was listed in ls-remote output, leading to an
inconsistent state.

[Michael CC'ed as he seems to be dead set tightening check_ref_format()]

The specific failure of "refs/stash" is fixed with this patch, but I think
this call to check_ref_format() in the filter_refs() should be removed.
The function is trying to see what we _asked_ against what the remote side
said they have, and if we tried to recover objects from a broken remote by
doing:

	git fetch $somewhere refs/heads/a..b:refs/heads/a_dot_dot_b

and the remote side advertised that it has such a ref (note that a..b is
an illegal path component), we should be able to do so without a misguided
call to check_refname_format() getting in the way.

It is the same story if the name advertised by a broken remote were
"refs/head/../heads/master".  As long as the RHS of the refspec
(i.e. refs/heads/a_dot_dot_b) is kosher, we must allow such a request to
succeed, so that people can interoperate in less than perfect world.

 builtin/fetch-pack.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/builtin/fetch-pack.c b/builtin/fetch-pack.c
index 7124c4b..34cd8a5 100644
--- a/builtin/fetch-pack.c
+++ b/builtin/fetch-pack.c
@@ -541,7 +541,7 @@ static void filter_refs(struct ref **refs, int nr_match, char **match)
 	for (ref = *refs; ref; ref = next) {
 		next = ref->next;
 		if (!memcmp(ref->name, "refs/", 5) &&
-		    check_refname_format(ref->name + 5, 0))
+		    check_refname_format(ref->name, 0))
 			; /* trash */
 		else if (args.fetch_all &&
 			 (!args.depth || prefixcmp(ref->name, "refs/tags/") )) {

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

end of thread, other threads:[~2012-05-15 15:19 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-05-01 22:19 [BUG] "fetch $there +refs/*:refs/*" fails if there is a stash Junio C Hamano
2012-05-02  9:15 ` Michael Haggerty
2012-05-02 16:26   ` Junio C Hamano
2012-05-04 22:30 ` [PATCH] fetch/push: allow refs/*:refs/* Junio C Hamano
2012-05-04 22:35   ` [PATCH] get_fetch_map(): tighten checks on dest refs Junio C Hamano
2012-05-05  6:03   ` [PATCH] fetch/push: allow refs/*:refs/* Michael Haggerty
2012-05-05 18:22     ` Michael Haggerty
2012-05-07 16:24     ` Junio C Hamano
2012-05-15  8:49       ` Michael Haggerty
2012-05-15 15:19         ` 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).