Fix serving fetch of existing shallow client

In certain cases a JGit server updating an existing shallow client
selected a common ancestor that was behind the shallow edge of
the client. This allowed the server to assume the client had some
objects it did not have and allowed creation of pack deltas the
client could never inflate.

Any commit the client has advertised as shallow must be treated
by UploadPack server as though it has no parents. With no parents
the walker cannot visit graph history the client does not have,
and PackWriter cannot consider delta base candidates the client
is lacking.

Change-Id: I4922b9354df9f490966a586fb693762e897345a2
This commit is contained in:
Shawn Pearce 2014-01-28 16:29:15 -08:00
parent ce5fd525be
commit b0174a089c
2 changed files with 16 additions and 2 deletions

View File

@ -1308,6 +1308,18 @@ void carryFlagsImpl(final RevCommit c) {
RevCommit.carryFlags(c, carry);
}
/**
* Assume additional commits are shallow (have no parents).
*
* @param ids
* commits that should be treated as shallow commits, in addition
* to any commits already known to be shallow by the repository.
*/
public void assumeShallow(Collection<? extends ObjectId> ids) {
for (ObjectId id : ids)
lookupCommit(id).parents = RevCommit.NO_PARENTS;
}
void initializeShallowCommits() throws IOException {
if (shallowCommitsInitialized)
throw new IllegalStateException(

View File

@ -684,6 +684,8 @@ else if (requestValidator instanceof AnyRequestValidator)
if (depth != 0)
processShallow();
if (!clientShallowCommits.isEmpty())
walk.assumeShallow(clientShallowCommits);
sendPack = negotiate();
} catch (PackProtocolException err) {
reportErrorDuringNegotiate(err.getMessage());
@ -756,7 +758,7 @@ private void processShallow() throws IOException {
// Commits not on the boundary which are shallow in the client
// need to become unshallowed
if (c.getDepth() < depth && clientShallowCommits.contains(c)) {
if (c.getDepth() < depth && clientShallowCommits.remove(c)) {
unshallowCommits.add(c.copy());
pckOut.writeString("unshallow " + c.name()); //$NON-NLS-1$
}
@ -1350,7 +1352,7 @@ private void sendPack(final boolean sideband) throws IOException {
try {
pw.setIndexDisabled(true);
pw.setUseCachedPacks(true);
pw.setUseBitmaps(true);
pw.setUseBitmaps(depth == 0 && clientShallowCommits.isEmpty());
pw.setReuseDeltaCommits(true);
pw.setDeltaBaseAsOffset(options.contains(OPTION_OFS_DELTA));
pw.setThin(options.contains(OPTION_THIN_PACK));