GitPython`repo.index.commit()`生成持久的git.exe实例,保存repo的句柄

时间:2016-11-21 16:15:24

标签: python git gitpython

我正在尝试使用GitPython进行一些repo操作,但遇到了我的应用程序的问题,句柄打开了,我不会期望。

Bug-jarring这个问题,似乎调用repo.index.commit()导致了目录的句柄(可能是.git\中的某个东西)。稍后这会导致我的应用程序尝试执行的其他操作失败。

这是一个工作单位测试:

import unittest
import git
import tempfile
import os.path

class Test(unittest.TestCase):

    def testCreateRepo(self):
        with tempfile.TemporaryDirectory(prefix=(__loader__.name) + "_") as mydir:

            # MAKE NEW REPO 
            repo = git.Repo.init(path=os.path.join(mydir, "newRepo"), mkdir=True)
            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())

            #### 
            # COMMENTING THIS OUT --> TEST PASSES
            repo.index.commit("added initial test file") 
            self.assertFalse(repo.is_dirty())
            #### 

            # adding this does not affect the handle
            git.cmd.Git.clear_cache()


            print("done") # exception thrown right after this, on __exit__

PermissionError:[WinError 32]进程无法访问该文件,因为它正由另一个进程使用:&#39; C:\ Users \%USER%\ AppData \ Local \ Temp \ EXAMPLE_gitpython_v3kbrly_ \ newRepo&#39; < / p>

深入挖掘,似乎gitPython会生成多个git.exe进程实例,并且每个实例都拥有repo newRepo root 文件夹的句柄。

  • 在错误发生之前设置一个断点,使用sysinternals / handle查看newRepo的打开句柄... git.exe(准确地说是4个单独的PID&g;)
  • 使用sysinternals / procexp我可以看到它们都是从日食中产生的 - &gt; python

单步执行,调用repo.index.commit()实际上导致生成的git.exe。

1 个答案:

答案 0 :(得分:0)

使用gitpython devs,我找到了答案:

由于gitpython的内部缓存行为,您必须强制进行垃圾收集,并告诉repo清除它的缓存。我正在做后者,但错误的对象。

在清理你的目录之前必须添加以下内容(__exit__()我的with: / context-manager子句,在上面的代码中

import gc
gc.collect()
repo.git.clear_cache()

那些似乎没有服从最少惊喜:)希望api可以在未来得到改善。