سؤال

I have a build tool that runs a patch command and if the patch command returns non-zero, it will cause the build to fail. I am applying a patch that may or may not already be applied, so I use the -N option to patch, which skips as it should. However, when it does skip, patch is returning non-zero. Is there a way to force it to return 0 even if it skips applying patches? I couldn't find any such capability from the man page.

هل كانت مفيدة؟

المحلول 2

I believe that the following recipe should do the trick, it is what I am using in the same situation;

patches: $(wildcard $(SOMEWHERE)/patches/*.patch)
    for patch_file in $^; do \
        patch --strip=2 --unified --backup --forward --directory=<somewhere> --input=$$patch_file; \
        retCode=$$?; \
        [[ $$retCode -gt 1 ]] && exit $$retCode; \
    done; \
    exit 0

This recipe loops over the dependencies (in my case the patch files) and calls patch for each one. The "trick" on which I am relying is that patch returns 1 if the patch has already been applied and other higher numbers for other errors (such as a non existent patch file). The DIAGNOSTICS section of the patch manual entry describes the return code situation. YMMV

نصائح أخرى

Accepted answer did not work for me because patch was returning 1 also on other types of errors (maybe different version or sth). So instead, in case of error I am checking output for "Skipping patch" message to ignore such but return error on other issues.

OUT="$(patch -p0 --forward < FILENAME)" || echo "${OUT}" | grep "Skipping patch" -q || (echo "$OUT" && false);

You can also do that as a one line only

patch -p0 --forward < patches/patch-babylonjs.diff || true

So if you want to apply the patch and make sure that's it's working:

(patch -p0 --forward < patches/patch-babylonjs.diff || true) && echo OK

No matter whether the patch has already been applied or not, you'll always get "OK" displayed here.

Below is a script that iterates on the above idea from @fsw and handles removal of .rej files as necessary.

#! /bin/sh

set +x
set -euo pipefail

bn=$(basename "$0")

patch="$1"; shift

r=$(mktemp /tmp/"$bn".XXXX)

if ! out=$(patch -p1 -N -r "$r" < "$patch")
then
    echo "$out" | grep -q "Reversed (or previously applied) patch detected!  Skipping patch."
    test -s "$r" # Make sure we have rejects.
else
    test -f "$r" && ! test -s "$r" # Make sure we have no rejects.
fi

rm -f "$r"
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top