in org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java [1151:1289]
private void fetchV2(PacketLineOut pckOut) throws IOException {
// Depending on the requestValidator, #processHaveLines may
// require that advertised be set. Set it only in the required
// circumstances (to avoid a full ref lookup in the case that
// we don't need it).
if (requestValidator instanceof TipRequestValidator ||
requestValidator instanceof ReachableCommitTipRequestValidator ||
requestValidator instanceof AnyRequestValidator) {
advertised = Collections.emptySet();
} else {
advertised = refIdSet(getAdvertisedOrDefaultRefs().values());
}
PackStatistics.Accumulator accumulator = new PackStatistics.Accumulator();
Instant negotiateStart = Instant.now();
ProtocolV2Parser parser = new ProtocolV2Parser(transferConfig);
FetchV2Request req = parser.parseFetchRequest(pckIn);
currentRequest = req;
rawOut.stopBuffering();
protocolV2Hook.onFetch(req);
if (req.getSidebandAll()) {
pckOut.setUsingSideband(true);
}
// TODO(ifrade): Refactor to pass around the Request object, instead of
// copying data back to class fields
List<ObjectId> deepenNots = new ArrayList<>();
for (String s : req.getDeepenNotRefs()) {
Ref ref = findRef(s);
if (ref == null) {
throw new PackProtocolException(MessageFormat
.format(JGitText.get().invalidRefName, s));
}
deepenNots.add(ref.getObjectId());
}
Map<String, ObjectId> wantedRefs = wantedRefs(req);
// TODO(ifrade): Avoid mutating the parsed request.
req.getWantIds().addAll(wantedRefs.values());
wantIds = req.getWantIds();
boolean sectionSent = false;
boolean mayHaveShallow = req.getDepth() != 0
|| req.getDeepenSince() != 0
|| !req.getDeepenNotRefs().isEmpty();
List<ObjectId> shallowCommits = new ArrayList<>();
List<ObjectId> unshallowCommits = new ArrayList<>();
if (!req.getClientShallowCommits().isEmpty()) {
verifyClientShallow(req.getClientShallowCommits());
}
if (mayHaveShallow) {
computeShallowsAndUnshallows(req,
shallowCommit -> shallowCommits.add(shallowCommit),
unshallowCommit -> unshallowCommits.add(unshallowCommit),
deepenNots);
}
if (!req.getClientShallowCommits().isEmpty())
walk.assumeShallow(req.getClientShallowCommits());
if (req.wasDoneReceived()) {
processHaveLines(
req.getPeerHas(), ObjectId.zeroId(),
new PacketLineOut(NullOutputStream.INSTANCE, false),
accumulator, req.wasWaitForDoneReceived() ? Option.WAIT_FOR_DONE : Option.NONE);
} else {
pckOut.writeString(
GitProtocolConstants.SECTION_ACKNOWLEDGMENTS + '\n');
for (ObjectId id : req.getPeerHas()) {
if (walk.getObjectReader().has(id)) {
pckOut.writeString("ACK " + id.getName() + "\n"); //$NON-NLS-1$ //$NON-NLS-2$
}
}
processHaveLines(req.getPeerHas(), ObjectId.zeroId(),
new PacketLineOut(NullOutputStream.INSTANCE, false),
accumulator, Option.NONE);
if (!req.wasWaitForDoneReceived() && okToGiveUp()) {
pckOut.writeString("ready\n"); //$NON-NLS-1$
} else if (commonBase.isEmpty()) {
pckOut.writeString("NAK\n"); //$NON-NLS-1$
}
sectionSent = true;
}
if (req.wasDoneReceived() || (!req.wasWaitForDoneReceived() && okToGiveUp())) {
if (mayHaveShallow) {
if (sectionSent)
pckOut.writeDelim();
pckOut.writeString("shallow-info\n"); //$NON-NLS-1$
for (ObjectId o : shallowCommits) {
pckOut.writeString("shallow " + o.getName() + '\n'); //$NON-NLS-1$
}
for (ObjectId o : unshallowCommits) {
pckOut.writeString("unshallow " + o.getName() + '\n'); //$NON-NLS-1$
}
sectionSent = true;
}
if (!wantedRefs.isEmpty()) {
if (sectionSent) {
pckOut.writeDelim();
}
pckOut.writeString("wanted-refs\n"); //$NON-NLS-1$
for (Map.Entry<String, ObjectId> entry :
wantedRefs.entrySet()) {
pckOut.writeString(entry.getValue().getName() + ' ' +
entry.getKey() + '\n');
}
sectionSent = true;
}
if (sectionSent)
pckOut.writeDelim();
if (!pckOut.isUsingSideband()) {
// sendPack will write "packfile\n" for us if sideband-all is used.
// But sideband-all is not used, so we have to write it ourselves.
pckOut.writeString(
GitProtocolConstants.SECTION_PACKFILE + '\n');
}
accumulator.timeNegotiating = Duration
.between(negotiateStart, Instant.now()).toMillis();
sendPack(accumulator,
req,
req.getClientCapabilities().contains(OPTION_INCLUDE_TAG)
? db.getRefDatabase().getRefsByPrefix(R_TAGS)
: null,
unshallowCommits, deepenNots, pckOut);
// sendPack invokes pckOut.end() for us, so we do not
// need to invoke it here.
} else {
// Invoke pckOut.end() by ourselves.
pckOut.end();
}
}