difffilter [-U <lines>] [-hv] [--] [-e <regex>] [-a] [-e <regex>] [-x] [-e <regex>] ...
If difffilter encounters a parsing or input reading error, it will exit after writing an error message to standard output. In such a case, difffilter’s return value is non-zero. As the parser is not guaranteed to be perfect and badly-formatted input may be accepted by commands like patch(1) , it is advised that scripts use error checking on difffilter.
$ difffilter -E ’(^|/)config.(log|status)$’ -a -E ’(^|/)Makefile.am$’ -x -E ’(^|/)Makefile’ < dirty.patch > clean.patchIf a dirty patch is submitted to a bugtracker with random whitespace changes which should be ignored, the patch may be feed through difffilter with the -b or -w options. For most cases, -b is more reasonable -- and is definitely safer than -w. See the CVS keyword removal example for information on how -U might apply to this situation.
$ difffilter -w < bug-34567-dirty.patch > bug-34567-clean.patchIf you want to see only changes made to a particular file in a multifile patch, such as README.txt, you may use the -a and -x flags to effectively invert the normal filtering convention. Any files which match expressions following an -a will be accepted if that rule is processed. To revert difffilter back to its normal mode of treating expressions as files to discard, use -x. We use an empty regular expression after the -x because the empty regular expression matches everything and we want to discard everything but README.txt. One can also easily modify this example to extract all changes to .c$ or .h$ files.
$ difffilter -a -e ’README.txt$’ -x -e ’’ < changes-bigpatch.patch > README.txt-changes.patchTo nullify diff lines which are caused by changes in CVS keywords’ content, use the -k and -K options. For example, a diff might catch changes in an $Id: $ line, which is likely to happen when creating diffs from tarballs, where CVS control files are not available. If the $Id: $ line has change in the diff meaning that there are two versions of the $Id: $, the user is likely going to be applying the diff to the same file which would have a third value for the $Id: $ line. Thus, applying such a patch would be troublesome (depending on the method of applying it). With -k and -K, we can get
$ difffilter -k Id < not-from-cvs.patch > not-from-cvs-fixed.patch
- /* $Id: binki /var/test/etc/rc.conf.RCS 1.1$ */
+ /* $Id: mgorny /var/test/etc/rc.conf.RCS 2.1.5.3$ */
to be nullified. This means that we end up getting rid of the ’+’ and ’-’ lines
and end up with a ’ ’ line:
/* $Id: binki /var/test/etc/rc.conf.RCS 1.1$ */To most effectively avoid such problems, the change should be first nullified with -k or -K. Then the -U option should be used. The -U option is used to reduce the number of lines of context a diff may have. It would be customary to pass the value 3 to this option. If a certain block or a portion of the diff has a series of 3 or more null or noop lines, then difffilter starts removing these. If a whole block (or chunk, as patch(1) calls it) contains no changes, then difffilter will completely drop that block from the diff. In many cases, this may completely remove the block, especially when (as is often the case) the CVS keyword being nullified is a line in the header comments of a file where actual edits occur infrequently.
$ difffilter -k Id -U 3 < not-from-cvs.patch > not-from-cvs-fixed.patch
There is a bug tracker at http://ohnopub.net/bugzilla/ .