Patch GitPython to not use leaky persistent processes
This commit is contained in:
parent
b957dcfece
commit
77a10c62c9
@ -3,9 +3,8 @@ import sys
|
|||||||
import threading
|
import threading
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
import git
|
|
||||||
|
|
||||||
from modules import shared
|
from modules import shared
|
||||||
|
from modules.gitpython_hack import Repo
|
||||||
from modules.paths_internal import extensions_dir, extensions_builtin_dir, script_path # noqa: F401
|
from modules.paths_internal import extensions_dir, extensions_builtin_dir, script_path # noqa: F401
|
||||||
|
|
||||||
extensions = []
|
extensions = []
|
||||||
@ -54,7 +53,7 @@ class Extension:
|
|||||||
repo = None
|
repo = None
|
||||||
try:
|
try:
|
||||||
if os.path.exists(os.path.join(self.path, ".git")):
|
if os.path.exists(os.path.join(self.path, ".git")):
|
||||||
repo = git.Repo(self.path)
|
repo = Repo(self.path)
|
||||||
except Exception:
|
except Exception:
|
||||||
print(f"Error reading github repository info from {self.path}:", file=sys.stderr)
|
print(f"Error reading github repository info from {self.path}:", file=sys.stderr)
|
||||||
print(traceback.format_exc(), file=sys.stderr)
|
print(traceback.format_exc(), file=sys.stderr)
|
||||||
@ -94,7 +93,7 @@ class Extension:
|
|||||||
return res
|
return res
|
||||||
|
|
||||||
def check_updates(self):
|
def check_updates(self):
|
||||||
repo = git.Repo(self.path)
|
repo = Repo(self.path)
|
||||||
for fetch in repo.remote().fetch(dry_run=True):
|
for fetch in repo.remote().fetch(dry_run=True):
|
||||||
if fetch.flags != fetch.HEAD_UPTODATE:
|
if fetch.flags != fetch.HEAD_UPTODATE:
|
||||||
self.can_update = True
|
self.can_update = True
|
||||||
@ -116,7 +115,7 @@ class Extension:
|
|||||||
self.status = "latest"
|
self.status = "latest"
|
||||||
|
|
||||||
def fetch_and_reset_hard(self, commit='origin'):
|
def fetch_and_reset_hard(self, commit='origin'):
|
||||||
repo = git.Repo(self.path)
|
repo = Repo(self.path)
|
||||||
# Fix: `error: Your local changes to the following files would be overwritten by merge`,
|
# Fix: `error: Your local changes to the following files would be overwritten by merge`,
|
||||||
# because WSL2 Docker set 755 file permissions instead of 644, this results to the error.
|
# because WSL2 Docker set 755 file permissions instead of 644, this results to the error.
|
||||||
repo.git.fetch(all=True)
|
repo.git.fetch(all=True)
|
||||||
|
42
modules/gitpython_hack.py
Normal file
42
modules/gitpython_hack.py
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import io
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
import git
|
||||||
|
|
||||||
|
|
||||||
|
class Git(git.Git):
|
||||||
|
"""
|
||||||
|
Git subclassed to never use persistent processes.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def _get_persistent_cmd(self, attr_name, cmd_name, *args, **kwargs):
|
||||||
|
raise NotImplementedError(f"Refusing to use persistent process: {attr_name} ({cmd_name} {args} {kwargs})")
|
||||||
|
|
||||||
|
def get_object_header(self, ref: str | bytes) -> tuple[str, str, int]:
|
||||||
|
ret = subprocess.check_output(
|
||||||
|
[self.GIT_PYTHON_GIT_EXECUTABLE, "cat-file", "--batch-check"],
|
||||||
|
input=self._prepare_ref(ref),
|
||||||
|
cwd=self._working_dir,
|
||||||
|
timeout=2,
|
||||||
|
)
|
||||||
|
return self._parse_object_header(ret)
|
||||||
|
|
||||||
|
def stream_object_data(self, ref: str) -> tuple[str, str, int, "Git.CatFileContentStream"]:
|
||||||
|
# Not really streaming, per se; this buffers the entire object in memory.
|
||||||
|
# Shouldn't be a problem for our use case, since we're only using this for
|
||||||
|
# object headers (commit objects).
|
||||||
|
ret = subprocess.check_output(
|
||||||
|
[self.GIT_PYTHON_GIT_EXECUTABLE, "cat-file", "--batch"],
|
||||||
|
input=self._prepare_ref(ref),
|
||||||
|
cwd=self._working_dir,
|
||||||
|
timeout=30,
|
||||||
|
)
|
||||||
|
bio = io.BytesIO(ret)
|
||||||
|
hexsha, typename, size = self._parse_object_header(bio.readline())
|
||||||
|
return (hexsha, typename, size, self.CatFileContentStream(size, bio))
|
||||||
|
|
||||||
|
|
||||||
|
class Repo(git.Repo):
|
||||||
|
GitCommandWrapperType = Git
|
@ -490,8 +490,14 @@ def refresh_available_extensions_from_data(hide_tags, sort_column, filter_text="
|
|||||||
|
|
||||||
|
|
||||||
def preload_extensions_git_metadata():
|
def preload_extensions_git_metadata():
|
||||||
|
t0 = time.time()
|
||||||
for extension in extensions.extensions:
|
for extension in extensions.extensions:
|
||||||
extension.read_info_from_repo()
|
extension.read_info_from_repo()
|
||||||
|
print(
|
||||||
|
f"preload_extensions_git_metadata for "
|
||||||
|
f"{len(extensions.extensions)} extensions took "
|
||||||
|
f"{time.time() - t0:.2f}s"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def create_ui():
|
def create_ui():
|
||||||
|
Loading…
Reference in New Issue
Block a user