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 ?
Open a Repository in TerminalIn the Repositories view, right-click an item and choose Open in Terminal. If the repository is already open in Tower, you can use Open in Terminal from the File menu.
The git init command creates a new Git repository. It can be used to convert an existing, unversioned project to a Git repository or initialize a new, empty repository. Most other Git commands are not available outside of an initialized repository, so this is usually the first command you'll run in a new project.
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/
After Rüdiger Herrmann's answer
public static Git open(Path p) throws GitterException {
// default LinkOption is follow links
try {
Files.createDirectories(p);
} catch (IOException e) {
throw new GitterException("Directory " + p + " can't be created", e);
}
RepositoryBuilder repositoryBuilder = new RepositoryBuilder();
if (!isRepo(p, repositoryBuilder)) {
LOGGER.debug(p.toAbsolutePath() + " is not a git repository.");
try {
return Git.init().setDirectory(p.toFile()).call();
} catch (GitAPIException e) {
throw new GitterException("Failed to create Git repository at "
+ p, e);
}
}
try {
return new Git(repositoryBuilder.build());
} catch (IOException e) {
throw new GitterException(
"Failed to create Repository instance at " + p, e);
}
}
static boolean isRepo(Path p, RepositoryBuilder rb)
throws GitterException {
if (!Files.isDirectory(p))
throw new GitterException(p + " can't be resolved to a directory");
final File directory = p.toFile();
rb.addCeilingDirectory(directory); // for find() below
// the docs say "Add a ceiling directory to the search limit list" which
// means in plain english that it will search up to this directory,
// which happens to be our directory, so it will only search there
rb.findGitDir(directory); // find **and** add it to the builder
return rb.getGitDir() != null;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With