如果在JGit中不存在,如何打开创建它的存储库?

时间:2014-07-07 22:01:09

标签: jgit

提出:

/**
 * 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)可以使用吗?

2 个答案:

答案 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;
}