如何使补丁忽略已应用的块


14

我有一个非常大的补丁文件,试图将其应用于我的代码。问题是,我的补丁程序中的某些更改已存在于代码中。有没有一种方法可以使补丁优雅地忽略已应用的更改?

-N选项无法满足我的要求。如果遇到已应用的大块,它将生成拒绝文件,并且不再将大块应用于该文件。我希望它只忽略该大块,并继续应用其余的补丁程序。我唯一希望它生成一个.rej文件的地方是,如果不能应用块并且似乎还没有应用块。

有没有办法做到这一点?

Answers:


7

您需要为此安装patchutils。

该脚本将一个大补丁分成较小的单独的补丁,每个补丁仅包含一个文件的块。然后,您可以使用来应用这些补丁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

编辑:将脚本保存到hunks.sh,然后调用它:

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

2

我最终使用类似于artyom的解决方案解决了这个问题。

第1步:将补丁分解为许多单独的补丁,每个大块一个。

我使用此脚本执行此操作:

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

用法示例:

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

这将在当前目录中填充名为0.diff 1.diff等的文件。

步骤2:应用每个补丁,丢弃已应用的补丁。

我使用此脚本执行此操作:

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

用法示例:

$ cd directory_containing_code
$ apply_patches.bash directory_containing_patch/foo

这将删除以前生成的任何补丁,这些补丁可以干净地应用或已经被应用。剩下的任何补丁foo都是需要手动检查和合并的废品。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.