private void fetchV2()

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();
		}
	}