通过 JGit 克隆 repo 后如何释放文件系统锁

Posted

技术标签:

【中文标题】通过 JGit 克隆 repo 后如何释放文件系统锁【英文标题】:How do I release file system locks after cloning repo via JGit 【发布时间】:2015-10-24 04:53:14 【问题描述】:

我正在按照此处的指南使用 jGit 克隆远程现有存储库:

https://github.com/centic9/jgit-cookbook/blob/master/src/main/java/org/dstadler/jgit/porcelain/CloneRemoteRepository.java

我使用 CFML 作为示例:

Git = createObject( 'java', 'org.eclipse.jgit.api.Git' );

localPath = createObject( 'java', 'java.io.File' ).init( expandPath( 'temp' ) );

result = Git.cloneRepository()
        .setURI( 'https://github.com/github/testrepo.git' )
        .setDirectory( localPath )
        .call();

result.close();

克隆效果很好,但在我停止 Java 进程之前,不会在 temp\.git\objects\pack 内的“打包”文件上释放文件锁。

然后我还注意到 API 文档对于结果的 .close() 方法的行为似乎有点虚伪。: http://download.eclipse.org/jgit/site/4.0.1.201506240215-r/apidocs/org/eclipse/jgit/lib/Repository.html#close()

减少使用次数,并可能关闭资源。

也许?那是什么意思?我需要做什么才能按照.close() 方法帮助实现的AutoCloseable 接口中指定的“放弃任何底层资源”?

关于 SO 有几个类似的问题,但没有一个涉及使用 org.eclipse.jgit.api.Git 上的静态方法来克隆新的 repo。

【问题讨论】:

【参考方案1】:

因此,经过几天的探索,当我点击提交时,我偶然发现了我认为的答案。

食谱示例仅对cloneRepository()call() 方法(一个Git 实例)的结果调用.close() 方法。 API 文档指出该方法还应该调用底层 Repository 实例的 .close 方法:

http://download.eclipse.org/jgit/site/4.0.1.201506240215-r/apidocs/org/eclipse/jgit/api/Git.html#close()

如果存储库是由此类中的静态工厂方法打开的,则此方法会在底层存储库实例上调用 Repository.close()。

但是,我发现如果我自己获取Repository 实例并调用它的.close() 方法,所有文件系统锁都会被释放。我认为这是我关注的 JGit 食谱参考中的一个遗漏,并将提交一个问题/拉动。

这是有效的 CFML 代码。现在注意底部的两个.close() 调用。

Git = createObject( 'java', 'org.eclipse.jgit.api.Git' );

localPath = createObject( 'java', 'java.io.File' ).init( expandPath( 'temp' ) );

result = Git.cloneRepository()
        .setURI( 'https://github.com/github/testrepo.git' )
        .setDirectory( localPath )
        .call();

result.getRepository().close();
result.close();

【讨论】:

所以这也是 Git.close() 方法或其 javadoc 中的错误,也许您也可以在那里提出问题以得到更正/澄清? 我很乐意提出一个关于 jGit 的问题,如果这实际上是库中的一个错误(而不仅仅是一个不完整的示例)。我会在今天晚些时候做一个记录。 是的,我看了一下,我认为 CloneCommand.call() 中有一个小错误,它应该在构造 Git 对象的实例时传递“true”作为附加参数以使广告结束工作,另见git.eclipse.org/c/jgit/jgit.git/tree/org.eclipse.jgit/src/org/… 此外,在该方法中获取和签出期间的错误将使存储库对象未关闭... 感谢您查看。我在这里放了一张 jGit 的票:bugs.eclipse.org/bugs/show_bug.cgi?id=474093【参考方案2】:

我也为此苦苦挣扎。这是我解决这个问题的方法。

CloneCommand cloneCommand = Git.cloneRepository();
URIish urIish = new URIish(getVersionControlPath().toString());
cloneCommand.setURI(urIish.toString());
Date date = new Date();
String testgit = "testgit_" + date.getTime();
cloneCommand.setDirectory(getVersionControlPath().getParent().resolve(testgit).toFile());
Git call = cloneCommand.call();
call.close();

【讨论】:

以上是关于通过 JGit 克隆 repo 后如何释放文件系统锁的主要内容,如果未能解决你的问题,请参考以下文章

Jgit中'pull'命令的使用

JGit 克隆仓库

使用 JGIT 进行浅克隆

使用 JGit 授权错误推送到 GitLab

USERAUTH 使用 JGit 为 PullCommand() 安全地访问 git repo 失败

如何使用 jgit 查找所有提交,而不仅仅是可引用的提交