-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstage_hunks.py
More file actions
executable file
·63 lines (52 loc) · 1.79 KB
/
Copy pathstage_hunks.py
File metadata and controls
executable file
·63 lines (52 loc) · 1.79 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
#!/usr/bin/env python3
"""Stage specific hunks (0-indexed) from a file's git diff.
Usage: stage_hunks.py <filename> <hunk_idx,...>
Example: stage_hunks.py backends/_sherpa_onnx.py 0
stage_hunks.py backends/_pipeline.py 0,1,2
"""
import subprocess
import sys
def stage_hunks(filename, hunk_indices):
result = subprocess.run(["git", "diff", filename], capture_output=True, text=True)
diff = result.stdout
if not diff:
print(f"No diff for {filename}")
return False
lines = diff.splitlines(keepends=True)
# Separate the file header (lines before first @@)
header_lines = []
i = 0
while i < len(lines) and not lines[i].startswith("@@"):
header_lines.append(lines[i])
i += 1
# Split into hunks
hunks = []
current = []
while i < len(lines):
if lines[i].startswith("@@") and current:
hunks.append(current)
current = []
current.append(lines[i])
i += 1
if current:
hunks.append(current)
print(f"Total hunks in {filename}: {len(hunks)}")
selected = [hunks[idx] for idx in hunk_indices if idx < len(hunks)]
if not selected:
print(f"No hunks selected for {filename}")
return False
patch = "".join(header_lines) + "".join("".join(h) for h in selected)
proc = subprocess.run(
["git", "apply", "--cached"],
input=patch, text=True, capture_output=True,
)
if proc.returncode != 0:
print(f"Error staging {filename} hunks {hunk_indices}:\n{proc.stderr}")
return False
print(f"Staged hunks {hunk_indices} from {filename}")
return True
if __name__ == "__main__":
fname = sys.argv[1]
indices = [int(x) for x in sys.argv[2].split(",")]
ok = stage_hunks(fname, indices)
sys.exit(0 if ok else 1)