-
-
Notifications
You must be signed in to change notification settings - Fork 933
GitPython repo.index.commit()
spawns persistent git.exe instance, holds handles to repo
#553
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
That's a quagmire of bugs!
So now the code becomes:
Please report if everything has been solved. |
@ankostis i do see the test passing now, thank you for your quick response. Definitely an error not to be calling clear_cache on my end, too - thanks for pointing that out. What are your thoughts on if this merits a fix/improvement in gitpython? IMHO, this is something that does merit a change. By least-surprise, i think the user rightly expects that IFF repo does not implement context-manager, then it doesn't have side effects like persistent ownership of the repo. "Caching" is this case is not something that should have visible effects (beyond performance) for the user. And exposing Many ways to solve this; it seems to me that adding a context manager (or at least a "release()" function) might be the most usable, and would would make the behavior discoverable. As a minor side point, i wasn't able to find any documentation that would definitively indicate clear_cache was actually necessary here, i just guessed as it was the closest thing to 'cleanup()' i could find. |
We would have fixed it yesterday, if we could :-) Just search for The 1st and easiest fix is to retrofit |
I think the fix @ankostis (turns out - previously) has developed adding context mgr to Repo will be sufficient to close this bug. @ankostis I'm new to github, don't see an easy way to label / vote for your fix ankostis@47f6442 to be included in gitpython 2.1.1 in the main gitpython repo? Thanks again for your quick response & resolution here. |
Improve API for problems like gitpython-developers#553.
Assuming #555 gets merged in the next release, in your case the code would become simply like that: class Test(unittest.TestCase):
def testCreateRepo(self):
with tempfile.TemporaryDirectory(prefix=(__loader__.name) + "_") as mydir:
with git.Repo.init(path=os.path.join(mydir, "newRepo"), mkdir=True) as repo:
self.assertTrue(os.path.isdir(os.path.join(repo.working_dir, ".git")), "Failed to make new repo?")
# MAKE FILE, COMMIT REPO
testFileName = "testFile.txt"
open(os.path.join(repo.working_dir, testFileName) , "w").close()
repo.index.add([testFileName])
self.assertTrue(repo.is_dirty())
repo.index.commit("added initial test file")
self.assertFalse(repo.is_dirty())
print("done") |
@mboard182 It looks like the context-manager addition is in-flight and might make it in the release planned for today. |
In issue gitpython-developers#553 it was originally mentioned that the gc.collect was required before clearing the cache, but in the code the collect happens after the cache clear. Move the first gc.collect to before the cache to be consistent with the original description.
Under Windows, tempfile objects are holding references to open files until the garbage collector closes them and frees them. Explicit calls to gc.collect() were added to the finalizer for the Repo class to force them to be closed synchronously. However, this is expensive, especially in large, long-running programs. As a temporary measure to alleviate the performance regression on other platforms, only perform these calls when running under Windows. Fixes gitpython-developers#553
I am trying to use GitPython for some repo manipulation, but ran into issues with my app, with handles open where i wouldn't expect.
Bug-jarring the issue, it seems that calling
repo.index.commit()
results in a several (4, consistently) git.exe processes being spawned, each holding a handle to the repo's root directorynewRepo
. When the test below goes to delete this TempDir, the processes are still up, causing a failure on context-manager__exit__()
. My app occasionally needs to do a similar cleanup, so hits the same issue.On the one hand, it looks like there is no contect-manager capable repo-wrapper, meaning it makes sense if some resources is open, it will not typically be cleaned/GC'd before the tempdir
__exit__()
. On the other hand - ifRepo
is going to behave like that, it really should not persist resources that have such side-effects.Here is a working unittest:
PermissionError: [WinError 32] The process cannot access the file because it is being used by another process: 'C:\Users\%USER%\AppData\Local\Temp\EXAMPLE_gitpython_v3kbrly_\newRepo'
digging a little deeper, it seems that gitPython spawns multiple instances of git.exe processes, and each of them holds a handle to the root folder of the repo
newRepo
.newRepo
... git.exe (4 separate PID's of git.exe to be precise)-- I'm typically running this from PyDev, but i verified the issue reproduces under vanila command line invocation of python.exe as well
newRepo
being held. Adding a little extra code to the above I think that is the only handle held. I am able to successfully os.remove/os.rmdir() every dir and file, including all of .git/; and i finally manually recreate the issue seen on exit() in my example when ios.rmdir(newRepo)
stepping through, it's the call to repo.index.commit() that actually leads to the the git.exe(s) being spawned.
The text was updated successfully, but these errors were encountered: