背景
我正在写一个Python程序来处理LFS错误信息,因为我在Bitbucket Server中有一些丢失了LFS文件的repo。当你想找出一个repo中丢失了哪些LFS文件时,运行git lfs fetch --all
的输出不是很有帮助。这就是为什么我在为它做一个工具。也许当我完成它时,它可以以某种形式贡献给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 []
环境
- Windows 10,64位
- Python 3.10.7语言
- git版本2.35.2.windows操作系统
- git-lfs/3.0.2版本(GitHub; windows amd64;参见1.17.2)
问题
有时候,subprocess.run()
方法永远不会返回,因为git-lfs
进程永远不会退出。通常,在我的测试存储库中运行git lfs fetch --all
命令需要几秒钟才能完成。作为一种解决方案,我向subprocess.run()
调用添加了一个2分钟的timeout
。我认为可以从异常的stderr获得我感兴趣的输出。因为git-lfs
已经完成了它应该做的所有事情。然而,这并没有帮助。Python似乎不能杀死git
子进程。我从文档中了解到,它向进程发送一个SIGKILL
,然后等待它退出。但它从未退出,即使设置了超时。
如果我从外部手动终止git-lfs
进程,我会从ex.stderr
打印预期的输出,所以git-lfs
看起来确实像是完成了,我的解决方案做了它应该做的事情。
修复我的工作区
当我以典型的rubberducking方式写这篇文章时,我有了一个想法。
因为Python无法强制终止git
子进程,所以我尝试直接使用git-lfs
,而不是让git
调用它,这样超时就起作用了。
subprocess.run(["git-lfs", "fetch", "--all"], ...)
我在寻找什么
我所寻找的解决方案是一种方法来找出为什么git-lfs
和git
不能正确终止,更好的是解决这个问题。
我在Linux和Windows上从Java和C#调用git
时遇到过类似的问题(几年前),也就是说,git
命令实际上完成了它应该完成的所有任务,但是git
进程却没有终止。所以我认为这个"挂起"可能是git本身的问题。我真的很想知道为什么git-lfs
进程没有终止。我不知道从哪里开始找。
1条答案
按热度按时间hfyxw5xn1#
通过使用这种方法