package org.eclipse.jgit.transport;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.hasItems;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Consumer;

import org.eclipse.jgit.dircache.DirCache;
import org.eclipse.jgit.dircache.DirCacheBuilder;
import org.eclipse.jgit.dircache.DirCacheEntry;
import org.eclipse.jgit.errors.TransportException;
import org.eclipse.jgit.internal.storage.dfs.DfsGarbageCollector;
import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
import org.eclipse.jgit.internal.storage.file.PackLock;
import org.eclipse.jgit.internal.storage.pack.CachedPack;
import org.eclipse.jgit.internal.storage.pack.CachedPackUriProvider;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.NullProgressMonitor;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.ProgressMonitor;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefDatabase;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.Sets;
import org.eclipse.jgit.lib.TextProgressMonitor;
import org.eclipse.jgit.revwalk.RevBlob;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevTag;
import org.eclipse.jgit.revwalk.RevTree;
import org.eclipse.jgit.storage.pack.PackStatistics;
import org.eclipse.jgit.transport.UploadPack.RequestPolicy;
import org.eclipse.jgit.util.io.NullOutputStream;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

/**
 * Tests for server upload-pack utilities.
 */
public class UploadPackTest {
	private URIish uri;

	private TestProtocol<Object> testProtocol;

	private final Object ctx = new Object();

	private InMemoryRepository server;

	private InMemoryRepository client;

	private TestRepository<InMemoryRepository> remote;

	private PackStatistics stats;

	@Before
	public void setUp() throws Exception {
		server = newRepo("server");
		client = newRepo("client");

		remote = new TestRepository<>(server);
	}

	@After
	public void tearDown() {
		Transport.unregister(testProtocol);
	}

	private static InMemoryRepository newRepo(String name) {
		return new InMemoryRepository(new DfsRepositoryDescription(name));
	}

	private void generateBitmaps(InMemoryRepository repo) throws Exception {
		new DfsGarbageCollector(repo).pack(null);
		repo.scanForRepoChanges();
	}

	@Test
	public void testFetchParentOfShallowCommit() throws Exception {
		RevCommit commit0 = remote.commit().message("0").create();
		RevCommit commit1 = remote.commit().message("1").parent(commit0).create();
		RevCommit tip = remote.commit().message("2").parent(commit1).create();
		remote.update("master", tip);

		testProtocol = new TestProtocol<>((Object req, Repository db) -> {
			UploadPack up = new UploadPack(db);
			up.setRequestPolicy(RequestPolicy.REACHABLE_COMMIT);
			// assume client has a shallow commit
			up.getRevWalk()
					.assumeShallow(Collections.singleton(commit1.getId()));
			return up;
		}, null);
		uri = testProtocol.register(ctx, server);

		assertFalse(client.getObjectDatabase().has(commit0.toObjectId()));

		// Fetch of the parent of the shallow commit
		try (Transport tn = testProtocol.open(uri, client, "server")) {
			tn.fetch(NullProgressMonitor.INSTANCE,
					Collections.singletonList(new RefSpec(commit0.name())));
			assertTrue(client.getObjectDatabase().has(commit0.toObjectId()));
		}
	}

	@Test
	public void testFetchWithBlobNoneFilter() throws Exception {
		InMemoryRepository server2 = newRepo("server2");
		try (TestRepository<InMemoryRepository> remote2 = new TestRepository<>(
				server2)) {
			RevBlob blob1 = remote2.blob("foobar");
			RevBlob blob2 = remote2.blob("fooba");
			RevTree tree = remote2.tree(remote2.file("1", blob1),
					remote2.file("2", blob2));
			RevCommit commit = remote2.commit(tree);
			remote2.update("master", commit);

			server2.getConfig().setBoolean("uploadpack", null, "allowfilter",
					true);

			testProtocol = new TestProtocol<>((Object req, Repository db) -> {
				UploadPack up = new UploadPack(db);
				return up;
			}, null);
			uri = testProtocol.register(ctx, server2);

			try (Transport tn = testProtocol.open(uri, client, "server2")) {
				tn.setFilterSpec(FilterSpec.withBlobLimit(0));
				tn.fetch(NullProgressMonitor.INSTANCE,
						Collections.singletonList(new RefSpec(commit.name())));
				assertTrue(client.getObjectDatabase().has(tree.toObjectId()));
				assertFalse(client.getObjectDatabase().has(blob1.toObjectId()));
				assertFalse(client.getObjectDatabase().has(blob2.toObjectId()));
			}
		}
	}

	@Test
	public void testFetchExplicitBlobWithFilter() throws Exception {
		InMemoryRepository server2 = newRepo("server2");
		try (TestRepository<InMemoryRepository> remote2 = new TestRepository<>(
				server2)) {
			RevBlob blob1 = remote2.blob("foobar");
			RevBlob blob2 = remote2.blob("fooba");
			RevTree tree = remote2.tree(remote2.file("1", blob1),
					remote2.file("2", blob2));
			RevCommit commit = remote2.commit(tree);
			remote2.update("master", commit);
			remote2.update("a_blob", blob1);

			server2.getConfig().setBoolean("uploadpack", null, "allowfilter",
					true);

			testProtocol = new TestProtocol<>((Object req, Repository db) -> {
				UploadPack up = new UploadPack(db);
				return up;
			}, null);
			uri = testProtocol.register(ctx, server2);

			try (Transport tn = testProtocol.open(uri, client, "server2")) {
				tn.setFilterSpec(FilterSpec.withBlobLimit(0));
				tn.fetch(NullProgressMonitor.INSTANCE, Arrays.asList(
						new RefSpec(commit.name()), new RefSpec(blob1.name())));
				assertTrue(client.getObjectDatabase().has(tree.toObjectId()));
				assertTrue(client.getObjectDatabase().has(blob1.toObjectId()));
				assertFalse(client.getObjectDatabase().has(blob2.toObjectId()));
			}
		}
	}

	@Test
	public void testFetchWithBlobLimitFilter() throws Exception {
		InMemoryRepository server2 = newRepo("server2");
		try (TestRepository<InMemoryRepository> remote2 = new TestRepository<>(
				server2)) {
			RevBlob longBlob = remote2.blob("foobar");
			RevBlob shortBlob = remote2.blob("fooba");
			RevTree tree = remote2.tree(remote2.file("1", longBlob),
					remote2.file("2", shortBlob));
			RevCommit commit = remote2.commit(tree);
			remote2.update("master", commit);

			server2.getConfig().setBoolean("uploadpack", null, "allowfilter",
					true);

			testProtocol = new TestProtocol<>((Object req, Repository db) -> {
				UploadPack up = new UploadPack(db);
				return up;
			}, null);
			uri = testProtocol.register(ctx, server2);

			try (Transport tn = testProtocol.open(uri, client, "server2")) {
				tn.setFilterSpec(FilterSpec.withBlobLimit(5));
				tn.fetch(NullProgressMonitor.INSTANCE,
						Collections.singletonList(new RefSpec(commit.name())));
				assertFalse(
						client.getObjectDatabase().has(longBlob.toObjectId()));
				assertTrue(
						client.getObjectDatabase().has(shortBlob.toObjectId()));
			}
		}
	}

	@Test
	public void testFetchExplicitBlobWithFilterAndBitmaps() throws Exception {
		InMemoryRepository server2 = newRepo("server2");
		try (TestRepository<InMemoryRepository> remote2 = new TestRepository<>(
				server2)) {
			RevBlob blob1 = remote2.blob("foobar");
			RevBlob blob2 = remote2.blob("fooba");
			RevTree tree = remote2.tree(remote2.file("1", blob1),
					remote2.file("2", blob2));
			RevCommit commit = remote2.commit(tree);
			remote2.update("master", commit);
			remote2.update("a_blob", blob1);

			server2.getConfig().setBoolean("uploadpack", null, "allowfilter",
					true);

			// generate bitmaps
			new DfsGarbageCollector(server2).pack(null);
			server2.scanForRepoChanges();

			testProtocol = new TestProtocol<>((Object req, Repository db) -> {
				UploadPack up = new UploadPack(db);
				return up;
			}, null);
			uri = testProtocol.register(ctx, server2);

			try (Transport tn = testProtocol.open(uri, client, "server2")) {
				tn.setFilterSpec(FilterSpec.withBlobLimit(0));
				tn.fetch(NullProgressMonitor.INSTANCE, Arrays.asList(
						new RefSpec(commit.name()), new RefSpec(blob1.name())));
				assertTrue(client.getObjectDatabase().has(blob1.toObjectId()));
				assertFalse(client.getObjectDatabase().has(blob2.toObjectId()));
			}
		}
	}

	@Test
	public void testFetchWithBlobLimitFilterAndBitmaps() throws Exception {
		InMemoryRepository server2 = newRepo("server2");
		try (TestRepository<InMemoryRepository> remote2 = new TestRepository<>(
				server2)) {
			RevBlob longBlob = remote2.blob("foobar");
			RevBlob shortBlob = remote2.blob("fooba");
			RevTree tree = remote2.tree(remote2.file("1", longBlob),
					remote2.file("2", shortBlob));
			RevCommit commit = remote2.commit(tree);
			remote2.update("master", commit);

			server2.getConfig().setBoolean("uploadpack", null, "allowfilter",
					true);

			// generate bitmaps
			new DfsGarbageCollector(server2).pack(null);
			server2.scanForRepoChanges();

			testProtocol = new TestProtocol<>((Object req, Repository db) -> {
				UploadPack up = new UploadPack(db);
				return up;
			}, null);
			uri = testProtocol.register(ctx, server2);

			try (Transport tn = testProtocol.open(uri, client, "server2")) {
				tn.setFilterSpec(FilterSpec.withBlobLimit(5));
				tn.fetch(NullProgressMonitor.INSTANCE,
						Collections.singletonList(new RefSpec(commit.name())));
				assertFalse(
						client.getObjectDatabase().has(longBlob.toObjectId()));
				assertTrue(
						client.getObjectDatabase().has(shortBlob.toObjectId()));
			}
		}
	}

	@Test
	public void testFetchWithNonSupportingServer() throws Exception {
		InMemoryRepository server2 = newRepo("server2");
		try (TestRepository<InMemoryRepository> remote2 = new TestRepository<>(
				server2)) {
			RevBlob blob = remote2.blob("foo");
			RevTree tree = remote2.tree(remote2.file("1", blob));
			RevCommit commit = remote2.commit(tree);
			remote2.update("master", commit);

			server2.getConfig().setBoolean("uploadpack", null, "allowfilter",
					false);

			testProtocol = new TestProtocol<>((Object req, Repository db) -> {
				UploadPack up = new UploadPack(db);
				return up;
			}, null);
			uri = testProtocol.register(ctx, server2);

			try (Transport tn = testProtocol.open(uri, client, "server2")) {
				tn.setFilterSpec(FilterSpec.withBlobLimit(0));

				TransportException e = assertThrows(TransportException.class,
						() -> tn.fetch(NullProgressMonitor.INSTANCE, Collections
								.singletonList(new RefSpec(commit.name()))));
				assertThat(e.getMessage(), containsString(
						"filter requires server to advertise that capability"));
			}
		}
	}

	/*
	 * Invokes UploadPack with protocol v2 and sends it the given lines,
	 * and returns UploadPack's output stream.
	 */
	private ByteArrayInputStream uploadPackV2Setup(
			Consumer<UploadPack> postConstructionSetup, String... inputLines)
			throws Exception {

		ByteArrayInputStream send = linesAsInputStream(inputLines);

		server.getConfig().setString("protocol", null, "version", "2");
		UploadPack up = new UploadPack(server);
		if (postConstructionSetup != null) {
			postConstructionSetup.accept(up);
		}
		up.setExtraParameters(Sets.of("version=2"));

		ByteArrayOutputStream recv = new ByteArrayOutputStream();
		up.upload(send, recv, null);
		stats = up.getStatistics();

		return new ByteArrayInputStream(recv.toByteArray());
	}

	private static ByteArrayInputStream linesAsInputStream(String... inputLines)
			throws IOException {
		try (ByteArrayOutputStream send = new ByteArrayOutputStream()) {
			PacketLineOut pckOut = new PacketLineOut(send);
			for (String line : inputLines) {
				Objects.requireNonNull(line);
				if (PacketLineIn.isEnd(line)) {
					pckOut.end();
				} else if (PacketLineIn.isDelimiter(line)) {
					pckOut.writeDelim();
				} else {
					pckOut.writeString(line);
				}
			}
			return new ByteArrayInputStream(send.toByteArray());
		}
	}

	/*
	 * Invokes UploadPack with protocol v2 and sends it the given lines.
	 * Returns UploadPack's output stream, not including the capability
	 * advertisement by the server.
	 */
	private ByteArrayInputStream uploadPackV2(
			Consumer<UploadPack> postConstructionSetup,
			String... inputLines)
			throws Exception {
		ByteArrayInputStream recvStream =
				uploadPackV2Setup(postConstructionSetup, inputLines);
		PacketLineIn pckIn = new PacketLineIn(recvStream);

		// drain capabilities
		while (!PacketLineIn.isEnd(pckIn.readString())) {
			// do nothing
		}
		return recvStream;
	}

	private ByteArrayInputStream uploadPackV2(String... inputLines) throws Exception {
		return uploadPackV2(null, inputLines);
	}

	private static class TestV2Hook implements ProtocolV2Hook {
		private CapabilitiesV2Request capabilitiesRequest;

		private LsRefsV2Request lsRefsRequest;

		private FetchV2Request fetchRequest;

		@Override
		public void onCapabilities(CapabilitiesV2Request req) {
			capabilitiesRequest = req;
		}

		@Override
		public void onLsRefs(LsRefsV2Request req) {
			lsRefsRequest = req;
		}

		@Override
		public void onFetch(FetchV2Request req) {
			fetchRequest = req;
		}
	}

	@Test
	public void testV2Capabilities() throws Exception {
		TestV2Hook hook = new TestV2Hook();
		ByteArrayInputStream recvStream = uploadPackV2Setup(
				(UploadPack up) -> {up.setProtocolV2Hook(hook);},
				PacketLineIn.end());
		PacketLineIn pckIn = new PacketLineIn(recvStream);
		assertThat(hook.capabilitiesRequest, notNullValue());
		assertThat(pckIn.readString(), is("version 2"));
		assertThat(
				Arrays.asList(pckIn.readString(), pckIn.readString(),
						pckIn.readString()),
				// TODO(jonathantanmy) This check is written this way
				// to make it simple to see that we expect this list of
				// capabilities, but probably should be loosened to
				// allow additional commands to be added to the list,
				// and additional capabilities to be added to existing
				// commands without requiring test changes.
				hasItems("ls-refs", "fetch=shallow", "server-option"));
		assertTrue(PacketLineIn.isEnd(pckIn.readString()));
	}

	private void checkAdvertisedIfAllowed(String configSection, String configName,
			String fetchCapability) throws Exception {
		server.getConfig().setBoolean(configSection, null, configName, true);
		ByteArrayInputStream recvStream =
				uploadPackV2Setup(null, PacketLineIn.end());
		PacketLineIn pckIn = new PacketLineIn(recvStream);

		assertThat(pckIn.readString(), is("version 2"));

		ArrayList<String> lines = new ArrayList<>();
		String line;
		while (!PacketLineIn.isEnd((line = pckIn.readString()))) {
			if (line.startsWith("fetch=")) {
				assertThat(
					Arrays.asList(line.substring(6).split(" ")),
					containsInAnyOrder(fetchCapability, "shallow"));
				lines.add("fetch");
			} else {
				lines.add(line);
			}
		}
		assertThat(lines, containsInAnyOrder("ls-refs", "fetch", "server-option"));
	}

	private void checkUnadvertisedIfUnallowed(String configSection,
			String configName, String fetchCapability) throws Exception {
		server.getConfig().setBoolean(configSection, null, configName, false);
		ByteArrayInputStream recvStream =
				uploadPackV2Setup(null, PacketLineIn.end());
		PacketLineIn pckIn = new PacketLineIn(recvStream);

		assertThat(pckIn.readString(), is("version 2"));

		ArrayList<String> lines = new ArrayList<>();
		String line;
		while (!PacketLineIn.isEnd((line = pckIn.readString()))) {
			if (line.startsWith("fetch=")) {
				List<String> fetchItems = Arrays.asList(line.substring(6).split(" "));
				assertThat(fetchItems, hasItems("shallow"));
				assertFalse(fetchItems.contains(fetchCapability));
				lines.add("fetch");
			} else {
				lines.add(line);
			}
		}
		assertThat(lines, hasItems("ls-refs", "fetch", "server-option"));
	}

	@Test
	public void testV2CapabilitiesAllowFilter() throws Exception {
		checkAdvertisedIfAllowed("uploadpack", "allowfilter", "filter");
		checkUnadvertisedIfUnallowed("uploadpack", "allowfilter", "filter");
	}

	@Test
	public void testV2CapabilitiesRefInWant() throws Exception {
		checkAdvertisedIfAllowed("uploadpack", "allowrefinwant", "ref-in-want");
	}

	@Test
	public void testV2CapabilitiesRefInWantNotAdvertisedIfUnallowed() throws Exception {
		checkUnadvertisedIfUnallowed("uploadpack", "allowrefinwant",
				"ref-in-want");
	}

	@Test
	public void testV2CapabilitiesAdvertiseSidebandAll() throws Exception {
		server.getConfig().setBoolean("uploadpack", null, "allowsidebandall",
				true);
		checkAdvertisedIfAllowed("uploadpack", "advertisesidebandall",
				"sideband-all");
		checkUnadvertisedIfUnallowed("uploadpack", "advertisesidebandall",
				"sideband-all");
	}

	@Test
	public void testV2CapabilitiesRefInWantNotAdvertisedIfAdvertisingForbidden() throws Exception {
		server.getConfig().setBoolean("uploadpack", null, "allowrefinwant", true);
		server.getConfig().setBoolean("uploadpack", null, "advertiserefinwant", false);
		ByteArrayInputStream recvStream =
				uploadPackV2Setup(null, PacketLineIn.end());
		PacketLineIn pckIn = new PacketLineIn(recvStream);

		assertThat(pckIn.readString(), is("version 2"));
		assertThat(
				Arrays.asList(pckIn.readString(), pckIn.readString(),
						pckIn.readString()),
				hasItems("ls-refs", "fetch=shallow", "server-option"));
		assertTrue(PacketLineIn.isEnd(pckIn.readString()));
	}

	@Test
	public void testV2EmptyRequest() throws Exception {
		ByteArrayInputStream recvStream = uploadPackV2(PacketLineIn.end());
		// Verify that there is nothing more after the capability
		// advertisement.
		assertEquals(0, recvStream.available());
	}

	@Test
	public void testV2LsRefs() throws Exception {
		RevCommit tip = remote.commit().message("message").create();
		remote.update("master", tip);
		server.updateRef("HEAD").link("refs/heads/master");
		RevTag tag = remote.tag("tag", tip);
		remote.update("refs/tags/tag", tag);

		TestV2Hook hook = new TestV2Hook();
		ByteArrayInputStream recvStream = uploadPackV2(
				(UploadPack up) -> {up.setProtocolV2Hook(hook);},
				"command=ls-refs\n", PacketLineIn.end());
		PacketLineIn pckIn = new PacketLineIn(recvStream);

		assertThat(hook.lsRefsRequest, notNullValue());
		assertThat(pckIn.readString(), is(tip.toObjectId().getName() + " HEAD"));
		assertThat(pckIn.readString(), is(tip.toObjectId().getName() + " refs/heads/master"));
		assertThat(pckIn.readString(), is(tag.toObjectId().getName() + " refs/tags/tag"));
		assertTrue(PacketLineIn.isEnd(pckIn.readString()));
	}

	@Test
	public void testV2LsRefsSymrefs() throws Exception {
		RevCommit tip = remote.commit().message("message").create();
		remote.update("master", tip);
		server.updateRef("HEAD").link("refs/heads/master");
		RevTag tag = remote.tag("tag", tip);
		remote.update("refs/tags/tag", tag);

		ByteArrayInputStream recvStream = uploadPackV2("command=ls-refs\n",
				PacketLineIn.delimiter(), "symrefs", PacketLineIn.end());
		PacketLineIn pckIn = new PacketLineIn(recvStream);

		assertThat(pckIn.readString(), is(tip.toObjectId().getName() + " HEAD symref-target:refs/heads/master"));
		assertThat(pckIn.readString(), is(tip.toObjectId().getName() + " refs/heads/master"));
		assertThat(pckIn.readString(), is(tag.toObjectId().getName() + " refs/tags/tag"));
		assertTrue(PacketLineIn.isEnd(pckIn.readString()));
	}

	@Test
	public void testV2LsRefsPeel() throws Exception {
		RevCommit tip = remote.commit().message("message").create();
		remote.update("master", tip);
		server.updateRef("HEAD").link("refs/heads/master");
		RevTag tag = remote.tag("tag", tip);
		remote.update("refs/tags/tag", tag);

		ByteArrayInputStream recvStream = uploadPackV2("command=ls-refs\n",
				PacketLineIn.delimiter(), "peel", PacketLineIn.end());
		PacketLineIn pckIn = new PacketLineIn(recvStream);

		assertThat(pckIn.readString(), is(tip.toObjectId().getName() + " HEAD"));
		assertThat(pckIn.readString(), is(tip.toObjectId().getName() + " refs/heads/master"));
		assertThat(
			pckIn.readString(),
			is(tag.toObjectId().getName() + " refs/tags/tag peeled:"
				+ tip.toObjectId().getName()));
		assertTrue(PacketLineIn.isEnd(pckIn.readString()));
	}

	@Test
	public void testV2LsRefsMultipleCommands() throws Exception {
		RevCommit tip = remote.commit().message("message").create();
		remote.update("master", tip);
		server.updateRef("HEAD").link("refs/heads/master");
		RevTag tag = remote.tag("tag", tip);
		remote.update("refs/tags/tag", tag);

		ByteArrayInputStream recvStream = uploadPackV2(
				"command=ls-refs\n", PacketLineIn.delimiter(), "symrefs",
				"peel", PacketLineIn.end(), "command=ls-refs\n",
				PacketLineIn.delimiter(), PacketLineIn.end());
		PacketLineIn pckIn = new PacketLineIn(recvStream);

		assertThat(pckIn.readString(), is(tip.toObjectId().getName() + " HEAD symref-target:refs/heads/master"));
		assertThat(pckIn.readString(), is(tip.toObjectId().getName() + " refs/heads/master"));
		assertThat(
			pckIn.readString(),
			is(tag.toObjectId().getName() + " refs/tags/tag peeled:"
				+ tip.toObjectId().getName()));
		assertTrue(PacketLineIn.isEnd(pckIn.readString()));
		assertThat(pckIn.readString(), is(tip.toObjectId().getName() + " HEAD"));
		assertThat(pckIn.readString(), is(tip.toObjectId().getName() + " refs/heads/master"));
		assertThat(pckIn.readString(), is(tag.toObjectId().getName() + " refs/tags/tag"));
		assertTrue(PacketLineIn.isEnd(pckIn.readString()));
	}

	@Test
	public void testV2LsRefsRefPrefix() throws Exception {
		RevCommit tip = remote.commit().message("message").create();
		remote.update("master", tip);
		remote.update("other", tip);
		remote.update("yetAnother", tip);

		ByteArrayInputStream recvStream = uploadPackV2(
			"command=ls-refs\n",
			PacketLineIn.delimiter(),
			"ref-prefix refs/heads/maste",
			"ref-prefix refs/heads/other",
				PacketLineIn.end());
		PacketLineIn pckIn = new PacketLineIn(recvStream);

		assertThat(pckIn.readString(), is(tip.toObjectId().getName() + " refs/heads/master"));
		assertThat(pckIn.readString(), is(tip.toObjectId().getName() + " refs/heads/other"));
		assertTrue(PacketLineIn.isEnd(pckIn.readString()));
	}

	@Test
	public void testV2LsRefsRefPrefixNoSlash() throws Exception {
		RevCommit tip = remote.commit().message("message").create();
		remote.update("master", tip);
		remote.update("other", tip);

		ByteArrayInputStream recvStream = uploadPackV2(
			"command=ls-refs\n",
			PacketLineIn.delimiter(),
			"ref-prefix refs/heads/maste",
			"ref-prefix r",
				PacketLineIn.end());
		PacketLineIn pckIn = new PacketLineIn(recvStream);

		assertThat(pckIn.readString(), is(tip.toObjectId().getName() + " refs/heads/master"));
		assertThat(pckIn.readString(), is(tip.toObjectId().getName() + " refs/heads/other"));
		assertTrue(PacketLineIn.isEnd(pckIn.readString()));
	}

	@Test
	public void testV2LsRefsUnrecognizedArgument() throws Exception {
		UploadPackInternalServerErrorException e = assertThrows(
				UploadPackInternalServerErrorException.class,
				() -> uploadPackV2("command=ls-refs\n",
						PacketLineIn.delimiter(), "invalid-argument\n",
						PacketLineIn.end()));
		assertThat(e.getCause().getMessage(),
				containsString("unexpected invalid-argument"));
	}

	@Test
	public void testV2LsRefsServerOptions() throws Exception {
		String[] lines = { "command=ls-refs\n",
				"server-option=one\n", "server-option=two\n",
				PacketLineIn.delimiter(),
				PacketLineIn.end() };

		TestV2Hook testHook = new TestV2Hook();
		uploadPackV2Setup((UploadPack up) -> {up.setProtocolV2Hook(testHook);}, lines);

		LsRefsV2Request req = testHook.lsRefsRequest;
		assertEquals(2, req.getServerOptions().size());
		assertThat(req.getServerOptions(), hasItems("one", "two"));
	}

	/*
	 * Parse multiplexed packfile output from upload-pack using protocol V2
	 * into the client repository.
	 */
	private ReceivedPackStatistics parsePack(ByteArrayInputStream recvStream) throws Exception {
		return parsePack(recvStream, NullProgressMonitor.INSTANCE);
	}

	private ReceivedPackStatistics parsePack(ByteArrayInputStream recvStream, ProgressMonitor pm)
			throws Exception {
		SideBandInputStream sb = new SideBandInputStream(
				recvStream, pm,
				new StringWriter(), NullOutputStream.INSTANCE);
		PackParser pp = client.newObjectInserter().newPackParser(sb);
		pp.parse(NullProgressMonitor.INSTANCE);

		// Ensure that there is nothing left in the stream.
		assertEquals(-1, recvStream.read());

		return pp.getReceivedPackStatistics();
	}

	@Test
	public void testV2FetchRequestPolicyAdvertised() throws Exception {
		RevCommit advertized = remote.commit().message("x").create();
		RevCommit unadvertized = remote.commit().message("y").create();
		remote.update("branch1", advertized);

		// This works
		uploadPackV2(
			(UploadPack up) -> {up.setRequestPolicy(RequestPolicy.ADVERTISED);},
			"command=fetch\n",
			PacketLineIn.delimiter(),
			"want " + advertized.name() + "\n",
			PacketLineIn.end());

		// This doesn't
		UploadPackInternalServerErrorException e = assertThrows(
				UploadPackInternalServerErrorException.class,
				() -> uploadPackV2(
						(UploadPack up) -> {up.setRequestPolicy(RequestPolicy.ADVERTISED);},
						"command=fetch\n", PacketLineIn.delimiter(),
						"want " + unadvertized.name() + "\n",
						PacketLineIn.end()));
		assertThat(e.getCause().getMessage(),
				containsString("want " + unadvertized.name() + " not valid"));
	}

	@Test
	public void testV2FetchRequestPolicyReachableCommit() throws Exception {
		RevCommit reachable = remote.commit().message("x").create();
		RevCommit advertized = remote.commit().message("x").parent(reachable)
				.create();
		RevCommit unreachable = remote.commit().message("y").create();
		remote.update("branch1", advertized);

		// This works
		uploadPackV2(
			(UploadPack up) -> {up.setRequestPolicy(RequestPolicy.REACHABLE_COMMIT);},
			"command=fetch\n",
			PacketLineIn.delimiter(),
			"want " + reachable.name() + "\n",
				PacketLineIn.end());

		// This doesn't
		UploadPackInternalServerErrorException e = assertThrows(
				UploadPackInternalServerErrorException.class,
				() -> uploadPackV2(
						(UploadPack up) -> {up.setRequestPolicy(RequestPolicy.REACHABLE_COMMIT);},
						"command=fetch\n", PacketLineIn.delimiter(),
						"want " + unreachable.name() + "\n",
						PacketLineIn.end()));
		assertThat(e.getCause().getMessage(),
				containsString("want " + unreachable.name() + " not valid"));
	}

	@Test
	public void testV2FetchRequestPolicyTip() throws Exception {
		RevCommit parentOfTip = remote.commit().message("x").create();
		RevCommit tip = remote.commit().message("y").parent(parentOfTip)
				.create();
		remote.update("secret", tip);

		// This works
		uploadPackV2(
			(UploadPack up) -> {
				up.setRequestPolicy(RequestPolicy.TIP);
				up.setRefFilter(new RejectAllRefFilter());
			},
			"command=fetch\n",
			PacketLineIn.delimiter(),
			"want " + tip.name() + "\n",
				PacketLineIn.end());

		// This doesn't
		UploadPackInternalServerErrorException e = assertThrows(
				UploadPackInternalServerErrorException.class,
				() -> uploadPackV2(
						(UploadPack up) -> {
							up.setRequestPolicy(RequestPolicy.TIP);
							up.setRefFilter(new RejectAllRefFilter());
						},
						"command=fetch\n", PacketLineIn.delimiter(),
						"want " + parentOfTip.name() + "\n",
						PacketLineIn.end()));
		assertThat(e.getCause().getMessage(),
				containsString("want " + parentOfTip.name() + " not valid"));
	}

	@Test
	public void testV2FetchRequestPolicyReachableCommitTip() throws Exception {
		RevCommit parentOfTip = remote.commit().message("x").create();
		RevCommit tip = remote.commit().message("y").parent(parentOfTip)
				.create();
		RevCommit unreachable = remote.commit().message("y").create();
		remote.update("secret", tip);

		// This works
		uploadPackV2(
				(UploadPack up) -> {
					up.setRequestPolicy(RequestPolicy.REACHABLE_COMMIT_TIP);
					up.setRefFilter(new RejectAllRefFilter());
				},
				"command=fetch\n",
				PacketLineIn.delimiter(), "want " + parentOfTip.name() + "\n",
				PacketLineIn.end());

		// This doesn't
		UploadPackInternalServerErrorException e = assertThrows(
				UploadPackInternalServerErrorException.class,
				() -> uploadPackV2(
						(UploadPack up) -> {
							up.setRequestPolicy(RequestPolicy.REACHABLE_COMMIT_TIP);
							up.setRefFilter(new RejectAllRefFilter());
						},
						"command=fetch\n",
						PacketLineIn.delimiter(),
						"want " + unreachable.name() + "\n",
						PacketLineIn.end()));
		assertThat(e.getCause().getMessage(),
				containsString("want " + unreachable.name() + " not valid"));
	}

	@Test
	public void testV2FetchRequestPolicyAny() throws Exception {
		RevCommit unreachable = remote.commit().message("y").create();

		// Exercise to make sure that even unreachable commits can be fetched
		uploadPackV2(
			(UploadPack up) -> {up.setRequestPolicy(RequestPolicy.ANY);},
			"command=fetch\n",
			PacketLineIn.delimiter(),
			"want " + unreachable.name() + "\n",
				PacketLineIn.end());
	}

	@Test
	public void testV2FetchServerDoesNotStopNegotiation() throws Exception {
		RevCommit fooParent = remote.commit().message("x").create();
		RevCommit fooChild = remote.commit().message("x").parent(fooParent).create();
		RevCommit barParent = remote.commit().message("y").create();
		RevCommit barChild = remote.commit().message("y").parent(barParent).create();
		remote.update("branch1", fooChild);
		remote.update("branch2", barChild);

		ByteArrayInputStream recvStream = uploadPackV2(
			"command=fetch\n",
			PacketLineIn.delimiter(),
			"want " + fooChild.toObjectId().getName() + "\n",
			"want " + barChild.toObjectId().getName() + "\n",
			"have " + fooParent.toObjectId().getName() + "\n",
				PacketLineIn.end());
		PacketLineIn pckIn = new PacketLineIn(recvStream);

		assertThat(pckIn.readString(), is("acknowledgments"));
		assertThat(pckIn.readString(), is("ACK " + fooParent.toObjectId().getName()));
		assertTrue(PacketLineIn.isEnd(pckIn.readString()));
	}

	@Test
	public void testV2FetchServerStopsNegotiation() throws Exception {
		RevCommit fooParent = remote.commit().message("x").create();
		RevCommit fooChild = remote.commit().message("x").parent(fooParent).create();
		RevCommit barParent = remote.commit().message("y").create();
		RevCommit barChild = remote.commit().message("y").parent(barParent).create();
		remote.update("branch1", fooChild);
		remote.update("branch2", barChild);

		ByteArrayInputStream recvStream = uploadPackV2(
			"command=fetch\n",
			PacketLineIn.delimiter(),
			"want " + fooChild.toObjectId().getName() + "\n",
			"want " + barChild.toObjectId().getName() + "\n",
			"have " + fooParent.toObjectId().getName() + "\n",
			"have " + barParent.toObjectId().getName() + "\n",
				PacketLineIn.end());
		PacketLineIn pckIn = new PacketLineIn(recvStream);

		assertThat(pckIn.readString(), is("acknowledgments"));
		assertThat(
			Arrays.asList(pckIn.readString(), pckIn.readString()),
			hasItems(
				"ACK " + fooParent.toObjectId().getName(),
				"ACK " + barParent.toObjectId().getName()));
		assertThat(pckIn.readString(), is("ready"));
		assertTrue(PacketLineIn.isDelimiter(pckIn.readString()));
		assertThat(pckIn.readString(), is("packfile"));
		parsePack(recvStream);
		assertFalse(client.getObjectDatabase().has(fooParent.toObjectId()));
		assertTrue(client.getObjectDatabase().has(fooChild.toObjectId()));
		assertFalse(client.getObjectDatabase().has(barParent.toObjectId()));
		assertTrue(client.getObjectDatabase().has(barChild.toObjectId()));
	}

	@Test
	public void testV2FetchClientStopsNegotiation() throws Exception {
		RevCommit fooParent = remote.commit().message("x").create();
		RevCommit fooChild = remote.commit().message("x").parent(fooParent).create();
		RevCommit barParent = remote.commit().message("y").create();
		RevCommit barChild = remote.commit().message("y").parent(barParent).create();
		remote.update("branch1", fooChild);
		remote.update("branch2", barChild);

		ByteArrayInputStream recvStream = uploadPackV2(
			"command=fetch\n",
			PacketLineIn.delimiter(),
			"want " + fooChild.toObjectId().getName() + "\n",
			"want " + barChild.toObjectId().getName() + "\n",
			"have " + fooParent.toObjectId().getName() + "\n",
			"done\n",
				PacketLineIn.end());
		PacketLineIn pckIn = new PacketLineIn(recvStream);

		assertThat(pckIn.readString(), is("packfile"));
		parsePack(recvStream);
		assertFalse(client.getObjectDatabase().has(fooParent.toObjectId()));
		assertTrue(client.getObjectDatabase().has(fooChild.toObjectId()));
		assertTrue(client.getObjectDatabase().has(barParent.toObjectId()));
		assertTrue(client.getObjectDatabase().has(barChild.toObjectId()));
	}

	@Test
	public void testV2FetchThinPack() throws Exception {
		String commonInBlob = "abcdefghijklmnopqrstuvwxyz";

		RevBlob parentBlob = remote.blob(commonInBlob + "a");
		RevCommit parent = remote
				.commit(remote.tree(remote.file("foo", parentBlob)));
		RevBlob childBlob = remote.blob(commonInBlob + "b");
		RevCommit child = remote
				.commit(remote.tree(remote.file("foo", childBlob)), parent);
		remote.update("branch1", child);

		// Pretend that we have parent to get a thin pack based on it.
		ByteArrayInputStream recvStream = uploadPackV2("command=fetch\n",
				PacketLineIn.delimiter(),
				"want " + child.toObjectId().getName() + "\n",
				"have " + parent.toObjectId().getName() + "\n", "thin-pack\n",
				"done\n", PacketLineIn.end());
		PacketLineIn pckIn = new PacketLineIn(recvStream);

		assertThat(pckIn.readString(), is("packfile"));

		// Verify that we received a thin pack by trying to apply it
		// against the client repo, which does not have parent.
		IOException e = assertThrows(IOException.class,
				() -> parsePack(recvStream));
		assertThat(e.getMessage(),
				containsString("pack has unresolved deltas"));
	}

	@Test
	public void testV2FetchNoProgress() throws Exception {
		RevCommit commit = remote.commit().message("x").create();
		remote.update("branch1", commit);

		// Without no-progress, progress is reported.
		StringWriter sw = new StringWriter();
		ByteArrayInputStream recvStream = uploadPackV2(
			"command=fetch\n",
			PacketLineIn.delimiter(),
			"want " + commit.toObjectId().getName() + "\n",
			"done\n",
				PacketLineIn.end());
		PacketLineIn pckIn = new PacketLineIn(recvStream);
		assertThat(pckIn.readString(), is("packfile"));
		parsePack(recvStream, new TextProgressMonitor(sw));
		assertFalse(sw.toString().isEmpty());

		// With no-progress, progress is not reported.
		sw = new StringWriter();
		recvStream = uploadPackV2(
			"command=fetch\n",
			PacketLineIn.delimiter(),
			"want " + commit.toObjectId().getName() + "\n",
			"no-progress\n",
			"done\n",
				PacketLineIn.end());
		pckIn = new PacketLineIn(recvStream);
		assertThat(pckIn.readString(), is("packfile"));
		parsePack(recvStream, new TextProgressMonitor(sw));
		assertTrue(sw.toString().isEmpty());
	}

	@Test
	public void testV2FetchIncludeTag() throws Exception {
		RevCommit commit = remote.commit().message("x").create();
		RevTag tag = remote.tag("tag", commit);
		remote.update("branch1", commit);
		remote.update("refs/tags/tag", tag);

		// Without include-tag.
		ByteArrayInputStream recvStream = uploadPackV2(
			"command=fetch\n",
			PacketLineIn.delimiter(),
			"want " + commit.toObjectId().getName() + "\n",
			"done\n",
				PacketLineIn.end());
		PacketLineIn pckIn = new PacketLineIn(recvStream);
		assertThat(pckIn.readString(), is("packfile"));
		parsePack(recvStream);
		assertFalse(client.getObjectDatabase().has(tag.toObjectId()));

		// With tag.
		recvStream = uploadPackV2(
			"command=fetch\n",
			PacketLineIn.delimiter(),
			"want " + commit.toObjectId().getName() + "\n",
			"include-tag\n",
			"done\n",
				PacketLineIn.end());
		pckIn = new PacketLineIn(recvStream);
		assertThat(pckIn.readString(), is("packfile"));
		parsePack(recvStream);
		assertTrue(client.getObjectDatabase().has(tag.toObjectId()));
	}

	@Test
	public void testV2FetchOfsDelta() throws Exception {
		String commonInBlob = "abcdefghijklmnopqrstuvwxyz";

		RevBlob parentBlob = remote.blob(commonInBlob + "a");
		RevCommit parent = remote.commit(remote.tree(remote.file("foo", parentBlob)));
		RevBlob childBlob = remote.blob(commonInBlob + "b");
		RevCommit child = remote.commit(remote.tree(remote.file("foo", childBlob)), parent);
		remote.update("branch1", child);

		// Without ofs-delta.
		ByteArrayInputStream recvStream = uploadPackV2(
			"command=fetch\n",
			PacketLineIn.delimiter(),
			"want " + child.toObjectId().getName() + "\n",
			"done\n",
				PacketLineIn.end());
		PacketLineIn pckIn = new PacketLineIn(recvStream);
		assertThat(pckIn.readString(), is("packfile"));
		ReceivedPackStatistics receivedStats = parsePack(recvStream);
		assertTrue(receivedStats.getNumOfsDelta() == 0);

		// With ofs-delta.
		recvStream = uploadPackV2(
			"command=fetch\n",
			PacketLineIn.delimiter(),
			"want " + child.toObjectId().getName() + "\n",
			"ofs-delta\n",
			"done\n",
				PacketLineIn.end());
		pckIn = new PacketLineIn(recvStream);
		assertThat(pckIn.readString(), is("packfile"));
		receivedStats = parsePack(recvStream);
		assertTrue(receivedStats.getNumOfsDelta() != 0);
	}

	@Test
	public void testV2FetchShallow() throws Exception {
		RevCommit commonParent = remote.commit().message("parent").create();
		RevCommit fooChild = remote.commit().message("x").parent(commonParent).create();
		RevCommit barChild = remote.commit().message("y").parent(commonParent).create();
		remote.update("branch1", barChild);

		// Without shallow, the server thinks that we have
		// commonParent, so it doesn't send it.
		ByteArrayInputStream recvStream = uploadPackV2(
			"command=fetch\n",
			PacketLineIn.delimiter(),
			"want " + barChild.toObjectId().getName() + "\n",
			"have " + fooChild.toObjectId().getName() + "\n",
			"done\n",
				PacketLineIn.end());
		PacketLineIn pckIn = new PacketLineIn(recvStream);
		assertThat(pckIn.readString(), is("packfile"));
		parsePack(recvStream);
		assertTrue(client.getObjectDatabase().has(barChild.toObjectId()));
		assertFalse(client.getObjectDatabase().has(commonParent.toObjectId()));

		// With shallow, the server knows that we don't have
		// commonParent, so it sends it.
		recvStream = uploadPackV2(
			"command=fetch\n",
			PacketLineIn.delimiter(),
			"want " + barChild.toObjectId().getName() + "\n",
			"have " + fooChild.toObjectId().getName() + "\n",
			"shallow " + fooChild.toObjectId().getName() + "\n",
			"done\n",
				PacketLineIn.end());
		pckIn = new PacketLineIn(recvStream);
		assertThat(pckIn.readString(), is("packfile"));
		parsePack(recvStream);
		assertTrue(client.getObjectDatabase().has(commonParent.toObjectId()));
	}

	@Test
	public void testV2FetchDeepenAndDone() throws Exception {
		RevCommit parent = remote.commit().message("parent").create();
		RevCommit child = remote.commit().message("x").parent(parent).create();
		remote.update("branch1", child);

		// "deepen 1" sends only the child.
		ByteArrayInputStream recvStream = uploadPackV2(
			"command=fetch\n",
			PacketLineIn.delimiter(),
			"want " + child.toObjectId().getName() + "\n",
			"deepen 1\n",
			"done\n",
				PacketLineIn.end());
		PacketLineIn pckIn = new PacketLineIn(recvStream);
		assertThat(pckIn.readString(), is("shallow-info"));
		assertThat(pckIn.readString(), is("shallow " + child.toObjectId().getName()));
		assertTrue(PacketLineIn.isDelimiter(pckIn.readString()));
		assertThat(pckIn.readString(), is("packfile"));
		parsePack(recvStream);
		assertTrue(client.getObjectDatabase().has(child.toObjectId()));
		assertFalse(client.getObjectDatabase().has(parent.toObjectId()));

		// Without that, the parent is sent too.
		recvStream = uploadPackV2(
			"command=fetch\n",
			PacketLineIn.delimiter(),
			"want " + child.toObjectId().getName() + "\n",
			"done\n",
				PacketLineIn.end());
		pckIn = new PacketLineIn(recvStream);
		assertThat(pckIn.readString(), is("packfile"));
		parsePack(recvStream);
		assertTrue(client.getObjectDatabase().has(parent.toObjectId()));
	}

	@Test
	public void testV2FetchDeepenWithoutDone() throws Exception {
		RevCommit parent = remote.commit().message("parent").create();
		RevCommit child = remote.commit().message("x").parent(parent).create();
		remote.update("branch1", child);

		ByteArrayInputStream recvStream = uploadPackV2(
			"command=fetch\n",
			PacketLineIn.delimiter(),
			"want " + child.toObjectId().getName() + "\n",
			"deepen 1\n",
				PacketLineIn.end());
		PacketLineIn pckIn = new PacketLineIn(recvStream);

		// Verify that only the correct section is sent. "shallow-info"
		// is not sent because, according to the specification, it is
		// sent only if a packfile is sent.
		assertThat(pckIn.readString(), is("acknowledgments"));
		assertThat(pckIn.readString(), is("NAK"));
		assertTrue(PacketLineIn.isEnd(pckIn.readString()));
	}

	@Test
	public void testV2FetchShallowSince() throws Exception {
		PersonIdent person = new PersonIdent(remote.getRepository());

		RevCommit beyondBoundary = remote.commit()
			.committer(new PersonIdent(person, 1510000000, 0)).create();
		RevCommit boundary = remote.commit().parent(beyondBoundary)
			.committer(new PersonIdent(person, 1520000000, 0)).create();
		RevCommit tooOld = remote.commit()
			.committer(new PersonIdent(person, 1500000000, 0)).create();
		RevCommit merge = remote.commit().parent(boundary).parent(tooOld)
			.committer(new PersonIdent(person, 1530000000, 0)).create();

		remote.update("branch1", merge);

		// Report that we only have "boundary" as a shallow boundary.
		ByteArrayInputStream recvStream = uploadPackV2(
			"command=fetch\n",
			PacketLineIn.delimiter(),
			"shallow " + boundary.toObjectId().getName() + "\n",
			"deepen-since 1510000\n",
			"want " + merge.toObjectId().getName() + "\n",
			"have " + boundary.toObjectId().getName() + "\n",
			"done\n",
				PacketLineIn.end());
		PacketLineIn pckIn = new PacketLineIn(recvStream);
		assertThat(pckIn.readString(), is("shallow-info"));

		// "merge" is shallow because one of its parents is committed
		// earlier than the given deepen-since time.
		assertThat(pckIn.readString(), is("shallow " + merge.toObjectId().getName()));

		// "boundary" is unshallow because its parent committed at or
		// later than the given deepen-since time.
		assertThat(pckIn.readString(), is("unshallow " + boundary.toObjectId().getName()));

		assertTrue(PacketLineIn.isDelimiter(pckIn.readString()));
		assertThat(pckIn.readString(), is("packfile"));
		parsePack(recvStream);

		// The server does not send this because it is committed
		// earlier than the given deepen-since time.
		assertFalse(client.getObjectDatabase().has(tooOld.toObjectId()));

		// The server does not send this because the client claims to
		// have it.
		assertFalse(client.getObjectDatabase().has(boundary.toObjectId()));

		// The server sends both these commits.
		assertTrue(client.getObjectDatabase().has(beyondBoundary.toObjectId()));
		assertTrue(client.getObjectDatabase().has(merge.toObjectId()));
	}

	@Test
	public void testV2FetchShallowSince_excludedParentWithMultipleChildren() throws Exception {
		PersonIdent person = new PersonIdent(remote.getRepository());

		RevCommit base = remote.commit()
			.committer(new PersonIdent(person, 1500000000, 0)).create();
		RevCommit child1 = remote.commit().parent(base)
			.committer(new PersonIdent(person, 1510000000, 0)).create();
		RevCommit child2 = remote.commit().parent(base)
			.committer(new PersonIdent(person, 1520000000, 0)).create();

		remote.update("branch1", child1);
		remote.update("branch2", child2);

		ByteArrayInputStream recvStream = uploadPackV2(
			"command=fetch\n",
			PacketLineIn.delimiter(),
			"deepen-since 1510000\n",
			"want " + child1.toObjectId().getName() + "\n",
			"want " + child2.toObjectId().getName() + "\n",
			"done\n",
				PacketLineIn.end());
		PacketLineIn pckIn = new PacketLineIn(recvStream);
		assertThat(pckIn.readString(), is("shallow-info"));

		// "base" is excluded, so its children are shallow.
		assertThat(
			Arrays.asList(pckIn.readString(), pckIn.readString()),
			hasItems(
				"shallow " + child1.toObjectId().getName(),
				"shallow " + child2.toObjectId().getName()));

		assertTrue(PacketLineIn.isDelimiter(pckIn.readString()));
		assertThat(pckIn.readString(), is("packfile"));
		parsePack(recvStream);

		// Only the children are sent.
		assertFalse(client.getObjectDatabase().has(base.toObjectId()));
		assertTrue(client.getObjectDatabase().has(child1.toObjectId()));
		assertTrue(client.getObjectDatabase().has(child2.toObjectId()));
	}

	@Test
	public void testV2FetchShallowSince_noCommitsSelected() throws Exception {
		PersonIdent person = new PersonIdent(remote.getRepository());

		RevCommit tooOld = remote.commit()
				.committer(new PersonIdent(person, 1500000000, 0)).create();

		remote.update("branch1", tooOld);

		UploadPackInternalServerErrorException e = assertThrows(
				UploadPackInternalServerErrorException.class,
				() -> uploadPackV2("command=fetch\n", PacketLineIn.delimiter(),
						"deepen-since 1510000\n",
						"want " + tooOld.toObjectId().getName() + "\n",
						"done\n", PacketLineIn.end()));
		assertThat(e.getCause().getMessage(),
				containsString("No commits selected for shallow request"));
	}

	@Test
	public void testV2FetchDeepenNot() throws Exception {
		RevCommit one = remote.commit().message("one").create();
		RevCommit two = remote.commit().message("two").parent(one).create();
		RevCommit three = remote.commit().message("three").parent(two).create();
		RevCommit side = remote.commit().message("side").parent(one).create();
		RevCommit merge = remote.commit().message("merge")
			.parent(three).parent(side).create();

		remote.update("branch1", merge);
		remote.update("side", side);

		// The client is a shallow clone that only has "three", and
		// wants "merge" while excluding "side".
		ByteArrayInputStream recvStream = uploadPackV2(
			"command=fetch\n",
			PacketLineIn.delimiter(),
			"shallow " + three.toObjectId().getName() + "\n",
			"deepen-not side\n",
			"want " + merge.toObjectId().getName() + "\n",
			"have " + three.toObjectId().getName() + "\n",
			"done\n",
				PacketLineIn.end());
		PacketLineIn pckIn = new PacketLineIn(recvStream);
		assertThat(pckIn.readString(), is("shallow-info"));

		// "merge" is shallow because "side" is excluded by deepen-not.
		// "two" is shallow because "one" (as parent of "side") is excluded by deepen-not.
		assertThat(
			Arrays.asList(pckIn.readString(), pckIn.readString()),
			hasItems(
				"shallow " + merge.toObjectId().getName(),
				"shallow " + two.toObjectId().getName()));

		// "three" is unshallow because its parent "two" is now available.
		assertThat(pckIn.readString(), is("unshallow " + three.toObjectId().getName()));

		assertTrue(PacketLineIn.isDelimiter(pckIn.readString()));
		assertThat(pckIn.readString(), is("packfile"));
		parsePack(recvStream);

		// The server does not send these because they are excluded by
		// deepen-not.
		assertFalse(client.getObjectDatabase().has(side.toObjectId()));
		assertFalse(client.getObjectDatabase().has(one.toObjectId()));

		// The server does not send this because the client claims to
		// have it.
		assertFalse(client.getObjectDatabase().has(three.toObjectId()));

		// The server sends both these commits.
		assertTrue(client.getObjectDatabase().has(merge.toObjectId()));
		assertTrue(client.getObjectDatabase().has(two.toObjectId()));
	}

	@Test
	public void testV2FetchDeepenNot_excludeDescendantOfWant()
			throws Exception {
		RevCommit one = remote.commit().message("one").create();
		RevCommit two = remote.commit().message("two").parent(one).create();
		RevCommit three = remote.commit().message("three").parent(two).create();
		RevCommit four = remote.commit().message("four").parent(three).create();

		remote.update("two", two);
		remote.update("four", four);

		UploadPackInternalServerErrorException e = assertThrows(
				UploadPackInternalServerErrorException.class,
				() -> uploadPackV2("command=fetch\n", PacketLineIn.delimiter(),
						"deepen-not four\n",
						"want " + two.toObjectId().getName() + "\n", "done\n",
						PacketLineIn.end()));
		assertThat(e.getCause().getMessage(),
				containsString("No commits selected for shallow request"));
	}

	@Test
	public void testV2FetchDeepenNot_supportAnnotatedTags() throws Exception {
		RevCommit one = remote.commit().message("one").create();
		RevCommit two = remote.commit().message("two").parent(one).create();
		RevCommit three = remote.commit().message("three").parent(two).create();
		RevCommit four = remote.commit().message("four").parent(three).create();
		RevTag twoTag = remote.tag("twotag", two);

		remote.update("refs/tags/twotag", twoTag);
		remote.update("four", four);

		ByteArrayInputStream recvStream = uploadPackV2(
			"command=fetch\n",
			PacketLineIn.delimiter(),
			"deepen-not twotag\n",
			"want " + four.toObjectId().getName() + "\n",
			"done\n",
				PacketLineIn.end());
		PacketLineIn pckIn = new PacketLineIn(recvStream);
		assertThat(pckIn.readString(), is("shallow-info"));
		assertThat(pckIn.readString(), is("shallow " + three.toObjectId().getName()));
		assertTrue(PacketLineIn.isDelimiter(pckIn.readString()));
		assertThat(pckIn.readString(), is("packfile"));
		parsePack(recvStream);
		assertFalse(client.getObjectDatabase().has(one.toObjectId()));
		assertFalse(client.getObjectDatabase().has(two.toObjectId()));
		assertTrue(client.getObjectDatabase().has(three.toObjectId()));
		assertTrue(client.getObjectDatabase().has(four.toObjectId()));
	}

	@Test
	public void testV2FetchDeepenNot_excludedParentWithMultipleChildren() throws Exception {
		PersonIdent person = new PersonIdent(remote.getRepository());

		RevCommit base = remote.commit()
			.committer(new PersonIdent(person, 1500000000, 0)).create();
		RevCommit child1 = remote.commit().parent(base)
			.committer(new PersonIdent(person, 1510000000, 0)).create();
		RevCommit child2 = remote.commit().parent(base)
			.committer(new PersonIdent(person, 1520000000, 0)).create();

		remote.update("base", base);
		remote.update("branch1", child1);
		remote.update("branch2", child2);

		ByteArrayInputStream recvStream = uploadPackV2(
			"command=fetch\n",
			PacketLineIn.delimiter(),
			"deepen-not base\n",
			"want " + child1.toObjectId().getName() + "\n",
			"want " + child2.toObjectId().getName() + "\n",
			"done\n",
				PacketLineIn.end());
		PacketLineIn pckIn = new PacketLineIn(recvStream);
		assertThat(pckIn.readString(), is("shallow-info"));

		// "base" is excluded, so its children are shallow.
		assertThat(
			Arrays.asList(pckIn.readString(), pckIn.readString()),
			hasItems(
				"shallow " + child1.toObjectId().getName(),
				"shallow " + child2.toObjectId().getName()));

		assertTrue(PacketLineIn.isDelimiter(pckIn.readString()));
		assertThat(pckIn.readString(), is("packfile"));
		parsePack(recvStream);

		// Only the children are sent.
		assertFalse(client.getObjectDatabase().has(base.toObjectId()));
		assertTrue(client.getObjectDatabase().has(child1.toObjectId()));
		assertTrue(client.getObjectDatabase().has(child2.toObjectId()));
	}

	@Test
	public void testV2FetchUnrecognizedArgument() throws Exception {
		UploadPackInternalServerErrorException e = assertThrows(
				UploadPackInternalServerErrorException.class,
				() -> uploadPackV2("command=fetch\n", PacketLineIn.delimiter(),
						"invalid-argument\n", PacketLineIn.end()));
		assertThat(e.getCause().getMessage(),
				containsString("unexpected invalid-argument"));
	}

	@Test
	public void testV2FetchServerOptions() throws Exception {
		String[] lines = { "command=fetch\n", "server-option=one\n",
				"server-option=two\n", PacketLineIn.delimiter(),
				PacketLineIn.end() };

		TestV2Hook testHook = new TestV2Hook();
		uploadPackV2Setup((UploadPack up) -> {up.setProtocolV2Hook(testHook);}, lines);

		FetchV2Request req = testHook.fetchRequest;
		assertNotNull(req);
		assertEquals(2, req.getServerOptions().size());
		assertThat(req.getServerOptions(), hasItems("one", "two"));
	}

	@Test
	public void testV2FetchFilter() throws Exception {
		RevBlob big = remote.blob("foobar");
		RevBlob small = remote.blob("fooba");
		RevTree tree = remote.tree(remote.file("1", big),
				remote.file("2", small));
		RevCommit commit = remote.commit(tree);
		remote.update("master", commit);

		server.getConfig().setBoolean("uploadpack", null, "allowfilter", true);

		ByteArrayInputStream recvStream = uploadPackV2(
			"command=fetch\n",
			PacketLineIn.delimiter(),
			"want " + commit.toObjectId().getName() + "\n",
			"filter blob:limit=5\n",
			"done\n",
				PacketLineIn.end());
		PacketLineIn pckIn = new PacketLineIn(recvStream);
		assertThat(pckIn.readString(), is("packfile"));
		parsePack(recvStream);

		assertFalse(client.getObjectDatabase().has(big.toObjectId()));
		assertTrue(client.getObjectDatabase().has(small.toObjectId()));
	}

	abstract class TreeBuilder {
		abstract void addElements(DirCacheBuilder dcBuilder) throws Exception;

		RevTree build() throws Exception {
			DirCache dc = DirCache.newInCore();
			DirCacheBuilder dcBuilder = dc.builder();
			addElements(dcBuilder);
			dcBuilder.finish();
			ObjectId id;
			try (ObjectInserter ins =
					remote.getRepository().newObjectInserter()) {
				id = dc.writeTree(ins);
				ins.flush();
			}
			return remote.getRevWalk().parseTree(id);
		}
	}

	class DeepTreePreparator {
		RevBlob blobLowDepth = remote.blob("lo");
		RevBlob blobHighDepth = remote.blob("hi");

		RevTree subtree = remote.tree(remote.file("1", blobHighDepth));
		RevTree rootTree = (new TreeBuilder() {
				@Override
				void addElements(DirCacheBuilder dcBuilder) throws Exception {
					dcBuilder.add(remote.file("1", blobLowDepth));
					dcBuilder.addTree(new byte[] {'2'}, DirCacheEntry.STAGE_0,
							remote.getRevWalk().getObjectReader(), subtree);
				}
			}).build();
		RevCommit commit = remote.commit(rootTree);

		DeepTreePreparator() throws Exception {}
	}

	private void uploadV2WithTreeDepthFilter(
			long depth, ObjectId... wants) throws Exception {
		server.getConfig().setBoolean("uploadpack", null, "allowfilter", true);

		List<String> input = new ArrayList<>();
		input.add("command=fetch\n");
		input.add(PacketLineIn.delimiter());
		for (ObjectId want : wants) {
			input.add("want " + want.getName() + "\n");
		}
		input.add("filter tree:" + depth + "\n");
		input.add("done\n");
		input.add(PacketLineIn.end());
		ByteArrayInputStream recvStream =
				uploadPackV2(
						(UploadPack up) -> {up.setRequestPolicy(RequestPolicy.ANY);},
						input.toArray(new String[0]));
		PacketLineIn pckIn = new PacketLineIn(recvStream);
		assertThat(pckIn.readString(), is("packfile"));
		parsePack(recvStream);
	}

	@Test
	public void testV2FetchFilterTreeDepth0() throws Exception {
		DeepTreePreparator preparator = new DeepTreePreparator();
		remote.update("master", preparator.commit);

		uploadV2WithTreeDepthFilter(0, preparator.commit.toObjectId());

		assertFalse(client.getObjectDatabase()
				.has(preparator.rootTree.toObjectId()));
		assertFalse(client.getObjectDatabase()
				.has(preparator.subtree.toObjectId()));
		assertFalse(client.getObjectDatabase()
				.has(preparator.blobLowDepth.toObjectId()));
		assertFalse(client.getObjectDatabase()
				.has(preparator.blobHighDepth.toObjectId()));
		assertEquals(1, stats.getTreesTraversed());
	}

	@Test
	public void testV2FetchFilterTreeDepth1_serverHasBitmap() throws Exception {
		DeepTreePreparator preparator = new DeepTreePreparator();
		remote.update("master", preparator.commit);

		// The bitmap should be ignored since we need to track the depth while
		// traversing the trees.
		generateBitmaps(server);

		uploadV2WithTreeDepthFilter(1, preparator.commit.toObjectId());

		assertTrue(client.getObjectDatabase()
				.has(preparator.rootTree.toObjectId()));
		assertFalse(client.getObjectDatabase()
				.has(preparator.subtree.toObjectId()));
		assertFalse(client.getObjectDatabase()
				.has(preparator.blobLowDepth.toObjectId()));
		assertFalse(client.getObjectDatabase()
				.has(preparator.blobHighDepth.toObjectId()));
		assertEquals(1, stats.getTreesTraversed());
	}

	@Test
	public void testV2FetchFilterTreeDepth2() throws Exception {
		DeepTreePreparator preparator = new DeepTreePreparator();
		remote.update("master", preparator.commit);

		uploadV2WithTreeDepthFilter(2, preparator.commit.toObjectId());

		assertTrue(client.getObjectDatabase()
				.has(preparator.rootTree.toObjectId()));
		assertTrue(client.getObjectDatabase()
				.has(preparator.subtree.toObjectId()));
		assertTrue(client.getObjectDatabase()
				.has(preparator.blobLowDepth.toObjectId()));
		assertFalse(client.getObjectDatabase()
				.has(preparator.blobHighDepth.toObjectId()));
		assertEquals(2, stats.getTreesTraversed());
	}

	/**
	 * Creates a commit with the following files:
	 * <pre>
	 * a/x/b/foo
	 * x/b/foo
	 * </pre>
	 * which has an identical tree in two locations: once at / and once at /a
	 */
	class RepeatedSubtreePreparator {
		RevBlob foo = remote.blob("foo");
		RevTree subtree3 = remote.tree(remote.file("foo", foo));
		RevTree subtree2 = (new TreeBuilder() {
			@Override
			void addElements(DirCacheBuilder dcBuilder) throws Exception {
				dcBuilder.addTree(new byte[] {'b'}, DirCacheEntry.STAGE_0,
						remote.getRevWalk().getObjectReader(), subtree3);
			}
		}).build();
		RevTree subtree1 = (new TreeBuilder() {
			@Override
			void addElements(DirCacheBuilder dcBuilder) throws Exception {
				dcBuilder.addTree(new byte[] {'x'}, DirCacheEntry.STAGE_0,
						remote.getRevWalk().getObjectReader(), subtree2);
			}
		}).build();
		RevTree rootTree = (new TreeBuilder() {
			@Override
			void addElements(DirCacheBuilder dcBuilder) throws Exception {
				dcBuilder.addTree(new byte[] {'a'}, DirCacheEntry.STAGE_0,
						remote.getRevWalk().getObjectReader(), subtree1);
				dcBuilder.addTree(new byte[] {'x'}, DirCacheEntry.STAGE_0,
						remote.getRevWalk().getObjectReader(), subtree2);
			}
		}).build();
		RevCommit commit = remote.commit(rootTree);

		RepeatedSubtreePreparator() throws Exception {}
	}

	@Test
	public void testV2FetchFilterTreeDepth_iterateOverTreeAtTwoLevels()
			throws Exception {
		// Test tree:<depth> where a tree is iterated to twice - once where a
		// subentry is too deep to be included, and again where the blob inside
		// it is shallow enough to be included.
		RepeatedSubtreePreparator preparator = new RepeatedSubtreePreparator();
		remote.update("master", preparator.commit);

		uploadV2WithTreeDepthFilter(4, preparator.commit.toObjectId());

		assertTrue(client.getObjectDatabase()
				.has(preparator.foo.toObjectId()));
	}

	/**
	 * Creates a commit with the following files:
	 * <pre>
	 * a/x/b/foo
	 * b/u/c/baz
	 * y/x/b/foo
	 * z/v/c/baz
	 * </pre>
	 * which has two pairs of identical trees:
	 * <ul>
	 * <li>one at /a and /y
	 * <li>one at /b/u and /z/v
	 * </ul>
	 * Note that this class defines unique 8 trees (rootTree and subtree1-7)
	 * which means PackStatistics should report having visited 8 trees.
	 */
	class RepeatedSubtreeAtSameLevelPreparator {
		RevBlob foo = remote.blob("foo");

		/** foo */
		RevTree subtree1 = remote.tree(remote.file("foo", foo));

		/** b/foo */
		RevTree subtree2 = (new TreeBuilder() {
			@Override
			void addElements(DirCacheBuilder dcBuilder) throws Exception {
				dcBuilder.addTree(new byte[] {'b'}, DirCacheEntry.STAGE_0,
						remote.getRevWalk().getObjectReader(), subtree1);
			}
		}).build();

		/** x/b/foo */
		RevTree subtree3 = (new TreeBuilder() {
			@Override
			void addElements(DirCacheBuilder dcBuilder) throws Exception {
				dcBuilder.addTree(new byte[] {'x'}, DirCacheEntry.STAGE_0,
						remote.getRevWalk().getObjectReader(), subtree2);
			}
		}).build();

		RevBlob baz = remote.blob("baz");

		/** baz */
		RevTree subtree4 = remote.tree(remote.file("baz", baz));

		/** c/baz */
		RevTree subtree5 = (new TreeBuilder() {
			@Override
			void addElements(DirCacheBuilder dcBuilder) throws Exception {
				dcBuilder.addTree(new byte[] {'c'}, DirCacheEntry.STAGE_0,
						remote.getRevWalk().getObjectReader(), subtree4);
			}
		}).build();

		/** u/c/baz */
		RevTree subtree6 = (new TreeBuilder() {
			@Override
			void addElements(DirCacheBuilder dcBuilder) throws Exception {
				dcBuilder.addTree(new byte[] {'u'}, DirCacheEntry.STAGE_0,
						remote.getRevWalk().getObjectReader(), subtree5);
			}
		}).build();

		/** v/c/baz */
		RevTree subtree7 = (new TreeBuilder() {
			@Override
			void addElements(DirCacheBuilder dcBuilder) throws Exception {
				dcBuilder.addTree(new byte[] {'v'}, DirCacheEntry.STAGE_0,
						remote.getRevWalk().getObjectReader(), subtree5);
			}
		}).build();

		RevTree rootTree = (new TreeBuilder() {
			@Override
			void addElements(DirCacheBuilder dcBuilder) throws Exception {
				dcBuilder.addTree(new byte[] {'a'}, DirCacheEntry.STAGE_0,
						remote.getRevWalk().getObjectReader(), subtree3);
				dcBuilder.addTree(new byte[] {'b'}, DirCacheEntry.STAGE_0,
						remote.getRevWalk().getObjectReader(), subtree6);
				dcBuilder.addTree(new byte[] {'y'}, DirCacheEntry.STAGE_0,
						remote.getRevWalk().getObjectReader(), subtree3);
				dcBuilder.addTree(new byte[] {'z'}, DirCacheEntry.STAGE_0,
						remote.getRevWalk().getObjectReader(), subtree7);
			}
		}).build();
		RevCommit commit = remote.commit(rootTree);

		RepeatedSubtreeAtSameLevelPreparator() throws Exception {}
	}

	@Test
	public void testV2FetchFilterTreeDepth_repeatTreeAtSameLevelIncludeFile()
			throws Exception {
		RepeatedSubtreeAtSameLevelPreparator preparator =
				new RepeatedSubtreeAtSameLevelPreparator();
		remote.update("master", preparator.commit);

		uploadV2WithTreeDepthFilter(5, preparator.commit.toObjectId());

		assertTrue(client.getObjectDatabase()
				.has(preparator.foo.toObjectId()));
		assertTrue(client.getObjectDatabase()
				.has(preparator.baz.toObjectId()));
		assertEquals(8, stats.getTreesTraversed());
	}

	@Test
	public void testV2FetchFilterTreeDepth_repeatTreeAtSameLevelExcludeFile()
			throws Exception {
		RepeatedSubtreeAtSameLevelPreparator preparator =
				new RepeatedSubtreeAtSameLevelPreparator();
		remote.update("master", preparator.commit);

		uploadV2WithTreeDepthFilter(4, preparator.commit.toObjectId());

		assertFalse(client.getObjectDatabase()
				.has(preparator.foo.toObjectId()));
		assertFalse(client.getObjectDatabase()
				.has(preparator.baz.toObjectId()));
		assertEquals(8, stats.getTreesTraversed());
	}

	@Test
	public void testWantFilteredObject() throws Exception {
		RepeatedSubtreePreparator preparator = new RepeatedSubtreePreparator();
		remote.update("master", preparator.commit);

		// Specify wanted blob objects that are deep enough to be filtered. We
		// should still upload them.
		uploadV2WithTreeDepthFilter(
				3,
				preparator.commit.toObjectId(),
				preparator.foo.toObjectId());
		assertTrue(client.getObjectDatabase()
				.has(preparator.foo.toObjectId()));

		client = newRepo("client");
		// Specify a wanted tree object that is deep enough to be filtered. We
		// should still upload it.
		uploadV2WithTreeDepthFilter(
				2,
				preparator.commit.toObjectId(),
				preparator.subtree3.toObjectId());
		assertTrue(client.getObjectDatabase()
				.has(preparator.foo.toObjectId()));
		assertTrue(client.getObjectDatabase()
				.has(preparator.subtree3.toObjectId()));
	}

	private void checkV2FetchWhenNotAllowed(String fetchLine, String expectedMessage)
			throws Exception {
		RevCommit commit = remote.commit().message("0").create();
		remote.update("master", commit);

		UploadPackInternalServerErrorException e = assertThrows(
				UploadPackInternalServerErrorException.class,
				() -> uploadPackV2("command=fetch\n", PacketLineIn.delimiter(),
						"want " + commit.toObjectId().getName() + "\n",
						fetchLine, "done\n", PacketLineIn.end()));
		assertThat(e.getCause().getMessage(),
				containsString(expectedMessage));
	}

	@Test
	public void testV2FetchFilterWhenNotAllowed() throws Exception {
		checkV2FetchWhenNotAllowed(
			"filter blob:limit=5\n",
			"unexpected filter blob:limit=5");
	}

	@Test
	public void testV2FetchWantRefIfNotAllowed() throws Exception {
		checkV2FetchWhenNotAllowed(
			"want-ref refs/heads/one\n",
			"unexpected want-ref refs/heads/one");
	}

	@Test
	public void testV2FetchSidebandAllIfNotAllowed() throws Exception {
		checkV2FetchWhenNotAllowed(
			"sideband-all\n",
			"unexpected sideband-all");
	}

	@Test
	public void testV2FetchWantRef() throws Exception {
		RevCommit one = remote.commit().message("1").create();
		RevCommit two = remote.commit().message("2").create();
		RevCommit three = remote.commit().message("3").create();
		remote.update("one", one);
		remote.update("two", two);
		remote.update("three", three);

		server.getConfig().setBoolean("uploadpack", null, "allowrefinwant", true);

		ByteArrayInputStream recvStream = uploadPackV2(
			"command=fetch\n",
			PacketLineIn.delimiter(),
			"want-ref refs/heads/one\n",
			"want-ref refs/heads/two\n",
			"done\n",
				PacketLineIn.end());
		PacketLineIn pckIn = new PacketLineIn(recvStream);
		assertThat(pckIn.readString(), is("wanted-refs"));
		assertThat(
				Arrays.asList(pckIn.readString(), pckIn.readString()),
				hasItems(
					one.toObjectId().getName() + " refs/heads/one",
					two.toObjectId().getName() + " refs/heads/two"));
		assertTrue(PacketLineIn.isDelimiter(pckIn.readString()));
		assertThat(pckIn.readString(), is("packfile"));
		parsePack(recvStream);

		assertTrue(client.getObjectDatabase().has(one.toObjectId()));
		assertTrue(client.getObjectDatabase().has(two.toObjectId()));
		assertFalse(client.getObjectDatabase().has(three.toObjectId()));
	}

	@Test
	public void testV2FetchBadWantRef() throws Exception {
		RevCommit one = remote.commit().message("1").create();
		remote.update("one", one);

		server.getConfig().setBoolean("uploadpack", null, "allowrefinwant",
				true);

		UploadPackInternalServerErrorException e = assertThrows(
				UploadPackInternalServerErrorException.class,
				() -> uploadPackV2("command=fetch\n", PacketLineIn.delimiter(),
						"want-ref refs/heads/one\n",
						"want-ref refs/heads/nonExistentRef\n", "done\n",
						PacketLineIn.end()));
		assertThat(e.getCause().getMessage(),
				containsString("Invalid ref name: refs/heads/nonExistentRef"));
	}

	@Test
	public void testV2FetchMixedWantRef() throws Exception {
		RevCommit one = remote.commit().message("1").create();
		RevCommit two = remote.commit().message("2").create();
		RevCommit three = remote.commit().message("3").create();
		remote.update("one", one);
		remote.update("two", two);
		remote.update("three", three);

		server.getConfig().setBoolean("uploadpack", null, "allowrefinwant", true);

		ByteArrayInputStream recvStream = uploadPackV2(
			"command=fetch\n",
			PacketLineIn.delimiter(),
			"want-ref refs/heads/one\n",
			"want " + two.toObjectId().getName() + "\n",
			"done\n",
				PacketLineIn.end());
		PacketLineIn pckIn = new PacketLineIn(recvStream);
		assertThat(pckIn.readString(), is("wanted-refs"));
		assertThat(
				pckIn.readString(),
				is(one.toObjectId().getName() + " refs/heads/one"));
		assertTrue(PacketLineIn.isDelimiter(pckIn.readString()));
		assertThat(pckIn.readString(), is("packfile"));
		parsePack(recvStream);

		assertTrue(client.getObjectDatabase().has(one.toObjectId()));
		assertTrue(client.getObjectDatabase().has(two.toObjectId()));
		assertFalse(client.getObjectDatabase().has(three.toObjectId()));
	}

	@Test
	public void testV2FetchWantRefWeAlreadyHave() throws Exception {
		RevCommit one = remote.commit().message("1").create();
		remote.update("one", one);

		server.getConfig().setBoolean("uploadpack", null, "allowrefinwant", true);

		ByteArrayInputStream recvStream = uploadPackV2(
			"command=fetch\n",
			PacketLineIn.delimiter(),
			"want-ref refs/heads/one\n",
			"have " + one.toObjectId().getName(),
			"done\n",
				PacketLineIn.end());
		PacketLineIn pckIn = new PacketLineIn(recvStream);

		// The client still needs to know the hash of the object that
		// refs/heads/one points to, even though it already has the
		// object ...
		assertThat(pckIn.readString(), is("wanted-refs"));
		assertThat(
				pckIn.readString(),
				is(one.toObjectId().getName() + " refs/heads/one"));
		assertTrue(PacketLineIn.isDelimiter(pckIn.readString()));

		// ... but the client does not need the object itself.
		assertThat(pckIn.readString(), is("packfile"));
		parsePack(recvStream);
		assertFalse(client.getObjectDatabase().has(one.toObjectId()));
	}

	@Test
	public void testV2FetchWantRefAndDeepen() throws Exception {
		RevCommit parent = remote.commit().message("parent").create();
		RevCommit child = remote.commit().message("x").parent(parent).create();
		remote.update("branch1", child);

		server.getConfig().setBoolean("uploadpack", null, "allowrefinwant", true);

		ByteArrayInputStream recvStream = uploadPackV2(
			"command=fetch\n",
			PacketLineIn.delimiter(),
			"want-ref refs/heads/branch1\n",
			"deepen 1\n",
			"done\n",
				PacketLineIn.end());
		PacketLineIn pckIn = new PacketLineIn(recvStream);

		// shallow-info appears first, then wanted-refs.
		assertThat(pckIn.readString(), is("shallow-info"));
		assertThat(pckIn.readString(), is("shallow " + child.toObjectId().getName()));
		assertTrue(PacketLineIn.isDelimiter(pckIn.readString()));
		assertThat(pckIn.readString(), is("wanted-refs"));
		assertThat(pckIn.readString(), is(child.toObjectId().getName() + " refs/heads/branch1"));
		assertTrue(PacketLineIn.isDelimiter(pckIn.readString()));
		assertThat(pckIn.readString(), is("packfile"));
		parsePack(recvStream);
		assertTrue(client.getObjectDatabase().has(child.toObjectId()));
		assertFalse(client.getObjectDatabase().has(parent.toObjectId()));
	}

	@Test
	public void testV2FetchMissingShallow() throws Exception {
		RevCommit one = remote.commit().message("1").create();
		RevCommit two = remote.commit().message("2").parent(one).create();
		RevCommit three = remote.commit().message("3").parent(two).create();
		remote.update("three", three);

		server.getConfig().setBoolean("uploadpack", null, "allowrefinwant",
				true);

		ByteArrayInputStream recvStream = uploadPackV2("command=fetch\n",
				PacketLineIn.delimiter(),
				"want-ref refs/heads/three\n",
				"deepen 3",
				"shallow 0123012301230123012301230123012301230123",
				"shallow " + two.getName() + '\n',
				"done\n",
				PacketLineIn.end());
		PacketLineIn pckIn = new PacketLineIn(recvStream);

		assertThat(pckIn.readString(), is("shallow-info"));
		assertThat(pckIn.readString(),
				is("shallow " + one.toObjectId().getName()));
		assertThat(pckIn.readString(),
				is("unshallow " + two.toObjectId().getName()));
		assertTrue(PacketLineIn.isDelimiter(pckIn.readString()));
		assertThat(pckIn.readString(), is("wanted-refs"));
		assertThat(pckIn.readString(),
				is(three.toObjectId().getName() + " refs/heads/three"));
		assertTrue(PacketLineIn.isDelimiter(pckIn.readString()));
		assertThat(pckIn.readString(), is("packfile"));
		parsePack(recvStream);

		assertTrue(client.getObjectDatabase().has(one.toObjectId()));
		assertTrue(client.getObjectDatabase().has(two.toObjectId()));
		assertTrue(client.getObjectDatabase().has(three.toObjectId()));
	}

	@Test
	public void testV2FetchSidebandAllNoPackfile() throws Exception {
		RevCommit fooParent = remote.commit().message("x").create();
		RevCommit fooChild = remote.commit().message("x").parent(fooParent).create();
		RevCommit barParent = remote.commit().message("y").create();
		RevCommit barChild = remote.commit().message("y").parent(barParent).create();
		remote.update("branch1", fooChild);
		remote.update("branch2", barChild);

		server.getConfig().setBoolean("uploadpack", null, "allowsidebandall", true);

		ByteArrayInputStream recvStream = uploadPackV2(
			"command=fetch\n",
			PacketLineIn.delimiter(),
			"sideband-all\n",
			"want " + fooChild.toObjectId().getName() + "\n",
			"want " + barChild.toObjectId().getName() + "\n",
			"have " + fooParent.toObjectId().getName() + "\n",
			PacketLineIn.end());
		PacketLineIn pckIn = new PacketLineIn(recvStream);

		assertThat(pckIn.readString(), is("\001acknowledgments"));
		assertThat(pckIn.readString(), is("\001ACK " + fooParent.getName()));
		assertTrue(PacketLineIn.isEnd(pckIn.readString()));
	}

	@Test
	public void testV2FetchSidebandAllPackfile() throws Exception {
		RevCommit commit = remote.commit().message("x").create();
		remote.update("master", commit);

		server.getConfig().setBoolean("uploadpack", null, "allowsidebandall", true);

		ByteArrayInputStream recvStream = uploadPackV2("command=fetch\n",
				PacketLineIn.delimiter(),
				"want " + commit.getName() + "\n",
				"sideband-all\n",
				"done\n",
				PacketLineIn.end());
		PacketLineIn pckIn = new PacketLineIn(recvStream);

		String s;
		// When sideband-all is used, object counting happens before
		// "packfile" is written, and object counting outputs progress
		// in sideband 2. Skip all these lines.
		for (s = pckIn.readString(); s.startsWith("\002"); s = pckIn.readString()) {
			// do nothing
		}
		assertThat(s, is("\001packfile"));
		parsePack(recvStream);
	}

	@Test
	public void testV2FetchPackfileUris() throws Exception {
		// Inside the pack
		RevCommit commit = remote.commit().message("x").create();
		remote.update("master", commit);
		generateBitmaps(server);

		// Outside the pack
		RevCommit commit2 = remote.commit().message("x").parent(commit).create();
		remote.update("master", commit2);

		server.getConfig().setBoolean("uploadpack", null, "allowsidebandall", true);

		ByteArrayInputStream recvStream = uploadPackV2(
			(UploadPack up) -> {
				up.setCachedPackUriProvider(new CachedPackUriProvider() {
					@Override
					public PackInfo getInfo(CachedPack pack,
							Collection<String> protocolsSupported)
							throws IOException {
						assertThat(protocolsSupported, hasItems("https"));
						if (!protocolsSupported.contains("https"))
							return null;
						return new PackInfo("myhash", "myuri", 100);
					}

				});
			},
			"command=fetch\n",
			PacketLineIn.delimiter(),
			"want " + commit2.getName() + "\n",
			"sideband-all\n",
			"packfile-uris https\n",
			"done\n",
			PacketLineIn.end());
		PacketLineIn pckIn = new PacketLineIn(recvStream);

		String s;
		// skip all \002 strings
		for (s = pckIn.readString(); s.startsWith("\002"); s = pckIn.readString()) {
			// do nothing
		}
		assertThat(s, is("\001packfile-uris"));
		assertThat(pckIn.readString(), is("\001myhash myuri"));
		assertTrue(PacketLineIn.isDelimiter(pckIn.readString()));
		assertThat(pckIn.readString(), is("\001packfile"));
		parsePack(recvStream);

		assertFalse(client.getObjectDatabase().has(commit.toObjectId()));
		assertTrue(client.getObjectDatabase().has(commit2.toObjectId()));
	}

	@Test
	public void testGetPeerAgentProtocolV0() throws Exception {
		RevCommit one = remote.commit().message("1").create();
		remote.update("one", one);

		UploadPack up = new UploadPack(server);
		ByteArrayInputStream send = linesAsInputStream(
				"want " + one.getName() + " agent=JGit-test/1.2.3\n",
				PacketLineIn.end(),
				"have 11cedf1b796d44207da702f7d420684022fc0f09\n", "done\n");

		ByteArrayOutputStream recv = new ByteArrayOutputStream();
		up.upload(send, recv, null);

		assertEquals(up.getPeerUserAgent(), "JGit-test/1.2.3");
	}

	@Test
	public void testGetPeerAgentProtocolV2() throws Exception {
		server.getConfig().setString("protocol", null, "version", "2");

		RevCommit one = remote.commit().message("1").create();
		remote.update("one", one);

		UploadPack up = new UploadPack(server);
		up.setExtraParameters(Sets.of("version=2"));

		ByteArrayInputStream send = linesAsInputStream(
				"command=fetch\n", "agent=JGit-test/1.2.4\n",
				PacketLineIn.delimiter(), "want " + one.getName() + "\n",
				"have 11cedf1b796d44207da702f7d420684022fc0f09\n", "done\n",
				PacketLineIn.end());

		ByteArrayOutputStream recv = new ByteArrayOutputStream();
		up.upload(send, recv, null);

		assertEquals(up.getPeerUserAgent(), "JGit-test/1.2.4");
	}

	private static class RejectAllRefFilter implements RefFilter {
		@Override
		public Map<String, Ref> filter(Map<String, Ref> refs) {
			return new HashMap<>();
		}
	}

	@Test
	public void testSingleBranchCloneTagChain() throws Exception {
		RevBlob blob0 = remote.blob("Initial content of first file");
		RevBlob blob1 = remote.blob("Second file content");
		RevCommit commit0 = remote
				.commit(remote.tree(remote.file("prvni.txt", blob0)));
		RevCommit commit1 = remote
				.commit(remote.tree(remote.file("druhy.txt", blob1)), commit0);
		remote.update("master", commit1);

		RevTag heavyTag1 = remote.tag("commitTagRing", commit0);
		remote.getRevWalk().parseHeaders(heavyTag1);
		RevTag heavyTag2 = remote.tag("middleTagRing", heavyTag1);
		remote.lightweightTag("refTagRing", heavyTag2);

		UploadPack uploadPack = new UploadPack(remote.getRepository());

		ByteArrayOutputStream cli = new ByteArrayOutputStream();
		PacketLineOut clientWant = new PacketLineOut(cli);
		clientWant.writeString("want " + commit1.name()
				+ " multi_ack_detailed include-tag thin-pack ofs-delta agent=tempo/pflaska");
		clientWant.end();
		clientWant.writeString("done\n");

		try (ByteArrayOutputStream serverResponse = new ByteArrayOutputStream()) {

			uploadPack.setPreUploadHook(new PreUploadHook() {
				@Override
				public void onBeginNegotiateRound(UploadPack up,
						Collection<? extends ObjectId> wants, int cntOffered)
						throws ServiceMayNotContinueException {
					// Do nothing.
				}

				@Override
				public void onEndNegotiateRound(UploadPack up,
						Collection<? extends ObjectId> wants, int cntCommon,
						int cntNotFound, boolean ready)
						throws ServiceMayNotContinueException {
					// Do nothing.
				}

				@Override
				public void onSendPack(UploadPack up,
						Collection<? extends ObjectId> wants,
						Collection<? extends ObjectId> haves)
						throws ServiceMayNotContinueException {
					// collect pack data
					serverResponse.reset();
				}
			});
			uploadPack.upload(new ByteArrayInputStream(cli.toByteArray()),
					serverResponse, System.err);
			InputStream packReceived = new ByteArrayInputStream(
					serverResponse.toByteArray());
			PackLock lock = null;
			try (ObjectInserter ins = client.newObjectInserter()) {
				PackParser parser = ins.newPackParser(packReceived);
				parser.setAllowThin(true);
				parser.setLockMessage("receive-tag-chain");
				ProgressMonitor mlc = NullProgressMonitor.INSTANCE;
				lock = parser.parse(mlc, mlc);
				ins.flush();
			} finally {
				if (lock != null) {
					lock.unlock();
				}
			}
			InMemoryRepository.MemObjDatabase objDb = client
					.getObjectDatabase();
			assertTrue(objDb.has(blob0.toObjectId()));
			assertTrue(objDb.has(blob1.toObjectId()));
			assertTrue(objDb.has(commit0.toObjectId()));
			assertTrue(objDb.has(commit1.toObjectId()));
			assertTrue(objDb.has(heavyTag1.toObjectId()));
			assertTrue(objDb.has(heavyTag2.toObjectId()));
		}
	}

	@Test
	public void testSafeToClearRefsInFetchV0() throws Exception {
		server =
			new RefCallsCountingRepository(
				new DfsRepositoryDescription("server"));
		remote = new TestRepository<>(server);
		RevCommit one = remote.commit().message("1").create();
		remote.update("one", one);
		testProtocol = new TestProtocol<>((Object req, Repository db) -> {
			UploadPack up = new UploadPack(db);
			return up;
		}, null);
		uri = testProtocol.register(ctx, server);
		try (Transport tn = testProtocol.open(uri, client, "server")) {
			tn.fetch(NullProgressMonitor.INSTANCE,
				Collections.singletonList(new RefSpec(one.name())));
		}
		assertTrue(client.getObjectDatabase().has(one.toObjectId()));
		assertEquals(1, ((RefCallsCountingRepository)server).numRefCalls());
	}

	@Test
	public void testSafeToClearRefsInFetchV2() throws Exception {
		server =
			new RefCallsCountingRepository(
				new DfsRepositoryDescription("server"));
		remote = new TestRepository<>(server);
		RevCommit one = remote.commit().message("1").create();
		RevCommit two = remote.commit().message("2").create();
		remote.update("one", one);
		remote.update("two", two);
		server.getConfig().setBoolean("uploadpack", null, "allowrefinwant", true);
		ByteArrayInputStream recvStream = uploadPackV2(
			"command=fetch\n",
			PacketLineIn.delimiter(),
			"want-ref refs/heads/one\n",
			"want-ref refs/heads/two\n",
			"done\n",
			PacketLineIn.end());
		PacketLineIn pckIn = new PacketLineIn(recvStream);
		assertThat(pckIn.readString(), is("wanted-refs"));
		assertThat(
			Arrays.asList(pckIn.readString(), pckIn.readString()),
			hasItems(
				one.toObjectId().getName() + " refs/heads/one",
				two.toObjectId().getName() + " refs/heads/two"));
		assertTrue(PacketLineIn.isDelimiter(pckIn.readString()));
		assertThat(pckIn.readString(), is("packfile"));
		parsePack(recvStream);
		assertTrue(client.getObjectDatabase().has(one.toObjectId()));
		assertEquals(1, ((RefCallsCountingRepository)server).numRefCalls());
	}

	private class RefCallsCountingRepository extends InMemoryRepository {
		private final InMemoryRepository.MemRefDatabase refdb;
		private int numRefCalls;

		public RefCallsCountingRepository(DfsRepositoryDescription repoDesc) {
			super(repoDesc);
			refdb = new InMemoryRepository.MemRefDatabase() {
				@Override
				public List<Ref> getRefs() throws IOException {
					numRefCalls++;
					return super.getRefs();
				}
			};
		}

		public int numRefCalls() {
			return numRefCalls;
		}

		@Override
		public RefDatabase getRefDatabase() {
			return refdb;
		}
	}
}
