Merge branch 'stable-6.0' into stable-6.1

* stable-6.0:
  UploadPack: don't prematurely terminate timer in case of error
  Do not create reflog for remote tracking branches during clone
  UploadPack: do not check reachability of visible SHA1s
  Add missing package import javax.management to org.eclipse.jgit

Change-Id: I08734ee2c8f3296d908da6a29d53ed87c4b48eb2
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/UploadPackServlet.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/UploadPackServlet.java
index d3437b7..23a398f 100644
--- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/UploadPackServlet.java
+++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/UploadPackServlet.java
@@ -208,6 +208,8 @@ public void flush() throws IOException {
 				log(up.getRepository(), e.getCause());
 				consumeRequestBody(req);
 				out.close();
+			} finally {
+				up.close();
 			}
 		};
 
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CloneCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CloneCommandTest.java
index de25870..c928d2a 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CloneCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CloneCommandTest.java
@@ -22,6 +22,7 @@
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Stream;
 
 import org.eclipse.jgit.api.ListBranchCommand.ListMode;
 import org.eclipse.jgit.api.errors.GitAPIException;
@@ -115,6 +116,49 @@ public void testCloneRepository() throws IOException,
 	}
 
 	@Test
+	public void testCloneRepository_refLogForLocalRefs()
+			throws IOException, JGitInternalException, GitAPIException {
+		File directory = createTempDirectory("testCloneRepository");
+		CloneCommand command = Git.cloneRepository();
+		command.setDirectory(directory);
+		command.setURI(fileUri());
+		Git git2 = command.call();
+		Repository clonedRepo = git2.getRepository();
+		addRepoToClose(clonedRepo);
+
+		List<Ref> clonedRefs = clonedRepo.getRefDatabase().getRefs();
+		Stream<Ref> remoteRefs = clonedRefs.stream()
+				.filter(CloneCommandTest::isRemote);
+		Stream<Ref> localHeadsRefs = clonedRefs.stream()
+				.filter(CloneCommandTest::isLocalHead);
+
+		remoteRefs.forEach(ref -> assertFalse(
+				"Ref " + ref.getName()
+						+ " is remote and should not have a reflog",
+				hasRefLog(clonedRepo, ref)));
+		localHeadsRefs.forEach(ref -> assertTrue(
+				"Ref " + ref.getName()
+						+ " is local head and should have a reflog",
+				hasRefLog(clonedRepo, ref)));
+	}
+
+	private static boolean isRemote(Ref ref) {
+		return ref.getName().startsWith(Constants.R_REMOTES);
+	}
+
+	private static boolean isLocalHead(Ref ref) {
+		return !isRemote(ref) && ref.getName().startsWith(Constants.R_HEADS);
+	}
+
+	private static boolean hasRefLog(Repository repo, Ref ref) {
+		try {
+			return repo.getReflogReader(ref.getName()).getLastEntry() != null;
+		} catch (IOException ioe) {
+			throw new IllegalStateException(ioe);
+		}
+	}
+
+	@Test
 	public void testCloneRepositoryExplicitGitDir() throws IOException,
 			JGitInternalException, GitAPIException {
 		File directory = createTempDirectory("testCloneRepository");
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/FetchCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/FetchCommandTest.java
index 6479d15..b608afa 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/FetchCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/FetchCommandTest.java
@@ -77,6 +77,26 @@ public void testFetch() throws Exception {
 	}
 
 	@Test
+	public void testFetchHasRefLogForRemoteRef() throws Exception {
+		// create an initial commit SHA1 for the default branch
+		ObjectId defaultBranchSha1 = remoteGit.commit()
+				.setMessage("initial commit").call().getId();
+
+		git.fetch().setRemote("test")
+				.setRefSpecs("refs/heads/*:refs/remotes/origin/*").call();
+
+		List<Ref> allFetchedRefs = git.getRepository().getRefDatabase()
+				.getRefs();
+		assertEquals(allFetchedRefs.size(), 1);
+		Ref remoteRef = allFetchedRefs.get(0);
+
+		assertTrue(remoteRef.getName().startsWith(Constants.R_REMOTES));
+		assertEquals(defaultBranchSha1, remoteRef.getObjectId());
+		assertNotNull(git.getRepository().getReflogReader(remoteRef.getName())
+				.getLastEntry());
+	}
+
+	@Test
 	public void testForcedFetch() throws Exception {
 		remoteGit.commit().setMessage("commit").call();
 		remoteGit.commit().setMessage("commit2").call();
diff --git a/org.eclipse.jgit/META-INF/MANIFEST.MF b/org.eclipse.jgit/META-INF/MANIFEST.MF
index eb8eb8b..808d5d3 100644
--- a/org.eclipse.jgit/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit/META-INF/MANIFEST.MF
@@ -226,6 +226,7 @@
 Bundle-RequiredExecutionEnvironment: JavaSE-11
 Import-Package: com.googlecode.javaewah;version="[1.1.6,2.0.0)",
  javax.crypto,
+ javax.management,
  javax.net.ssl,
  org.slf4j;version="[1.7.0,2.0.0)",
  org.xml.sax,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java
index 7d7b3ee..2b4deb3 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java
@@ -204,8 +204,13 @@ else if (tagopt == TagOpt.FETCH_TAGS)
 
 		BatchRefUpdate batch = transport.local.getRefDatabase()
 				.newBatchUpdate()
-				.setAllowNonFastForwards(true)
-				.setRefLogMessage("fetch", true); //$NON-NLS-1$
+				.setAllowNonFastForwards(true);
+
+		// Generate reflog only when fetching updates and not at the first clone
+		if (initialBranch == null) {
+			batch.setRefLogMessage("fetch", true); //$NON-NLS-1$
+		}
+
 		try (RevWalk walk = new RevWalk(transport.local)) {
 			walk.setRetainBody(false);
 			if (monitor instanceof BatchingProgressMonitor) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java
index b5062fd..1617c50 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java
@@ -39,6 +39,7 @@
 import static org.eclipse.jgit.util.RefMap.toRefMap;
 
 import java.io.ByteArrayOutputStream;
+import java.io.Closeable;
 import java.io.EOFException;
 import java.io.IOException;
 import java.io.InputStream;
@@ -105,7 +106,7 @@
 /**
  * Implements the server side of a fetch connection, transmitting objects.
  */
-public class UploadPack {
+public class UploadPack implements Closeable {
 	/** Policy the server uses to validate client requests */
 	public enum RequestPolicy {
 		/** Client may only ask for objects the server advertised a reference for. */
@@ -733,6 +734,17 @@ private boolean useProtocolV2() {
 				&& clientRequestedV2;
 	}
 
+	@Override
+	public void close() {
+		if (timer != null) {
+			try {
+				timer.terminate();
+			} finally {
+				timer = null;
+			}
+		}
+	}
+
 	/**
 	 * Execute the upload task on the socket.
 	 *
@@ -780,6 +792,8 @@ public void upload(InputStream input, OutputStream output,
 				throw new UploadPackInternalServerErrorException(err);
 			}
 			throw err;
+		} finally {
+			close();
 		}
 	}
 
@@ -789,6 +803,10 @@ public void upload(InputStream input, OutputStream output,
 	 * <p>
 	 * If the client passed extra parameters (e.g., "version=2") through a side
 	 * channel, the caller must call setExtraParameters first to supply them.
+	 * Callers of this method should call {@link #close()} to terminate the
+	 * internal interrupt timer thread. If the caller fails to terminate the
+	 * thread, it will (eventually) terminate itself when the InterruptTimer
+	 * instance is garbage collected.
 	 *
 	 * @param input
 	 *            raw input to read client commands from. Caller must ensure the
@@ -845,13 +863,6 @@ public void uploadWithExceptionPropagation(InputStream input,
 		} finally {
 			msgOut = NullOutputStream.INSTANCE;
 			walk.close();
-			if (timer != null) {
-				try {
-					timer.terminate();
-				} finally {
-					timer = null;
-				}
-			}
 		}
 	}
 
@@ -1998,12 +2009,16 @@ private static void checkNotAdvertisedWants(UploadPack up,
 			throws IOException {
 
 		ObjectReader reader = up.getRevWalk().getObjectReader();
+		Set<ObjectId> directlyVisibleObjects = refIdSet(visibleRefs);
+		List<ObjectId> nonTipWants = notAdvertisedWants.stream()
+				.filter(not(directlyVisibleObjects::contains))
+				.collect(Collectors.toList());
 
 		try (RevWalk walk = new RevWalk(reader)) {
 			walk.setRetainBody(false);
 			// Missing "wants" throw exception here
 			List<RevObject> wantsAsObjs = objectIdsToRevObjects(walk,
-					notAdvertisedWants);
+					nonTipWants);
 			List<RevCommit> wantsAsCommits = wantsAsObjs.stream()
 					.filter(obj -> obj instanceof RevCommit)
 					.map(obj -> (RevCommit) obj)
@@ -2063,6 +2078,10 @@ private static void checkNotAdvertisedWants(UploadPack up,
 		}
 	}
 
+	private static <T> Predicate<T> not(Predicate<T> t) {
+	    return t.negate();
+	}
+
 	static Stream<Ref> importantRefsFirst(
 			Collection<Ref> visibleRefs) {
 		Predicate<Ref> startsWithRefsHeads = ref -> ref.getName()