首页 > 解决方案 > 如何通过 JGit java 库克隆的 Java 代码删除本地存储库?

问题描述

我使用 Java JGit 库(最新版本为 5.9.0.202009080501-r)将远程存储库克隆到本地环境。

Git git = Git.cloneRepository().setURI(repositoryUrl).setCredentialsProvider(new UsernamePasswordCredentialsProvider(user, password)).setDirectory(targetDir).call();

使用存储库的内容后,我想通过删除此本地存储库的目录将其从本地环境中删除。

FileUtils.deleteDirectory(gitDirectory);

问题是我无法从 Java 代码中删除 .git 目录,因为对 '.git\objects\pack' 目录中的文件的访问被拒绝

java.io.IOException:无法删除文件:'本地存储库目录'.git\objects ...原因:java.nio.file.AccessDeniedException:'本地存储库目录'.git\objects\pack\pack- ** ***********.idx**

锁定这些文件的是 JGit 库。停止 Java 程序后,我可以手动删除这些文件。但我想从代码中删除它们,因为在服务器上没有办法停止应用程序只是为了删除一些东西。

我正在调查这个问题好几天了。到目前为止我尝试了什么:

  1. 关闭 Jgit 库提供的所有内容。

git.close();

git.getRepository().close();

git.getRepository().getObjectDatabase().close();

Git.shutdown();

  1. 一些线程状态文件被Jgit的垃圾收集器锁定,我试图通过配置参数将其关闭
StoredConfig configuration = git.getRepository().getConfig();
configuration.setBoolean( CONFIG_GC_SECTION, null, CONFIG_KEY_AUTODETACH, false );
configuration.setInt( CONFIG_GC_SECTION, null, CONFIG_KEY_AUTOPACKLIMIT, 0 );
configuration.setInt( CONFIG_GC_SECTION, null, CONFIG_KEY_AUTO, 0 );
configuration.save();
  1. 一些线程建议这个问题可以通过WindowCacheConfig的以下配置来解决。
WindowCacheConfig config = new WindowCacheConfig();
config.setPackedGitMMAP(false);
WindowCache.reconfigure(config);
  1. 尝试使用 JGit 垃圾收集器的不同设置。我尝试了以下设置的多种组合和值(真/假)。在大多数情况下,这些设置会使情况变得更糟,因为在 pack 目录中创建了一个额外的 .bitmap 文件,该文件再次无法删除。
git.gc().setPreserveOldPacks(false).call();
git.gc().setPrunePreserved(true).call();
git.gc().setAggressive(true).call();

以上尝试都没有帮助,结果总是相同的 AccessDeniedException。任何帮助表示赞赏。

标签: javajgit

解决方案


假设你有这个:

 File dir = new File( "c:/users/master/documents/test" );
 dir.mkdir();
 Git git = Git.cloneRepository()
              .setDirectory( dir )
              .setURI( "http://git.com/scm/devenv/jira.git" )
              .call();
          
 // you do your stuff with the cloned files here

完成后调用它:

git.close();          
git = null;
Git.shutdown();
removeRecursively( dir );

添加这个方法:

private static void removeRecursively(File f) {
    if (f.isDirectory()) {
        for (File c : f.listFiles()) {
           removeRecursively(c);
        }
    }
    f.delete();
}

推荐阅读