Enable cloning only specific tags
Single-branch-clone should be able to clone a single tag. Enhance CloneCommand to accept also full refs of tags in setBranchesToClone(). Make sure we also include fetch ref specs for the fetch command for tags. This mimics the behavior of native git's single-branch clone: git clone --branch <tag> --single-branch <URI> Bug: 542611 Change-Id: I285cf043751d9b0ba71258ee8214c0e5d1191428 Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
This commit is contained in:
parent
0d33af9ff5
commit
e7b4d108e1
|
@ -424,6 +424,32 @@ public void testBareCloneRepositoryOnlyOneBranch() throws Exception {
|
||||||
specs.get(0));
|
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<RefSpec> 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<Ref> refs) {
|
public static String allRefNames(List<Ref> refs) {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
for (Ref f : refs) {
|
for (Ref f : refs) {
|
||||||
|
|
|
@ -303,18 +303,25 @@ private FetchResult fetch(Repository clonedRepo, URIish u)
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<RefSpec> calculateRefSpecs(boolean fetchAll, String dst) {
|
private List<RefSpec> calculateRefSpecs(boolean fetchAll, String dst) {
|
||||||
RefSpec wcrs = new RefSpec();
|
RefSpec heads = new RefSpec();
|
||||||
wcrs = wcrs.setForceUpdate(true);
|
heads = heads.setForceUpdate(true);
|
||||||
wcrs = wcrs.setSourceDestination(Constants.R_HEADS + '*', dst);
|
heads = heads.setSourceDestination(Constants.R_HEADS + '*', dst);
|
||||||
List<RefSpec> specs = new ArrayList<>();
|
List<RefSpec> specs = new ArrayList<>();
|
||||||
if (!fetchAll) {
|
if (!fetchAll) {
|
||||||
|
RefSpec tags = new RefSpec();
|
||||||
|
tags = tags.setForceUpdate(true);
|
||||||
|
tags = tags.setSourceDestination(Constants.R_TAGS + '*',
|
||||||
|
Constants.R_TAGS + '*');
|
||||||
for (String selectedRef : branchesToClone) {
|
for (String selectedRef : branchesToClone) {
|
||||||
if (wcrs.matchSource(selectedRef)) {
|
if (heads.matchSource(selectedRef)) {
|
||||||
specs.add(wcrs.expandFromSource(selectedRef));
|
specs.add(heads.expandFromSource(selectedRef));
|
||||||
|
} else if (tags.matchSource(selectedRef)) {
|
||||||
|
specs.add(tags.expandFromSource(selectedRef));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
specs.add(wcrs);
|
// We'll fetch the tags anyway.
|
||||||
|
specs.add(heads);
|
||||||
}
|
}
|
||||||
return specs;
|
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.
|
||||||
|
* <p>
|
||||||
|
* If {@code false}, use {@link #setBranchesToClone(Collection)} to define
|
||||||
|
* what will be cloned. If neither are set, all branches will be cloned.
|
||||||
|
* </p>
|
||||||
*
|
*
|
||||||
* @param cloneAllBranches
|
* @param cloneAllBranches
|
||||||
* true when all branches have to be fetched (indicates wildcard
|
* {@code true} when all branches have to be fetched (indicates
|
||||||
* in created fetch refspec), false otherwise.
|
* wildcard in created fetch refspec), {@code false} otherwise.
|
||||||
* @return {@code this}
|
* @return {@code this}
|
||||||
*/
|
*/
|
||||||
public CloneCommand setCloneAllBranches(boolean cloneAllBranches) {
|
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.
|
||||||
|
* <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.
|
||||||
|
* </p>
|
||||||
*
|
*
|
||||||
* @param branchesToClone
|
* @param branchesToClone
|
||||||
* collection of branches to clone. Ignored when allSelected is
|
* collection of branches to clone. Must be specified as full ref
|
||||||
* true. Must be specified as full ref names (e.g.
|
* names (e.g. {@code refs/heads/master} or
|
||||||
* <code>refs/heads/master</code>).
|
* {@code refs/tags/v1.0.0}).
|
||||||
* @return {@code this}
|
* @return {@code this}
|
||||||
*/
|
*/
|
||||||
public CloneCommand setBranchesToClone(Collection<String> branchesToClone) {
|
public CloneCommand setBranchesToClone(Collection<String> branchesToClone) {
|
||||||
|
|
Loading…
Reference in New Issue