summaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit
diff options
context:
space:
mode:
authorKevin Sawicki <kevin@github.com>2011-05-03 08:07:15 -0700
committerKevin Sawicki <kevin@github.com>2011-05-03 08:07:15 -0700
commitec92f8f59e1365048866d875458ff999f9c41bae (patch)
treea8adef8bc07afe82768f0cea900c26cc50b43ee1 /org.eclipse.jgit
parentd05d351f3be5207a168c43b7cc52404195c2d567 (diff)
downloadjgit-ec92f8f59e1365048866d875458ff999f9c41bae.tar.gz
jgit-ec92f8f59e1365048866d875458ff999f9c41bae.zip
Add path support to checkout command.
Change-Id: I89e8edfc6dd87d5bf8fd08704df2432720084330 Signed-off-by: Kevin Sawicki <kevin@github.com>
Diffstat (limited to 'org.eclipse.jgit')
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java87
1 files changed, 84 insertions, 3 deletions
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 16c1fcfa33..f3a2e53602 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java
@@ -43,8 +43,11 @@
*/
package org.eclipse.jgit.api;
+import java.io.File;
import java.io.IOException;
import java.text.MessageFormat;
+import java.util.LinkedList;
+import java.util.List;
import org.eclipse.jgit.JGitText;
import org.eclipse.jgit.api.CheckoutResult.Status;
@@ -52,7 +55,12 @@ 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.dircache.DirCache;
import org.eclipse.jgit.dircache.DirCacheCheckout;
+import org.eclipse.jgit.dircache.DirCacheEditor;
+import org.eclipse.jgit.dircache.DirCacheEditor.PathEdit;
+import org.eclipse.jgit.dircache.DirCacheEntry;
+import org.eclipse.jgit.dircache.DirCacheIterator;
import org.eclipse.jgit.errors.AmbiguousObjectException;
import org.eclipse.jgit.errors.CheckoutConflictException;
import org.eclipse.jgit.lib.AnyObjectId;
@@ -65,6 +73,8 @@ import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevTree;
import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.treewalk.TreeWalk;
+import org.eclipse.jgit.treewalk.filter.PathFilterGroup;
/**
* Checkout a branch to the working tree
@@ -82,17 +92,20 @@ public class CheckoutCommand extends GitCommand<Ref> {
private CreateBranchCommand.SetupUpstreamMode upstreamMode;
- private String startPoint = Constants.HEAD;
+ private String startPoint = null;
private RevCommit startCommit;
private CheckoutResult status;
+ private List<String> paths;
+
/**
* @param repo
*/
protected CheckoutCommand(Repository repo) {
super(repo);
+ this.paths = new LinkedList<String>();
}
/**
@@ -111,6 +124,12 @@ public class CheckoutCommand extends GitCommand<Ref> {
checkCallable();
processOptions();
try {
+ if (!paths.isEmpty()) {
+ checkoutPaths();
+ status = CheckoutResult.OK_RESULT;
+ setCallable(false);
+ return null;
+ }
if (createBranch) {
Git git = new Git(repo);
@@ -196,6 +215,67 @@ public class CheckoutCommand extends GitCommand<Ref> {
}
}
+ /**
+ * @param path
+ * Path to update in the working tree and index.
+ * @return {@code this}
+ */
+ public CheckoutCommand addPath(String path) {
+ checkCallable();
+ this.paths.add(path);
+ return this;
+ }
+
+ /**
+ * Checkout paths into index and working directory
+ *
+ * @return this instance
+ * @throws IOException
+ * @throws RefNotFoundException
+ */
+ protected CheckoutCommand checkoutPaths() throws IOException,
+ RefNotFoundException {
+ RevWalk revWalk = new RevWalk(repo);
+ DirCache dc = repo.lockDirCache();
+ try {
+ TreeWalk treeWalk = new TreeWalk(revWalk.getObjectReader());
+ treeWalk.setRecursive(true);
+ treeWalk.addTree(new DirCacheIterator(dc));
+ treeWalk.setFilter(PathFilterGroup.createFromStrings(paths));
+ List<String> files = new LinkedList<String>();
+ while (treeWalk.next())
+ files.add(treeWalk.getPathString());
+
+ if (startCommit != null || startPoint != null) {
+ DirCacheEditor editor = dc.editor();
+ TreeWalk startWalk = new TreeWalk(revWalk.getObjectReader());
+ startWalk.setRecursive(true);
+ startWalk.setFilter(treeWalk.getFilter());
+ startWalk.addTree(revWalk.parseCommit(getStartPoint())
+ .getTree());
+ while (startWalk.next()) {
+ final ObjectId blobId = startWalk.getObjectId(0);
+ editor.add(new PathEdit(startWalk.getPathString()) {
+
+ public void apply(DirCacheEntry ent) {
+ ent.setObjectId(blobId);
+ }
+ });
+ }
+ editor.commit();
+ }
+
+ File workTree = repo.getWorkTree();
+ for (String file : files)
+ DirCacheCheckout.checkoutEntry(repo, new File(workTree, file),
+ dc.getEntry(file));
+ } finally {
+ dc.unlock();
+ revWalk.release();
+ }
+ return this;
+ }
+
private ObjectId getStartPoint() throws AmbiguousObjectException,
RefNotFoundException, IOException {
if (startCommit != null)
@@ -215,8 +295,9 @@ public class CheckoutCommand extends GitCommand<Ref> {
}
private void processOptions() throws InvalidRefNameException {
- if (name == null
- || !Repository.isValidRefName(Constants.R_HEADS + name))
+ if (paths.isEmpty()
+ && (name == null || !Repository
+ .isValidRefName(Constants.R_HEADS + name)))
throw new InvalidRefNameException(MessageFormat.format(JGitText
.get().branchNameInvalid, name == null ? "<null>" : name));
}