提出:
/**
* 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);
}
我错过了一些明显的东西吗?这样复杂吗?
在BaseRepositoryBuilder中运行setMustExist(boolean)可以使用吗?
答案 0 :(得分:6)
我能找到的最短解决方案是始终致电create()
并忽略已存在例外。
static Git openOrCreate( File gitDirectory ) throws IOException {
Repository repository = new FileRepository( gitDirectory );
try {
repository.create();
} catch( IllegalStateException repositoryExists ) {
}
return new Git( repository );
}
该代码有其警告。 IllegalStateException
似乎是一个可能会改变并破坏上述代码的实现细节。此外,FileRepository
驻留在内部包中,不属于公共JGit API。
以下是避免这些问题的解决方案:
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;
}
请注意,省略了异常处理,以便专注于代码段的实际用途。
setMustExist
无法按需创建存储库 。如果在指定位置找不到存储库,则只会导致build()
引发RepositoryNotFoundException
。
Repository
表示存储库本身,而Git
用作创建命令的工厂,命令在其包装的存储库上运行。 工厂方法旁边有close()
,它只是委托给Repository.close()
。
存储库维护一个使用计数器,该计数器递减close()
。您可以在关闭后通过Git或Repository自己的方法继续使用存储库,但如有必要,它将重新打开。为避免泄漏文件句柄,您不应在关闭后使用存储库。
可以找到有关如何使用JGit访问和初始化存储库的深入讨论
此处:http://www.codeaffine.com/2014/09/22/access-git-repository-with-jgit/和
此处:http://www.codeaffine.com/2015/05/06/jgit-initialize-repository/
答案 1 :(得分:1)
在RüdigerHerrmann之后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;
}