10

Using ordinary git checkout the command works exactly how I would expect it to. Here are the use cases I am trying to allow for with the same piece of code:

1) git checkout branchname where branchname does not exist locally but does on remote

2) git checkout branchname where branchname already exists locally

3) git checkout commitid

For context, the repository has previously been cloned as follows:

repo = Git.cloneRepository()
    .setCloneSubmodules(true)
    .setURI(repoUrl)
    .setDirectory(createTempDir())
    .setCloneAllBranches(true)
    .call();

The standard JGit checkout command does not automatically create branches locally. The following piece of code works for scenarios 2 and 3:

repo.checkout()
      .setName(branchOrCommitId)
      .call();

With the amendment to create a new branch it only works with scenario 1:

repo.checkout()
      .setCreateBranch(true)
      .setName(branchOrCommitId)
      .call();

Is there a neat solution to this issue I can use, considering the standard Git CLI already provides the automatic functionality within the command I am looking for?

Zoe
  • 27,060
  • 21
  • 118
  • 148
MarkRobbo
  • 975
  • 1
  • 9
  • 31

2 Answers2

9

What you want to do is create a branch if and only if a local one is NOT present. Here's what I came up with using streams where exampleRepo is the git repo object, checkout command is the CheckoutCommand, and branchName is the branch name.:

git.setCreateBranch(git.branchList()
        .call()
        .stream()
        .map(Ref::getName)
        .noneMatch(("refs/heads/" + branchName)::equals));
rolve
  • 10,083
  • 4
  • 55
  • 75
randypaq13
  • 432
  • 3
  • 9
2

One possible solution to this I have found so far is to check whether the local branch exists and is an ID in order to combine the two approaches mentioned in the question:

    boolean createBranch = !ObjectId.isId(branchOrCommitId);
    if (createBranch) {
        Ref ref = repo.getRepository().exactRef("refs/heads/" + branchOrCommitId);
        if (ref != null) {
            createBranch = false;
        }
    }
    repo.checkout()
            .setCreateBranch(createBranch)
            .setName(branchOrCommitId)
            .call();
MarkRobbo
  • 975
  • 1
  • 9
  • 31
  • The CLI `git checkout` command just tries to use the name as a branch name (tries to resolve to a ref it by adding `refs/heads/`), and if that fails, scans all `refs/remotes/` references for all remotes to see if subtracting `refs/remotes/` plus the remote name matches. If the result of the scan is exactly 1 `refs/remotes/` name, it then act like `git checkout -b --track `. Your code above is not quite the same: what happens if there are 0 or 2-or-more matches? – torek Aug 09 '17 at 14:39