-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgit_repository.py
More file actions
125 lines (110 loc) · 3.9 KB
/
git_repository.py
File metadata and controls
125 lines (110 loc) · 3.9 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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import subprocess, sys
from typing import List
class GitRepository:
"""Handles Git repository operations."""
@staticmethod
def get_root_path() -> str:
"""
Get the root path of the current Git repository.
Returns:
str: Absolute path to the repository root
Raises:
SystemExit: If not inside a Git repository
"""
try:
result = subprocess.run(
["git", "rev-parse", "--show-toplevel"],
capture_output=True,
text=True,
check=True,
encoding='utf-8',
errors='replace'
)
if result and result.stdout:
return result.stdout.strip()
return ""
except subprocess.CalledProcessError:
print("Error: Not inside a Git repository.", file=sys.stderr)
sys.exit(1)
@staticmethod
def get_staged_diff() -> str:
"""
Get the full diff of staged changes.
Returns:
str: Git diff output for staged changes
Raises:
SystemExit: If git diff command fails
"""
try:
result = subprocess.run(
["git", "diff", "--cached"],
capture_output=True,
text=True,
check=True,
encoding='utf-8',
errors='replace'
)
if result and result.stdout:
return result.stdout.strip()
return ""
except subprocess.CalledProcessError as e:
print(f"Error getting diff: {e}", file=sys.stderr)
sys.exit(1)
except UnicodeDecodeError as e:
print(f"Unicode decode error in git diff: {e}", file=sys.stderr)
# Try again with binary mode and manual decoding
try:
result = subprocess.run(
["git", "diff", "--cached"],
capture_output=True,
check=True
)
return result.stdout.decode('utf-8', errors='replace').strip()
except Exception as e2:
print(f"Fallback decode also failed: {e2}", file=sys.stderr)
return ""
@staticmethod
def get_changed_files() -> List[str]:
"""
Get list of files that have staged changes.
Returns:
List[str]: List of file paths with staged changes
Raises:
SystemExit: If git command fails
"""
try:
result = subprocess.run(
["git", "diff", "--cached", "--name-only"],
capture_output=True,
text=True,
check=True,
encoding='utf-8',
errors='replace'
)
if result and result.stdout:
return result.stdout.strip().splitlines() if result.stdout.strip() else []
return []
except subprocess.CalledProcessError as e:
print(f"Error getting changed files: {e}", file=sys.stderr)
sys.exit(1)
@staticmethod
def get_tracked_files() -> List[str]:
"""
Get all files tracked by Git (including staged and committed).
Returns:
List[str]: List of all tracked file paths
"""
try:
result = subprocess.run(
["git", "ls-files", "--exclude-standard", "--others", "--cached"],
capture_output=True,
text=True,
check=True,
encoding='utf-8',
errors='replace'
)
if result and result.stdout:
return result.stdout.strip().splitlines() if result.stdout.strip() else []
return []
except subprocess.CalledProcessError:
return []