-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdiff_generator.py
More file actions
75 lines (62 loc) · 2.7 KB
/
diff_generator.py
File metadata and controls
75 lines (62 loc) · 2.7 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
import re
import subprocess
from importlib import util
from pathlib import Path
import click
from git import GitCommandError, Repo
from assistant import Assistant
assistant_module = util.find_spec(Assistant.__module__)
assistant_path = assistant_module.origin if assistant_module else ""
class DiffGenerator:
blacklist = [assistant_path, "instructions_prompt.md"]
def __init__(self, max_diff_size: int = 1024) -> None:
self.max_diff_size = max_diff_size
def generate(self, repo_path: Path) -> str:
max_diff_size = self.max_diff_size
try:
repo = Repo(repo_path)
if repo.bare:
raise ValueError(
"The provided path is a bare repository or not a valid Git repository."
)
diffs = repo.git.diff("--cached", "--name-status").splitlines()
result = []
for diff in diffs:
parts = re.split(r"\t+", diff, maxsplit=2)
status, file = (parts[0][0], parts[-1])
if any(file in blacklisted_file for blacklisted_file in self.blacklist):
result.append(f"* Changes to {file} were made")
continue
if status == "D":
result.append(f"* file: {file} was deleted")
else:
file_diff = repo.git.diff("--cached", file)
if max_diff_size != 0 and len(file_diff.encode("utf-8")) > max_diff_size:
result.append(
f"Diff for {file} is too large, truncated:\n{file_diff[:max_diff_size]}... [truncated up to {max_diff_size} bytes]\n"
)
else:
result.append(file_diff)
return "\n".join(result)
except GitCommandError as e:
click.secho(e)
return f"Error generating diff: {e}"
def open_for_edit(self, repo_path: Path, message: str) -> str:
try:
repo = Repo(repo_path)
if repo.bare:
raise ValueError(
"The provided path is a bare repository or not a valid Git repository."
)
if not repo.is_dirty(index=True, working_tree=False):
raise ValueError("No changes are staged for commit.")
subprocess.run(
["git", "-C", str(repo_path), "commit", "--edit", "-m", message], check=True
)
return "Commit editor opened successfully."
except GitCommandError as e:
click.secho(e)
return f"Error opening commit editor: {e}"
except Exception as e:
click.secho(e)
return f"Error: {e}"