[英]The git process never exits when running as a Python subprocess
I'm writing a Python program to process LFS error messages as I have some repos with missing LFS files in Bitbucket Server.我正在编写一个 Python 程序来处理 LFS 错误消息,因为我在 Bitbucket 服务器中有一些缺少 LFS 文件的回购协议。 The output when running
git lfs fetch --all
isn't very helpful when you want to find out which LFS files are missing from a repo.运行
git lfs fetch --all
时的 output 当您想找出存储库中缺少哪些 LFS 文件时不是很有帮助。 That's why I'm making a tool for it.这就是为什么我要为它制作一个工具。 Maybe it can be contributed back to the git project in some form when I'm done with it?
也许它可以在我完成后以某种形式回馈给 git 项目?
import subprocess
def git_lfs_fetch(repo_dir) -> list:
timeout_sec = 120
try:
completed_process = subprocess.run(
["git", "lfs", "fetch", "--all"], check=False, cwd=repo_dir,
capture_output=True, text=True, timeout=timeout_sec, shell=False)
return completed_process.stderr.split('\n')
except subprocess.TimeoutExpired as ex:
print(f'ERROR Could not complete "{ex.cmd}" before timeout of {timeout_sec} s!')
print(ex.stderr)
return []
Sometimes, and not in any consistent way, the subprocess.run()
method never returns because the git-lfs
process never exits.有时,
subprocess.run()
方法不会以任何一致的方式返回,因为git-lfs
进程永远不会退出。 Usually running the git lfs fetch --all
command in my test repos takes a few seconds to complete.通常在我的测试存储库中运行
git lfs fetch --all
命令需要几秒钟才能完成。 As a workaround, I added a 2 min timeout
to the subprocess.run()
call.作为解决方法,我向
subprocess.run()
调用添加了 2 分钟的timeout
。 I figured I could get the output I'm interested in from stderr from the exception, since the git-lfs
was done with all it should do.我想我可以从异常中从 stderr 得到我感兴趣的 output,因为
git-lfs
已经完成了它应该做的所有事情。 However, that did not help.然而,这并没有帮助。 Python does not seem to be able to kill the
git
subprocess. Python 似乎无法杀死
git
子进程。 I understand from the doc that it sends a SIGKILL
to the process and then waits for it to exit.我从文档中了解到它向进程发送一个
SIGKILL
,然后等待它退出。 But it never exits, even with the timeout set.但它永远不会退出,即使设置了超时。
If I manually kill the git-lfs
process from the outside I get the expected output printed from ex.stderr
so git-lfs
sure looks like it is done, and my workaround does what it should.如果我从外部手动终止
git-lfs
进程,我会从 ex.stderr 打印出预期的ex.stderr
,因此git-lfs
确实看起来已经完成,并且我的解决方法可以完成它应该做的事情。
As I was writing this, in a typical rubberducking fashion, I had an idea.在我写这篇文章时,以一种典型的橡皮鸭式方式,我有了一个主意。
Since Python fails to forcibly terminate the git
subprocess I tried using git-lfs
directly, instead of letting git
call it.由于 Python 无法强制终止
git
子进程,我尝试直接使用git-lfs
,而不是让git
调用它。 This made the timeout work.这使超时工作。
subprocess.run(["git-lfs", "fetch", "--all"], ...)
The solution I'm looking for is a way to figure out why git-lfs
and consequently git
won't terminate properly.我正在寻找的解决方案是一种找出
git-lfs
和git
无法正常终止的原因的方法。 Even better would be a fix for that problem.更好的方法是解决该问题。
I have seen similar problems when calling git
from Java and C# on both Linux and Windows (several years ago), ie the git
command actually completes all it should do but the git
process never terminates.我在 Linux 和 Windows(几年前)上从 Java 和 C# 调用
git
时看到了类似的问题,即git
命令实际上完成了它应该做的所有事情,但git
从未终止。 So I'm thinking this "hanging" could be a problem in git itself.所以我认为这种“挂起”可能是 git 本身的问题。 I really would like to be able to find out why the
git-lfs
process won't exit.我真的很想知道为什么
git-lfs
进程不会退出。 I don't know where to start looking.我不知道从哪里开始寻找。
By using this method通过使用这种方法
def git_lfs_fetch(repo_dir) -> list:
timeout_sec = 120
try:
completed_process = subprocess.run(
["git", "lfs", "fetch", "--all"], check=False, cwd=repo_dir,
capture_output=True, text=True, timeout=timeout_sec, shell=False)
return completed_process.stderr.split('\n')
except subprocess.TimeoutExpired as ex:
print(f'ERROR Could not complete "{ex.cmd}" before timeout of {timeout_sec} s!')
print(ex.stderr)
return []
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.