diff options
author | Aarni Koskela <akx@iki.fi> | 2023-05-28 21:41:12 +0000 |
---|---|---|
committer | Aarni Koskela <akx@iki.fi> | 2023-05-29 05:31:11 +0000 |
commit | 77a10c62c9a44a27e8030eff6e5b3fb182be55ae (patch) | |
tree | debebaf8d5ea5f533cab56077b172c6e5e5e871d | |
parent | b957dcfece29c84ac0cfcd5a69475ff8684c531f (diff) | |
download | stable-diffusion-webui-gfx803-77a10c62c9a44a27e8030eff6e5b3fb182be55ae.tar.gz stable-diffusion-webui-gfx803-77a10c62c9a44a27e8030eff6e5b3fb182be55ae.tar.bz2 stable-diffusion-webui-gfx803-77a10c62c9a44a27e8030eff6e5b3fb182be55ae.zip |
Patch GitPython to not use leaky persistent processes
-rw-r--r-- | modules/extensions.py | 9 | ||||
-rw-r--r-- | modules/gitpython_hack.py | 42 | ||||
-rw-r--r-- | modules/ui_extensions.py | 6 |
3 files changed, 52 insertions, 5 deletions
diff --git a/modules/extensions.py b/modules/extensions.py index 624832a0..fb7250e6 100644 --- a/modules/extensions.py +++ b/modules/extensions.py @@ -3,9 +3,8 @@ import sys import threading
import traceback
-import git
-
from modules import shared
+from modules.gitpython_hack import Repo
from modules.paths_internal import extensions_dir, extensions_builtin_dir, script_path # noqa: F401
extensions = []
@@ -54,7 +53,7 @@ class Extension: repo = None
try:
if os.path.exists(os.path.join(self.path, ".git")):
- repo = git.Repo(self.path)
+ repo = Repo(self.path)
except Exception:
print(f"Error reading github repository info from {self.path}:", file=sys.stderr)
print(traceback.format_exc(), file=sys.stderr)
@@ -94,7 +93,7 @@ class Extension: return res
def check_updates(self):
- repo = git.Repo(self.path)
+ repo = Repo(self.path)
for fetch in repo.remote().fetch(dry_run=True):
if fetch.flags != fetch.HEAD_UPTODATE:
self.can_update = True
@@ -116,7 +115,7 @@ class Extension: self.status = "latest"
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`,
# because WSL2 Docker set 755 file permissions instead of 644, this results to the error.
repo.git.fetch(all=True)
diff --git a/modules/gitpython_hack.py b/modules/gitpython_hack.py new file mode 100644 index 00000000..e537c1df --- /dev/null +++ b/modules/gitpython_hack.py @@ -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 diff --git a/modules/ui_extensions.py b/modules/ui_extensions.py index 515ec262..1c3f5ed9 100644 --- a/modules/ui_extensions.py +++ b/modules/ui_extensions.py @@ -490,8 +490,14 @@ def refresh_available_extensions_from_data(hide_tags, sort_column, filter_text=" def preload_extensions_git_metadata():
+ t0 = time.time()
for extension in extensions.extensions:
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():
|