Merge branch 'stable-5.6'

* stable-5.6:
  Restore behavior of CloneCommand

Change-Id: I3092bf214c41436b57e0ede9d2202f8aabf15471
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
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 cee898a..3d0daca 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
@@ -408,6 +408,7 @@
 		Git git2 = command.call();
 		addRepoToClose(git2.getRepository());
 		assertNotNull(git2);
+		assertTrue(git2.getRepository().isBare());
 		assertNotNull(git2.getRepository().resolve("tag-for-blob"));
 		assertNotNull(git2.getRepository().resolve("tag-initial"));
 		assertEquals(git2.getRepository().getFullBranch(), "refs/heads/master");
@@ -448,6 +449,60 @@
 				specs.get(0));
 	}
 
+	@Test
+	public void testCloneRepositoryAllBranchesTakesPreference()
+			throws Exception {
+		File directory = createTempDirectory(
+				"testCloneRepositoryAllBranchesTakesPreference");
+		CloneCommand command = Git.cloneRepository();
+		command.setCloneAllBranches(true);
+		command.setBranchesToClone(
+				Collections.singletonList("refs/heads/test"));
+		command.setDirectory(directory);
+		command.setURI(fileUri());
+		Git git2 = command.call();
+		addRepoToClose(git2.getRepository());
+		assertNotNull(git2);
+		assertEquals(git2.getRepository().getFullBranch(), "refs/heads/test");
+		// Expect both remote branches to exist; setCloneAllBranches(true)
+		// should override any setBranchesToClone().
+		assertNotNull(
+				git2.getRepository().resolve("refs/remotes/origin/master"));
+		assertNotNull(git2.getRepository().resolve("refs/remotes/origin/test"));
+		RemoteConfig cfg = new RemoteConfig(git2.getRepository().getConfig(),
+				Constants.DEFAULT_REMOTE_NAME);
+		List<RefSpec> specs = cfg.getFetchRefSpecs();
+		assertEquals(1, specs.size());
+		assertEquals(new RefSpec("+refs/heads/*:refs/remotes/origin/*"),
+				specs.get(0));
+	}
+
+	@Test
+	public void testCloneRepositoryAllBranchesIndependent() throws Exception {
+		File directory = createTempDirectory(
+				"testCloneRepositoryAllBranchesIndependent");
+		CloneCommand command = Git.cloneRepository();
+		command.setCloneAllBranches(true);
+		command.setBranchesToClone(
+				Collections.singletonList("refs/heads/test"));
+		command.setCloneAllBranches(false);
+		command.setDirectory(directory);
+		command.setURI(fileUri());
+		Git git2 = command.call();
+		addRepoToClose(git2.getRepository());
+		assertNotNull(git2);
+		assertEquals(git2.getRepository().getFullBranch(), "refs/heads/test");
+		// Expect only the test branch; allBranches was re-set to false
+		assertNull(git2.getRepository().resolve("refs/remotes/origin/master"));
+		assertNotNull(git2.getRepository().resolve("refs/remotes/origin/test"));
+		RemoteConfig cfg = new RemoteConfig(git2.getRepository().getConfig(),
+				Constants.DEFAULT_REMOTE_NAME);
+		List<RefSpec> specs = cfg.getFetchRefSpecs();
+		assertEquals(1, specs.size());
+		assertEquals(new RefSpec("+refs/heads/test:refs/remotes/origin/test"),
+				specs.get(0));
+	}
+
 	public static String allRefNames(List<Ref> refs) {
 		StringBuilder sb = new StringBuilder();
 		for (Ref f : refs) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java
index eef7940..78afe18 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java
@@ -71,7 +71,9 @@
 
 	private ProgressMonitor monitor = NullProgressMonitor.INSTANCE;
 
-	private FETCH_TYPE fetchType = FETCH_TYPE.ALL_BRANCHES;
+	private boolean cloneAllBranches;
+
+	private boolean mirror;
 
 	private boolean cloneSubmodules;
 
@@ -85,6 +87,8 @@
 
 	private boolean gitDirExistsInitially;
 
+	private FETCH_TYPE fetchType;
+
 	private enum FETCH_TYPE {
 		MULTIPLE_BRANCHES, ALL_BRANCHES, MIRROR
 	}
@@ -162,6 +166,7 @@
 			throw new InvalidRemoteException(
 					MessageFormat.format(JGitText.get().invalidURL, uri), e);
 		}
+		setFetchType();
 		@SuppressWarnings("resource") // Closed by caller
 		Repository repository = init();
 		FetchResult fetchResult = null;
@@ -206,6 +211,20 @@
 		return new Git(repository, true);
 	}
 
+	private void setFetchType() {
+		if (mirror) {
+			fetchType = FETCH_TYPE.MIRROR;
+			setBare(true);
+		} else if (cloneAllBranches) {
+			fetchType = FETCH_TYPE.ALL_BRANCHES;
+		} else if (branchesToClone != null && !branchesToClone.isEmpty()) {
+			fetchType = FETCH_TYPE.MULTIPLE_BRANCHES;
+		} else {
+			// Default: neither mirror nor all nor specific refs given
+			fetchType = FETCH_TYPE.ALL_BRANCHES;
+		}
+	}
+
 	private static boolean isNonEmptyDirectory(File dir) {
 		if (dir != null && dir.exists()) {
 			File[] files = dir.listFiles();
@@ -587,8 +606,7 @@
 	 * @return {@code this}
 	 */
 	public CloneCommand setCloneAllBranches(boolean cloneAllBranches) {
-		this.fetchType = cloneAllBranches ? FETCH_TYPE.ALL_BRANCHES
-				: this.fetchType;
+		this.cloneAllBranches = cloneAllBranches;
 		return this;
 	}
 
@@ -608,10 +626,7 @@
 	 * @since 5.6
 	 */
 	public CloneCommand setMirror(boolean mirror) {
-		if (mirror) {
-			this.fetchType = FETCH_TYPE.MIRROR;
-			setBare(true);
-		}
+		this.mirror = mirror;
 		return this;
 	}
 
@@ -632,8 +647,9 @@
 	 * Set the branches or tags to clone.
 	 * <p>
 	 * This is ignored if {@link #setCloneAllBranches(boolean)
-	 * setCloneAllBranches(true)} is used. If {@code branchesToClone} is
-	 * {@code null} or empty, it's also ignored and all branches will be cloned.
+	 * setCloneAllBranches(true)} or {@link #setMirror(boolean) setMirror(true)}
+	 * is used. If {@code branchesToClone} is {@code null} or empty, it's also
+	 * ignored.
 	 * </p>
 	 *
 	 * @param branchesToClone
@@ -643,13 +659,7 @@
 	 * @return {@code this}
 	 */
 	public CloneCommand setBranchesToClone(Collection<String> branchesToClone) {
-		if (branchesToClone == null || branchesToClone.isEmpty()) {
-			// fallback to default
-			fetchType = FETCH_TYPE.ALL_BRANCHES;
-		} else {
-			this.fetchType = FETCH_TYPE.MULTIPLE_BRANCHES;
-			this.branchesToClone = branchesToClone;
-		}
+		this.branchesToClone = branchesToClone;
 		return this;
 	}