Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [jgit-dev] Best way to emulate "git checkout"?

Andrew Bayer <andrew.bayer@xxxxxxxxx> wrote:
> I'm working on rewriting the internals of the Hudson git plugin to use jgit
> rather than the git executable (as much as possible, at least), and I'm
> trying to figure out the best/right way to do the equivalent of "git
> checkout" - I've been aping the code I find in org.eclipse.jgit.pgm for
> clone/fetch so far, but the checkout implementation in
> org.eclipse.jgit.pgm.Clone.doCheckout uses a deprecated method
> (Repository.mapCommit) and in any case isn't quite as
> intuitive/obvious/simple as cloning or fetching.

We're still trying to move away from the deprecated code.  Not all
of it has been replaced... which is why for example Clone still
uses WorkDirCheckout.  We don't yet have the replacement done.  :-\

If you are always dropping into a clean directory, you can probably
get away with something like this.  Otherwise you'll need to use
WorkDirCheckout, even though its deprecated.

  File root = ...;
  ObjectId commitId = ...;
  ObjectReader reader = repo.newObjectReader();
  try {
    RevWalk rw = new RevWalk(reader);

    TreeWalk tw = new TreeWalk(reader);
    tw.reset(rw.parseCommit(commitId).getTree());

    while (tw.next()) {
      File path = new File(root, tw.getPathString());
      switch (tw.getFileMode(0).getObjectType()) {
      case Constants.OBJ_TREE:
        path.mkdir();
        tw.enterSubtree();
        break;

      case Constants.OBJ_BLOB:
        OutputStream out = new FileOutputStream(path);
        InputStream in = reader.open(tw.getObjectId(0), Constants.OBJ_BLOB).openStream();
        ... copy in to out and close both ...
        if (tw.getFileMode(0) == FileMode.EXECUTABLE_FILE)
          path.setExecutable(...);
        break;

      default:
        if (tw.getFileMode(0) == FileMode.GITLINK) {
          // submodule "directory"
        } else if (tw.getFileMode(0) == FileMode.SYMLINK) {
          // Java needs to get a clue...
        } else {
          // this is probably an issue for you.
        }
      }
    }
  } finally {
    reader.release();
  }

> For that matter, I'm also
> not entirely sure what the right way to go from a string (i.e., a branch or
> SHA1) to a checkout, even with what's used in Clone. Any
> suggestions/pointers on what I should I look at? Thanks!

Repository.resolve() is your friend.  It will take a string and
return an ObjectId.  From that you can cast it down to a commit or
a tree, either by appending "^{commit}" or "^{tree}" to the input
string and making resolve() do the work for you, or by calling the
parseFoo method on your own RevWalk.

-- 
Shawn.


Back to the top