liu
9 小时以前 724be707ec15ac6558f1561366dd367d75f28bf7
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
"""从 git diff 补丁中只保留指定序号的 hunk,用于精确暂存(git add -p 是交互式的,脚本里用不了)。
 
用法:
  python split-hunks.py <补丁文件> <保留的hunk序号,逗号分隔> [--list]
  --list  只列出 hunk 序号与首行,不输出补丁
"""
import sys
 
# 必须强制 UTF-8 且不做换行翻译:否则中文上下文行会被按 GBK 写坏、\n 被写成 \r\n,
# 两者都会让 git apply 匹配不上(纯 ASCII 的补丁不会暴露这个问题,容易误判)
try:
    sys.stdout.reconfigure(encoding='utf-8', newline='')
except Exception:
    pass
 
path = sys.argv[1]
if len(sys.argv) < 3:
    print(__doc__)
    sys.exit(1)
list_only = '--list' in sys.argv
keep = set()
if not list_only:
    keep = {int(x) for x in sys.argv[2].split(',') if x.strip() != ''}
 
lines = open(path, encoding='utf-8', errors='surrogateescape').read().split('\n')
header, hunks, cur = [], [], None
for ln in lines:
    if ln.startswith('@@'):
        if cur is not None:
            hunks.append(cur)
        cur = [ln]
    elif cur is None:
        header.append(ln)
    else:
        cur.append(ln)
if cur is not None:
    hunks.append(cur)
 
if list_only:
    for i, h in enumerate(hunks):
        print(f'  [{i}] {h[0]}')
    sys.exit(0)
 
out = list(header)
for i, h in enumerate(hunks):
    if i in keep:
        out.extend(h)
# 结尾补回换行
sys.stdout.write('\n'.join(out))