This is touched on in two questions, 'Check if a file or folder has been patched already' and 'Make
patch return 0 when skipping an already applied patch' however neither had a satisfying answer.
I am writing a script and want to test the following for a patch:
Fully applied: continue
Partially applied: exit
Not applied: if it can be applied successfully do it and continue, otherwise exit
The problem is handling the partially applied case:
mkdir test && cd test cat << EOF > foobar.patch --- /dev/null +++ foo @@ -0,0 +1 @@ +foo --- /dev/null +++ bar @@ -0,0 +1 @@ +bar EOF patch --forward -i foobar.patch rm foo
So bar exists but foo doesn't because at some point it was removed. Now if I apply the patch forward in a dry-run the exit code is 1 since it's not applied successfully.
$ patch --dry-run --forward --force -i foobar.patch checking file foo The next patch would create the file bar, which already exists! Skipping patch. 1 out of 1 hunk ignored $ echo $? 1
That does not tell me whether the patch is fully applied though, just that it failed the dry-run. I don't know why that's marked correct as the stackoverflow answer. I tried reversing but since it's a non-interactive script it only worked with force:
$ patch --dry-run --reverse --force -i foobar.patch The next patch, when reversed, would delete the file foo, which does not exist! Applying it anyway. checking file foo Hunk #1 FAILED at 1. 1 out of 1 hunk FAILED checking file bar $ echo $? 1
So does it always hold that if I try to forcibly reverse a patch in a dry-run and it succeeds that the patch is fully applied, and if it fails that it's not fully applied (or applied at all)? Because if so then I can do something like
patch --dry-run --reverse --force -i foobar.patch || (patch --dry-run --forward --force -i foobar.patch && patch --forward --force -i foobar.patch) || exit 1