diff
has more than one option related to whitespace. However, one is less useful for patches. The manual page gives an obscure hint, referring to both GNU:
-B, --ignore-blank-lines
ignore changes where lines are all blank
-b, --ignore-space-change
ignore changes in the amount of white space
-w, --ignore-all-space
ignore all white space
and FreeBSD
-b Ignore changes in amount of white space.
-B Ignore changes that just insert or delete blank lines.
-w Ignore white space when comparing lines.
Usually one uses -b
, because that is less likely to overlook significant changes. If you have changed only indentation, then both -b
and -w
give the same result. On the other hand, if you inserted spaces where there were none, or deleted existing spaces (leaving none), that could be a change in your program. Here is an example:
$ diff foo.c foo2.c
4c4
< setlocale(LC_ALL, "");
---
> setlocale(LC_ALL, " ");
6,7c6,7
< printw("\U0001F0A1");
< getch();
---
> printw ("\U0001F0A1");
> getch(); /* comment */
$ diff -b foo.c foo2.c
4c4
< setlocale(LC_ALL, "");
---
> setlocale(LC_ALL, " ");
6,7c6,7
< printw("\U0001F0A1");
< getch();
---
> printw ("\U0001F0A1");
> getch(); /* comment */
$ diff -w foo.c foo2.c
7c7
< getch();
---
> getch(); /* comment */
In this case, the -w
option allows you to ignore the change to the setlocale
parameter (perhaps not what was intended).
POSIX diff, by the way, has only the -b
option.
For patch
, POSIX documents the -l
option:
-l
(The letter ell.) Cause any sequence of <blank>
characters in the difference script to match any sequence of <blank>
characters in the input file. Other characters shall be matched exactly.
This is actually a very short diff command. It says to remove the line //#define DEBUG
and replace it with #define DEBUG
.
In this diff format, lines starting with a single -
are removed and those with +
are added. The other lines are for context, and the @@
tells the offset into the file and number of lines referenced. (And the triple +++
---
lines tell you which file was modified.)
The two common reasons for a patch to fail to apply are:
- The actual affected lines have changed, or
- The context around those lines has changed (possibly, changed too much, because patch usually uses a "fuzzy" algorithm.
In this case, it's probably easiest to look at the section of code by hand (in the linux-user/flatload.c
file, as you can see from the first line), and see if there's a commented-out #define DEBUG
anywhere, and then remove the //
comment characters.
Looking at the code myself, I see that the problem is probably actually reason #3 — the patch is mangled because it's been rendered in a way it wasn't supposed to be. See that line that just says #include
? In the original source, it says #include <target_flat.h>
. The blog software where you found the patch probably decided that <target_flat.h>
is a suspicious HTML tag and silently deleted it, and the author didn't notice.
Best Answer
Yes, this is a good way to create a patch.
In short:
To create patch for single file your command may look like
diff -Naru file_original file_updated > file.patch
where
-N
: treat absent files as empty-a
: treat all files as text-r
: recursively compare any subdirectories found-u
: output NUM (default 3) lines of unified contextTo create patch for whole directory:
diff -crB dir_original dir_updated > dfile.patch
where
-c
: output NUM (default 3) lines of copied context-r
: recursively compare any subdirectories-B
: ignore changes whose lines are all blankAfter all to apply this patch one can run
where switch
p
instructs patch to strip the path prefix so that files will be identified correctly. In most cases it should be1
.Remove
--dry-run
if you are happy from the result printed on the screen.