gitpython_hack.py 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142
  1. from __future__ import annotations
  2. import io
  3. import subprocess
  4. import git
  5. class Git(git.Git):
  6. """
  7. Git subclassed to never use persistent processes.
  8. """
  9. def _get_persistent_cmd(self, attr_name, cmd_name, *args, **kwargs):
  10. raise NotImplementedError(f"Refusing to use persistent process: {attr_name} ({cmd_name} {args} {kwargs})")
  11. def get_object_header(self, ref: str | bytes) -> tuple[str, str, int]:
  12. ret = subprocess.check_output(
  13. [self.GIT_PYTHON_GIT_EXECUTABLE, "cat-file", "--batch-check"],
  14. input=self._prepare_ref(ref),
  15. cwd=self._working_dir,
  16. timeout=2,
  17. )
  18. return self._parse_object_header(ret)
  19. def stream_object_data(self, ref: str) -> tuple[str, str, int, "Git.CatFileContentStream"]:
  20. # Not really streaming, per se; this buffers the entire object in memory.
  21. # Shouldn't be a problem for our use case, since we're only using this for
  22. # object headers (commit objects).
  23. ret = subprocess.check_output(
  24. [self.GIT_PYTHON_GIT_EXECUTABLE, "cat-file", "--batch"],
  25. input=self._prepare_ref(ref),
  26. cwd=self._working_dir,
  27. timeout=30,
  28. )
  29. bio = io.BytesIO(ret)
  30. hexsha, typename, size = self._parse_object_header(bio.readline())
  31. return (hexsha, typename, size, self.CatFileContentStream(size, bio))
  32. class Repo(git.Repo):
  33. GitCommandWrapperType = Git