From: Tay Ray Chuan <rctay89@gmail.com>
To: Jeff King <peff@peff.net>
Cc: Kevin Menard <nirvdrum@gmail.com>,
Ilari Liusvaara <ilari.liusvaara@elisanet.fi>,
git@vger.kernel.org
Subject: Re: git fetch origin hanging in 1.7.0
Date: Tue, 16 Feb 2010 15:18:21 +0800 [thread overview]
Message-ID: <20100216151821.994ace31.rctay89@gmail.com> (raw)
In-Reply-To: <20100216063959.GC2169@coredump.intra.peff.net>
Hi,
On Tue, 16 Feb 2010 01:39:59 -0500
Jeff King <peff@peff.net> wrote:
> I can reproduce the bug with:
>
> $ mkdir foo && (cd foo && git init)
> $ git clone foo bar
> Initialized empty Git repository in /home/peff/bar/.git/
> warning: You appear to have cloned an empty repository.
> $ cd bar && git fetch
>
> which hangs on a pipe read(). It bisects to 61b075b (Support taking over
> transports, 2009-12-09) from Ilari (cc'd). It looks like we get the
> empty ref list once in get_remote_heads, and then try to get it again
> and hang.
I agree with the diagnosis. With gdb, I find that program execution
hangs on the packet_read_line() call in connect.c::get_remote_heads().
> diff --git a/transport.c b/transport.c
> index ad25b98..e6f9464 100644
> --- a/transport.c
> +++ b/transport.c
> @@ -1010,7 +1010,8 @@ int transport_push(struct transport *transport,
>
> const struct ref *transport_get_remote_refs(struct transport *transport)
> {
> - if (!transport->remote_refs)
> + struct git_transport_data *data = transport->data;
> + if (!data->got_remote_heads)
> transport->remote_refs = transport->get_refs_list(transport, 0);
>
> return transport->remote_refs;
NAK. This will only work if the given transport is git://. (My take
below.)
> That fixes the problem for me, but I am totally clueless about this
> code. Do all transports have a git_transport_data (if so, then why is it
> a void pointer?).
It is void so that it can be any struct - for example,
git_transport_data, bundle_transport_data. That way, transport->data
can point to any transport-specific data, while keeping the compiler
satisfied at compile-time.
-- >8 --
Subject: [PATCH] transport: add got_remote_refs flag
tranport.c::transport_get_remote_refs() used to check
transport->remote_refs to determine whether transport->get_refs_list()
should be invoked.
However, transport->remote_refs could evaluate to false (eg. if it is
NULL), causingo transport->get_refs_list() to be invoked unnecessarily.
Introduce a flag, transport->got_remote_refs, and make
tranport.c::transport_get_remote_refs() check this flag rather than
evaluating transport->remote_refs.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
---
transport.c | 5 ++++-
transport.h | 6 ++++++
2 files changed, 10 insertions(+), 1 deletions(-)
diff --git a/transport.c b/transport.c
index 3846aac..08e4fa0 100644
--- a/transport.c
+++ b/transport.c
@@ -918,6 +918,7 @@ struct transport *transport_get(struct remote *remote, const char *url)
if (!remote)
die("No remote provided to transport_get()");
+ ret->got_remote_refs = 0;
ret->remote = remote;
helper = remote->foreign_vcs;
@@ -1079,8 +1080,10 @@ int transport_push(struct transport *transport,
const struct ref *transport_get_remote_refs(struct transport *transport)
{
- if (!transport->remote_refs)
+ if (!transport->got_remote_refs) {
transport->remote_refs = transport->get_refs_list(transport, 0);
+ transport->got_remote_refs = 1;
+ }
return transport->remote_refs;
}
diff --git a/transport.h b/transport.h
index 7cea5cc..1cca13b 100644
--- a/transport.h
+++ b/transport.h
@@ -20,6 +20,12 @@ struct transport {
const struct ref *remote_refs;
/**
+ * Indicates whether the remote_refs member has been set. Set by
+ * transport.c::transport_get_remote_refs().
+ */
+ unsigned got_remote_refs : 1;
+
+ /**
* Returns 0 if successful, positive if the option is not
* recognized or is inapplicable, and negative if the option
* is applicable but the value is invalid.
--
1.7.0.1.gcd472.dirty
--
Cheers,
Ray Chuan
next prev parent reply other threads:[~2010-02-16 7:18 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-02-16 0:08 git fetch origin hanging in 1.7.0 Kevin Menard
2010-02-16 6:39 ` Jeff King
2010-02-16 7:18 ` Tay Ray Chuan [this message]
2010-02-16 7:24 ` Jeff King
2010-02-16 7:32 ` Tay Ray Chuan
2010-02-16 13:20 ` Kevin Menard
2010-02-16 12:27 ` Ilari Liusvaara
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20100216151821.994ace31.rctay89@gmail.com \
--to=rctay89@gmail.com \
--cc=git@vger.kernel.org \
--cc=ilari.liusvaara@elisanet.fi \
--cc=nirvdrum@gmail.com \
--cc=peff@peff.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.