Python:致命:不是 git 存储库在文件系统边界处停止未设置 GIT_DISCOVERY_ACROSS_FILESYSTEM

问题描述

当我跑步时

proc = subprocess.Popen(['git','add','-A'],stdout=subprocess.PIPE)

我收到此错误

fatal: not a git repository (or any parent up to mount point /media)
Stopping at filesystem boundary (GIT_disCOVERY_ACROSS_FILESYstem not set).

但是正在运行

os.system('git add -A')

完美地完成工作。

如果您认为文件夹中没有 .git 文件

proc = subprocess.Popen(['ls','-a'],stdout=subprocess.PIPE)

表明它已经在 cwd 中。

为什么 Popen 不能暂存文件,也不能提交,而 os.system 两者都可以?


更新:

这是我失败的 MWE

import subprocess
import os

cwd = os.getcwd()
proj_path = os.path.join(cwd,'newproj')
os.makedirs(proj_path)
os.chdir(proj_path)
proc = subprocess.Popen(['git','init'],stdout=subprocess.PIPE)
proc = subprocess.Popen(['ls',stdout=subprocess.PIPE)
print(proc.stdout.read().decode('ascii'))
proc = subprocess.Popen(['git',stdout=subprocess.PIPE)
out,err = proc.communicate()
if err:
    print('Error:\n',err.decode())
print(out.decode('ascii'))

输出

.
..
.git

fatal: not a git repository (or any parent up to mount point /media)
Stopping at filesystem boundary (GIT_disCOVERY_ACROSS_FILESYstem not set).

解决方法

我的 Python 版本有点落后于你,但我能够重现该问题,这实际上非常简单:

proc = subprocess.Popen(['git','init'],stdout=subprocess.PIPE)
proc = subprocess.Popen(['ls','-a'],stdout=subprocess.PIPE)
print(proc.stdout.read().decode('ascii'))
proc = subprocess.Popen(['git','add','-A'],stdout=subprocess.PIPE)

注意没有对 proc.wait() 或类似的调用。这意味着我们剥离了一个 git init 并且不要等待它

接下来,我们运行 ls -a。在这里,我们确实等待了一点——足够长的时间将其输出读取到 EOF,这实际上相对较长,因为 EOF 仅在 ls -a 完成时发生——同时 git init 仍在运行。根据 git init 的工作速度,我们可能会也可能不会在这里找到 .git 目录。如果这需要足够长的时间,git init 也可能会结束。幸运的是,我系统上的 git initls -a 慢得多,我看到的效果与您相同。 (嗯,我发现 .git 目录有时还不存在。)

最后,我们运行 git add -Agit init 可能仍在运行,也可能不在运行。事实证明,它仍在运行,还没有达到将 .git 目录建立为 Git 存储库 的程度。因此 git add -A 抱怨,并显示您观察到的错误。

如果我们在 proc.wait() 之后立即添加 git init——理想情况下,我们应该检查返回码,或者在这里简单地使用 subprocess.check_callsubprocess.run——问题就会消失。