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 6b5fe502b..1523b49ec 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 @@ -424,6 +424,32 @@ public void testBareCloneRepositoryOnlyOneBranch() throws Exception { specs.get(0)); } + @Test + public void testCloneRepositoryOnlyOneTag() throws Exception { + File directory = createTempDirectory("testCloneRepositoryWithBranch"); + CloneCommand command = Git.cloneRepository(); + command.setBranch("tag-initial"); + command.setBranchesToClone( + Collections.singletonList("refs/tags/tag-initial")); + command.setDirectory(directory); + command.setURI(fileUri()); + Git git2 = command.call(); + addRepoToClose(git2.getRepository()); + assertNotNull(git2); + assertNull(git2.getRepository().resolve("tag-for-blob")); + assertNull(git2.getRepository().resolve("refs/heads/master")); + assertNotNull(git2.getRepository().resolve("tag-initial")); + ObjectId taggedCommit = db.resolve("tag-initial^{commit}"); + assertEquals(taggedCommit.name(), git2.getRepository().getFullBranch()); + RemoteConfig cfg = new RemoteConfig(git2.getRepository().getConfig(), + Constants.DEFAULT_REMOTE_NAME); + List specs = cfg.getFetchRefSpecs(); + assertEquals(1, specs.size()); + assertEquals( + new RefSpec("+refs/tags/tag-initial:refs/tags/tag-initial"), + specs.get(0)); + } + public static String allRefNames(List 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 73af8ba16..0248ba279 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java @@ -303,18 +303,25 @@ private FetchResult fetch(Repository clonedRepo, URIish u) } private List calculateRefSpecs(boolean fetchAll, String dst) { - RefSpec wcrs = new RefSpec(); - wcrs = wcrs.setForceUpdate(true); - wcrs = wcrs.setSourceDestination(Constants.R_HEADS + '*', dst); + RefSpec heads = new RefSpec(); + heads = heads.setForceUpdate(true); + heads = heads.setSourceDestination(Constants.R_HEADS + '*', dst); List specs = new ArrayList<>(); if (!fetchAll) { + RefSpec tags = new RefSpec(); + tags = tags.setForceUpdate(true); + tags = tags.setSourceDestination(Constants.R_TAGS + '*', + Constants.R_TAGS + '*'); for (String selectedRef : branchesToClone) { - if (wcrs.matchSource(selectedRef)) { - specs.add(wcrs.expandFromSource(selectedRef)); + if (heads.matchSource(selectedRef)) { + specs.add(heads.expandFromSource(selectedRef)); + } else if (tags.matchSource(selectedRef)) { + specs.add(tags.expandFromSource(selectedRef)); } } } else { - specs.add(wcrs); + // We'll fetch the tags anyway. + specs.add(heads); } return specs; } @@ -590,11 +597,15 @@ public CloneCommand setProgressMonitor(ProgressMonitor monitor) { } /** - * Set whether all branches have to be fetched + * Set whether all branches have to be fetched. + *

+ * If {@code false}, use {@link #setBranchesToClone(Collection)} to define + * what will be cloned. If neither are set, all branches will be cloned. + *

* * @param cloneAllBranches - * true when all branches have to be fetched (indicates wildcard - * in created fetch refspec), false otherwise. + * {@code true} when all branches have to be fetched (indicates + * wildcard in created fetch refspec), {@code false} otherwise. * @return {@code this} */ public CloneCommand setCloneAllBranches(boolean cloneAllBranches) { @@ -616,12 +627,17 @@ public CloneCommand setCloneSubmodules(boolean cloneSubmodules) { } /** - * Set branches to clone + * Set the branches or tags to clone. + *

+ * 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. + *

* * @param branchesToClone - * collection of branches to clone. Ignored when allSelected is - * true. Must be specified as full ref names (e.g. - * refs/heads/master). + * collection of branches to clone. Must be specified as full ref + * names (e.g. {@code refs/heads/master} or + * {@code refs/tags/v1.0.0}). * @return {@code this} */ public CloneCommand setBranchesToClone(Collection branchesToClone) {