Edit on GitHub

sqlmesh.utils.git

 1from __future__ import annotations
 2
 3import subprocess
 4import typing as t
 5from functools import cached_property
 6from pathlib import Path
 7
 8
 9class GitClient:
10    def __init__(self, repo: str | Path):
11        self._work_dir = Path(repo)
12
13    def list_untracked_files(self) -> t.List[Path]:
14        return self._execute_list_output(
15            ["ls-files", "--others", "--exclude-standard"], self._work_dir
16        )
17
18    def list_uncommitted_changed_files(self) -> t.List[Path]:
19        return self._execute_list_output(
20            ["diff", "--name-only", "--diff-filter=d", "HEAD"], self._git_root
21        )
22
23    def list_committed_changed_files(self, target_branch: str = "main") -> t.List[Path]:
24        return self._execute_list_output(
25            ["diff", "--name-only", "--diff-filter=d", f"{target_branch}..."], self._git_root
26        )
27
28    def _execute_list_output(self, commands: t.List[str], base_path: Path) -> t.List[Path]:
29        return [(base_path / o).absolute() for o in self._execute(commands).split("\n") if o]
30
31    def _execute(self, commands: t.List[str]) -> str:
32        result = subprocess.run(
33            ["git"] + commands,
34            cwd=self._work_dir,
35            stdout=subprocess.PIPE,
36            stderr=subprocess.PIPE,
37            check=False,
38        )
39
40        # If the Git command failed, extract and raise the error message in the console
41        if result.returncode != 0:
42            stderr_output = result.stderr.decode("utf-8").strip()
43            error_message = next(
44                (line for line in stderr_output.splitlines() if line.lower().startswith("fatal:")),
45                stderr_output,
46            )
47            raise RuntimeError(f"Git error: {error_message}")
48
49        return result.stdout.decode("utf-8").strip()
50
51    @cached_property
52    def _git_root(self) -> Path:
53        return Path(self._execute(["rev-parse", "--show-toplevel"]))
class GitClient:
10class GitClient:
11    def __init__(self, repo: str | Path):
12        self._work_dir = Path(repo)
13
14    def list_untracked_files(self) -> t.List[Path]:
15        return self._execute_list_output(
16            ["ls-files", "--others", "--exclude-standard"], self._work_dir
17        )
18
19    def list_uncommitted_changed_files(self) -> t.List[Path]:
20        return self._execute_list_output(
21            ["diff", "--name-only", "--diff-filter=d", "HEAD"], self._git_root
22        )
23
24    def list_committed_changed_files(self, target_branch: str = "main") -> t.List[Path]:
25        return self._execute_list_output(
26            ["diff", "--name-only", "--diff-filter=d", f"{target_branch}..."], self._git_root
27        )
28
29    def _execute_list_output(self, commands: t.List[str], base_path: Path) -> t.List[Path]:
30        return [(base_path / o).absolute() for o in self._execute(commands).split("\n") if o]
31
32    def _execute(self, commands: t.List[str]) -> str:
33        result = subprocess.run(
34            ["git"] + commands,
35            cwd=self._work_dir,
36            stdout=subprocess.PIPE,
37            stderr=subprocess.PIPE,
38            check=False,
39        )
40
41        # If the Git command failed, extract and raise the error message in the console
42        if result.returncode != 0:
43            stderr_output = result.stderr.decode("utf-8").strip()
44            error_message = next(
45                (line for line in stderr_output.splitlines() if line.lower().startswith("fatal:")),
46                stderr_output,
47            )
48            raise RuntimeError(f"Git error: {error_message}")
49
50        return result.stdout.decode("utf-8").strip()
51
52    @cached_property
53    def _git_root(self) -> Path:
54        return Path(self._execute(["rev-parse", "--show-toplevel"]))
GitClient(repo: str | pathlib.Path)
11    def __init__(self, repo: str | Path):
12        self._work_dir = Path(repo)
def list_untracked_files(self) -> List[pathlib.Path]:
14    def list_untracked_files(self) -> t.List[Path]:
15        return self._execute_list_output(
16            ["ls-files", "--others", "--exclude-standard"], self._work_dir
17        )
def list_uncommitted_changed_files(self) -> List[pathlib.Path]:
19    def list_uncommitted_changed_files(self) -> t.List[Path]:
20        return self._execute_list_output(
21            ["diff", "--name-only", "--diff-filter=d", "HEAD"], self._git_root
22        )
def list_committed_changed_files(self, target_branch: str = 'main') -> List[pathlib.Path]:
24    def list_committed_changed_files(self, target_branch: str = "main") -> t.List[Path]:
25        return self._execute_list_output(
26            ["diff", "--name-only", "--diff-filter=d", f"{target_branch}..."], self._git_root
27        )