Table of Contents

Name

difffilter - Filter diffs out of multi-file patches

Synopsis


difffilter [-U <lines>] [-hv] [--] [-e <regex>] [-a] [-e <regex>] [-x] [-e <regex>] ...

Description

difffilter reads in a series of unified-diffs and filters out any file which matches one of the passed extended regular expressions. The remaining diffs are written to standard out. difffilter is a traditional unix filter, reading input from standard input and writing the results to standard output.

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.

Options

-h
Displays some amount of helpful or unhelpful information which is intended to be helpful. difffilter will exit without performing any filtering.
-v
Displays difffilter’s version information.
-e BRE
A POSIX Basic Regular Expression which a filename in the input diff may be matched against. The default action for a matched regex is to exclude that portion of the diff from the output.
-E ERE
Like -e but uses a POSIX Extended Regular Expression.
-a
Any following -e options will cause files which match the regex to be included in the output diff. This allows one to preserve selected files which later patterns will exclude. See EXAMPLE for an application.
-x
Any following -e options will cause files matching the regex to be excluded from the output diff. This is the default state of difffilter. I.e., $ difffilter -e ’configure$’ has the same functionality of $ difffilter -x -e ’configure$’ .
-b
Attempt to make the patch appear as if it were generated using diff(1) ’s -b option. This is similar to -w but only removes changes involving changes in the amount of whitespace. This means that completely removing a block of whitespace or inserting whitespace between two non-whitespace characters will still be seen as a change. See diff(1) for more details.
-k BRE
A POSIX Basic Regular Expression which will be matched against the name of a CVS keyword whose effect is to be nullified. For example, if the CVS keyword looks like $Pizza: I’m hungry$, a regex of ‘hungry’ would not match but a regex of ‘Pi.*a$’ would.
-K ERE
Like -k but uses a POSIX Extended Regular Expression.
-R
Reverse the patch. This is intended to recover from accidents when the sources used to generate a diff are not available but the reverse diff is.
-U lines
Reduce the number of lines of context of the diff to the specified number of lines. Specify -1 or a high number to avoid reducing the number of lines of context. This is set to -1 by default. You should set it to 3 in most cases so that the effects of -k, -b, -w, and other flags can be more useful.
-w
Attempt to make the patch as if it had been created by diff(1) with the -w option. This removes changes from the input diff for which only whitespace was added or removed.

Examples

This command should be adequate to filter out many auto-generated files that don’t belong in a Version Control System. This will filter out files like config.log, config.status, Makefile, and Makefile.in. It preserves Makefile.am and sourcecode files. Not that -E is used instead of -e because the command utilizes Extended Regular Expressions.


    $ difffilter -E ’(^|/)config.(log|status)$’ -a -E ’(^|/)Makefile.am$’ -x -E ’(^|/)Makefile’
< dirty.patch > clean.patch
If 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.patch
If 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.patch
To 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

See Also

diff(1) , patch(1) , hg(1)

Bugs

There are no known bugs.

There is a bug tracker at http://ohnopub.net/bugzilla/ .

Author

Nathan Phillip Brink (binki) <ohnobinki@ohnopublishing.net>


Table of Contents