Cara membuat tambalan abaikan sudah diterapkan bakhil

14

Saya memiliki file tambalan yang sangat besar yang saya coba terapkan pada kode saya. Masalahnya adalah, beberapa perubahan pada tambalan saya sudah ada dalam kode. Apakah ada cara untuk membuat tambalan dengan anggun mengabaikan perubahan yang telah diterapkan?

The -Npilihan tidak melakukan apa yang saya inginkan. Jika menemukan bingkah yang sudah diterapkan itu akan menghasilkan file tolak dan tidak akan berlaku bakhil lagi untuk file itu. Saya ingin mengabaikan bingkah itu dan terus menerapkan sisa tambalan. Satu-satunya waktu saya ingin menghasilkan file .rej adalah jika sebongkah tidak dapat diterapkan dan tampaknya tidak sudah diterapkan.

Apakah ada cara untuk melakukan ini?

Shum
sumber

Jawaban:

7

Anda harus memasang patchutils untuk ini.

Skrip ini akan membagi satu tambalan besar ke dalam petak terpisah yang lebih kecil, masing-masing berisi hanya satu paket untuk satu file. Anda kemudian dapat menerapkan tambalan ini dengan 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

Edit : simpan skrip ke hunks.sh, dan panggil:

./hunks.sh path/to/big.diff path/to/output/directory
artyom
sumber
2

Saya akhirnya memecahkan ini menggunakan solusi yang mirip dengan artyom.

Langkah 1: Meledakkan tambalan menjadi banyak tambalan terpisah, satu untuk masing-masing bongkahan.

Saya menggunakan skrip ini untuk melakukan ini:

#!/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()

Contoh penggunaan:

$ cd directory_containing_patch
$ mkdir foo
$ cd foo
$ explode.py ../huge_patch.diff

Ini akan mengisi direktori saat ini dengan file yang disebut 0.diff 1.diff et cetera.

Langkah 2: Terapkan setiap tambalan, buang tambalan yang sudah diterapkan.

Saya menggunakan skrip ini untuk melakukan ini:

#!/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

Contoh penggunaan:

$ cd directory_containing_code
$ apply_patches.bash directory_containing_patch/foo

Ini akan menghapus semua tambalan yang dibuat sebelumnya yang berlaku bersih atau yang telah diterapkan. Setiap tambalan yang tersisa fooadalah penolakan yang perlu diperiksa dan digabung secara manual.

Shum
sumber