diff options
author | Robin Rosenberg <robin.rosenberg@dewire.com> | 2014-03-03 18:10:44 -0500 |
---|---|---|
committer | Gerrit Code Review @ Eclipse.org <gerrit@eclipse.org> | 2014-03-03 18:10:44 -0500 |
commit | b640e3ab319ca6bf4310d2a1e681e4a08f5ddd50 (patch) | |
tree | c2d6ef5a0902a05f62db87032b65a7afd3db51db | |
parent | 1328bfdfeb0b401d2e15e32c605515e1ea02216b (diff) | |
parent | c096b42e3e6714f3df3dec317cf1826c43734eb1 (diff) | |
download | jgit-b640e3ab319ca6bf4310d2a1e681e4a08f5ddd50.tar.gz jgit-b640e3ab319ca6bf4310d2a1e681e4a08f5ddd50.zip |
Merge "Add setContains to ListBranchCommand (branch --contains)"
-rw-r--r-- | org.eclipse.jgit.test/tst/org/eclipse/jgit/api/BranchCommandTest.java | 14 | ||||
-rw-r--r-- | org.eclipse.jgit/src/org/eclipse/jgit/api/ListBranchCommand.java | 78 |
2 files changed, 81 insertions, 11 deletions
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/BranchCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/BranchCommandTest.java index 91ced0a596..c0e2e2ca8a 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/BranchCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/BranchCommandTest.java @@ -197,6 +197,20 @@ public class BranchCommandTest extends RepositoryTestCase { } @Test + public void testListBranchesWithContains() throws Exception { + git.branchCreate().setName("foo").setStartPoint(secondCommit).call(); + + List<Ref> refs = git.branchList().call(); + assertEquals(2, refs.size()); + + List<Ref> refsContainingSecond = git.branchList() + .setContains(secondCommit.name()).call(); + assertEquals(1, refsContainingSecond.size()); + // master is on initial commit, so it should not be returned + assertEquals("refs/heads/foo", refsContainingSecond.get(0).getName()); + } + + @Test public void testCreateFromCommit() throws Exception { Ref branch = git.branchCreate().setName("FromInitial").setStartPoint( initialCommit).call(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ListBranchCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ListBranchCommand.java index ea6f34b414..32ee651485 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ListBranchCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ListBranchCommand.java @@ -1,6 +1,7 @@ /* * Copyright (C) 2010, Mathias Kinzler <mathias.kinzler@sap.com> * Copyright (C) 2010, Chris Aniszczyk <caniszczyk@gmail.com> + * Copyright (C) 2014, Robin Stocker <robin@nibor.org> * and other copyright owners as documented in the project's IP log. * * This program and the accompanying materials are made available @@ -44,21 +45,30 @@ package org.eclipse.jgit.api; import java.io.IOException; +import java.text.MessageFormat; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.Comparator; -import java.util.HashMap; import java.util.List; -import java.util.Map; import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.api.errors.JGitInternalException; +import org.eclipse.jgit.api.errors.RefNotFoundException; +import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.revwalk.RevWalk; +import org.eclipse.jgit.revwalk.RevWalkUtils; /** * Used to obtain a list of branches. + * <p> + * In case HEAD is detached (it points directly to a commit), it is also + * returned in the results. * * @see <a * href="http://www.kernel.org/pub/software/scm/git/docs/git-branch.html" @@ -67,6 +77,8 @@ import org.eclipse.jgit.lib.Repository; public class ListBranchCommand extends GitCommand<List<Ref>> { private ListMode listMode; + private String containsCommitish; + /** * The modes available for listing branches (corresponding to the -r and -a * options) @@ -91,23 +103,28 @@ public class ListBranchCommand extends GitCommand<List<Ref>> { public List<Ref> call() throws GitAPIException { checkCallable(); - Map<String, Ref> refList; + List<Ref> resultRefs; try { + Collection<Ref> refs = new ArrayList<Ref>(); + + // Also return HEAD if it's detached + Ref head = repo.getRef(Constants.HEAD); + if (head != null && head.getLeaf().getName().equals(Constants.HEAD)) + refs.add(head); + if (listMode == null) { - refList = repo.getRefDatabase().getRefs(Constants.R_HEADS); + refs.addAll(getRefs(Constants.R_HEADS)); } else if (listMode == ListMode.REMOTE) { - refList = repo.getRefDatabase().getRefs(Constants.R_REMOTES); + refs.addAll(getRefs(Constants.R_REMOTES)); } else { - refList = new HashMap<String,Ref>(repo.getRefDatabase().getRefs( - Constants.R_HEADS)); - refList.putAll(repo.getRefDatabase().getRefs( - Constants.R_REMOTES)); + refs.addAll(getRefs(Constants.R_HEADS)); + refs.addAll(getRefs(Constants.R_REMOTES)); } + resultRefs = new ArrayList<Ref>(filterRefs(refs)); } catch (IOException e) { throw new JGitInternalException(e.getMessage(), e); } - List<Ref> resultRefs = new ArrayList<Ref>(); - resultRefs.addAll(refList.values()); + Collections.sort(resultRefs, new Comparator<Ref>() { public int compare(Ref o1, Ref o2) { return o1.getName().compareTo(o2.getName()); @@ -117,6 +134,26 @@ public class ListBranchCommand extends GitCommand<List<Ref>> { return resultRefs; } + private Collection<Ref> filterRefs(Collection<Ref> refs) + throws RefNotFoundException, IOException { + if (containsCommitish == null) + return refs; + + RevWalk walk = new RevWalk(repo); + try { + ObjectId resolved = repo.resolve(containsCommitish); + if (resolved == null) + throw new RefNotFoundException(MessageFormat.format( + JGitText.get().refNotResolved, containsCommitish)); + + RevCommit containsCommit = walk.parseCommit(resolved); + return RevWalkUtils.findBranchesReachableFrom(containsCommit, walk, + refs); + } finally { + walk.release(); + } + } + /** * @param listMode * optional: corresponds to the -r/-a options; by default, only @@ -128,4 +165,23 @@ public class ListBranchCommand extends GitCommand<List<Ref>> { this.listMode = listMode; return this; } + + /** + * If this is set, only the branches that contain the specified commit-ish + * as an ancestor are returned. + * + * @param containsCommitish + * a commit ID or ref name + * @return this instance + * @since 3.3 + */ + public ListBranchCommand setContains(String containsCommitish) { + checkCallable(); + this.containsCommitish = containsCommitish; + return this; + } + + private Collection<Ref> getRefs(String prefix) throws IOException { + return repo.getRefDatabase().getRefs(prefix).values(); + } } |