Avoid using #refs in UploadPack#sendPack

When OPTION_INCLUDE_TAG is set, UploadPack#sendPack uses the #refs
instance variable as a source of information of tags. A subsequent patch
will need to supply this information to #sendPack without
modifying #refs, so refactor #sendPack to take in this information
through a parameter instead.

Note that prior to this patch, #refs was used twice in #sendPack: once
to generate the argument to PackWriter#setTagTargets, and once to
determine if any tags need to be included in the packfile. This patch
only updates the latter use, since the former is meant not only for
"true" tag targets but any object that should be hoisted earlier during
packing (see the documentation of PackWriter#setTagTargets).

This patch does not introduce any functionality change.

Change-Id: I70ed65a1041334abeda8d4bac98cce7cae7efcdf
Signed-off-by: Jonathan Tan <jonathantanmy@google.com>
Signed-off-by: Jonathan Nieder <jrn@google.com>
This commit is contained in:
Jonathan Tan 2018-04-23 13:03:04 -07:00 committed by Jonathan Nieder
parent 1046ba12f9
commit c79e7f1c27
1 changed files with 41 additions and 9 deletions

View File

@ -76,6 +76,7 @@
import java.util.Map;
import java.util.Set;
import org.eclipse.jgit.annotations.Nullable;
import org.eclipse.jgit.errors.CorruptObjectException;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException;
@ -866,7 +867,7 @@ else if (requestValidator instanceof AnyRequestValidator)
}
if (sendPack)
sendPack(accumulator);
sendPack(accumulator, refs == null ? null : refs.values());
}
private void lsRefsV2() throws IOException {
@ -988,7 +989,8 @@ private void fetchV2() throws IOException {
if (sectionSent)
pckOut.writeDelim();
pckOut.writeString("packfile\n"); //$NON-NLS-1$
sendPack(new PackStatistics.Accumulator());
sendPack(new PackStatistics.Accumulator(),
refs == null ? null : refs.values());
}
pckOut.end();
}
@ -1734,13 +1736,25 @@ private boolean wantSatisfied(RevObject want) throws IOException {
return false;
}
private void sendPack(PackStatistics.Accumulator accumulator)
throws IOException {
/**
* Send the requested objects to the client.
*
* @param accumulator
* where to write statistics about the content of the pack.
* @param allTags
* refs to search for annotated tags to include in the pack
* if the {@link #OPTION_INCLUDE_TAG} capability was
* requested.
* @throws IOException
* if an error occured while generating or writing the pack.
*/
private void sendPack(PackStatistics.Accumulator accumulator,
@Nullable Collection<Ref> allTags) throws IOException {
final boolean sideband = options.contains(OPTION_SIDE_BAND)
|| options.contains(OPTION_SIDE_BAND_64K);
if (sideband) {
try {
sendPack(true, accumulator);
sendPack(true, accumulator, allTags);
} catch (ServiceMayNotContinueException noPack) {
// This was already reported on (below).
throw noPack;
@ -1761,7 +1775,7 @@ private void sendPack(PackStatistics.Accumulator accumulator)
throw err;
}
} else {
sendPack(false, accumulator);
sendPack(false, accumulator, allTags);
}
}
@ -1781,8 +1795,24 @@ private boolean reportInternalServerErrorOverSideband() {
}
}
/**
* Send the requested objects to the client.
*
* @param sideband
* whether to wrap the pack in side-band pkt-lines,
* interleaved with progress messages and errors.
* @param accumulator
* where to write statistics about the content of the pack.
* @param allTags
* refs to search for annotated tags to include in the pack
* if the {@link #OPTION_INCLUDE_TAG} capability was
* requested.
* @throws IOException
* if an error occured while generating or writing the pack.
*/
private void sendPack(final boolean sideband,
PackStatistics.Accumulator accumulator) throws IOException {
PackStatistics.Accumulator accumulator,
@Nullable Collection<Ref> allTags) throws IOException {
ProgressMonitor pm = NullProgressMonitor.INSTANCE;
OutputStream packOut = rawOut;
@ -1842,6 +1872,8 @@ private void sendPack(final boolean sideband,
pw.setThin(options.contains(OPTION_THIN_PACK));
pw.setReuseValidatingObjects(false);
// Objects named directly by references go at the beginning
// of the pack.
if (commonBase.isEmpty() && refs != null) {
Set<ObjectId> tagTargets = new HashSet<>();
for (Ref ref : refs.values()) {
@ -1872,8 +1904,8 @@ else if (ref.getName().startsWith(Constants.R_HEADS))
rw = ow;
}
if (options.contains(OPTION_INCLUDE_TAG) && refs != null) {
for (Ref ref : refs.values()) {
if (options.contains(OPTION_INCLUDE_TAG) && allTags != null) {
for (Ref ref : allTags) {
ObjectId objectId = ref.getObjectId();
if (objectId == null) {
// skip unborn branch