diff options
author | Ronald Bhuleskar <funronald@google.com> | 2023-09-21 16:12:06 -0700 |
---|---|---|
committer | Ronald Bhuleskar <funronald@google.com> | 2023-10-25 16:43:25 -0400 |
commit | 093bde518118175e1542fa2561f8d2f20649879b (patch) | |
tree | 2af4dffee0e58f5228c74e9666bb330b5b09849c /org.eclipse.jgit.test | |
parent | 7b2005d5200bd62b6aff66760460033f631e3718 (diff) | |
download | jgit-093bde518118175e1542fa2561f8d2f20649879b.tar.gz jgit-093bde518118175e1542fa2561f8d2f20649879b.zip |
BasePackFetchConnection: Avoid full clone with useNegotiationTip
With the useNegotiationTip flag (introduced in change 738dacb), the client sends to the server only the tips of the wanted refs for the negotiation. Some wanted refs may not exist in the client (yet) and our implementation ignores them. So when only non-existing refs are wanted, jgit doesn't send any tips and the server understands it is a full clone.
In useNegotiationTip, send ALL_REFS if any of the wanted refs does not exists locally.
Change-Id: Ide04c5df785b9212abcd9d3cba194515e0af166f
Diffstat (limited to 'org.eclipse.jgit.test')
-rw-r--r-- | org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java | 67 |
1 files changed, 65 insertions, 2 deletions
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java index f9687f9f82..278c9f8616 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java @@ -2215,7 +2215,8 @@ public class UploadPackTest { uri = testProtocol.register(ctx, server); - TestProtocol.setFetchConfig(new FetchConfig(true, MAX_HAVES, true)); + TestProtocol.setFetchConfig(new FetchConfig(true, MAX_HAVES, + /* useNegotiationTip= */true)); try (Transport tn = testProtocol.open(uri, clientRepo.getRepository(), "server")) { @@ -2335,7 +2336,8 @@ public class UploadPackTest { }, null); uri = testProtocol.register(ctx, server); - TestProtocol.setFetchConfig(new FetchConfig(true, MAX_HAVES, true)); + TestProtocol.setFetchConfig(new FetchConfig(true, MAX_HAVES, + /* useNegotiationTip= */true)); try (Transport tn = testProtocol.open(uri, clientRepo.getRepository(), "server")) { @@ -2362,6 +2364,67 @@ public class UploadPackTest { } } + /** + * <pre> + * remote: + * foo <- foofoo <-- branchFoo + * bar <- barbar <-- branchBar + * + * client: + * none + * + * fetch(branchFoo) should not send have and should get only branchFoo back + * </pre> + */ + @Test + public void testNegotiationTipDoesNotDoFullClone() throws Exception { + RevCommit fooParent = remote.commit().message("foo").create(); + RevCommit fooChild = remote.commit().message("foofoo").parent(fooParent) + .create(); + RevCommit barParent = remote.commit().message("bar").create(); + RevCommit barChild = remote.commit().message("barbar").parent(barParent) + .create(); + + // Remote has branchFoo at fooChild and branchBar at barChild + remote.update("branchFoo", fooChild); + remote.update("branchBar", barChild); + + AtomicReference<UploadPack> uploadPack = new AtomicReference<>(); + CountHavesPreUploadHook countHavesHook = new CountHavesPreUploadHook(); + + // Client does not have branchFoo & branchBar + try (TestRepository<InMemoryRepository> clientRepo = new TestRepository<>( + client)) { + testProtocol = new TestProtocol<>((Object req, Repository db) -> { + UploadPack up = new UploadPack(db); + up.setPreUploadHook(countHavesHook); + uploadPack.set(up); + return up; + }, null); + + uri = testProtocol.register(ctx, server); + + TestProtocol.setFetchConfig(new FetchConfig(true, MAX_HAVES, + /* useNegotiationTip= */true)); + try (Transport tn = testProtocol.open(uri, + clientRepo.getRepository(), "server")) { + + tn.fetch(NullProgressMonitor.INSTANCE, + Collections.singletonList( + new RefSpec("refs/heads/branchFoo")), + "branchFoo"); + } + } + + assertTrue(client.getObjectDatabase().has(fooParent.toObjectId())); + assertTrue(client.getObjectDatabase().has(fooChild.toObjectId())); + assertFalse(client.getObjectDatabase().has(barParent.toObjectId())); + assertFalse(client.getObjectDatabase().has(barChild.toObjectId())); + + assertEquals(0, uploadPack.get().getStatistics().getHaves()); + assertTrue(countHavesHook.havesSentDuringNegotiation.isEmpty()); + } + private static class CountHavesPreUploadHook implements PreUploadHook { Set<ObjectId> havesSentDuringNegotiation = new HashSet<>(); |