Cuối cùng tôi đã giải quyết điều này bằng cách sử dụng một giải pháp tương tự như artyom.
Bước 1: Phát nổ miếng vá thành nhiều miếng vá riêng biệt, mỗi miếng cho mỗi hunk.
Tôi đã sử dụng kịch bản này để làm điều này:
#!/usr/bin/python2
import sys
header = []
writing_header = False
patchnum = 0
patch = open(sys.argv[1], "r")
out = open("/dev/null", "w")
for line in patch.readlines():
if line.startswith("diff"):
header = []
writing_header = True
if line.startswith("@@"):
out.close()
out = open(str(patchnum) + ".diff", "w")
patchnum += 1
writing_header = False
out.writelines(header)
if writing_header:
header.append(line)
else:
out.write(line)
out.close()
Ví dụ sử dụng:
$ cd directory_containing_patch
$ mkdir foo
$ cd foo
$ explode.py ../huge_patch.diff
Điều này sẽ điền vào thư mục hiện tại với các tệp có tên 0.diff 1.diff et cetera.
Bước 2: Áp dụng từng bản vá, loại bỏ các bản vá đã áp dụng.
Tôi đã sử dụng kịch bản này để làm điều này:
#!/bin/bash
if [[ $# -ne 1 || ! -d "${1}/" ]]; then
echo "Usage: $0 dirname"
exit 1
fi
find "$1" -name \*.diff | while read f; do
OUTPUT=$(patch -s -p1 -r- -i"$f")
if [ $? -eq 0 ]; then
rm "$f"
else
if echo "$OUTPUT" | grep -q "Reversed (or previously applied) patch detected!"; then
rm "$f"
fi
fi
done
Ví dụ sử dụng:
$ cd directory_containing_code
$ apply_patches.bash directory_containing_patch/foo
Điều này sẽ xóa bất kỳ bản vá nào được tạo trước đó áp dụng sạch hoặc đã được áp dụng. Bất kỳ bản vá nào còn lại foo
là những từ chối cần được kiểm tra và sáp nhập thủ công.