Browse Source

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 <spearce@spearce.org>
stable-0.12
Shawn O. Pearce 14 years ago
parent
commit
04f7acb7e7
  1. 39
      org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java

39
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<ObjectId> 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<Ref> want) throws IOException {
final PacketLineOut p = statelessRPC ? pckState : pckOut;
boolean first = true;

Loading…
Cancel
Save