Browse Source

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
stable-3.3
Shawn Pearce 11 years ago
parent
commit
b0174a089c
  1. 12
      org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java
  2. 6
      org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java

12
org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java

@ -1308,6 +1308,18 @@ public class RevWalk implements Iterable<RevCommit> {
RevCommit.carryFlags(c, carry); 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 { void initializeShallowCommits() throws IOException {
if (shallowCommitsInitialized) if (shallowCommitsInitialized)
throw new IllegalStateException( throw new IllegalStateException(

6
org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java

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

Loading…
Cancel
Save