Browse Source
The need for branching becomes more pressing with pull support: we need to make sure the upstream configuration entries are written correctly when creating and renaming branches (and of course are cleaned up when deleting them). This adds support for listing, adding, deleting and renaming branches including the more common options. Bug: 326938 Change-Id: I00bcc19476e835d6fd78fd188acde64946c1505c Signed-off-by: Mathias Kinzler <mathias.kinzler@sap.com> Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>stable-0.10
Mathias Kinzler
14 years ago
committed by
Chris Aniszczyk
14 changed files with 1643 additions and 0 deletions
@ -0,0 +1,416 @@
|
||||
/* |
||||
* Copyright (C) 2010, Mathias Kinzler <mathias.kinzler@sap.com> |
||||
* and other copyright owners as documented in the project's IP log. |
||||
* |
||||
* This program and the accompanying materials are made available |
||||
* under the terms of the Eclipse Distribution License v1.0 which |
||||
* accompanies this distribution, is reproduced below, and is |
||||
* available at http://www.eclipse.org/org/documents/edl-v10.php
|
||||
* |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or |
||||
* without modification, are permitted provided that the following |
||||
* conditions are met: |
||||
* |
||||
* - Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* |
||||
* - Redistributions in binary form must reproduce the above |
||||
* copyright notice, this list of conditions and the following |
||||
* disclaimer in the documentation and/or other materials provided |
||||
* with the distribution. |
||||
* |
||||
* - Neither the name of the Eclipse Foundation, Inc. nor the |
||||
* names of its contributors may be used to endorse or promote |
||||
* products derived from this software without specific prior |
||||
* written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND |
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, |
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
package org.eclipse.jgit.api; |
||||
|
||||
import java.util.List; |
||||
|
||||
import org.eclipse.jgit.api.CreateBranchCommand.SetupUpstreamMode; |
||||
import org.eclipse.jgit.api.ListBranchCommand.ListMode; |
||||
import org.eclipse.jgit.api.errors.CannotDeleteCurrentBranchException; |
||||
import org.eclipse.jgit.api.errors.DetachedHeadException; |
||||
import org.eclipse.jgit.api.errors.InvalidRefNameException; |
||||
import org.eclipse.jgit.api.errors.JGitInternalException; |
||||
import org.eclipse.jgit.api.errors.NotMergedException; |
||||
import org.eclipse.jgit.api.errors.RefAlreadyExistsException; |
||||
import org.eclipse.jgit.api.errors.RefNotFoundException; |
||||
import org.eclipse.jgit.errors.AmbiguousObjectException; |
||||
import org.eclipse.jgit.lib.Constants; |
||||
import org.eclipse.jgit.lib.Ref; |
||||
import org.eclipse.jgit.lib.RefUpdate; |
||||
import org.eclipse.jgit.lib.Repository; |
||||
import org.eclipse.jgit.lib.RepositoryTestCase; |
||||
import org.eclipse.jgit.lib.StoredConfig; |
||||
import org.eclipse.jgit.revwalk.RevCommit; |
||||
import org.eclipse.jgit.transport.FetchResult; |
||||
import org.eclipse.jgit.transport.RefSpec; |
||||
import org.eclipse.jgit.transport.RemoteConfig; |
||||
import org.eclipse.jgit.transport.URIish; |
||||
|
||||
public class BranchCommandTest extends RepositoryTestCase { |
||||
private Git git; |
||||
|
||||
RevCommit initialCommit; |
||||
|
||||
RevCommit secondCommit; |
||||
|
||||
@Override |
||||
protected void setUp() throws Exception { |
||||
super.setUp(); |
||||
git = new Git(db); |
||||
// checkout master
|
||||
git.commit().setMessage("initial commit").call(); |
||||
// commit something
|
||||
writeTrashFile("Test.txt", "Hello world"); |
||||
git.add().addFilepattern("Test.txt").call(); |
||||
initialCommit = git.commit().setMessage("Initial commit").call(); |
||||
writeTrashFile("Test.txt", "Some change"); |
||||
git.add().addFilepattern("Test.txt").call(); |
||||
secondCommit = git.commit().setMessage("Second commit").call(); |
||||
// create a master branch
|
||||
RefUpdate rup = db.updateRef("refs/heads/master"); |
||||
rup.setNewObjectId(initialCommit.getId()); |
||||
rup.setForceUpdate(true); |
||||
rup.update(); |
||||
} |
||||
|
||||
private Git setUpRepoWithRemote() throws Exception { |
||||
Repository remoteRepository = createWorkRepository(); |
||||
Git remoteGit = new Git(remoteRepository); |
||||
// commit something
|
||||
writeTrashFile("Test.txt", "Hello world"); |
||||
remoteGit.add().addFilepattern("Test.txt").call(); |
||||
initialCommit = remoteGit.commit().setMessage("Initial commit").call(); |
||||
writeTrashFile("Test.txt", "Some change"); |
||||
remoteGit.add().addFilepattern("Test.txt").call(); |
||||
secondCommit = remoteGit.commit().setMessage("Second commit").call(); |
||||
// create a master branch
|
||||
RefUpdate rup = remoteRepository.updateRef("refs/heads/master"); |
||||
rup.setNewObjectId(initialCommit.getId()); |
||||
rup.forceUpdate(); |
||||
|
||||
Repository localRepository = createWorkRepository(); |
||||
Git localGit = new Git(localRepository); |
||||
StoredConfig config = localRepository.getConfig(); |
||||
RemoteConfig rc = new RemoteConfig(config, "origin"); |
||||
rc.addURI(new URIish(remoteRepository.getDirectory().getPath())); |
||||
rc.addFetchRefSpec(new RefSpec("+refs/heads/*:refs/remotes/origin/*")); |
||||
rc.update(config); |
||||
config.save(); |
||||
FetchResult res = localGit.fetch().setRemote("origin").call(); |
||||
assertFalse(res.getTrackingRefUpdates().isEmpty()); |
||||
rup = localRepository.updateRef("refs/heads/master"); |
||||
rup.setNewObjectId(initialCommit.getId()); |
||||
rup.forceUpdate(); |
||||
rup = localRepository.updateRef(Constants.HEAD); |
||||
rup.link("refs/heads/master"); |
||||
rup.setNewObjectId(initialCommit.getId()); |
||||
rup.update(); |
||||
return localGit; |
||||
} |
||||
|
||||
public void testCreateAndList() throws Exception { |
||||
int localBefore; |
||||
int remoteBefore; |
||||
int allBefore; |
||||
|
||||
// invalid name not allowed
|
||||
try { |
||||
git.branchCreate().setName("In va lid").call(); |
||||
fail("Create branch with invalid ref name should fail"); |
||||
} catch (InvalidRefNameException e) { |
||||
// expected
|
||||
} |
||||
// existing name not allowed w/o force
|
||||
try { |
||||
git.branchCreate().setName("master").call(); |
||||
fail("Create branch with existing ref name should fail"); |
||||
} catch (RefAlreadyExistsException e) { |
||||
// expected
|
||||
} |
||||
|
||||
localBefore = git.branchList().call().size(); |
||||
remoteBefore = git.branchList().setListMode(ListMode.REMOTE).call() |
||||
.size(); |
||||
allBefore = git.branchList().setListMode(ListMode.ALL).call().size(); |
||||
|
||||
assertEquals(localBefore + remoteBefore, allBefore); |
||||
Ref newBranch = createBranch(git, "NewForTestList", false, "master", |
||||
null); |
||||
assertEquals("refs/heads/NewForTestList", newBranch.getName()); |
||||
|
||||
assertEquals(1, git.branchList().call().size() - localBefore); |
||||
assertEquals(0, git.branchList().setListMode(ListMode.REMOTE).call() |
||||
.size() |
||||
- remoteBefore); |
||||
assertEquals(1, git.branchList().setListMode(ListMode.ALL).call() |
||||
.size() |
||||
- allBefore); |
||||
// we can only create local branches
|
||||
newBranch = createBranch(git, |
||||
"refs/remotes/origin/NewRemoteForTestList", false, "master", |
||||
null); |
||||
assertEquals("refs/heads/refs/remotes/origin/NewRemoteForTestList", |
||||
newBranch.getName()); |
||||
assertEquals(2, git.branchList().call().size() - localBefore); |
||||
assertEquals(0, git.branchList().setListMode(ListMode.REMOTE).call() |
||||
.size() |
||||
- remoteBefore); |
||||
assertEquals(2, git.branchList().setListMode(ListMode.ALL).call() |
||||
.size() |
||||
- allBefore); |
||||
} |
||||
|
||||
public void testCreateFromCommit() throws Exception { |
||||
Ref branch = git.branchCreate().setName("FromInitial").setStartPoint( |
||||
initialCommit).call(); |
||||
assertEquals(initialCommit.getId(), branch.getObjectId()); |
||||
branch = git.branchCreate().setName("FromInitial2").setStartPoint( |
||||
initialCommit.getId().name()).call(); |
||||
assertEquals(initialCommit.getId(), branch.getObjectId()); |
||||
try { |
||||
git.branchCreate().setName("FromInitial").setStartPoint( |
||||
secondCommit).call(); |
||||
} catch (RefAlreadyExistsException e) { |
||||
// expected
|
||||
} |
||||
branch = git.branchCreate().setName("FromInitial").setStartPoint( |
||||
secondCommit).setForce(true).call(); |
||||
assertEquals(secondCommit.getId(), branch.getObjectId()); |
||||
} |
||||
|
||||
public void testCreateForce() throws Exception { |
||||
// using commits
|
||||
Ref newBranch = createBranch(git, "NewForce", false, secondCommit |
||||
.getId().name(), null); |
||||
assertEquals(newBranch.getTarget().getObjectId(), secondCommit.getId()); |
||||
try { |
||||
newBranch = createBranch(git, "NewForce", false, initialCommit |
||||
.getId().name(), null); |
||||
fail("Should have failed"); |
||||
} catch (RefAlreadyExistsException e) { |
||||
// expected
|
||||
} |
||||
newBranch = createBranch(git, "NewForce", true, initialCommit.getId() |
||||
.name(), null); |
||||
assertEquals(newBranch.getTarget().getObjectId(), initialCommit.getId()); |
||||
git.branchDelete().setBranchNames("NewForce").call(); |
||||
// using names
|
||||
|
||||
git.branchCreate().setName("NewForce").setStartPoint("master").call(); |
||||
assertEquals(newBranch.getTarget().getObjectId(), initialCommit.getId()); |
||||
try { |
||||
git.branchCreate().setName("NewForce").setStartPoint("master") |
||||
.call(); |
||||
fail("Should have failed"); |
||||
} catch (RefAlreadyExistsException e) { |
||||
// expected
|
||||
} |
||||
git.branchCreate().setName("NewForce").setStartPoint("master") |
||||
.setForce(true).call(); |
||||
assertEquals(newBranch.getTarget().getObjectId(), initialCommit.getId()); |
||||
} |
||||
|
||||
public void testDelete() throws Exception { |
||||
createBranch(git, "ForDelete", false, "master", null); |
||||
git.branchDelete().setBranchNames("ForDelete").call(); |
||||
// now point the branch to a non-merged commit
|
||||
createBranch(git, "ForDelete", false, secondCommit.getId().name(), null); |
||||
try { |
||||
git.branchDelete().setBranchNames("ForDelete").call(); |
||||
fail("Deletion of a non-merged branch without force should have failed"); |
||||
} catch (NotMergedException e) { |
||||
// expected
|
||||
} |
||||
List<String> deleted = git.branchDelete().setBranchNames("ForDelete") |
||||
.setForce(true).call(); |
||||
assertEquals(1, deleted.size()); |
||||
assertEquals(Constants.R_HEADS + "ForDelete", deleted.get(0)); |
||||
createBranch(git, "ForDelete", false, "master", null); |
||||
try { |
||||
createBranch(git, "ForDelete", false, "master", null); |
||||
fail("Repeated creation of same branch without force should fail"); |
||||
} catch (RefAlreadyExistsException e) { |
||||
// expected
|
||||
} |
||||
// change starting point
|
||||
Ref newBranch = createBranch(git, "ForDelete", true, initialCommit |
||||
.name(), null); |
||||
assertEquals(newBranch.getTarget().getObjectId(), initialCommit.getId()); |
||||
newBranch = createBranch(git, "ForDelete", true, secondCommit.name(), |
||||
null); |
||||
assertEquals(newBranch.getTarget().getObjectId(), secondCommit.getId()); |
||||
git.branchDelete().setBranchNames("ForDelete").setForce(true); |
||||
try { |
||||
git.branchDelete().setBranchNames("master").call(); |
||||
fail("Deletion of checked out branch without force should have failed"); |
||||
} catch (CannotDeleteCurrentBranchException e) { |
||||
// expected
|
||||
} |
||||
try { |
||||
git.branchDelete().setBranchNames("master").setForce(true).call(); |
||||
fail("Deletion of checked out branch with force should have failed"); |
||||
} catch (CannotDeleteCurrentBranchException e) { |
||||
// expected
|
||||
} |
||||
} |
||||
|
||||
public void testPullConfigRemoteBranch() throws Exception { |
||||
Git localGit = setUpRepoWithRemote(); |
||||
Ref remote = localGit.branchList().setListMode(ListMode.REMOTE).call() |
||||
.get(0); |
||||
assertEquals("refs/remotes/origin/master", remote.getName()); |
||||
// by default, we should create pull configuration
|
||||
createBranch(localGit, "newFromRemote", false, remote.getName(), null); |
||||
assertEquals("origin", localGit.getRepository().getConfig().getString( |
||||
"branch", "newFromRemote", "remote")); |
||||
localGit.branchDelete().setBranchNames("newFromRemote").call(); |
||||
// the pull configuration should be gone after deletion
|
||||
assertNull(localGit.getRepository().getConfig().getString("branch", |
||||
"newFromRemote", "remote")); |
||||
// use --no-track
|
||||
createBranch(localGit, "newFromRemote", false, remote.getName(), |
||||
SetupUpstreamMode.NOTRACK); |
||||
assertNull(localGit.getRepository().getConfig().getString("branch", |
||||
"newFromRemote", "remote")); |
||||
localGit.branchDelete().setBranchNames("newFromRemote").call(); |
||||
} |
||||
|
||||
public void testPullConfigLocalBranch() throws Exception { |
||||
Git localGit = setUpRepoWithRemote(); |
||||
// by default, we should not create pull configuration
|
||||
createBranch(localGit, "newFromMaster", false, "master", null); |
||||
assertNull(localGit.getRepository().getConfig().getString("branch", |
||||
"newFromMaster", "remote")); |
||||
localGit.branchDelete().setBranchNames("newFromMaster").call(); |
||||
// use --track
|
||||
createBranch(localGit, "newFromMaster", false, "master", |
||||
SetupUpstreamMode.TRACK); |
||||
assertEquals(".", localGit.getRepository().getConfig().getString( |
||||
"branch", "newFromMaster", "remote")); |
||||
localGit.branchDelete().setBranchNames("newFromMaster").call(); |
||||
// the pull configuration should be gone after deletion
|
||||
assertNull(localGit.getRepository().getConfig().getString("branch", |
||||
"newFromRemote", "remote")); |
||||
} |
||||
|
||||
public void testPullConfigRenameLocalBranch() throws Exception { |
||||
Git localGit = setUpRepoWithRemote(); |
||||
// by default, we should not create pull configuration
|
||||
createBranch(localGit, "newFromMaster", false, "master", null); |
||||
assertNull(localGit.getRepository().getConfig().getString("branch", |
||||
"newFromMaster", "remote")); |
||||
localGit.branchDelete().setBranchNames("newFromMaster").call(); |
||||
// use --track
|
||||
createBranch(localGit, "newFromMaster", false, "master", |
||||
SetupUpstreamMode.TRACK); |
||||
assertEquals(".", localGit.getRepository().getConfig().getString( |
||||
"branch", "newFromMaster", "remote")); |
||||
localGit.branchRename().setOldName("newFromMaster").setNewName( |
||||
"renamed").call(); |
||||
assertNull(".", localGit.getRepository().getConfig().getString( |
||||
"branch", "newFromMaster", "remote")); |
||||
assertEquals(".", localGit.getRepository().getConfig().getString( |
||||
"branch", "renamed", "remote")); |
||||
localGit.branchDelete().setBranchNames("renamed").call(); |
||||
// the pull configuration should be gone after deletion
|
||||
assertNull(localGit.getRepository().getConfig().getString("branch", |
||||
"newFromRemote", "remote")); |
||||
} |
||||
|
||||
public void testRenameLocalBranch() throws Exception { |
||||
// null newName not allowed
|
||||
try { |
||||
git.branchRename().call(); |
||||
} catch (InvalidRefNameException e) { |
||||
// expected
|
||||
} |
||||
// invalid newName not allowed
|
||||
try { |
||||
git.branchRename().setNewName("In va lid").call(); |
||||
} catch (InvalidRefNameException e) { |
||||
// expected
|
||||
} |
||||
// not existing name not allowed
|
||||
try { |
||||
git.branchRename().setOldName("notexistingbranch").setNewName( |
||||
"newname").call(); |
||||
} catch (RefNotFoundException e) { |
||||
// expected
|
||||
} |
||||
// create some branch
|
||||
createBranch(git, "existing", false, "master", null); |
||||
// a local branch
|
||||
Ref branch = createBranch(git, "fromMasterForRename", false, "master", |
||||
null); |
||||
assertEquals(Constants.R_HEADS + "fromMasterForRename", branch |
||||
.getName()); |
||||
Ref renamed = git.branchRename().setOldName("fromMasterForRename") |
||||
.setNewName("newName").call(); |
||||
assertEquals(Constants.R_HEADS + "newName", renamed.getName()); |
||||
try { |
||||
git.branchRename().setOldName(renamed.getName()).setNewName( |
||||
"existing").call(); |
||||
fail("Should have failed"); |
||||
} catch (RefAlreadyExistsException e) { |
||||
// expected
|
||||
} |
||||
try { |
||||
git.branchRename().setNewName("In va lid").call(); |
||||
fail("Rename with invalid ref name should fail"); |
||||
} catch (InvalidRefNameException e) { |
||||
// expected
|
||||
} |
||||
// rename without old name and detached head not allowed
|
||||
RefUpdate rup = git.getRepository().updateRef(Constants.HEAD, true); |
||||
rup.setNewObjectId(initialCommit); |
||||
rup.forceUpdate(); |
||||
try { |
||||
git.branchRename().setNewName("detached").call(); |
||||
} catch (DetachedHeadException e) { |
||||
// expected
|
||||
} |
||||
} |
||||
|
||||
public void testRenameRemoteTrackingBranch() throws Exception { |
||||
Git localGit = setUpRepoWithRemote(); |
||||
Ref remoteBranch = localGit.branchList().setListMode(ListMode.REMOTE) |
||||
.call().get(0); |
||||
Ref renamed = localGit.branchRename() |
||||
.setOldName(remoteBranch.getName()).setNewName("newRemote") |
||||
.call(); |
||||
assertEquals(Constants.R_REMOTES + "newRemote", renamed.getName()); |
||||
} |
||||
|
||||
public Ref createBranch(Git actGit, String name, boolean force, |
||||
String startPoint, SetupUpstreamMode mode) |
||||
throws JGitInternalException, RefAlreadyExistsException, |
||||
AmbiguousObjectException, RefNotFoundException, |
||||
InvalidRefNameException { |
||||
CreateBranchCommand cmd = actGit.branchCreate(); |
||||
cmd.setName(name); |
||||
cmd.setForce(force); |
||||
cmd.setStartPoint(startPoint); |
||||
cmd.setUpstreamMode(mode); |
||||
return cmd.call(); |
||||
} |
||||
} |
@ -0,0 +1,365 @@
|
||||
/* |
||||
* Copyright (C) 2010, Mathias Kinzler <mathias.kinzler@sap.com> |
||||
* Copyright (C) 2010, Chris Aniszczyk <caniszczyk@gmail.com> |
||||
* and other copyright owners as documented in the project's IP log. |
||||
* |
||||
* This program and the accompanying materials are made available |
||||
* under the terms of the Eclipse Distribution License v1.0 which |
||||
* accompanies this distribution, is reproduced below, and is |
||||
* available at http://www.eclipse.org/org/documents/edl-v10.php
|
||||
* |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or |
||||
* without modification, are permitted provided that the following |
||||
* conditions are met: |
||||
* |
||||
* - Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* |
||||
* - Redistributions in binary form must reproduce the above |
||||
* copyright notice, this list of conditions and the following |
||||
* disclaimer in the documentation and/or other materials provided |
||||
* with the distribution. |
||||
* |
||||
* - Neither the name of the Eclipse Foundation, Inc. nor the |
||||
* names of its contributors may be used to endorse or promote |
||||
* products derived from this software without specific prior |
||||
* written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND |
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, |
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
package org.eclipse.jgit.api; |
||||
|
||||
import java.io.IOException; |
||||
import java.text.MessageFormat; |
||||
|
||||
import org.eclipse.jgit.JGitText; |
||||
import org.eclipse.jgit.api.errors.InvalidRefNameException; |
||||
import org.eclipse.jgit.api.errors.JGitInternalException; |
||||
import org.eclipse.jgit.api.errors.RefAlreadyExistsException; |
||||
import org.eclipse.jgit.api.errors.RefNotFoundException; |
||||
import org.eclipse.jgit.errors.AmbiguousObjectException; |
||||
import org.eclipse.jgit.lib.ConfigConstants; |
||||
import org.eclipse.jgit.lib.Constants; |
||||
import org.eclipse.jgit.lib.ObjectId; |
||||
import org.eclipse.jgit.lib.Ref; |
||||
import org.eclipse.jgit.lib.RefUpdate; |
||||
import org.eclipse.jgit.lib.Repository; |
||||
import org.eclipse.jgit.lib.StoredConfig; |
||||
import org.eclipse.jgit.lib.RefUpdate.Result; |
||||
import org.eclipse.jgit.revwalk.RevCommit; |
||||
import org.eclipse.jgit.revwalk.RevWalk; |
||||
|
||||
/** |
||||
* Used to create a local branch. |
||||
* |
||||
* @see <a |
||||
* href="http://www.kernel.org/pub/software/scm/git/docs/git-branch.html" |
||||
* >Git documentation about Branch</a> |
||||
*/ |
||||
public class CreateBranchCommand extends GitCommand<Ref> { |
||||
private String name; |
||||
|
||||
private boolean force = false; |
||||
|
||||
private SetupUpstreamMode upstreamMode; |
||||
|
||||
private String startPoint; |
||||
|
||||
private RevCommit startCommit; |
||||
|
||||
/** |
||||
* The modes available for setting up the upstream configuration |
||||
* (corresponding to the --set-upstream, --track, --no-track options |
||||
* |
||||
*/ |
||||
public enum SetupUpstreamMode { |
||||
/** |
||||
* Corresponds to the --track option |
||||
*/ |
||||
TRACK, |
||||
/** |
||||
* Corresponds to the --no-track option |
||||
*/ |
||||
NOTRACK, |
||||
/** |
||||
* Corresponds to the --set-upstream option |
||||
*/ |
||||
SET_UPSTREAM; |
||||
} |
||||
|
||||
/** |
||||
* @param repo |
||||
*/ |
||||
protected CreateBranchCommand(Repository repo) { |
||||
super(repo); |
||||
} |
||||
|
||||
/** |
||||
* @throws RefAlreadyExistsException |
||||
* when trying to create (without force) a branch with a name |
||||
* that already exists |
||||
* @throws RefNotFoundException |
||||
* if the start point can not be found |
||||
* @throws AmbiguousObjectException |
||||
* if the start point is ambiguous |
||||
* @throws InvalidRefNameException |
||||
* if the provided name is <code>null</code> or otherwise |
||||
* invalid |
||||
* @return the newly created branch |
||||
*/ |
||||
public Ref call() throws JGitInternalException, RefAlreadyExistsException, |
||||
RefNotFoundException, AmbiguousObjectException, |
||||
InvalidRefNameException { |
||||
checkCallable(); |
||||
processOptions(); |
||||
try { |
||||
boolean exists = repo.getRef(name) != null; |
||||
if (!force && exists) |
||||
throw new RefAlreadyExistsException(MessageFormat.format( |
||||
JGitText.get().refAlreadExists, name)); |
||||
|
||||
ObjectId startAt = getStartPoint(); |
||||
String startPointFullName = null; |
||||
if (startPoint != null) { |
||||
Ref baseRef = repo.getRef(startPoint); |
||||
if (baseRef != null) |
||||
startPointFullName = baseRef.getName(); |
||||
} |
||||
|
||||
// determine whether we are based on a commit,
|
||||
// a branch, or a tag and compose the reflog message
|
||||
String refLogMessage; |
||||
String baseBranch = ""; |
||||
if (startPointFullName == null) { |
||||
String baseCommit; |
||||
if (startCommit != null) |
||||
baseCommit = startCommit.getShortMessage(); |
||||
else { |
||||
RevCommit commit = new RevWalk(repo).parseCommit(repo |
||||
.resolve(startPoint)); |
||||
baseCommit = commit.getShortMessage(); |
||||
} |
||||
if (exists) |
||||
refLogMessage = "branch: Reset start-point to commit " |
||||
+ baseCommit; |
||||
else |
||||
refLogMessage = "branch: Created from commit " + baseCommit; |
||||
|
||||
} else if (startPointFullName.startsWith(Constants.R_HEADS) |
||||
|| startPointFullName.startsWith(Constants.R_REMOTES)) { |
||||
baseBranch = startPointFullName; |
||||
if (exists) |
||||
refLogMessage = "branch: Reset start-point to branch " |
||||
+ startPointFullName; // TODO
|
||||
else |
||||
refLogMessage = "branch: Created from branch " + baseBranch; |
||||
} else { |
||||
if (exists) |
||||
refLogMessage = "branch: Reset start-point to tag " |
||||
+ startPointFullName; |
||||
else |
||||
refLogMessage = "branch: Created from tag " |
||||
+ startPointFullName; |
||||
} |
||||
|
||||
RefUpdate updateRef = repo.updateRef(Constants.R_HEADS + name); |
||||
updateRef.setNewObjectId(startAt); |
||||
updateRef.setRefLogMessage(refLogMessage, false); |
||||
Result updateResult; |
||||
if (exists && force) |
||||
updateResult = updateRef.forceUpdate(); |
||||
else |
||||
updateResult = updateRef.update(); |
||||
|
||||
setCallable(false); |
||||
|
||||
boolean ok = false; |
||||
switch (updateResult) { |
||||
case NEW: |
||||
ok = !exists; |
||||
break; |
||||
case NO_CHANGE: |
||||
case FAST_FORWARD: |
||||
case FORCED: |
||||
ok = exists; |
||||
break; |
||||
default: |
||||
break; |
||||
} |
||||
|
||||
if (!ok) |
||||
throw new JGitInternalException(MessageFormat.format(JGitText |
||||
.get().createBranchUnexpectedResult, updateResult |
||||
.name())); |
||||
|
||||
Ref result = repo.getRef(name); |
||||
if (result == null) |
||||
throw new JGitInternalException( |
||||
JGitText.get().createBranchFailedUnknownReason); |
||||
|
||||
if (baseBranch.length() == 0) { |
||||
return result; |
||||
} |
||||
|
||||
// if we are based on another branch, see
|
||||
// if we need to configure upstream configuration: first check
|
||||
// whether the setting was done explicitly
|
||||
boolean doConfigure; |
||||
if (upstreamMode == SetupUpstreamMode.SET_UPSTREAM |
||||
|| upstreamMode == SetupUpstreamMode.TRACK) |
||||
// explicitly set to configure
|
||||
doConfigure = true; |
||||
else if (upstreamMode == SetupUpstreamMode.NOTRACK) |
||||
// explicitly set to not configure
|
||||
doConfigure = false; |
||||
else { |
||||
// if there was no explicit setting, check the configuration
|
||||
String autosetupflag = repo.getConfig().getString( |
||||
ConfigConstants.CONFIG_BRANCH_SECTION, null, |
||||
ConfigConstants.CONFIG_KEY_AUTOSETUPMERGE); |
||||
if ("false".equals(autosetupflag)) { |
||||
doConfigure = false; |
||||
} else if ("always".equals(autosetupflag)) { |
||||
doConfigure = true; |
||||
} else { |
||||
// in this case, the default is to configure
|
||||
// only in case the base branch was a remote branch
|
||||
doConfigure = baseBranch.startsWith(Constants.R_REMOTES); |
||||
} |
||||
} |
||||
|
||||
if (doConfigure) { |
||||
StoredConfig config = repo.getConfig(); |
||||
String[] tokens = baseBranch.split("/", 4); |
||||
boolean isRemote = tokens[1].equals("remotes"); |
||||
if (isRemote) { |
||||
// refs/remotes/<remote name>/<branch>
|
||||
String remoteName = tokens[2]; |
||||
String branchName = tokens[3]; |
||||
config |
||||
.setString(ConfigConstants.CONFIG_BRANCH_SECTION, |
||||
name, ConfigConstants.CONFIG_KEY_REMOTE, |
||||
remoteName); |
||||
config.setString(ConfigConstants.CONFIG_BRANCH_SECTION, |
||||
name, ConfigConstants.CONFIG_KEY_MERGE, |
||||
Constants.R_HEADS + branchName); |
||||
} else { |
||||
// set "." as remote
|
||||
config.setString(ConfigConstants.CONFIG_BRANCH_SECTION, |
||||
name, ConfigConstants.CONFIG_KEY_REMOTE, "."); |
||||
config.setString(ConfigConstants.CONFIG_BRANCH_SECTION, |
||||
name, ConfigConstants.CONFIG_KEY_MERGE, baseBranch); |
||||
} |
||||
config.save(); |
||||
} |
||||
return result; |
||||
} catch (AmbiguousObjectException e) { |
||||
throw e; |
||||
} catch (IOException ioe) { |
||||
throw new JGitInternalException(ioe.getMessage(), ioe); |
||||
} |
||||
} |
||||
|
||||
private ObjectId getStartPoint() throws AmbiguousObjectException, |
||||
RefNotFoundException, IOException { |
||||
if (startCommit != null) |
||||
return startCommit.getId(); |
||||
ObjectId result = null; |
||||
try { |
||||
if (startPoint == null) |
||||
result = repo.resolve(Constants.HEAD); |
||||
result = repo.resolve(startPoint); |
||||
} catch (AmbiguousObjectException e) { |
||||
throw e; |
||||
} |
||||
if (result == null) |
||||
throw new RefNotFoundException(MessageFormat.format( |
||||
JGitText.get().refNotResolved, |
||||
startPoint != null ? startPoint : Constants.HEAD)); |
||||
return result; |
||||
} |
||||
|
||||
private void processOptions() throws InvalidRefNameException { |
||||
if (name == null |
||||
|| !Repository.isValidRefName(Constants.R_HEADS + name)) |
||||
throw new InvalidRefNameException(MessageFormat.format(JGitText |
||||
.get().branchNameInvalid, name == null ? "<null>" : name)); |
||||
} |
||||
|
||||
/** |
||||
* @param name |
||||
* the name of the new branch |
||||
* @return this instance |
||||
*/ |
||||
public CreateBranchCommand setName(String name) { |
||||
checkCallable(); |
||||
this.name = name; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* @param force |
||||
* if <code>true</code> and the branch with the given name |
||||
* already exists, the start-point of an existing branch will be |
||||
* set to a new start-point; if false, the existing branch will |
||||
* not be changed |
||||
* @return this instance |
||||
*/ |
||||
public CreateBranchCommand setForce(boolean force) { |
||||
checkCallable(); |
||||
this.force = force; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* @param startPoint |
||||
* corresponds to the start-point option; if <code>null</code>, |
||||
* the current HEAD will be used |
||||
* @return this instance |
||||
*/ |
||||
public CreateBranchCommand setStartPoint(String startPoint) { |
||||
checkCallable(); |
||||
this.startPoint = startPoint; |
||||
this.startCommit = null; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* @param startPoint |
||||
* corresponds to the start-point option; if <code>null</code>, |
||||
* the current HEAD will be used |
||||
* @return this instance |
||||
*/ |
||||
public CreateBranchCommand setStartPoint(RevCommit startPoint) { |
||||
checkCallable(); |
||||
this.startCommit = startPoint; |
||||
this.startPoint = null; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* @param mode |
||||
* corresponds to the --track/--no-track/--set-upstream options; |
||||
* may be <code>null</code> |
||||
* @return this instance |
||||
*/ |
||||
public CreateBranchCommand setUpstreamMode(SetupUpstreamMode mode) { |
||||
checkCallable(); |
||||
this.upstreamMode = mode; |
||||
return this; |
||||
} |
||||
} |
@ -0,0 +1,197 @@
|
||||
/* |
||||
* Copyright (C) 2010, Mathias Kinzler <mathias.kinzler@sap.com> |
||||
* Copyright (C) 2010, Chris Aniszczyk <caniszczyk@gmail.com> |
||||
* and other copyright owners as documented in the project's IP log. |
||||
* |
||||
* This program and the accompanying materials are made available |
||||
* under the terms of the Eclipse Distribution License v1.0 which |
||||
* accompanies this distribution, is reproduced below, and is |
||||
* available at http://www.eclipse.org/org/documents/edl-v10.php
|
||||
* |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or |
||||
* without modification, are permitted provided that the following |
||||
* conditions are met: |
||||
* |
||||
* - Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* |
||||
* - Redistributions in binary form must reproduce the above |
||||
* copyright notice, this list of conditions and the following |
||||
* disclaimer in the documentation and/or other materials provided |
||||
* with the distribution. |
||||
* |
||||
* - Neither the name of the Eclipse Foundation, Inc. nor the |
||||
* names of its contributors may be used to endorse or promote |
||||
* products derived from this software without specific prior |
||||
* written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND |
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, |
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
package org.eclipse.jgit.api; |
||||
|
||||
import java.io.IOException; |
||||
import java.text.MessageFormat; |
||||
import java.util.ArrayList; |
||||
import java.util.HashSet; |
||||
import java.util.List; |
||||
import java.util.Set; |
||||
|
||||
import org.eclipse.jgit.JGitText; |
||||
import org.eclipse.jgit.api.errors.CannotDeleteCurrentBranchException; |
||||
import org.eclipse.jgit.api.errors.JGitInternalException; |
||||
import org.eclipse.jgit.api.errors.NotMergedException; |
||||
import org.eclipse.jgit.lib.ConfigConstants; |
||||
import org.eclipse.jgit.lib.Constants; |
||||
import org.eclipse.jgit.lib.Ref; |
||||
import org.eclipse.jgit.lib.RefUpdate; |
||||
import org.eclipse.jgit.lib.Repository; |
||||
import org.eclipse.jgit.lib.RefUpdate.Result; |
||||
import org.eclipse.jgit.revwalk.RevCommit; |
||||
import org.eclipse.jgit.revwalk.RevWalk; |
||||
|
||||
/** |
||||
* Used to delete one or several branches. |
||||
* |
||||
* The result of {@link #call()} is a list with the (full) names of the deleted |
||||
* branches. |
||||
* |
||||
* Note that we don't have a setter corresponding to the -r option; remote |
||||
* tracking branches are simply deleted just like local branches. |
||||
* |
||||
* @see <a |
||||
* href="http://www.kernel.org/pub/software/scm/git/docs/git-branch.html" |
||||
* >Git documentation about Branch</a> |
||||
*/ |
||||
public class DeleteBranchCommand extends GitCommand<List<String>> { |
||||
private final Set<String> branchNames = new HashSet<String>(); |
||||
|
||||
private boolean force; |
||||
|
||||
/** |
||||
* @param repo |
||||
*/ |
||||
protected DeleteBranchCommand(Repository repo) { |
||||
super(repo); |
||||
} |
||||
|
||||
/** |
||||
* @throws NotMergedException |
||||
* when trying to delete a branch which has not been merged into |
||||
* the currently checked out branch without force |
||||
* @return the list with the (full) names of the deleted branches |
||||
*/ |
||||
public List<String> call() throws JGitInternalException, |
||||
NotMergedException, CannotDeleteCurrentBranchException { |
||||
checkCallable(); |
||||
List<String> result = new ArrayList<String>(); |
||||
if (branchNames.isEmpty()) |
||||
return result; |
||||
try { |
||||
String currentBranch = repo.getFullBranch(); |
||||
if (!force) { |
||||
// check if the branches to be deleted
|
||||
// are all merged into the current branch
|
||||
RevWalk walk = new RevWalk(repo); |
||||
RevCommit tip = walk.parseCommit(repo.resolve(Constants.HEAD)); |
||||
for (String branchName : branchNames) { |
||||
if (branchName == null) |
||||
continue; |
||||
Ref currentRef = repo.getRef(branchName); |
||||
if (currentRef == null) |
||||
continue; |
||||
|
||||
RevCommit base = walk.parseCommit(repo.resolve(branchName)); |
||||
if (!walk.isMergedInto(base, tip)) { |
||||
throw new NotMergedException(); |
||||
} |
||||
} |
||||
} |
||||
setCallable(false); |
||||
for (String branchName : branchNames) { |
||||
if (branchName == null) |
||||
continue; |
||||
Ref currentRef = repo.getRef(branchName); |
||||
if (currentRef == null) |
||||
continue; |
||||
if (currentRef.getName().equals(currentBranch)) |
||||
throw new CannotDeleteCurrentBranchException( |
||||
MessageFormat |
||||
.format( |
||||
JGitText.get().cannotDeleteCheckedOutBranch, |
||||
branchName)); |
||||
RefUpdate update = repo.updateRef(currentRef.getName()); |
||||
update.setRefLogMessage("branch deleted", false); |
||||
update.setForceUpdate(true); |
||||
Result deleteResult = update.delete(); |
||||
|
||||
boolean ok = true; |
||||
switch (deleteResult) { |
||||
case IO_FAILURE: |
||||
case LOCK_FAILURE: |
||||
case REJECTED: |
||||
ok = false; |
||||
break; |
||||
default: |
||||
break; |
||||
} |
||||
|
||||
if (ok) { |
||||
result.add(currentRef.getName()); |
||||
// remove upstream configuration if any
|
||||
repo.getConfig().unsetSection( |
||||
ConfigConstants.CONFIG_BRANCH_SECTION, branchName); |
||||
repo.getConfig().save(); |
||||
} else |
||||
throw new JGitInternalException(MessageFormat.format( |
||||
JGitText.get().deleteBranchUnexpectedResult, |
||||
deleteResult.name())); |
||||
} |
||||
return result; |
||||
} catch (IOException ioe) { |
||||
throw new JGitInternalException(ioe.getMessage(), ioe); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* @param branchnames |
||||
* the names of the branches to delete; if not set, this will do |
||||
* nothing; invalid branch names will simply be ignored |
||||
* @return this instance |
||||
*/ |
||||
public DeleteBranchCommand setBranchNames(String... branchnames) { |
||||
checkCallable(); |
||||
this.branchNames.clear(); |
||||
for (String branch : branchnames) |
||||
this.branchNames.add(branch); |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* @param force |
||||
* <code>true</code> corresponds to the -D option, |
||||
* <code>false</code> to the -d option (default) <br> |
||||
* if <code>false</code> a check will be performed whether the |
||||
* branch to be deleted is already merged into the current branch |
||||
* and deletion will be refused in this case |
||||
* @return this instance |
||||
*/ |
||||
public DeleteBranchCommand setForce(boolean force) { |
||||
checkCallable(); |
||||
this.force = force; |
||||
return this; |
||||
} |
||||
} |
@ -0,0 +1,132 @@
|
||||
/* |
||||
* Copyright (C) 2010, Mathias Kinzler <mathias.kinzler@sap.com> |
||||
* Copyright (C) 2010, Chris Aniszczyk <caniszczyk@gmail.com> |
||||
* and other copyright owners as documented in the project's IP log. |
||||
* |
||||
* This program and the accompanying materials are made available |
||||
* under the terms of the Eclipse Distribution License v1.0 which |
||||
* accompanies this distribution, is reproduced below, and is |
||||
* available at http://www.eclipse.org/org/documents/edl-v10.php
|
||||
* |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or |
||||
* without modification, are permitted provided that the following |
||||
* conditions are met: |
||||
* |
||||
* - Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* |
||||
* - Redistributions in binary form must reproduce the above |
||||
* copyright notice, this list of conditions and the following |
||||
* disclaimer in the documentation and/or other materials provided |
||||
* with the distribution. |
||||
* |
||||
* - Neither the name of the Eclipse Foundation, Inc. nor the |
||||
* names of its contributors may be used to endorse or promote |
||||
* products derived from this software without specific prior |
||||
* written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND |
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, |
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
package org.eclipse.jgit.api; |
||||
|
||||
import java.io.IOException; |
||||
import java.util.ArrayList; |
||||
import java.util.Collections; |
||||
import java.util.Comparator; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
import org.eclipse.jgit.api.errors.JGitInternalException; |
||||
import org.eclipse.jgit.lib.Constants; |
||||
import org.eclipse.jgit.lib.Ref; |
||||
import org.eclipse.jgit.lib.Repository; |
||||
|
||||
/** |
||||
* Used to obtain a list of branches. |
||||
* |
||||
* @see <a |
||||
* href="http://www.kernel.org/pub/software/scm/git/docs/git-branch.html" |
||||
* >Git documentation about Branch</a> |
||||
*/ |
||||
public class ListBranchCommand extends GitCommand<List<Ref>> { |
||||
private ListMode listMode; |
||||
|
||||
/** |
||||
* The modes available for listing branches (corresponding to the -r and -a |
||||
* options) |
||||
*/ |
||||
public enum ListMode { |
||||
/** |
||||
* Corresponds to the -a option (all branches) |
||||
*/ |
||||
ALL, |
||||
/** |
||||
* Corresponds to the -r option (remote branches only) |
||||
*/ |
||||
REMOTE; |
||||
} |
||||
|
||||
/** |
||||
* @param repo |
||||
*/ |
||||
protected ListBranchCommand(Repository repo) { |
||||
super(repo); |
||||
} |
||||
|
||||
/** |
||||
* @throws JGitInternalException |
||||
* upon internal failure |
||||
*/ |
||||
public List<Ref> call() throws JGitInternalException { |
||||
checkCallable(); |
||||
Map<String, Ref> refList; |
||||
try { |
||||
if (listMode == null) { |
||||
refList = repo.getRefDatabase().getRefs(Constants.R_HEADS); |
||||
} else if (listMode == ListMode.REMOTE) { |
||||
refList = repo.getRefDatabase().getRefs(Constants.R_REMOTES); |
||||
} else { |
||||
refList = repo.getRefDatabase().getRefs(Constants.R_HEADS); |
||||
refList.putAll(repo.getRefDatabase().getRefs( |
||||
Constants.R_REMOTES)); |
||||
} |
||||
} 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()); |
||||
} |
||||
}); |
||||
setCallable(false); |
||||
return resultRefs; |
||||
} |
||||
|
||||
/** |
||||
* @param listMode |
||||
* optional: corresponds to the -r/-a options; by default, only |
||||
* local branches will be listed |
||||
* @return this instance |
||||
*/ |
||||
public ListBranchCommand setListMode(ListMode listMode) { |
||||
checkCallable(); |
||||
this.listMode = listMode; |
||||
return this; |
||||
} |
||||
} |
@ -0,0 +1,207 @@
|
||||
/* |
||||
* Copyright (C) 2010, Mathias Kinzler <mathias.kinzler@sap.com> |
||||
* Copyright (C) 2010, Chris Aniszczyk <caniszczyk@gmail.com> |
||||
* and other copyright owners as documented in the project's IP log. |
||||
* |
||||
* This program and the accompanying materials are made available |
||||
* under the terms of the Eclipse Distribution License v1.0 which |
||||
* accompanies this distribution, is reproduced below, and is |
||||
* available at http://www.eclipse.org/org/documents/edl-v10.php
|
||||
* |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or |
||||
* without modification, are permitted provided that the following |
||||
* conditions are met: |
||||
* |
||||
* - Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* |
||||
* - Redistributions in binary form must reproduce the above |
||||
* copyright notice, this list of conditions and the following |
||||
* disclaimer in the documentation and/or other materials provided |
||||
* with the distribution. |
||||
* |
||||
* - Neither the name of the Eclipse Foundation, Inc. nor the |
||||
* names of its contributors may be used to endorse or promote |
||||
* products derived from this software without specific prior |
||||
* written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND |
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, |
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
package org.eclipse.jgit.api; |
||||
|
||||
import java.io.IOException; |
||||
import java.text.MessageFormat; |
||||
|
||||
import org.eclipse.jgit.JGitText; |
||||
import org.eclipse.jgit.api.errors.DetachedHeadException; |
||||
import org.eclipse.jgit.api.errors.InvalidRefNameException; |
||||
import org.eclipse.jgit.api.errors.JGitInternalException; |
||||
import org.eclipse.jgit.api.errors.RefAlreadyExistsException; |
||||
import org.eclipse.jgit.api.errors.RefNotFoundException; |
||||
import org.eclipse.jgit.lib.ConfigConstants; |
||||
import org.eclipse.jgit.lib.Constants; |
||||
import org.eclipse.jgit.lib.ObjectId; |
||||
import org.eclipse.jgit.lib.Ref; |
||||
import org.eclipse.jgit.lib.RefRename; |
||||
import org.eclipse.jgit.lib.Repository; |
||||
import org.eclipse.jgit.lib.RefUpdate.Result; |
||||
|
||||
/** |
||||
* Used to rename branches. |
||||
* |
||||
* @see <a |
||||
* href="http://www.kernel.org/pub/software/scm/git/docs/git-branch.html" |
||||
* >Git documentation about Branch</a> |
||||
*/ |
||||
public class RenameBranchCommand extends GitCommand<Ref> { |
||||
private String oldName; |
||||
|
||||
private String newName; |
||||
|
||||
/** |
||||
* @param repo |
||||
*/ |
||||
protected RenameBranchCommand(Repository repo) { |
||||
super(repo); |
||||
} |
||||
|
||||
/** |
||||
* @throws RefNotFoundException |
||||
* if the old branch can not be found (branch with provided old |
||||
* name does not exist or old name resolves to a tag) |
||||
* @throws InvalidRefNameException |
||||
* if the provided new name is <code>null</code> or otherwise |
||||
* invalid |
||||
* @throws RefAlreadyExistsException |
||||
* if a branch with the new name already exists |
||||
* @throws DetachedHeadException |
||||
* if rename is tried without specifying the old name and HEAD |
||||
* is detached |
||||
*/ |
||||
public Ref call() throws RefNotFoundException, InvalidRefNameException, |
||||
RefAlreadyExistsException, DetachedHeadException { |
||||
checkCallable(); |
||||
|
||||
if (newName == null) |
||||
throw new InvalidRefNameException(MessageFormat.format(JGitText |
||||
.get().branchNameInvalid, "<null>")); |
||||
|
||||
try { |
||||
String fullOldName; |
||||
String fullNewName; |
||||
if (repo.getRef(newName) != null) |
||||
throw new RefAlreadyExistsException(MessageFormat.format( |
||||
JGitText.get().refAlreadExists, newName)); |
||||
if (oldName != null) { |
||||
Ref ref = repo.getRef(oldName); |
||||
if (ref == null) |
||||
throw new RefNotFoundException(MessageFormat.format( |
||||
JGitText.get().refNotResolved, oldName)); |
||||
if (ref.getName().startsWith(Constants.R_TAGS)) |
||||
throw new RefNotFoundException(MessageFormat.format( |
||||
JGitText.get().renameBranchFailedBecauseTag, |
||||
oldName)); |
||||
fullOldName = ref.getName(); |
||||
} else { |
||||
fullOldName = repo.getFullBranch(); |
||||
if (ObjectId.isId(fullOldName)) |
||||
throw new DetachedHeadException(); |
||||
} |
||||
|
||||
if (fullOldName.startsWith(Constants.R_REMOTES)) |
||||
fullNewName = Constants.R_REMOTES + newName; |
||||
else { |
||||
fullNewName = Constants.R_HEADS + newName; |
||||
} |
||||
|
||||
if (!Repository.isValidRefName(fullNewName)) |
||||
throw new InvalidRefNameException(MessageFormat.format(JGitText |
||||
.get().branchNameInvalid, fullNewName)); |
||||
|
||||
RefRename rename = repo.renameRef(fullOldName, fullNewName); |
||||
Result renameResult = rename.rename(); |
||||
|
||||
setCallable(false); |
||||
|
||||
boolean ok = Result.RENAMED == renameResult; |
||||
|
||||
if (ok) { |
||||
if (fullNewName.startsWith(Constants.R_HEADS)) { |
||||
// move the upstream configuration over to the new branch
|
||||
String shortOldName = fullOldName |
||||
.substring(Constants.R_HEADS.length()); |
||||
String oldRemote = repo.getConfig().getString( |
||||
ConfigConstants.CONFIG_BRANCH_SECTION, |
||||
shortOldName, ConfigConstants.CONFIG_KEY_REMOTE); |
||||
if (oldRemote != null) { |
||||
repo.getConfig().setString( |
||||
ConfigConstants.CONFIG_BRANCH_SECTION, newName, |
||||
ConfigConstants.CONFIG_KEY_REMOTE, oldRemote); |
||||
} |
||||
String oldMerge = repo.getConfig().getString( |
||||
ConfigConstants.CONFIG_BRANCH_SECTION, |
||||
shortOldName, ConfigConstants.CONFIG_KEY_MERGE); |
||||
if (oldMerge != null) { |
||||
repo.getConfig().setString( |
||||
ConfigConstants.CONFIG_BRANCH_SECTION, newName, |
||||
ConfigConstants.CONFIG_KEY_MERGE, oldMerge); |
||||
} |
||||
repo.getConfig() |
||||
.unsetSection( |
||||
ConfigConstants.CONFIG_BRANCH_SECTION, |
||||
shortOldName); |
||||
repo.getConfig().save(); |
||||
} |
||||
|
||||
} else |
||||
throw new JGitInternalException(MessageFormat.format(JGitText |
||||
.get().renameBranchUnexpectedResult, renameResult |
||||
.name())); |
||||
|
||||
Ref resultRef = repo.getRef(newName); |
||||
if (resultRef == null) |
||||
throw new JGitInternalException( |
||||
JGitText.get().renameBranchFailedUnknownReason); |
||||
return resultRef; |
||||
} catch (IOException ioe) { |
||||
throw new JGitInternalException(ioe.getMessage(), ioe); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* @param newName |
||||
* the new name |
||||
* @return this instance |
||||
*/ |
||||
public RenameBranchCommand setNewName(String newName) { |
||||
checkCallable(); |
||||
this.newName = newName; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* @param oldName |
||||
* the name of the branch to rename; if not set, the currently |
||||
* checked out branch (if any) will be renamed |
||||
* @return this instance |
||||
*/ |
||||
public RenameBranchCommand setOldName(String oldName) { |
||||
checkCallable(); |
||||
this.oldName = oldName; |
||||
return this; |
||||
} |
||||
} |
@ -0,0 +1,53 @@
|
||||
/* |
||||
* Copyright (C) 2010,Mathias Kinzler <mathias.kinzler@sap.com> and |
||||
* other copyright owners as documented in the project's IP log. |
||||
* |
||||
* This program and the accompanying materials are made available under the |
||||
* terms of the Eclipse Distribution License v1.0 which accompanies this |
||||
* distribution, is reproduced below, and is available at |
||||
* http://www.eclipse.org/org/documents/edl-v10.php
|
||||
* |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* |
||||
* - Redistributions of source code must retain the above copyright notice, this |
||||
* list of conditions and the following disclaimer. |
||||
* |
||||
* - Redistributions in binary form must reproduce the above copyright notice, |
||||
* this list of conditions and the following disclaimer in the documentation |
||||
* and/or other materials provided with the distribution. |
||||
* |
||||
* - Neither the name of the Eclipse Foundation, Inc. nor the names of its |
||||
* contributors may be used to endorse or promote products derived from this |
||||
* software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
||||
* POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
package org.eclipse.jgit.api.errors; |
||||
|
||||
/** |
||||
* Thrown when trying to delete a branch which is currently checked out |
||||
*/ |
||||
public class CannotDeleteCurrentBranchException extends GitAPIException { |
||||
private static final long serialVersionUID = 1L; |
||||
|
||||
/** |
||||
* @param message |
||||
* the message |
||||
*/ |
||||
public CannotDeleteCurrentBranchException(String message) { |
||||
super(message); |
||||
} |
||||
} |
@ -0,0 +1,52 @@
|
||||
/* |
||||
* Copyright (C) 2010, Mathias Kinzler <mathias.kinzler@sap.com> and |
||||
* other copyright owners as documented in the project's IP log. |
||||
* |
||||
* This program and the accompanying materials are made available under the |
||||
* terms of the Eclipse Distribution License v1.0 which accompanies this |
||||
* distribution, is reproduced below, and is available at |
||||
* http://www.eclipse.org/org/documents/edl-v10.php
|
||||
* |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* |
||||
* - Redistributions of source code must retain the above copyright notice, this |
||||
* list of conditions and the following disclaimer. |
||||
* |
||||
* - Redistributions in binary form must reproduce the above copyright notice, |
||||
* this list of conditions and the following disclaimer in the documentation |
||||
* and/or other materials provided with the distribution. |
||||
* |
||||
* - Neither the name of the Eclipse Foundation, Inc. nor the names of its |
||||
* contributors may be used to endorse or promote products derived from this |
||||
* software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
||||
* POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
package org.eclipse.jgit.api.errors; |
||||
|
||||
/** |
||||
* Exception thrown when an invalid Ref name was encountered |
||||
*/ |
||||
public class InvalidRefNameException extends GitAPIException { |
||||
private static final long serialVersionUID = 1L; |
||||
|
||||
/** |
||||
* @param msg |
||||
*/ |
||||
public InvalidRefNameException(String msg) { |
||||
super(msg); |
||||
} |
||||
} |
@ -0,0 +1,54 @@
|
||||
/* |
||||
* Copyright (C) 2010,Mathias Kinzler <mathias.kinzler@sap.com> and |
||||
* other copyright owners as documented in the project's IP log. |
||||
* |
||||
* This program and the accompanying materials are made available under the |
||||
* terms of the Eclipse Distribution License v1.0 which accompanies this |
||||
* distribution, is reproduced below, and is available at |
||||
* http://www.eclipse.org/org/documents/edl-v10.php
|
||||
* |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* |
||||
* - Redistributions of source code must retain the above copyright notice, this |
||||
* list of conditions and the following disclaimer. |
||||
* |
||||
* - Redistributions in binary form must reproduce the above copyright notice, |
||||
* this list of conditions and the following disclaimer in the documentation |
||||
* and/or other materials provided with the distribution. |
||||
* |
||||
* - Neither the name of the Eclipse Foundation, Inc. nor the names of its |
||||
* contributors may be used to endorse or promote products derived from this |
||||
* software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
||||
* POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
package org.eclipse.jgit.api.errors; |
||||
|
||||
import org.eclipse.jgit.JGitText; |
||||
|
||||
/** |
||||
* Thrown when branch deletion fails due to unmerged data |
||||
*/ |
||||
public class NotMergedException extends GitAPIException { |
||||
private static final long serialVersionUID = 1L; |
||||
|
||||
/** |
||||
* The default constructor with a default message |
||||
*/ |
||||
public NotMergedException() { |
||||
super(JGitText.get().notMergedExceptionMessage); |
||||
} |
||||
} |
@ -0,0 +1,55 @@
|
||||
/* |
||||
* Copyright (C) 2010,Mathias Kinzler <mathias.kinzler@sap.com> and |
||||
* other copyright owners as documented in the project's IP log. |
||||
* |
||||
* This program and the accompanying materials are made available under the |
||||
* terms of the Eclipse Distribution License v1.0 which accompanies this |
||||
* distribution, is reproduced below, and is available at |
||||
* http://www.eclipse.org/org/documents/edl-v10.php
|
||||
* |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* |
||||
* - Redistributions of source code must retain the above copyright notice, this |
||||
* list of conditions and the following disclaimer. |
||||
* |
||||
* - Redistributions in binary form must reproduce the above copyright notice, |
||||
* this list of conditions and the following disclaimer in the documentation |
||||
* and/or other materials provided with the distribution. |
||||
* |
||||
* - Neither the name of the Eclipse Foundation, Inc. nor the names of its |
||||
* contributors may be used to endorse or promote products derived from this |
||||
* software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
||||
* POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
package org.eclipse.jgit.api.errors; |
||||
|
||||
import org.eclipse.jgit.lib.Ref; |
||||
|
||||
/** |
||||
* Thrown when trying to create a {@link Ref} with the same name as an exsiting |
||||
* one |
||||
*/ |
||||
public class RefAlreadyExistsException extends GitAPIException { |
||||
private static final long serialVersionUID = 1L; |
||||
|
||||
/** |
||||
* @param message |
||||
*/ |
||||
public RefAlreadyExistsException(String message) { |
||||
super(message); |
||||
} |
||||
} |
@ -0,0 +1,52 @@
|
||||
/* |
||||
* Copyright (C) 2010,Mathias Kinzler <mathias.kinzler@sap.com> and |
||||
* other copyright owners as documented in the project's IP log. |
||||
* |
||||
* This program and the accompanying materials are made available under the |
||||
* terms of the Eclipse Distribution License v1.0 which accompanies this |
||||
* distribution, is reproduced below, and is available at |
||||
* http://www.eclipse.org/org/documents/edl-v10.php
|
||||
* |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* |
||||
* - Redistributions of source code must retain the above copyright notice, this |
||||
* list of conditions and the following disclaimer. |
||||
* |
||||
* - Redistributions in binary form must reproduce the above copyright notice, |
||||
* this list of conditions and the following disclaimer in the documentation |
||||
* and/or other materials provided with the distribution. |
||||
* |
||||
* - Neither the name of the Eclipse Foundation, Inc. nor the names of its |
||||
* contributors may be used to endorse or promote products derived from this |
||||
* software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
||||
* POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
package org.eclipse.jgit.api.errors; |
||||
|
||||
/** |
||||
* Thrown when a Ref can not be resolved |
||||
*/ |
||||
public class RefNotFoundException extends GitAPIException { |
||||
private static final long serialVersionUID = 1L; |
||||
|
||||
/** |
||||
* @param message |
||||
*/ |
||||
public RefNotFoundException(String message) { |
||||
super(message); |
||||
} |
||||
} |
Loading…
Reference in new issue