"""从 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))