|
|
@ -100,6 +100,8 @@ public class UploadPack { |
|
|
|
|
|
|
|
|
|
|
|
static final String OPTION_NO_PROGRESS = BasePackFetchConnection.OPTION_NO_PROGRESS; |
|
|
|
static final String OPTION_NO_PROGRESS = BasePackFetchConnection.OPTION_NO_PROGRESS; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static final String OPTION_NO_DONE = BasePackFetchConnection.OPTION_NO_DONE; |
|
|
|
|
|
|
|
|
|
|
|
/** Database we read the objects from. */ |
|
|
|
/** Database we read the objects from. */ |
|
|
|
private final Repository db; |
|
|
|
private final Repository db; |
|
|
|
|
|
|
|
|
|
|
@ -163,6 +165,8 @@ public class UploadPack { |
|
|
|
/** null if {@link #commonBase} should be examined again. */ |
|
|
|
/** null if {@link #commonBase} should be examined again. */ |
|
|
|
private Boolean okToGiveUp; |
|
|
|
private Boolean okToGiveUp; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private boolean sentReady; |
|
|
|
|
|
|
|
|
|
|
|
/** Objects we sent in our advertisement list, clients can ask for these. */ |
|
|
|
/** Objects we sent in our advertisement list, clients can ask for these. */ |
|
|
|
private Set<ObjectId> advertised; |
|
|
|
private Set<ObjectId> advertised; |
|
|
|
|
|
|
|
|
|
|
@ -182,6 +186,8 @@ public class UploadPack { |
|
|
|
|
|
|
|
|
|
|
|
private MultiAck multiAck = MultiAck.OFF; |
|
|
|
private MultiAck multiAck = MultiAck.OFF; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private boolean noDone; |
|
|
|
|
|
|
|
|
|
|
|
private PackWriter.Statistics statistics; |
|
|
|
private PackWriter.Statistics statistics; |
|
|
|
|
|
|
|
|
|
|
|
private UploadPackLogger logger; |
|
|
|
private UploadPackLogger logger; |
|
|
@ -401,9 +407,10 @@ public class UploadPack { |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (options.contains(OPTION_MULTI_ACK_DETAILED)) |
|
|
|
if (options.contains(OPTION_MULTI_ACK_DETAILED)) { |
|
|
|
multiAck = MultiAck.DETAILED; |
|
|
|
multiAck = MultiAck.DETAILED; |
|
|
|
else if (options.contains(OPTION_MULTI_ACK)) |
|
|
|
noDone = options.contains(OPTION_NO_DONE); |
|
|
|
|
|
|
|
} else if (options.contains(OPTION_MULTI_ACK)) |
|
|
|
multiAck = MultiAck.CONTINUE; |
|
|
|
multiAck = MultiAck.CONTINUE; |
|
|
|
else |
|
|
|
else |
|
|
|
multiAck = MultiAck.OFF; |
|
|
|
multiAck = MultiAck.OFF; |
|
|
@ -443,6 +450,8 @@ public class UploadPack { |
|
|
|
adv.advertiseCapability(OPTION_SIDE_BAND_64K); |
|
|
|
adv.advertiseCapability(OPTION_SIDE_BAND_64K); |
|
|
|
adv.advertiseCapability(OPTION_THIN_PACK); |
|
|
|
adv.advertiseCapability(OPTION_THIN_PACK); |
|
|
|
adv.advertiseCapability(OPTION_NO_PROGRESS); |
|
|
|
adv.advertiseCapability(OPTION_NO_PROGRESS); |
|
|
|
|
|
|
|
if (!biDirectionalPipe) |
|
|
|
|
|
|
|
adv.advertiseCapability(OPTION_NO_DONE); |
|
|
|
adv.setDerefTags(true); |
|
|
|
adv.setDerefTags(true); |
|
|
|
advertised = adv.send(getAdvertisedRefs()); |
|
|
|
advertised = adv.send(getAdvertisedRefs()); |
|
|
|
adv.end(); |
|
|
|
adv.end(); |
|
|
@ -496,6 +505,10 @@ public class UploadPack { |
|
|
|
last = processHaveLines(peerHas, last); |
|
|
|
last = processHaveLines(peerHas, last); |
|
|
|
if (commonBase.isEmpty() || multiAck != MultiAck.OFF) |
|
|
|
if (commonBase.isEmpty() || multiAck != MultiAck.OFF) |
|
|
|
pckOut.writeString("NAK\n"); |
|
|
|
pckOut.writeString("NAK\n"); |
|
|
|
|
|
|
|
if (noDone && sentReady) { |
|
|
|
|
|
|
|
pckOut.writeString("ACK " + last.name() + "\n"); |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
if (!biDirectionalPipe) |
|
|
|
if (!biDirectionalPipe) |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
pckOut.flush(); |
|
|
|
pckOut.flush(); |
|
|
@ -538,6 +551,7 @@ public class UploadPack { |
|
|
|
List<ObjectId> toParse = peerHas; |
|
|
|
List<ObjectId> toParse = peerHas; |
|
|
|
HashSet<ObjectId> peerHasSet = null; |
|
|
|
HashSet<ObjectId> peerHasSet = null; |
|
|
|
boolean needMissing = false; |
|
|
|
boolean needMissing = false; |
|
|
|
|
|
|
|
sentReady = false; |
|
|
|
|
|
|
|
|
|
|
|
if (wantAll.isEmpty() && !wantIds.isEmpty()) { |
|
|
|
if (wantAll.isEmpty() && !wantIds.isEmpty()) { |
|
|
|
// We have not yet parsed the want list. Parse it now.
|
|
|
|
// We have not yet parsed the want list. Parse it now.
|
|
|
@ -644,7 +658,6 @@ public class UploadPack { |
|
|
|
// telling us about its history.
|
|
|
|
// telling us about its history.
|
|
|
|
//
|
|
|
|
//
|
|
|
|
boolean didOkToGiveUp = false; |
|
|
|
boolean didOkToGiveUp = false; |
|
|
|
boolean sentReady = false; |
|
|
|
|
|
|
|
if (0 < missCnt) { |
|
|
|
if (0 < missCnt) { |
|
|
|
for (int i = peerHas.size() - 1; i >= 0; i--) { |
|
|
|
for (int i = peerHas.size() - 1; i >= 0; i--) { |
|
|
|
ObjectId id = peerHas.get(i); |
|
|
|
ObjectId id = peerHas.get(i); |
|
|
@ -670,6 +683,7 @@ public class UploadPack { |
|
|
|
|
|
|
|
|
|
|
|
if (multiAck == MultiAck.DETAILED && !didOkToGiveUp && okToGiveUp()) { |
|
|
|
if (multiAck == MultiAck.DETAILED && !didOkToGiveUp && okToGiveUp()) { |
|
|
|
ObjectId id = peerHas.get(peerHas.size() - 1); |
|
|
|
ObjectId id = peerHas.get(peerHas.size() - 1); |
|
|
|
|
|
|
|
sentReady = true; |
|
|
|
pckOut.writeString("ACK " + id.name() + " ready\n"); |
|
|
|
pckOut.writeString("ACK " + id.name() + " ready\n"); |
|
|
|
sentReady = true; |
|
|
|
sentReady = true; |
|
|
|
} |
|
|
|
} |
|
|
|