Merge "Fix ReceivePack connectivity validation with alternates"

This commit is contained in:
Chris Aniszczyk 2011-04-02 09:44:26 -04:00 committed by Code Review
commit 2b42869912
2 changed files with 29 additions and 24 deletions

View File

@ -166,6 +166,9 @@ public class ReceivePack {
/** The refs we advertised as existing at the start of the connection. */
private Map<String, Ref> refs;
/** All SHA-1s shown to the client, which can be possible edges. */
private Set<ObjectId> advertisedHaves;
/** Capabilities requested by the client. */
private Set<String> enabledCapablities;
@ -208,6 +211,7 @@ public ReceivePack(final Repository into) {
refFilter = RefFilter.DEFAULT;
preReceive = PreReceiveHook.NULL;
postReceive = PostReceiveHook.NULL;
advertisedHaves = new HashSet<ObjectId>();
}
private static class ReceiveConfig {
@ -251,9 +255,28 @@ public final RevWalk getRevWalk() {
/** @return all refs which were advertised to the client. */
public final Map<String, Ref> getAdvertisedRefs() {
if (refs == null) {
refs = refFilter.filter(db.getAllRefs());
Ref head = refs.get(Constants.HEAD);
if (head != null && head.isSymbolic())
refs.remove(Constants.HEAD);
for (Ref ref : refs.values()) {
if (ref.getObjectId() != null)
advertisedHaves.add(ref.getObjectId());
}
advertisedHaves.addAll(db.getAdditionalHaves());
}
return refs;
}
/** @return the set of objects advertised as present in this repository. */
public final Set<ObjectId> getAdvertisedObjects() {
getAdvertisedRefs();
return advertisedHaves;
}
/**
* @return true if this instance will validate all referenced, but not
* supplied by the client, objects are reachable from another
@ -629,7 +652,7 @@ private void service() throws IOException {
sendAdvertisedRefs(new PacketLineOutRefAdvertiser(pckOut));
pckOut.flush();
} else
refs = refFilter.filter(db.getAllRefs());
getAdvertisedRefs();
if (advertiseError != null)
return;
recvCommands();
@ -707,12 +730,9 @@ public void sendAdvertisedRefs(final RefAdvertiser adv) throws IOException {
adv.advertiseCapability(CAPABILITY_REPORT_STATUS);
if (allowOfsDelta)
adv.advertiseCapability(CAPABILITY_OFS_DELTA);
refs = refFilter.filter(db.getAllRefs());
final Ref head = refs.remove(Constants.HEAD);
adv.send(refs);
if (head != null && !head.isSymbolic())
adv.advertiseHave(head.getObjectId());
adv.includeAdditionalHaves(db);
adv.send(getAdvertisedRefs());
for (ObjectId obj : advertisedHaves)
adv.advertiseHave(obj);
if (adv.isEmpty())
adv.advertiseId(ObjectId.zeroId(), "capabilities^{}");
adv.end();
@ -847,8 +867,8 @@ private void checkConnectivity() throws IOException {
continue;
ow.markStart(ow.parseAny(cmd.getNewId()));
}
for (final Ref ref : refs.values()) {
RevObject o = ow.parseAny(ref.getObjectId());
for (final ObjectId have : advertisedHaves) {
RevObject o = ow.parseAny(have);
ow.markUninteresting(o);
if (checkReferencedIsReachable && !baseObjects.isEmpty()) {

View File

@ -133,7 +133,6 @@ public void setDerefTags(final boolean deref) {
* <ul>
* <li>{@link #send(Map)}
* <li>{@link #advertiseHave(AnyObjectId)}
* <li>{@link #includeAdditionalHaves(Repository)}
* </ul>
*
* @param name
@ -205,20 +204,6 @@ public void advertiseHave(AnyObjectId id) throws IOException {
advertiseAnyOnce(id, ".have");
}
/**
* Include references of alternate repositories as {@code .have} lines.
*
* @param src
* repository to get the additional reachable objects from.
* @throws IOException
* the underlying output stream failed to write out an
* advertisement record.
*/
public void includeAdditionalHaves(Repository src) throws IOException {
for (ObjectId id : src.getAdditionalHaves())
advertiseHave(id);
}
/** @return true if no advertisements have been sent yet. */
public boolean isEmpty() {
return first;