-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathgit.py
More file actions
59 lines (43 loc) · 1.78 KB
/
git.py
File metadata and controls
59 lines (43 loc) · 1.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
"""Contains all functions related to git."""
from __future__ import annotations
import shutil
import subprocess
from pathlib import Path
from typing import Any
def is_git_installed() -> bool:
"""Check if git is installed."""
return shutil.which("git") is not None
def cmd_output(*cmd: str, **kwargs: Any) -> tuple[int, str, str]:
"""Execute a command and capture the output."""
r = subprocess.run(cmd, capture_output=True, check=False, **kwargs)
stdout = r.stdout.decode() if r.stdout is not None else ""
stderr = r.stderr.decode() if r.stderr is not None else ""
assert isinstance(stdout, str)
assert isinstance(stderr, str)
return r.returncode, stdout, stderr
def init_repo(path: Path) -> None:
"""Initialize a git repository."""
subprocess.run(("git", "init"), check=False, cwd=path)
def zsplit(s: str) -> list[str]:
"""Split string which uses the NUL character as a separator."""
s = s.strip("\0")
if s:
return s.split("\0")
return []
def get_all_files(cwd: Path | None = None) -> list[Path]:
"""Get all files tracked by git - even new, staged files."""
str_paths = zsplit(cmd_output("git", "ls-files", "-z", cwd=cwd)[1])
return [Path(x) for x in str_paths]
def get_root(cwd: Path) -> Path | None:
"""Get the root path of a git repository.
Git 2.25 introduced a change to ``rev-parse --show-toplevel`` that exposed
underlying volumes for Windows drives mapped with ``SUBST``. We use ``rev-parse
--show-cdup`` to get the appropriate path.
"""
try:
_, stdout, _ = cmd_output("git", "rev-parse", "--show-cdup", cwd=cwd)
root = Path(cwd) / stdout.strip()
except subprocess.CalledProcessError: # pragma: no cover
# User is not in git repo.
root = None
return root