Checkout of remote tracking branch failed when no local branch existed. Also enhance RepositoryTestCase to enable checking index state of another test repository. Bug: 337695 Change-Id: Idf4c05bdf23b5161688818342b2bf9a45b49f479 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>tags/v0.12.1
@@ -1,5 +1,6 @@ | |||
/* | |||
* Copyright (C) 2010, Chris Aniszczyk <caniszczyk@gmail.com> | |||
* Copyright (C) 2011, Matthias Sohn <matthias.sohn@sap.com> | |||
* and other copyright owners as documented in the project's IP log. | |||
* | |||
* This program and the accompanying materials are made available | |||
@@ -61,8 +62,13 @@ 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.Repository; | |||
import org.eclipse.jgit.lib.RepositoryTestCase; | |||
import org.eclipse.jgit.lib.StoredConfig; | |||
import org.eclipse.jgit.revwalk.RevCommit; | |||
import org.eclipse.jgit.transport.RefSpec; | |||
import org.eclipse.jgit.transport.RemoteConfig; | |||
import org.eclipse.jgit.transport.URIish; | |||
import org.eclipse.jgit.util.FileUtils; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
@@ -205,4 +211,32 @@ public class CheckoutCommandTest extends RepositoryTestCase { | |||
fail(e.getMessage()); | |||
} | |||
} | |||
@Test | |||
public void testCheckoutRemoteTrackingWithoutLocalBranch() { | |||
try { | |||
// create second repository | |||
Repository db2 = createWorkRepository(); | |||
Git git2 = new Git(db2); | |||
// setup the second repository to fetch from the first repository | |||
final StoredConfig config = db2.getConfig(); | |||
RemoteConfig remoteConfig = new RemoteConfig(config, "origin"); | |||
URIish uri = new URIish(db.getDirectory().toURI().toURL()); | |||
remoteConfig.addURI(uri); | |||
remoteConfig.update(config); | |||
config.save(); | |||
// fetch from first repository | |||
RefSpec spec = new RefSpec("+refs/heads/*:refs/remotes/origin/*"); | |||
git2.fetch().setRemote("origin").setRefSpecs(spec).call(); | |||
// checkout remote tracking branch in second repository | |||
// (no local branches exist yet in second repository) | |||
git2.checkout().setName("remotes/origin/test").call(); | |||
assertEquals("[Test.txt, mode:100644, content:Some change]", | |||
indexState(db2, CONTENT)); | |||
} catch (Exception e) { | |||
fail(e.getMessage()); | |||
} | |||
} | |||
} |
@@ -167,20 +167,24 @@ public abstract class RepositoryTestCase extends LocalDiskRepositoryTestCase { | |||
* 'stage' is only presented when the stage is different from 0. All | |||
* reported time stamps are mapped to strings like "t0", "t1", ... "tn". The | |||
* smallest reported time-stamp will be called "t0". This allows to write | |||
* assertions against the string although the concrete value of the | |||
* time stamps is unknown. | |||
* assertions against the string although the concrete value of the time | |||
* stamps is unknown. | |||
* | |||
* @param repo | |||
* the repository the index state should be determined for | |||
* | |||
* @param includedOptions | |||
* a bitmask constructed out of the constants {@link #MOD_TIME}, | |||
* {@link #SMUDGE}, {@link #LENGTH}, {@link #CONTENT_ID} and {@link #CONTENT} | |||
* controlling which info is present in the resulting string. | |||
* {@link #SMUDGE}, {@link #LENGTH}, {@link #CONTENT_ID} and | |||
* {@link #CONTENT} controlling which info is present in the | |||
* resulting string. | |||
* @return a string encoding the index state | |||
* @throws IllegalStateException | |||
* @throws IOException | |||
*/ | |||
public String indexState(int includedOptions) | |||
public String indexState(Repository repo, int includedOptions) | |||
throws IllegalStateException, IOException { | |||
DirCache dc = db.readDirCache(); | |||
DirCache dc = repo.readDirCache(); | |||
StringBuilder sb = new StringBuilder(); | |||
TreeSet<Long> timeStamps = null; | |||
@@ -223,6 +227,46 @@ public abstract class RepositoryTestCase extends LocalDiskRepositoryTestCase { | |||
return sb.toString(); | |||
} | |||
/** | |||
* Represent the state of the index in one String. This representation is | |||
* useful when writing tests which do assertions on the state of the index. | |||
* By default information about path, mode, stage (if different from 0) is | |||
* included. A bitmask controls which additional info about | |||
* modificationTimes, smudge state and length is included. | |||
* <p> | |||
* The format of the returned string is described with this BNF: | |||
* | |||
* <pre> | |||
* result = ( "[" path mode stage? time? smudge? length? sha1? content? "]" )* . | |||
* mode = ", mode:" number . | |||
* stage = ", stage:" number . | |||
* time = ", time:t" timestamp-index . | |||
* smudge = "" | ", smudged" . | |||
* length = ", length:" number . | |||
* sha1 = ", sha1:" hex-sha1 . | |||
* content = ", content:" blob-data . | |||
* </pre> | |||
* | |||
* 'stage' is only presented when the stage is different from 0. All | |||
* reported time stamps are mapped to strings like "t0", "t1", ... "tn". The | |||
* smallest reported time-stamp will be called "t0". This allows to write | |||
* assertions against the string although the concrete value of the time | |||
* stamps is unknown. | |||
* | |||
* @param includedOptions | |||
* a bitmask constructed out of the constants {@link #MOD_TIME}, | |||
* {@link #SMUDGE}, {@link #LENGTH}, {@link #CONTENT_ID} and | |||
* {@link #CONTENT} controlling which info is present in the | |||
* resulting string. | |||
* @return a string encoding the index state | |||
* @throws IllegalStateException | |||
* @throws IOException | |||
*/ | |||
public String indexState(int includedOptions) | |||
throws IllegalStateException, IOException { | |||
return indexState(db, includedOptions); | |||
} | |||
/** | |||
* Resets the index to represent exactly some filesystem content. E.g. the | |||
* following call will replace the index with the working tree content: |
@@ -1,5 +1,6 @@ | |||
/* | |||
* Copyright (C) 2010, Chris Aniszczyk <caniszczyk@gmail.com> | |||
* Copyright (C) 2011, Matthias Sohn <matthias.sohn@sap.com> | |||
* and other copyright owners as documented in the project's IP log. | |||
* | |||
* This program and the accompanying materials are made available | |||
@@ -54,13 +55,15 @@ import org.eclipse.jgit.api.errors.RefNotFoundException; | |||
import org.eclipse.jgit.dircache.DirCacheCheckout; | |||
import org.eclipse.jgit.errors.AmbiguousObjectException; | |||
import org.eclipse.jgit.errors.CheckoutConflictException; | |||
import org.eclipse.jgit.lib.AnyObjectId; | |||
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.RefUpdate.Result; | |||
import org.eclipse.jgit.lib.Repository; | |||
import org.eclipse.jgit.revwalk.RevCommit; | |||
import org.eclipse.jgit.revwalk.RevTree; | |||
import org.eclipse.jgit.revwalk.RevWalk; | |||
/** | |||
@@ -119,21 +122,22 @@ public class CheckoutCommand extends GitCommand<Ref> { | |||
command.call(); | |||
} | |||
RevWalk revWalk = new RevWalk(repo); | |||
Ref headRef = repo.getRef(Constants.HEAD); | |||
RevCommit headCommit = revWalk.parseCommit(headRef.getObjectId()); | |||
String refLogMessage = "checkout: moving from " | |||
+ headRef.getTarget().getName(); | |||
ObjectId branch = repo.resolve(name); | |||
if (branch == null) | |||
throw new RefNotFoundException(MessageFormat.format(JGitText | |||
.get().refNotResolved, name)); | |||
RevWalk revWalk = new RevWalk(repo); | |||
AnyObjectId headId = headRef.getObjectId(); | |||
RevCommit headCommit = headId == null ? null : revWalk | |||
.parseCommit(headId); | |||
RevCommit newCommit = revWalk.parseCommit(branch); | |||
DirCacheCheckout dco = new DirCacheCheckout(repo, headCommit | |||
.getTree(), repo.lockDirCache(), newCommit.getTree()); | |||
RevTree headTree = headCommit == null ? null : headCommit.getTree(); | |||
DirCacheCheckout dco = new DirCacheCheckout(repo, headTree, | |||
repo.lockDirCache(), newCommit.getTree()); | |||
dco.setFailOnConflict(true); | |||
try { | |||
dco.checkout(); |