eclipse-jgit / jgit

JGit, the Java implementation of git
https://www.eclipse.org/jgit/
Other
90 stars 31 forks source link

Pack file is not released on repository.close() #66

Open arysin opened 2 weeks ago

arysin commented 2 weeks ago

Version

6.7.0

Operating System

Windows

Bug description

I clone a repository (with try/resouce on Git object) and after it's closed the git directory can't be deleted on Windows

Actual behavior

I get a message "C:\Users\user\AppData\Local\Temp\jgitRepository14654396429264831000.git\objects\pack\pack-065d80f75516484c8e0c0a3631b7cdf620f27328.pack: The process cannot access the file because it is being used by another process" I tried to force close but it does not help and the message states the repo is already closed:

                git.close();
                git.getRepository().close();
                FileUtils.deleteDirectory(tmpJgitPath);

close() called when useCnt is already zero for Repository

Expected behavior

The pack file should be released on repository.close() and .git directory should be deleted

Relevant log output

It looks like repository.objectDatabase.packed.packList.value.packs[0].fd (RandomAccessFile) is still open.

From what I can see this is still the case in master: the org.eclipse.jgit.internal.storage.file.Pack.close() does not release the "fd".

Other information

No response

arysin commented 2 weeks ago

The (ugly) workaround like this removes the error message:

                ObjectDatabase objectDatabase = git.getRepository().getObjectDatabase();
                Object packed = FieldUtils.getDeclaredField(ObjectDirectory.class, "packed", true).get(objectDatabase);
                AtomicReference packList = (AtomicReference) FieldUtils.getDeclaredField(packed.getClass(), "packList", true).get(packed);
                Object packList_ = packList.get();
                Pack[] packs = (Pack[]) FieldUtils.getDeclaredField(packList_.getClass(), "packs", true).get(packList_);
                for(Pack pack: packs) {
                    RandomAccessFile fd = (RandomAccessFile) FieldUtils.getDeclaredField(pack.getClass(), "fd", true).get(pack);
                    fd.close();
                }