Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/api/BranchCommandTest.java416
-rw-r--r--org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties11
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java11
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/api/CreateBranchCommand.java365
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteBranchCommand.java197
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/api/Git.java36
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/api/ListBranchCommand.java132
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/api/RenameBranchCommand.java207
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/api/errors/CannotDeleteCurrentBranchException.java53
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/api/errors/InvalidRefNameException.java52
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/api/errors/NotMergedException.java54
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/api/errors/RefAlreadyExistsException.java55
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/api/errors/RefNotFoundException.java52
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java2
14 files changed, 1643 insertions, 0 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
new file mode 100644
index 0000000000..07dc560030
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/BranchCommandTest.java
@@ -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();
+ }
+}
diff --git a/org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties b/org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties
index 2b0bf515d2..3cc144a75e 100644
--- a/org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties
+++ b/org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties
@@ -30,6 +30,7 @@ base64InputNotProperlyPadded=Base64 input not properly padded.
baseLengthIncorrect=base length incorrect
bareRepositoryNoWorkdirAndIndex=Bare Repository has neither a working tree, nor an index
blobNotFound=Blob not found: {0}
+branchNameInvalid=Branch name {0} is not allowed
blobNotFoundForPath=Blob not found: {0} for path: {1}
cannotBeCombined=Cannot be combined.
cannotCombineTreeFilterWithRevFilter=Cannot combine TreeFilter {0} with RefFilter {1}.
@@ -40,6 +41,7 @@ cannotConvertScriptToText=Cannot convert script to text
cannotCreateConfig=cannot create config
cannotCreateDirectory=Cannot create directory {0}
cannotCreateHEAD=cannot create HEAD
+cannotDeleteCheckedOutBranch=Branch {0} is checked out and can not be deleted
cannotDeleteFile=Cannot delete file: {0}
cannotDeleteStaleTrackingRef2=Cannot delete stale tracking ref {0}: {1}
cannotDeleteStaleTrackingRef=Cannot delete stale tracking ref {0}
@@ -118,8 +120,11 @@ couldNotRenameTemporaryIndexFileToIndex=Could not rename temporary index file to
couldNotURLEncodeToUTF8=Could not URL encode to UTF-8
couldNotWriteFile=Could not write file {0}
countingObjects=Counting objects
+createBranchFailedUnknownReason=Create branch failed for unknown reason
+createBranchUnexpectedResult=Create branch returned unexpected result {0}
creatingDeltasIsNotImplemented=creating deltas is not implemented
daemonAlreadyRunning=Daemon already running
+deleteBranchUnexpectedResult=Delete branch returned unexpected result {0}
deletingNotSupported=Deleting {0} not supported.
destinationIsNotAWildcard=Destination is not a wildcard.
detachedHeadDetected=HEAD is detached
@@ -277,6 +282,7 @@ notFound=not found.
notValid={0} not valid
nothingToFetch=Nothing to fetch.
nothingToPush=Nothing to push.
+notMergedExceptionMessage=Branch was not deleted as it has not been merged yet; use the force option to delete it anyway
objectAtHasBadZlibStream=Object at {0} in {1} has bad zlib stream
objectAtPathDoesNotHaveId=Object at path "{0}" does not have an id assigned. All object ids must be assigned prior to writing a tree.
objectIsCorrupt=Object {0} is corrupt: {1}
@@ -317,6 +323,8 @@ rawLogMessageDoesNotParseAsLogEntry=Raw log message does not parse as log entry
readTimedOut=Read timed out
readingObjectsFromLocalRepositoryFailed=reading objects from local repository failed: {0}
receivingObjects=Receiving objects
+refAlreadExists=Ref {0} already exists
+refNotResolved=Ref {0} can not be resolved
refUpdateReturnCodeWas=RefUpdate return code was: {0}
reflogsNotYetSupportedByRevisionParser=reflogs not yet supported by revision parser
remoteConfigHasNoURIAssociated=Remote config "{0}" has no URIs associated
@@ -324,6 +332,9 @@ remoteDoesNotHaveSpec=Remote does not have {0} available for fetch.
remoteDoesNotSupportSmartHTTPPush=remote does not support smart HTTP push
remoteHungUpUnexpectedly=remote hung up unexpectedly
remoteNameCantBeNull=Remote name can't be null.
+renameBranchFailedBecauseTag=Can not rename as Ref {0} is a tag
+renameBranchFailedUnknownReason=Rename failed with unknown reason
+renameBranchUnexpectedResult=Unexpected rename result {0}
renamesAlreadyFound=Renames have already been found.
renamesBreakingModifies=Breaking apart modified file pairs
renamesFindingByContent=Finding renames by content similarity
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java b/org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java
index 6019b6a5d4..93b9700395 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java
@@ -91,6 +91,7 @@ public class JGitText extends TranslationBundle {
/***/ public String bareRepositoryNoWorkdirAndIndex;
/***/ public String blobNotFound;
/***/ public String blobNotFoundForPath;
+ /***/ public String branchNameInvalid;
/***/ public String cannotBeCombined;
/***/ public String cannotCombineTreeFilterWithRevFilter;
/***/ public String cannotCommitOnARepoWithState;
@@ -100,6 +101,7 @@ public class JGitText extends TranslationBundle {
/***/ public String cannotCreateConfig;
/***/ public String cannotCreateDirectory;
/***/ public String cannotCreateHEAD;
+ /***/ public String cannotDeleteCheckedOutBranch;
/***/ public String cannotDeleteFile;
/***/ public String cannotDeleteStaleTrackingRef2;
/***/ public String cannotDeleteStaleTrackingRef;
@@ -178,8 +180,11 @@ public class JGitText extends TranslationBundle {
/***/ public String couldNotURLEncodeToUTF8;
/***/ public String couldNotWriteFile;
/***/ public String countingObjects;
+ /***/ public String createBranchFailedUnknownReason;
+ /***/ public String createBranchUnexpectedResult;
/***/ public String creatingDeltasIsNotImplemented;
/***/ public String daemonAlreadyRunning;
+ /***/ public String deleteBranchUnexpectedResult;
/***/ public String deletingNotSupported;
/***/ public String destinationIsNotAWildcard;
/***/ public String detachedHeadDetected;
@@ -337,6 +342,7 @@ public class JGitText extends TranslationBundle {
/***/ public String notValid;
/***/ public String nothingToFetch;
/***/ public String nothingToPush;
+ /***/ public String notMergedExceptionMessage;
/***/ public String objectAtHasBadZlibStream;
/***/ public String objectAtPathDoesNotHaveId;
/***/ public String objectIsCorrupt;
@@ -377,6 +383,8 @@ public class JGitText extends TranslationBundle {
/***/ public String readTimedOut;
/***/ public String readingObjectsFromLocalRepositoryFailed;
/***/ public String receivingObjects;
+ /***/ public String refAlreadExists;
+ /***/ public String refNotResolved;
/***/ public String refUpdateReturnCodeWas;
/***/ public String reflogsNotYetSupportedByRevisionParser;
/***/ public String remoteConfigHasNoURIAssociated;
@@ -384,6 +392,9 @@ public class JGitText extends TranslationBundle {
/***/ public String remoteDoesNotSupportSmartHTTPPush;
/***/ public String remoteHungUpUnexpectedly;
/***/ public String remoteNameCantBeNull;
+ /***/ public String renameBranchFailedBecauseTag;
+ /***/ public String renameBranchFailedUnknownReason;
+ /***/ public String renameBranchUnexpectedResult;
/***/ public String renamesAlreadyFound;
/***/ public String renamesBreakingModifies;
/***/ public String renamesFindingByContent;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CreateBranchCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CreateBranchCommand.java
new file mode 100644
index 0000000000..4c584c33bd
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CreateBranchCommand.java
@@ -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;
+ }
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteBranchCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteBranchCommand.java
new file mode 100644
index 0000000000..c0d95f3f5c
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteBranchCommand.java
@@ -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;
+ }
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/Git.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/Git.java
index 493019a152..eef5ab98d4 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/Git.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/Git.java
@@ -143,6 +143,42 @@ public class Git {
}
/**
+ * Returns a command object used to create branches
+ *
+ * @return a {@link CreateBranchCommand}
+ */
+ public CreateBranchCommand branchCreate() {
+ return new CreateBranchCommand(repo);
+ }
+
+ /**
+ * Returns a command object used to delete branches
+ *
+ * @return a {@link DeleteBranchCommand}
+ */
+ public DeleteBranchCommand branchDelete() {
+ return new DeleteBranchCommand(repo);
+ }
+
+ /**
+ * Returns a command object used to list branches
+ *
+ * @return a {@link ListBranchCommand}
+ */
+ public ListBranchCommand branchList() {
+ return new ListBranchCommand(repo);
+ }
+
+ /**
+ * Returns a command object used to rename branches
+ *
+ * @return a {@link RenameBranchCommand}
+ */
+ public RenameBranchCommand branchRename() {
+ return new RenameBranchCommand(repo);
+ }
+
+ /**
* Returns a command object to execute a {@code Add} command
*
* @see <a
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ListBranchCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ListBranchCommand.java
new file mode 100644
index 0000000000..8329fca569
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ListBranchCommand.java
@@ -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;
+ }
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/RenameBranchCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/RenameBranchCommand.java
new file mode 100644
index 0000000000..4654981329
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/RenameBranchCommand.java
@@ -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;
+ }
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/CannotDeleteCurrentBranchException.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/CannotDeleteCurrentBranchException.java
new file mode 100644
index 0000000000..76d773229d
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/CannotDeleteCurrentBranchException.java
@@ -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);
+ }
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/InvalidRefNameException.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/InvalidRefNameException.java
new file mode 100644
index 0000000000..139c41cd5f
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/InvalidRefNameException.java
@@ -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);
+ }
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/NotMergedException.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/NotMergedException.java
new file mode 100644
index 0000000000..917c6355f7
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/NotMergedException.java
@@ -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);
+ }
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/RefAlreadyExistsException.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/RefAlreadyExistsException.java
new file mode 100644
index 0000000000..5e3ebf8d82
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/RefAlreadyExistsException.java
@@ -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);
+ }
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/RefNotFoundException.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/RefNotFoundException.java
new file mode 100644
index 0000000000..c8d96a0263
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/RefNotFoundException.java
@@ -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);
+ }
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
index e63f4e9d08..4ca11d0faf 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
@@ -87,4 +87,6 @@ public class ConfigConstants {
/** The "url" key */
public static final String CONFIG_KEY_URL = "url";
+ /** The "autosetupmerge" key */
+ public static final String CONFIG_KEY_AUTOSETUPMERGE = "autosetupmerge";
}

Back to the top