If you're not giving any option to patch
other than -pN
, it only creates those files when a patch fails to apply cleanly.
So, one option is to stop creating (or accepting) bad patches. :)
Back in the real world, this is a feature. When patch(1)
fails to apply a patch segment to the original file, it saves the temporary original file copy out durably as *.orig
, dumps the rejected segment to *.rej
, and continues trying to apply patch segments. The idea is that you can open the *.rej
file and complete the patch process manually by copying bits and pieces over to the patched file. The *.orig
file can also be useful when the patch process accidentally wrecks something, and you need to refer to the original version to fix it.
I don't always fix a bad patch with text from the *.rej
and *.orig
files, but it's nice to have them in case I need them.
Once I've fixed up a bad patch, I run the following script at the project root to quickly clean things up:
#!/bin/bash
find . '(' \
-name \*-baseline -o \
-name \*-merge -o \
-name \*-original -o \
-name \*.orig -o \
-name \*.rej \
')' -delete
I call it cleanup-after-bad-patch
because the long name partially insures against running this accidentally, since it could remove files you still need. To be honest, though, I normally run it by typing clean
TabEnter, that being sufficient to find this script in the PATH
on my development machines.
The additional patterns it checks for are for the files output by my version control system of choice when it encounters the same problem during a merge operation. You may wish to adjust it for your VCS/SCM tools.
You'll need patchutils installed for this.
This script will split one large patch into smaller separate paches, each of them containing only one hunk for one file. You can then apply these patches with 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: save script to hunks.sh
, and call it:
./hunks.sh path/to/big.diff path/to/output/directory
Best Answer
It is always a good idea to make backup copies from the original files.
This can be done automatically if you call
patch
with option-b
.Background: in case that there is no
.rej
file, you could call:to reverse the patch, but this does not work in case of a problem.
Note that in case that
file2.c.orig
already exists whenpatch
starts, this file is removed and replaced by a backup copy of the current state.If you have these
.orig
files, you could easily rename them to the original filename in order to undo the patch.Note that it may be a good idea to reverse all patches to all files in a project in case that a single patch fails. Since this requires
.orig
files for all patched files, it is recommended to useIf you have these
.orig
files, you could call: