From 04f7acb7e7c667b2a91cff2fe63c18df34924757 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Mon, 14 Mar 2011 18:52:00 -0700 Subject: [PATCH] Assume refs of alternates are reachable during fetch When fetching from a remote peer, consider all of the refs of any alternate repository to be reachable locally, in addition to the refs of the local repository. This mirrors the push protocol and may avoid unnecessary object transfer when the local repository is empty, but its alternate and the remote share a lot of common history. Junio C Hamano recently proposed a similar change to C Git's fetch client, in order to work around a performance bug I identified when fetching between two repositories that actually shared the same alternate repository on the local system. Change-Id: Iffb0b70e1223901ce2caac3b87ba7e0d6634d265 Signed-off-by: Shawn O. Pearce --- .../transport/BasePackFetchConnection.java | 39 +++++++++++-------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java index 7d8590a77..4ae26a3e5 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java @@ -317,24 +317,19 @@ public abstract class BasePackFetchConnection extends BasePackConnection private void markReachable(final Set have, final int maxTime) throws IOException { for (final Ref r : local.getAllRefs().values()) { - try { - final RevCommit o = walk.parseCommit(r.getObjectId()); - o.add(REACHABLE); - reachableCommits.add(o); - } catch (IOException readError) { - // If we cannot read the value of the ref skip it. - } + ObjectId id = r.getPeeledObjectId(); + if (id == null) + id = r.getObjectId(); + if (id == null) + continue; + parseReachable(id); } - for (final ObjectId id : have) { - try { - final RevCommit o = walk.parseCommit(id); - o.add(REACHABLE); - reachableCommits.add(o); - } catch (IOException readError) { - // If we cannot read the value of the ref skip it. - } - } + for (ObjectId id : local.getAdditionalHaves()) + parseReachable(id); + + for (ObjectId id : have) + parseReachable(id); if (maxTime > 0) { // Mark reachable commits until we reach maxTime. These may @@ -361,6 +356,18 @@ public abstract class BasePackFetchConnection extends BasePackConnection } } + private void parseReachable(ObjectId id) { + try { + RevCommit o = walk.parseCommit(id); + if (!o.has(REACHABLE)) { + o.add(REACHABLE); + reachableCommits.add(o); + } + } catch (IOException readError) { + // If we cannot read the value of the ref skip it. + } + } + private boolean sendWants(final Collection want) throws IOException { final PacketLineOut p = statelessRPC ? pckState : pckOut; boolean first = true;