diff options
| author | Mathias Kinzler | 2010-12-20 09:35:10 +0000 |
|---|---|---|
| committer | Chris Aniszczyk | 2010-12-20 15:30:40 +0000 |
| commit | 89a4dcf71ff3326aa6313b3a988b7721c3470858 (patch) | |
| tree | a5286f9b13d5d634f9bf2704f6a1996444a807c1 | |
| parent | 0c22243c4a59560529e7bd271094837c0fbf5295 (diff) | |
| download | jgit-89a4dcf71ff3326aa6313b3a988b7721c3470858.tar.gz jgit-89a4dcf71ff3326aa6313b3a988b7721c3470858.tar.xz jgit-89a4dcf71ff3326aa6313b3a988b7721c3470858.zip | |
Checkout: fix handling if name does not refer to a local branch
The CheckoutCommand does not handle names other than local branch
names properly; it must detach HEAD if such a name is encountered (for
example a commit ID or a remote tracking branch).
Change-Id: I5d55177f4029bcc34fc2649fd564b125a2929cc4
Signed-off-by: Mathias Kinzler <mathias.kinzler@sap.com>
Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
| -rw-r--r-- | org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CheckoutCommandTest.java | 19 | ||||
| -rw-r--r-- | org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java | 19 |
2 files changed, 31 insertions, 7 deletions
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CheckoutCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CheckoutCommandTest.java index cf78a0e563..1166464d5e 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CheckoutCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CheckoutCommandTest.java @@ -52,6 +52,7 @@ 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.Constants; +import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.RefUpdate; import org.eclipse.jgit.lib.RepositoryTestCase; import org.eclipse.jgit.revwalk.RevCommit; @@ -97,9 +98,12 @@ public class CheckoutCommandTest extends RepositoryTestCase { git.checkout().setName("test").call(); assertEquals("[Test.txt, mode:100644, content:Some change]", indexState(CONTENT)); - git.checkout().setName("master").call(); + Ref result = git.checkout().setName("master").call(); assertEquals("[Test.txt, mode:100644, content:Hello world]", indexState(CONTENT)); + assertEquals("refs/heads/master", result.getName()); + assertEquals("refs/heads/master", git.getRepository() + .getFullBranch()); } catch (Exception e) { fail(e.getMessage()); } @@ -171,4 +175,17 @@ public class CheckoutCommandTest extends RepositoryTestCase { fis.close(); } } + + public void testCheckoutCommit() { + try { + Ref result = git.checkout().setName(initialCommit.name()).call(); + assertEquals("[Test.txt, mode:100644, content:Hello world]", + indexState(CONTENT)); + assertNull(result); + assertEquals(initialCommit.name(), git.getRepository() + .getFullBranch()); + } catch (Exception e) { + fail(e.getMessage()); + } + } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java index 2546231cfd..cb261a0ace 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java @@ -128,7 +128,7 @@ public class CheckoutCommand extends GitCommand<Ref> { String refLogMessage = "checkout: moving from " + headRef.getTarget().getName(); ObjectId branch = repo.resolve(name); - Ref ref = repo.getRef(name); + if (branch == null) throw new RefNotFoundException(MessageFormat.format(JGitText .get().refNotResolved, name)); @@ -148,11 +148,20 @@ public class CheckoutCommand extends GitCommand<Ref> { status = new CheckoutResult(Status.CONFLICTS, fileList); throw e; } - RefUpdate refUpdate = repo.updateRef(Constants.HEAD); + Ref ref = repo.getRef(name); + if (ref != null && !ref.getName().startsWith(Constants.R_HEADS)) + ref = null; + RefUpdate refUpdate = repo.updateRef(Constants.HEAD, ref == null); refUpdate.setForceUpdate(force); refUpdate.setRefLogMessage(refLogMessage + "to " + newCommit.getName(), false); - Result updateResult = refUpdate.link(ref.getName()); + Result updateResult; + if (ref != null) + updateResult = refUpdate.link(ref.getName()); + else { + refUpdate.setNewObjectId(newCommit); + updateResult = refUpdate.forceUpdate(); + } setCallable(false); @@ -174,8 +183,6 @@ public class CheckoutCommand extends GitCommand<Ref> { throw new JGitInternalException(MessageFormat.format(JGitText .get().checkoutUnexpectedResult, updateResult.name())); - Ref result = repo.getRef(name); - if (!repo.isBare() && !dco.getToBeDeleted().isEmpty()) { List<File> fileList = new ArrayList<File>(); for (String filePath : dco.getToBeDeleted()) { @@ -185,7 +192,7 @@ public class CheckoutCommand extends GitCommand<Ref> { } else status = CheckoutResult.OK_RESULT; - return result; + return ref; } catch (IOException ioe) { throw new JGitInternalException(ioe.getMessage(), ioe); } finally { |
