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:
parent
ce5fd525be
commit
b0174a089c
|
@ -1308,6 +1308,18 @@ void carryFlagsImpl(final RevCommit c) {
|
||||||
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(
|
||||||
|
|
|
@ -684,6 +684,8 @@ else if (requestValidator instanceof AnyRequestValidator)
|
||||||
|
|
||||||
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 @@ private void processShallow() throws IOException {
|
||||||
|
|
||||||
// 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 @@ private void sendPack(final boolean sideband) throws IOException {
|
||||||
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…
Reference in New Issue