Subject: Re: [PATCH] git-fetch: avoid local fetching from alternate (again)

From: Junio C Hamano <[email-masked]>
Date: Tue, 06 Nov 2007 23:45:35 -0800

Junio C Hamano <[email-masked]> writes:

> "Shawn O. Pearce" <[email-masked]> writes:
>
>> Back in e3c6f240fd9c5bdeb33f2d47adc859f37935e2df Junio taught
>> git-fetch to avoid copying objects when we are fetching from
>> a repository that is already registered as an alternate object
>> database.  In such a case there is no reason to copy any objects
>> as we can already obtain them through the alternate.
>
> Well spotted.  It would be a good idea to commit the big comment
> from contrib/examples/git-fetch.sh to fetch_local_nocopy()
> function, which would have made us realize that the patch does
> not refrain from applying this optimization even when shallow
> is in effect.  But I think that is actually a good change.

Having thought about this further by writing that comment myself
(patch attached), I suspect that the test at the beginning of
the function to see if we are talking to another local
repository is not necessary.  Even if we are _not_ fetching from
the remote, we could have all the necessary objects connected,
albeit the chance of that is rather slim.  But that means the
rev-list test will error out rather quickly because objects near
the tips are more likely to be missing, and if we are talking
about a true remote connection, networking cost will most likely
outweigh the cost to do this checking.

---

 transport.c |   14 ++++++++++++++
 1 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/transport.c b/transport.c
index 0604dc6..a887491 100644
--- a/transport.c
+++ b/transport.c
@@ -614,6 +614,20 @@ static struct ref *get_refs_via_connect(const struct transport *transport)
 	return refs;
 }
 
+/*
+ * We would want to bypass the object transfer altogether if
+ * everything we are going to fetch already exists and connected
+ * locally.
+ *
+ * The refs we are going to fetch are in to_fetch (nr_heads in
+ * total).  If running
+ *
+ *  $ git-rev-list --objects to_fetch[0] to_fetch[1] ... --not --all
+ *
+ * does not error out, that means everything reachable from the
+ * refs we are going to fetch exists and is connected to some of
+ * our existing refs.
+ */
 static int fetch_local_nocopy(struct transport *transport,
 			       int nr_heads, struct ref **to_fetch)
 {