PATCH(1P)

๐ŸŒธ PATCH(1P) โ€” the POSIX Programmer's Manual, bestie edition ๐ŸŒธ

okay so before we even get into it โ€” this is the POSIX Programmer's Manual page for patch, and I need you to know: the Linux implementation of this interface may differ (so pls consult the corresponding Linux manual page for the deets on Linux behavior), and also the interface may not be implemented on Linux at all. just so we're clear, no surprises ๐Ÿ’…


โœจ PROLOG โœจ

This manual page is part of the POSIX Programmer's Manual. The Linux implementation of this interface may differ (consult the corresponding Linux manual page for details on Linux behavior), or the interface may not be implemented on Linux.


๐Ÿ’– NAME ๐Ÿ’–

patch โ€” apply changes to files

like, that's the whole vibe. you have changes. you apply them. iconic.


๐Ÿฆ‹ SYNOPSIS ๐Ÿฆ‹

patch [-blNR] [-c|-e|-n|-u] [-d dir] [-D define] [-i patchfile]
    [-o outfile] [-p num] [-r rejectfile] [file]

look at that little one-liner. so much power in so few characters, fr fr.


๐ŸŒˆ DESCRIPTION ๐ŸŒˆ

Okay so here's the tea โ˜• โ€” patch shall read a source (patch) file containing any of four forms of difference (diff) listings produced by the diff utility, and apply those differences to a file. The four forms are:

  • normal
  • copied context
  • unified context
  • or in the style of ed

By default, patch shall read from the standard input. yes bestie, it just waits there like a good listener ๐Ÿซถ

The patch utility shall attempt to determine the type of the diff listing, unless you overrule it with a -c, -e, -n, or -u option. it's giving detective energy ๐Ÿ”

If the patch file contains more than one patch, patch shall attempt to apply each of them as if they came from separate patch files. (In this case, the application shall ensure that the name of the patch file is determinable for each diff listing.) so like, each patch needs to know its own name, okay? no anonymous patches, this isn't a burner account ๐Ÿ”ฅ


โœจ OPTIONS โœจ

The patch utility shall conform to the Base Definitions volume of POSIX.1โ€2017, Section 12.2, Utility Syntax Guidelines. very demure, very mindful.

The following options shall be supported:

  • -b โ€” Save a copy of the original contents of each modified file, before the differences are applied, in a file of the same name with the suffix .orig appended to it. If the file already exists, it shall be overwritten; if multiple patches are applied to the same file, the .orig file shall be written only for the first patch. When the -o outfile option is also specified, file.orig shall not be created but, if outfile already exists, outfile.orig shall be created. (backup bestie behavior, we love a safety net ๐ŸŽ€)
  • -c โ€” Interpret the patch file as a copied context difference (the output of the utility diff when the -c or -C options are specified).
  • -d dir โ€” Change the current directory to dir before processing as described in the EXTENDED DESCRIPTION section. (we're moving, packing up, new directory era ๐Ÿงณ)
  • -D define โ€” Mark changes with one of the following C preprocessor constructs:
#ifdef define
...
#endif
#ifndef define
...
#endif

optionally combined with the C preprocessor construct #else. If the patched file is processed with the C preprocessor, where the macro define is defined, the output shall contain the changes from the patch file; otherwise, the output shall not contain the patches specified in the patch file. conditional queen ๐Ÿ’…

  • -e โ€” Interpret the patch file as an ed script, rather than a diff script.
  • -i patchfile โ€” Read the patch information from the file named by the pathname patchfile, rather than the standard input.
  • -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. yes this is the lowercase L, not a one, don't get got ๐Ÿ˜ญ
  • -n โ€” Interpret the script as a normal difference.
  • -N โ€” Ignore patches where the differences have already been applied to the file; by default, already-applied patches shall be rejected. so by default it's like "um this is already done?? rejected" and -N is like "it's fine, moving on ๐Ÿ’…"
  • -o outfile โ€” Instead of modifying the files (specified by the file operand or the difference listings) directly, write a copy of the file referenced by each patch, with the appropriate differences applied, to outfile. Multiple patches for a single file shall be applied to the intermediate versions of the file created by any previous patches, and shall result in multiple, concatenated versions of the file being written to outfile. (yes it just keeps stacking them, we love a growing pile ๐Ÿซถ)
  • -p num โ€” For all pathnames in the patch file that indicate the names of files to be patched, delete num pathname components from the beginning of each pathname. If the pathname in the patch file is absolute, any leading <slash> characters shall be considered the first component (that is, -p 1 shall remove the leading <slash> characters). Specifying -p 0 shall cause the full pathname to be used. If -p is not specified, only the basename (the final pathname component) shall be used. (trimming the path like a lil haircut โœ‚๏ธ)
  • -R โ€” Reverse the sense of the patch script; that is, assume that the difference script was created from the new version to the old version. The -R option cannot be used with ed scripts. The patch utility shall attempt to reverse each portion of the script before applying it. Rejected differences shall be saved in swapped format. If this option is not specified, and until a portion of the patch file is successfully applied, patch attempts to apply each portion in its reversed sense as well as in its normal sense. If the attempt is successful, the user shall be prompted to determine whether the -R option should be set. (it's literally asking you "bestie, did you mean to run this backwards?" ๐Ÿ˜ญ)
  • -r rejectfile โ€” Override the default reject filename. In the default case, the reject file shall have the same name as the output file, with the suffix .rej appended to it; see Patch Application.
  • -u โ€” Interpret the patch file as a unified context difference (the output of the diff utility when the -u or -U options are specified).

๐ŸŽ€ OPERANDS ๐ŸŽ€

The following operand shall be supported:

  • file โ€” A pathname of a file to patch.

one operand. one lil pathname. simple. elegant. slay.


๐Ÿ’œ STDIN ๐Ÿ’œ

See the INPUT FILES section. (it's right below, keep scrolling bestie)


๐ŸŒธ INPUT FILES ๐ŸŒธ

Input files shall be text files.


๐Ÿงš ENVIRONMENT VARIABLES ๐Ÿงš

The following environment variables shall affect the execution of patch:

  • LANG โ€” Provide a default value for the internationalization variables that are unset or null. (See the Base Definitions volume of POSIX.1โ€2017, Section 8.2, Internationalization Variables for the precedence of internationalization variables used to determine the values of locale categories.)
  • LC_ALL โ€” If set to a non-empty string value, override the values of all the other internationalization variables. it's the main character, it overrules everyone ๐Ÿ‘‘
  • LC_COLLATE โ€” Determine the locale for the behavior of ranges, equivalence classes, and multi-character collating elements used in the extended regular expression defined for the yesexpr locale keyword in the LC_MESSAGES category.
  • LC_CTYPE โ€” Determine the locale for the interpretation of sequences of bytes of text data as characters (for example, single-byte as opposed to multi-byte characters in arguments and input files), and the behavior of character classes used in the extended regular expression defined for the yesexpr locale keyword in the LC_MESSAGES category.
  • LC_MESSAGES โ€” Determine the locale used to process affirmative responses, and the locale used to affect the format and contents of diagnostic messages and prompts written to standard error.
  • NLSPATH โ€” Determine the location of message catalogs for the processing of LC_MESSAGES.
  • LC_TIME โ€” Determine the locale for recognizing the format of file timestamps written by the diff utility in a context-difference input file. (timestamps, but make it localized โฐ)

โญ ASYNCHRONOUS EVENTS โญ

Default. no drama here, we love a low-maintenance section ๐Ÿซถ


๐Ÿ’– STDOUT ๐Ÿ’–

Not used. it's silent, it's mysterious, it says nothing ๐Ÿ˜Œ


๐Ÿ’œ STDERR ๐Ÿ’œ

The standard error shall be used for diagnostic and informational messages. this is where the yapping happens ๐Ÿ’ฌ


๐ŸŽ€ OUTPUT FILES ๐ŸŽ€

The output of the patch utility, the save files (.orig suffixes), and the reject files (.rej suffixes) shall be text files. all text, all the time, no binary nonsense ๐Ÿ’…

๐ŸŒธ EXTENDED DESCRIPTION ๐ŸŒธ

okay so a single patch file can carry patching instructions for more than one file, bestie. The filenames get figured out exactly like it says in Filename Determination (we're getting there, hold on).

When you pass the -b option, for every patched file the original gets saved into a file with the same name, with the suffix .orig tacked on the end. ๐Ÿ’พ

For each patched file, a reject file may also show up, as mentioned over in Patch Application. If you didn't give a -r option, the name of that reject file is made by appending the suffix .rej to the original filename. ๐Ÿ˜ญ (yes, reject files are a whole mood, we'll get to them)

Patch File Format ๐Ÿ“„

So the patch file contains zero or more lines of header info, followed by one or more patches. Each patch contains zero or more lines of filename identification in the format produced by the -c, -C, -u, or -U options of the diff utility, plus one or more sets of diff output, which everyone customarily calls hunks. ๐Ÿ’…

The patch utility shall recognize this expression in the header information:

  • Index: pathname โ€” the file to be patched is named pathname. slay, mystery solved โœจ

If all the lines (headers included) within a patch start with the same leading sequence of <blank> characters, patch shall strip that sequence out before proceeding. No cap.

Within each patch, if the type of difference is common context, patch shall recognize these expressions:

  • *** filename timestamp โ€” the patches arose from filename.
  • --- filename timestamp โ€” the patches should be applied to filename.

And if the type of difference is unified context, it shall recognize these:

  • --- filename timestamp โ€” the patches arose from filename.
  • +++ filename timestamp โ€” the patches should be applied to filename.
โš ๏ธ not me pointing out how the --- line means opposite things depending on which diff flavor you're in. it's giving chaos. keep your eyes open, bestie. ๐Ÿ™ˆ

Each hunk within a patch shall be the diff output needed to change a line range within the original file. And the line numbers for successive hunks within a patch shall occur in ascending order โ€” no going backwards, that's the rule.

Filename Determination ๐Ÿ”

If you don't hand it a file operand, patch shall do these steps, in order, to figure out which filename to use:

  1. If the type of diff is context, the patch utility shall delete pathname components (as specified by the -p option) from the filename on the line beginning with *** (if copied context) or --- (if unified context), then test whether this file exists relative to the current directory (or the directory specified with the -d option). If the file exists, patch shall use this filename. ๐ŸŽฏ
  2. If the type of diff is context, patch shall delete the pathname components (as specified by the -p option) from the filename on the line beginning with --- (if copied context) or +++ (if unified context), then test whether this file exists relative to the current directory (or the directory specified with the -d option). If the file exists, patch shall use this filename.
  3. If the header information contains a line beginning with the string Index:, patch shall delete pathname components (as specified by the -p option) from this line, then test whether this file exists relative to the current directory (or the directory specified with the -d option). If the file exists, patch shall use this filename.
  4. If an SCCS directory exists in the current directory, patch shall attempt to perform a get -e SCCS/s.filename command to retrieve an editable version of the file. If the file exists, patch shall use this filename. (old-school behavior but okay, respect the elders ๐Ÿ‘‘)
  5. The patch utility shall write a prompt to standard output and request a filename interactively from the controlling terminal (for example, /dev/tty). bestie it's literally going to just ask you ๐Ÿ˜ญ

Patch Application ๐Ÿฉน

If the -c, -e, -n, or -u option is present, patch shall interpret the info inside each hunk as a copied context difference, an ed difference, a normal difference, or a unified context difference, respectively. If none of those options are given, patch shall figure out the type of difference by looking at the format of the information inside the hunk. detective mode ๐Ÿ”Žโœจ

For each hunk, patch shall start searching for the place to apply the patch at the line number at the beginning of the hunk, plus or minus any offset used while applying the previous hunk. If it can't find lines matching the hunk context, patch shall scan both forwards and backwards at least 1000 bytes for a set of lines that match the hunk context. go off, search party ๐Ÿ•ต๏ธ

If no such place is found and it's a context difference, then another scan happens, ignoring the first and last line of context. If that fails too, the first two and last two lines of context get ignored and another scan is made. Implementations may search more extensively for installation locations. (fr fr, they're allowed to try harder)

If no location can be found at all, patch shall append the hunk to the reject file. ๐Ÿ’€ A rejected hunk that is a copied context difference, an ed difference, or a normal difference shall be written in copied-context-difference format, no matter what format the patch file itself was in. It is implementation-defined whether a rejected hunk that is a unified context difference gets written in copied-context-difference format or in unified-context-difference format. And if the input was a normal or ed-style difference, the reject file may contain differences with zero lines of context. Also โ€” the line numbers on the hunks in the reject file may be different from the line numbers in the patch file, because they shall reflect the approximate locations for the failed hunks in the new file rather than the old one. yes that's a lot. yes it matters. ๐Ÿซถ

If the type of patch is an ed diff, the implementation may accomplish the patching by invoking the ed utility.


๐Ÿ’– EXIT STATUS ๐Ÿ’–

These are the exit values, bestie, memorize them:

  • 0 โ€” Successful completion. we ate. ๐ŸŽ€
  • 1 โ€” One or more lines were written to a reject file. ๐Ÿ˜ฌ
  • >1 โ€” An error occurred. ๐Ÿ’€

๐ŸŒˆ CONSEQUENCES OF ERRORS ๐ŸŒˆ

Patches that cannot be correctly placed in the file shall be written to a reject file.

The following sections are informative. (iykyk โ€” that means "not normative", keep reading)

โœจ APPLICATION USAGE โœจ

The -R option does not work with ed scripts, because there's just too little information to reconstruct the reverse operation. it's giving "we tried and the math wasn't mathing" ๐Ÿ˜ญ

The -p option makes it possible to customize a patch file to local user directory structures without manually editing the patch file. For example, if the filename in the patch file was:

/curds/whey/src/blurfl/blurfl.c

Setting -p 0 gives the entire pathname unmodified. -p 1 gives:

curds/whey/src/blurfl/blurfl.c

(without the leading <slash>), -p 4 gives:

blurfl/blurfl.c

and not specifying -p at all gives:

blurfl.c

โœจ iconic, truly the glow-up of pathnames.

๐ŸŒธ EXAMPLES ๐ŸŒธ

None. (yes, actually none, don't come for me ๐Ÿ™ˆ)

๐Ÿง  RATIONALE ๐Ÿง 

Some of the functionality in historical patch implementations was never specified. The following documents those features present in historical implementations that have not been specified. sit down, storytime ๐Ÿ“–

A deleted piece of functionality was the + pseudo-option, which let you give an additional set of options and a patch file operand. This was seen as being insufficiently useful to standardize. rip bozo ๐Ÿชฆ

In historical implementations, if the string Prereq: appeared in the header, the patch utility would search for the corresponding version information (the string specified in the header, delimited by <blank> characters or the beginning or end of a line or the file) anywhere in the original file. This was deleted as too simplistic and insufficiently trustworthy a mechanism to standardize. For example, if:

Prereq: 1.2

were in the header, the presence of a delimited 1.2 anywhere in the file would satisfy the prerequisite. yeah. anywhere. not it. ๐Ÿ™…

The following options were dropped from historical implementations of patch as insufficiently useful to standardize:

  • -b โ€” The -b option historically provided a method for changing the name extension of the backup file from the default .orig. This option has been modified and retained in this volume of POSIX.1โ€2017. ๐Ÿ‘‘ (glow-up arc complete)
  • -F โ€” The -F option specified the number of lines of a context diff to ignore when searching for a place to install a patch.
  • -f โ€” The -f option historically caused patch not to request additional information from the user.
  • -r โ€” The -r option historically provided a method of overriding the extension of the reject file from the default .rej.
  • -s โ€” The -s option historically caused patch to work silently unless an error occurred.
  • -x โ€” The -x option historically set internal debugging flags.

In some file system implementations, saving a .orig file may produce unwanted results. In the case of 12, 13, or 14-character filenames (on file systems supporting 14-character maximum filenames), the .orig file overwrites the new file. ๐Ÿ’€ The reject file may also exceed this filename limit. It was suggested, due to some historical practice, that a <tilde> (~) suffix be used instead of .orig and some other character instead of the .rej suffix. This was rejected because it is not obvious to the user which file is which. The suffixes .orig and .rej are clearer and more understandable. (periodt, clarity won ๐Ÿ†)

The -b option has the opposite sense in some historical implementations โ€” do not save the .orig file. The default case here is not to save the files, making patch behave more consistently with the other standard utilities.

The -w option in early proposals was changed to -l to match historical practice.

The -N option was included because without it, a non-interactive application cannot reject previously applied patches. For example, if a user is piping the output of diff into the patch utility, and the user only wants to patch a file to a newer version non-interactively, the -N option is required. ๐Ÿซถ

Changes to the -l option description were proposed to allow matching across <newline> characters in addition to just <blank> characters. Since this is not historical practice, and since some ambiguities could result, it is suggested that future developments in this area utilize another option letter, such as -L.

The -u option of GNU patch has been added, along with support for unified context formats. โœจ

๐Ÿ”ฎ FUTURE DIRECTIONS ๐Ÿ”ฎ

None.

๐Ÿ‘€ SEE ALSO ๐Ÿ‘€

diff, ed

The Base Definitions volume of POSIX.1โ€2017, Chapter 8, Environment Variables, Section 12.2, Utility Syntax Guidelines

Okay bestie, here's the legal tea โ€” read it, don't skip it, it's giving "important and also kind of iconic." โœจ

Portions of this text are reprinted and reproduced in electronic form from IEEE Std 1003.1-2017, Standard for Information Technology -- Portable Operating System Interface (POSIX), The Open Group Base Specifications Issue 7, 2018 Edition, Copyright (C) 2018 by the Institute of Electrical and Electronics Engineers, Inc and The Open Group. In the event of any discrepancy between this version and the original IEEE and The Open Group Standard, the original IEEE and The Open Group Standard is the referee document. The original Standard can be obtained online at http://www.opengroup.org/unix/online.html .

Lowkey crucial: if this page and the original IEEE + The Open Group Standard ever disagree, the original is the referee. Like, it's the final boss. Not this page. ๐Ÿซถ

Any typographical or formatting errors that appear in this page are most likely to have been introduced during the conversion of the source files to man page format. To report such errors, see https://www.kernel.org/doc/man-pages/reporting_bugs.html .


And that's the whole page, bestie!! You literally read an entire POSIX man page, main character behavior fr fr. ๐ŸŽ€ This one came from IEEE/The Open Group, dated 2017, and it's filed under PATCH(1P) โ€” so now you know the vibes, the flags, and the copyright. Go forth and patch responsibly, protect ya files, and remember: always check the exit status. No cap. ๐Ÿ’…๐Ÿฆ‹๐ŸŒธ

๐Ÿ“ฆ where this page comes from