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>
This commit is contained in:
Shawn O. Pearce 2011-03-14 18:52:00 -07:00
parent c9a6980a42
commit 04f7acb7e7
1 changed files with 23 additions and 16 deletions

View File

@ -317,24 +317,19 @@ private int maxTimeWanted(final Collection<Ref> wants) {
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 @@ private void markReachable(final Set<ObjectId> have, final int maxTime)
}
}
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;