How to open a repository creating it if it does not exist in JGit?

jgit

Solution

The shortest solution I could find is to always call `create()` and ignore the already exists exception.

static Git openOrCreate(File gitDirectory) throws IOException {
  Repository repository = new FileRepository(gitDirectory);
  try {
    repository.create();
  } catch(IllegalStateException repositoryExists) {
  }
  return new Git(repository);
}

The code has its caveats though. The `IllegalStateException` seems to be an implementation detail that might change and break the above code. In addition, `FileRepository` resides in an internal package and is not part of the public JGit API.

The following is a solution that avoids these problems:

static Git openOrCreate(File gitDirectory) throws IOException, GitAPIException {
  Git git;
  FileRepositoryBuilder repositoryBuilder = new FileRepositoryBuilder();
  repositoryBuilder.addCeilingDirectory(gitDirectory);
  repositoryBuilder.findGitDir(gitDirectory);
  if( repositoryBuilder.getGitDir() == null ) {
    git = Git.init().setDirectory(gitDirectory.getParentFile()).call();
  } else {
    git = new Git(repositoryBuilder.build());
  }
  return git;
}

Note that exception handling was left out in order to focus on the actual purpose of the snippets.

`setMustExist` doesn't help with creating a repository on demand. It only causes `build()`to raise a `RepositoryNotFoundException` if no repository can be found at the specified location.

`Repository` represents the repository itself whereas `Git` serves as a factory to create commands which operate on the repository that it wraps. Next to the factory methods there is `close()`, which simply delegates to `Repository.close()`.

A Repository maintains a use counter that is decremented by `close()`. You can continue to use a repository after it was closed (through Git or the Repository's own methods) but it will be re-opened if necessary. To avoid leaking file handles you should not use a repository after it was closed.

An in-depth discussion of of how to access and initialize repositories with JGit can be found

here: http://www.codeaffine.com/2014/09/22/access-git-repository-with-jgit/ and

here: http://www.codeaffine.com/2015/05/06/jgit-initialize-repository/

Problem

Came up with: ``` /** * Create a repo at the specified directory or open one if it already * exists. Return a {@link Git} object... * * @param p * Path to the repo root (the dir that contains the .git folder) * @return a "Git" object to run porcelain commands on... * @throws GitterException * if the specified path cannot be resolved to a directory, or * the repository failed to be build (...) or created */ public static Git open(Path p) throws GitterException { if (!Files.isDirectory(p)) // default LinkOption is follow links throw new GitterException(p + " can't be resolved to a directory"); Repository localRepo = null; try { localRepo = new FileRepository(Paths.get(p.toString(), ".git") .toFile()); // do I have to specify the .git folder ? } catch (IOException e) { throw new GitterException("Failed to build Repository instance", e); } try { localRepo.create(); } catch (IllegalStateException e) { // ISE when the repo exists ! } catch (IOException e) { throw new GitterException("Failed to create Repository instance", e); } return new Git(localRepo); } ``` Am I missing something obvious ? Is it as complicated as this ? Run across setMustExist(boolean) in the BaseRepositoryBuilder could it be used ?

Original source