From e24ab3ac9be848ea128504faad170076e244d100 Mon Sep 17 00:00:00 2001 From: Matthias Sohn Date: Tue, 11 May 2010 15:44:59 +0200 Subject: [PATCH] BranchOperation: fix checkout for tags and remote branches The current implementation wrongly changes the HEAD ref to point to the remote branch instead of to the underlying commit. Support for tags is not working at all. This fixes both issues. Bug: 312053 Signed-off-by: Mathias Kinzler --- .../org/eclipse/egit/core/op/BranchOperation.java | 38 +++++++++++++++++++--- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/BranchOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/BranchOperation.java index ca38e543..bd2a35ce 100644 --- a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/BranchOperation.java +++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/BranchOperation.java @@ -26,8 +26,10 @@ import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.GitIndex; import org.eclipse.jgit.lib.RefUpdate; import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.lib.Tag; import org.eclipse.jgit.lib.Tree; import org.eclipse.jgit.lib.WorkDirCheckout; +import org.eclipse.jgit.lib.RefUpdate.Result; import org.eclipse.osgi.util.NLS; import org.eclipse.team.core.TeamException; @@ -111,14 +113,35 @@ public class BranchOperation implements IEGitOperation { } private void updateHeadRef() throws TeamException { + boolean detach = false; + // in case of a non-local branch or a tag, + // we "detach" HEAD, i.e. point it to the + // underlying commit instead of to the Ref + if (!refName.startsWith(Constants.R_HEADS)) + detach = true; try { - RefUpdate u = repository.updateRef(Constants.HEAD); - u.setRefLogMessage(NLS.bind( - CoreText.BranchOperation_checkoutMovingTo, refName), false); - switch (u.link(refName)) { + RefUpdate u = repository.updateRef(Constants.HEAD, detach); + Result res; + if (detach) { + u.setNewObjectId(newCommit.getCommitId()); + // using forceUpdate instead of update avoids + // the merge tests which would otherwise make + // this fail + u.setRefLogMessage(NLS.bind( + CoreText.BranchOperation_checkoutMovingTo, newCommit + .getCommitId().toString()), false); + res = u.forceUpdate(); + } else { + u.setRefLogMessage(NLS.bind( + CoreText.BranchOperation_checkoutMovingTo, refName), + false); + res = u.link(refName); + } + switch (res) { case NEW: case FORCED: case NO_CHANGE: + case FAST_FORWARD: break; default: throw new IOException(u.getResult().name()); @@ -161,7 +184,12 @@ public class BranchOperation implements IEGitOperation { private void lookupRefs() throws TeamException { try { - newCommit = repository.mapCommit(refName); + // if we have a tag, we have to make an indirection + if (refName.startsWith(Constants.R_TAGS)) { + Tag tag = repository.mapTag(refName); + newCommit = repository.mapCommit(tag.getObjId()); + } else + newCommit = repository.mapCommit(refName); } catch (IOException e) { throw new TeamException(NLS.bind( CoreText.BranchOperation_mappingCommit, refName), e); -- 2.11.4.GIT