Làm thế nào để tạo bản vá bỏ qua hunk đã áp dụng


14

Tôi có một tệp vá rất lớn mà tôi đang cố gắng áp dụng cho mã của mình. Vấn đề là, một số thay đổi trong bản vá của tôi đã tồn tại trong mã. Có cách nào để tạo bản vá duyên dáng bỏ qua những thay đổi đã được áp dụng không?

Các -Ntùy chọn không làm những gì tôi muốn. Nếu nó gặp một hunk đã được áp dụng, nó sẽ tạo ra một tệp từ chối và sẽ không áp dụng bất kỳ hunk nào nữa cho tệp đó. Tôi muốn nó chỉ cần bỏ qua hunk đó và tiếp tục áp dụng phần còn lại của bản vá. Lần duy nhất tôi muốn nó tạo tệp .rej là nếu một khối không thể được áp dụng và dường như không được áp dụng.

Có cách nào để làm việc này không?

Câu trả lời:


7

Bạn sẽ cần patchutils cài đặt cho việc này.

Kịch bản lệnh này sẽ chia một bản vá lớn thành các bộ đệm riêng nhỏ hơn, mỗi bộ chỉ chứa một khối cho một tệp. Sau đó bạn có thể áp dụng các bản vá với patch --forward.

#!/bin/sh -eu

PATCH=$1
OUTDIR=$2

test -f "$PATCH" && test -d "$OUTDIR"

TDIR=$(mktemp -d)
trap 'rm -rf $TDIR' 0

INDEX=0
TEMPHUNK=$TDIR/current_hunk

lsdiff $1 | while read FNAME
do
    HUNK=1
    while :
    do
        filterdiff --annotate --hunks=$HUNK -i "$FNAME" "$PATCH" > "$TEMPHUNK"
        HUNK=$((HUNK+1))
        test -s "$TEMPHUNK" && \
            {
                mv "$TEMPHUNK" "$OUTDIR/$INDEX.diff"
                INDEX=$((INDEX+1))
            } || break
    done
done

Chỉnh sửa : lưu tập lệnh vào hunks.shvà gọi nó:

./hunks.sh path/to/big.diff path/to/output/directory

2

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 foolà những từ chối cần được kiểm tra và sáp nhập thủ công.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.