Comparing and Merging Files - 9. Merging with patch

Go to the first, previous, next, last section, table of contents.

# 9. Merging with `patch`

`patch` takes comparison output produced by `diff` and applies the differences to a copy of the original file, producing a patched version. With `patch`, you can distribute just the changes to a set of files instead of distributing the entire file set; your correspondents can apply `patch` to update their copy of the files with your changes. `patch` automatically determines the diff format, skips any leading or trailing headers, and uses the headers to determine which file to patch. This lets your correspondents feed an article or message containing a difference listing directly to `patch`.

`patch` detects and warns about common problems like forward patches. It saves the original version of the files it patches, and saves any patches that it could not apply. It can also maintain a `patchlevel.h` file to ensures that your correspondents apply diffs in the proper order.

`patch` accepts a series of diffs in its standard input, usually separated by headers that specify which file to patch. It applies `diff` hunks (see section 1.1 Hunks) one by one. If a hunk does not exactly match the original file, `patch` uses heuristics to try to patch the file as well as it can. If no approximate match can be found, `patch` rejects the hunk and skips to the next hunk. `patch` normally replaces each file f with its new version, saving the original file in ``f.orig'`, and putting reject hunks (if any) into ``f.rej'`.

See section 14. Invoking `patch`, for detailed information on the options to `patch`. See section 14.2 Backup File Names, for more information on how `patch` names backup files. See section 14.3 Reject File Names, for more information on where `patch` puts reject hunks.

## 9.1 Selecting the `patch` Input Format

`patch` normally determines which `diff` format the patch file uses by examining its contents. For patch files that contain particularly confusing leading text, you might need to use one of the following options to force `patch` to interpret the patch file as a certain format of diff. The output formats listed here are the only ones that `patch` can understand.

``-c'`
``--context'`
  context diff.
``-e'`
``--ed'`
  `ed` script.
``-n'`
``--normal'`
  normal diff.
``-u'`
``--unified'`
  unified diff.

## 9.2 Applying Imperfect Patches

`patch` tries to skip any leading text in the patch file, apply the diff, and then skip any trailing text. Thus you can feed a news article or mail message directly to `patch`, and it should work. If the entire diff is indented by a constant amount of white space, `patch` automatically ignores the indentation.

However, certain other types of imperfect input require user intervention.

### 9.2.1 Applying Patches with Changed White Space

Sometimes mailers, editors, or other programs change spaces into tabs, or vice versa. If this happens to a patch file or an input file, the files might look the same, but `patch` will not be able to match them properly. If this problem occurs, use the ``-l'` or ``--ignore-white-space'` option, which makes `patch` compare white space loosely so that any sequence of white space in the patch file matches any sequence of white space in the input files. Non-white-space characters must still match exactly. Each line of the context must still match a line in the input file.

### 9.2.2 Applying Reversed Patches

Sometimes people run `diff` with the new file first instead of second. This creates a diff that is "reversed". To apply such patches, give `patch` the ``-R'` or ``--reverse'` option. `patch` then attempts to swap each hunk around before applying it. Rejects come out in the swapped format. The ``-R'` option does not work with `ed` scripts because there is too little information in them to reconstruct the reverse operation.

Often `patch` can guess that the patch is reversed. If the first hunk of a patch fails, `patch` reverses the hunk to see if it can apply it that way. If it can, `patch` asks you if you want to have the ``-R'` option set; if it can't, `patch` continues to apply the patch normally. This method cannot detect a reversed patch if it is a normal diff and the first command is an append (which should have been a delete) since appends always succeed, because a null context matches anywhere. But most patches add or change lines rather than delete them, so most reversed normal diffs begin with a delete, which fails, and `patch` notices.

If you apply a patch that you have already applied, `patch` thinks it is a reversed patch and offers to un-apply the patch. This could be construed as a feature. If you did this inadvertently and you don't want to un-apply the patch, just answer ``n'` to this offer and to the subsequent "apply anyway" question--or type `C-c` to kill the `patch` process.

### 9.2.3 Helping `patch` Find Inexact Matches

For context diffs, and to a lesser extent normal diffs, `patch` can detect when the line numbers mentioned in the patch are incorrect, and it attempts to find the correct place to apply each hunk of the patch. As a first guess, it takes the line number mentioned in the hunk, plus or minus any offset used in applying the previous hunk. If that is not the correct place, `patch` scans both forward and backward for a set of lines matching the context given in the hunk.

First `patch` looks for a place where all lines of the context match. If it cannot find such a place, and it is reading a context or unified diff, and the maximum fuzz factor is set to 1 or more, then `patch` makes another scan, ignoring the first and last line of context. If that fails, and the maximum fuzz factor is set to 2 or more, it makes another scan, ignoring the first two and last two lines of context are ignored. It continues similarly if the maximum fuzz factor is larger.

The ``-F lines'` or ``--fuzz=lines'` option sets the maximum fuzz factor to lines. This option only applies to context and unified diffs; it ignores up to lines lines while looking for the place to install a hunk. Note that a larger fuzz factor increases the odds of making a faulty patch. The default fuzz factor is 2; it may not be set to more than the number of lines of context in the diff, ordinarily 3.

If `patch` cannot find a place to install a hunk of the patch, it writes the hunk out to a reject file (see section 14.3 Reject File Names, for information on how reject files are named). It writes out rejected hunks in context format no matter what form the input patch is in. If the input is a normal or `ed` diff, many of the contexts are simply null. The line numbers on the hunks in the reject file may be different from those in the patch file: they show the approximate location where `patch` thinks the failed hunks belong in the new file rather than in the old one.

As it completes each hunk, `patch` tells you whether the hunk succeeded or failed, and if it failed, on which line (in the new file) `patch` thinks the hunk should go. If this is different from the line number specified in the diff, it tells you the offset. A single large offset may indicate that `patch` installed a hunk in the wrong place. `patch` also tells you if it used a fuzz factor to make the match, in which case you should also be slightly suspicious.

`patch` cannot tell if the line numbers are off in an `ed` script, and can only detect wrong line numbers in a normal diff when it finds a change or delete command. It may have the same problem with a context diff using a fuzz factor equal to or greater than the number of lines of context shown in the diff (typically 3). In these cases, you should probably look at a context diff between your original and patched input files to see if the changes make sense. Compiling without errors is a pretty good indication that the patch worked, but not a guarantee.

`patch` usually produces the correct results, even when it must make many guesses. However, the results are guaranteed only when the patch is applied to an exact copy of the file that the patch was generated from.

## 9.3 Removing Empty Files

Sometimes when comparing two directories, the first directory contains a file that the second directory does not. If you give `diff` the ``-N'` or ``--new-file'` option, it outputs a diff that deletes the contents of this file. By default, `patch` leaves an empty file after applying such a diff. The ``-E'` or ``--remove-empty-files'` option to `patch` deletes output files that are empty after applying the diff.

## 9.4 Multiple Patches in a File

If the patch file contains more than one patch, `patch` tries to apply each of them as if they came from separate patch files. This means that it determines the name of the file to patch for each patch, and that it examines the leading text before each patch for file names and prerequisite revision level (see section 10. Tips for Making Patch Distributions, for more on that topic).

For the second and subsequent patches in the patch file, you can give options and another original file name by separating their argument lists with a ``+'`. However, the argument list for a second or subsequent patch may not specify a new patch file, since that does not make sense.

For example, to tell `patch` to strip the first three slashes from the name of the first patch in the patch file and none from subsequent patches, and to use ``code.c'` as the first input file, you can use:

    patch -p3 code.c + -p0 < patchfile

The ``-S'` or ``--skip'` option ignores the current patch from the patch file, but continue looking for the next patch in the file. Thus, to ignore the first and third patches in the patch file, you can use:

    patch -S + + -S + < patch file

## 9.5 Messages and Questions from `patch`

`patch` can produce a variety of messages, especially if it has trouble decoding its input. In a few situations where it's not sure how to proceed, `patch` normally prompts you for more information from the keyboard. There are options to suppress printing non-fatal messages and stopping for keyboard input.

The message ``Hmm...'` indicates that `patch` is reading text in the patch file, attempting to determine whether there is a patch in that text, and if so, what kind of patch it is.

You can inhibit all terminal output from `patch`, unless an error occurs, by using the ``-s'`, ``--quiet'`, or ``--silent'` option.

There are two ways you can prevent `patch` from asking you any questions. The ``-f'` or ``--force'` option assumes that you know what you are doing. It assumes the following:

- skip patches that do not contain file names in their headers;
- patch files even though they have the wrong version for the ``Prereq:'` line in the patch;
- assume that patches are not reversed even if they look like they are.

The ``-t'` or ``--batch'` option is similar to ``-f'`, in that it suppresses questions, but it makes somewhat different assumptions:

- skip patches that do not contain file names in their headers (the same as ``-f'`);
- skip patches for which the file has the wrong version for the ``Prereq:'` line in the patch;
- assume that patches are reversed if they look like they are.

`patch` exits with a non-zero status if it creates any reject files. When applying a set of patches in a loop, you should check the exit status, so you don't apply a later patch to a partially patched file.

Go to the first, previous, next, last section, table of contents.