logo

oasis-root

Compiled tree of Oasis Linux based on own branch at <https://hacktivis.me/git/oasis/> git clone https://anongit.hacktivis.me/git/oasis-root.git

patch.1 (19985B)


  1. .\" $OpenBSD: patch.1,v 1.37 2024/03/22 19:22:23 jcs Exp $
  2. .\" Copyright 1986, Larry Wall
  3. .\"
  4. .\" Redistribution and use in source and binary forms, with or without
  5. .\" modification, are permitted provided that the following condition
  6. .\" is met:
  7. .\" 1. Redistributions of source code must retain the above copyright
  8. .\" notice, this condition and the following disclaimer.
  9. .\"
  10. .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  11. .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  12. .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  13. .\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  14. .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  15. .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  16. .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  17. .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  18. .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  19. .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  20. .\" SUCH DAMAGE.
  21. .\"
  22. .Dd $Mdocdate: March 22 2024 $
  23. .Dt PATCH 1
  24. .Os
  25. .Sh NAME
  26. .Nm patch
  27. .Nd apply a diff file to an original
  28. .Sh SYNOPSIS
  29. .Nm patch
  30. .Bk -words
  31. .Op Fl bCcEeflNnRstuv
  32. .Op Fl B Ar backup-prefix
  33. .Op Fl D Ar symbol
  34. .Op Fl d Ar directory
  35. .Op Fl F Ar max-fuzz
  36. .Op Fl i Ar patchfile
  37. .Op Fl o Ar out-file
  38. .Op Fl p Ar strip-count
  39. .Op Fl r Ar rej-name
  40. .Op Fl V Cm t | nil | never | none
  41. .Op Fl x Ar number
  42. .Op Fl z Ar backup-ext
  43. .Op Fl Fl posix
  44. .Op Ar origfile Op Ar patchfile
  45. .Ek
  46. .Nm patch
  47. .Pf \*(Lt Ar patchfile
  48. .Sh DESCRIPTION
  49. .Nm
  50. takes the text file
  51. .Ar patchfile
  52. containing any of the four forms of difference
  53. listing produced by the
  54. .Xr diff 1
  55. program and applies those differences to an original text file,
  56. producing a patched version.
  57. If
  58. .Ar patchfile
  59. is omitted, or is a hyphen, the patch will be read from the standard input.
  60. .Pp
  61. .Nm
  62. will attempt to determine the type of the diff listing, unless overruled by a
  63. .Fl c ,
  64. .Fl e ,
  65. .Fl n ,
  66. or
  67. .Fl u
  68. option.
  69. .Pp
  70. If the
  71. .Ar patchfile
  72. contains more than one patch,
  73. .Nm
  74. will try to apply each of them as if they came from separate patch files.
  75. This means, among other things, that it is assumed that the name of the file
  76. to patch must be determined for each diff listing, and that the garbage before
  77. each diff listing will be examined for interesting things such as file names
  78. and revision level (see the section on
  79. .Sx Filename Determination
  80. below).
  81. .Pp
  82. The options are as follows:
  83. .Bl -tag -width Ds
  84. .It Xo
  85. .Fl B Ar backup-prefix ,
  86. .Fl Fl prefix Ar backup-prefix
  87. .Xc
  88. Causes the next argument to be interpreted as a prefix to the backup file
  89. name.
  90. If this argument is specified, any argument to
  91. .Fl z
  92. will be ignored.
  93. .It Fl b , Fl Fl backup
  94. Save a backup copy of the file before it is modified.
  95. By default the original file is saved with a backup extension of
  96. .Qq .orig
  97. unless the file already has a numbered backup, in which case a numbered
  98. backup is made.
  99. This is equivalent to specifying
  100. .Qo Fl V Cm existing Qc .
  101. This option is currently the default, unless
  102. .Fl -posix
  103. is specified.
  104. .It Fl C , Fl Fl check , Fl Fl dry-run
  105. Checks that the patch would apply cleanly, but does not modify anything.
  106. .It Fl c , Fl Fl context
  107. Forces
  108. .Nm
  109. to interpret the patch file as a context diff.
  110. .It Xo
  111. .Fl D Ar symbol ,
  112. .Fl Fl ifdef Ar symbol
  113. .Xc
  114. Causes
  115. .Nm
  116. to use the
  117. .Qq #ifdef...#endif
  118. construct to mark changes.
  119. The argument following will be used as the differentiating symbol.
  120. Note that, unlike the C compiler, there must be a space between the
  121. .Fl D
  122. and the argument.
  123. .It Xo
  124. .Fl d Ar directory ,
  125. .Fl Fl directory Ar directory
  126. .Xc
  127. Causes
  128. .Nm
  129. to interpret the next argument as a directory,
  130. and change working directory to it before doing anything else.
  131. .It Fl E , Fl Fl remove-empty-files
  132. Causes
  133. .Nm
  134. to remove output files that are empty after the patches have been applied.
  135. This option is useful when applying patches that create or remove files.
  136. .It Fl e , Fl Fl ed
  137. Forces
  138. .Nm
  139. to interpret the patch file as an
  140. .Xr ed 1
  141. script.
  142. .It Xo
  143. .Fl F Ar max-fuzz ,
  144. .Fl Fl fuzz Ar max-fuzz
  145. .Xc
  146. Sets the maximum fuzz factor.
  147. This option only applies to context diffs, and causes
  148. .Nm
  149. to ignore up to that many lines in looking for places to install a hunk.
  150. Note that a larger fuzz factor increases the odds of a faulty patch.
  151. The default fuzz factor is 2, and it may not be set to more than
  152. the number of lines of context in the context diff, ordinarily 3.
  153. .It Fl f , Fl Fl force
  154. Forces
  155. .Nm
  156. to assume that the user knows exactly what they are doing, and to not
  157. ask any questions.
  158. It assumes the following:
  159. skip patches for which a file to patch can't be found;
  160. patch files even though they have the wrong version for the
  161. .Qq Prereq:
  162. line in the patch;
  163. and assume that patches are not reversed even if they look like they are.
  164. This option does not suppress commentary; use
  165. .Fl s
  166. for that.
  167. .It Xo
  168. .Fl i Ar patchfile ,
  169. .Fl Fl input Ar patchfile
  170. .Xc
  171. Causes the next argument to be interpreted as the input file name
  172. (i.e. a patchfile).
  173. .It Fl l , Fl Fl ignore-whitespace
  174. Causes the pattern matching to be done loosely, in case the tabs and
  175. spaces have been munged in your input file.
  176. Any sequence of whitespace in the pattern line will match any sequence
  177. in the input file.
  178. Normal characters must still match exactly.
  179. Each line of the context must still match a line in the input file.
  180. .It Fl N , Fl Fl forward
  181. Causes
  182. .Nm
  183. to ignore patches that it thinks are reversed or already applied.
  184. See also
  185. .Fl R .
  186. .It Fl n , Fl Fl normal
  187. Forces
  188. .Nm
  189. to interpret the patch file as a normal diff.
  190. .It Xo
  191. .Fl o Ar out-file ,
  192. .Fl Fl output Ar out-file
  193. .Xc
  194. Causes the next argument to be interpreted as the output file name.
  195. .It Xo
  196. .Fl p Ar strip-count ,
  197. .Fl Fl strip Ar strip-count
  198. .Xc
  199. Sets the pathname strip count,
  200. which controls how pathnames found in the patch file are treated,
  201. in case you keep your files in a different directory than the person who sent
  202. out the patch.
  203. The strip count specifies how many slashes are to be stripped from
  204. the front of the pathname.
  205. (Any intervening directory names also go away.)
  206. For example, supposing the file name in the patch file was
  207. .Pa /u/howard/src/blurfl/blurfl.c :
  208. .Pp
  209. Setting
  210. .Fl p Ns Ar 0
  211. gives the entire pathname unmodified.
  212. .Pp
  213. .Fl p Ns Ar 1
  214. gives
  215. .Pp
  216. .D1 Pa u/howard/src/blurfl/blurfl.c
  217. .Pp
  218. without the leading slash.
  219. .Pp
  220. .Fl p Ns Ar 4
  221. gives
  222. .Pp
  223. .D1 Pa blurfl/blurfl.c
  224. .Pp
  225. Not specifying
  226. .Fl p
  227. at all just gives you
  228. .Pa blurfl.c ,
  229. unless all of the directories in the leading path
  230. .Pq Pa u/howard/src/blurfl
  231. exist and that path is relative,
  232. in which case you get the entire pathname unmodified.
  233. Whatever you end up with is looked for either in the current directory,
  234. or the directory specified by the
  235. .Fl d
  236. option.
  237. .It Fl R , Fl Fl reverse
  238. Tells
  239. .Nm
  240. that this patch was created with the old and new files swapped.
  241. (Yes, I'm afraid that does happen occasionally, human nature being what it
  242. is.)
  243. .Nm
  244. will attempt to swap each hunk around before applying it.
  245. Rejects will come out in the swapped format.
  246. The
  247. .Fl R
  248. option will not work with ed diff scripts because there is too little
  249. information to reconstruct the reverse operation.
  250. .Pp
  251. If the first hunk of a patch fails,
  252. .Nm
  253. will reverse the hunk to see if it can be applied that way.
  254. If it can, you will be asked if you want to have the
  255. .Fl R
  256. option set.
  257. If it can't, the patch will continue to be applied normally.
  258. (Note: this method cannot detect a reversed patch if it is a normal diff
  259. and if the first command is an append (i.e. it should have been a delete)
  260. since appends always succeed, due to the fact that a null context will match
  261. anywhere.
  262. Luckily, most patches add or change lines rather than delete them, so most
  263. reversed normal diffs will begin with a delete, which will fail, triggering
  264. the heuristic.)
  265. .It Xo
  266. .Fl r Ar rej-name ,
  267. .Fl Fl reject-file Ar rej-name
  268. .Xc
  269. Causes the next argument to be interpreted as the reject file name.
  270. .It Xo
  271. .Fl s , Fl Fl quiet ,
  272. .Fl Fl silent
  273. .Xc
  274. Makes
  275. .Nm
  276. do its work silently, unless an error occurs.
  277. .It Fl t , Fl Fl batch
  278. Similar to
  279. .Fl f ,
  280. in that it suppresses questions, but makes some different assumptions:
  281. skip patches for which a file to patch can't be found (the same as
  282. .Fl f ) ;
  283. skip patches for which the file has the wrong version for the
  284. .Qq Prereq:
  285. line in the patch;
  286. and assume that patches are reversed if they look like they are.
  287. .It Fl u , Fl Fl unified
  288. Forces
  289. .Nm
  290. to interpret the patch file as a unified context diff (a unidiff).
  291. .It Xo
  292. .Fl V Cm t | nil | never | none ,
  293. .Fl Fl version-control Cm t | nil | never | none
  294. .Xc
  295. Causes the next argument to be interpreted as a method for creating
  296. backup file names.
  297. The type of backups made can also be given in the
  298. .Ev PATCH_VERSION_CONTROL
  299. or
  300. .Ev VERSION_CONTROL
  301. environment variables, which are overridden by this option.
  302. The
  303. .Fl B
  304. option overrides this option, causing the prefix to always be used for
  305. making backup file names.
  306. The values of the
  307. .Ev PATCH_VERSION_CONTROL
  308. and
  309. .Ev VERSION_CONTROL
  310. environment variables and the argument to the
  311. .Fl V
  312. option are like the GNU Emacs
  313. .Dq version-control
  314. variable; they also recognize synonyms that are more descriptive.
  315. The valid values are (unique abbreviations are accepted):
  316. .Bl -tag -width Ds -offset indent
  317. .It Cm t , numbered
  318. Always make numbered backups.
  319. .It Cm nil , existing
  320. Make numbered backups of files that already have them,
  321. simple backups of the others.
  322. .It Cm never , simple
  323. Always make simple backups.
  324. .It Cm none
  325. Do not make backups.
  326. .El
  327. .It Fl v , Fl Fl version
  328. Causes
  329. .Nm
  330. to print out its revision header and patch level.
  331. .It Xo
  332. .Fl x Ar number ,
  333. .Fl Fl debug Ar number
  334. .Xc
  335. Sets internal debugging flags, and is of interest only to
  336. .Nm
  337. patchers.
  338. .It Xo
  339. .Fl z Ar backup-ext ,
  340. .Fl Fl suffix Ar backup-ext
  341. .Xc
  342. Causes the next argument to be interpreted as the backup extension, to be
  343. used in place of
  344. .Qq .orig .
  345. .It Fl Fl posix
  346. Enables strict
  347. .St -p1003.1-2008
  348. conformance, specifically:
  349. .Bl -enum
  350. .It
  351. Backup files are not created unless the
  352. .Fl b
  353. option is specified.
  354. .It
  355. If unspecified, the file name used is the first of the old, new and
  356. index files that exists.
  357. .El
  358. .El
  359. .Ss Patch Application
  360. .Nm
  361. will try to skip any leading garbage, apply the diff,
  362. and then skip any trailing garbage.
  363. Thus you could feed an article or message containing a
  364. diff listing to
  365. .Nm patch ,
  366. and it should work.
  367. If the entire diff is indented by a consistent amount,
  368. this will be taken into account.
  369. .Pp
  370. With context diffs, and to a lesser extent with normal diffs,
  371. .Nm
  372. can detect when the line numbers mentioned in the patch are incorrect,
  373. and will attempt to find the correct place to apply each hunk of the patch.
  374. As a first guess, it takes the line number mentioned for the hunk, plus or
  375. minus any offset used in applying the previous hunk.
  376. If that is not the correct place,
  377. .Nm
  378. will scan both forwards and backwards for a set of lines matching the context
  379. given in the hunk.
  380. First
  381. .Nm
  382. looks for a place where all lines of the context match.
  383. If no such place is found, and it's a context diff, and the maximum fuzz factor
  384. is set to 1 or more, then another scan takes place ignoring the first and last
  385. line of context.
  386. If that fails, and the maximum fuzz factor is set to 2 or more,
  387. the first two and last two lines of context are ignored,
  388. and another scan is made.
  389. .Pq The default maximum fuzz factor is 2.
  390. .Pp
  391. If
  392. .Nm
  393. cannot find a place to install that hunk of the patch, it will put the hunk
  394. out to a reject file, which normally is the name of the output file plus
  395. .Qq .rej .
  396. (Note that the rejected hunk will come out in context diff form whether the
  397. input patch was a context diff or a normal diff.
  398. If the input was a normal diff, many of the contexts will simply be null.)
  399. The line numbers on the hunks in the reject file may be different than
  400. in the patch file: they reflect the approximate location patch thinks the
  401. failed hunks belong in the new file rather than the old one.
  402. .Pp
  403. As each hunk is completed, you will be told whether the hunk succeeded or
  404. failed, and which line (in the new file)
  405. .Nm
  406. thought the hunk should go on.
  407. If this is different from the line number specified in the diff,
  408. you will be told the offset.
  409. A single large offset MAY be an indication that a hunk was installed in the
  410. wrong place.
  411. You will also be told if a fuzz factor was used to make the match, in which
  412. case you should also be slightly suspicious.
  413. .Ss Filename Determination
  414. If no original file is specified on the command line,
  415. .Nm
  416. will try to figure out from the leading garbage what the name of the file
  417. to edit is.
  418. When checking a prospective file name, pathname components are stripped
  419. as specified by the
  420. .Fl p
  421. option and the file's existence and writability are checked relative
  422. to the current working directory (or the directory specified by the
  423. .Fl d
  424. option).
  425. .Pp
  426. If the diff is a context or unified diff,
  427. .Nm
  428. is able to determine the old and new file names from the diff header.
  429. For context diffs, the
  430. .Dq old
  431. file is specified in the line beginning with
  432. .Qq ***
  433. and the
  434. .Dq new
  435. file is specified in the line beginning with
  436. .Qq --- .
  437. For a unified diff, the
  438. .Dq old
  439. file is specified in the line beginning with
  440. .Qq ---
  441. and the
  442. .Dq new
  443. file is specified in the line beginning with
  444. .Qq +++ .
  445. If there is an
  446. .Qq Index:
  447. line in the leading garbage (regardless of the diff type),
  448. .Nm
  449. will use the file name from that line as the
  450. .Dq index
  451. file.
  452. .Pp
  453. .Nm
  454. will choose the file name by performing the following steps, with the first
  455. match used:
  456. .Bl -enum
  457. .It
  458. If
  459. .Nm
  460. is operating in strict
  461. .St -p1003.1-2008
  462. mode, the first of the
  463. .Dq old ,
  464. .Dq new
  465. and
  466. .Dq index
  467. file names that exist is used.
  468. Otherwise,
  469. .Nm
  470. will examine either the
  471. .Dq old
  472. and
  473. .Dq new
  474. file names or, for a non-context diff, the
  475. .Dq index
  476. file name, and choose the file name with the fewest path components,
  477. the shortest basename, and the shortest total file name length (in that order).
  478. .It
  479. If no suitable file was found to patch, the patch file is a context or
  480. unified diff, and the old file was zero length, the new file name is
  481. created and used.
  482. .It
  483. If the file name still cannot be determined,
  484. .Nm
  485. will prompt the user for the file name to use.
  486. .El
  487. .Pp
  488. Additionally, if the leading garbage contains a
  489. .Qq Prereq:\ \&
  490. line,
  491. .Nm
  492. will take the first word from the prerequisites line (normally a version
  493. number) and check the input file to see if that word can be found.
  494. If not,
  495. .Nm
  496. will ask for confirmation before proceeding.
  497. .Pp
  498. The upshot of all this is that you should be able to say, while in a news
  499. interface, the following:
  500. .Pp
  501. .Dl | patch -d /usr/src/local/blurfl
  502. .Pp
  503. and patch a file in the blurfl directory directly from the article containing
  504. the patch.
  505. .Ss Backup Files
  506. By default, the patched version is put in place of the original, with
  507. the original file backed up to the same name with the extension
  508. .Qq .orig ,
  509. or as specified by the
  510. .Fl B ,
  511. .Fl V ,
  512. or
  513. .Fl z
  514. options.
  515. The extension used for making backup files may also be specified in the
  516. .Ev SIMPLE_BACKUP_SUFFIX
  517. environment variable, which is overridden by the options above.
  518. .Pp
  519. If the backup file is a symbolic or hard link to the original file,
  520. .Nm
  521. creates a new backup file name by changing the first lowercase letter
  522. in the last component of the file's name into uppercase.
  523. If there are no more lowercase letters in the name,
  524. it removes the first character from the name.
  525. It repeats this process until it comes up with a
  526. backup file that does not already exist or is not linked to the original file.
  527. .Pp
  528. You may also specify where you want the output to go with the
  529. .Fl o
  530. option; if that file already exists, it is backed up first.
  531. .Ss Notes For Patch Senders
  532. There are several things you should bear in mind if you are going to
  533. be sending out patches:
  534. .Pp
  535. First, you can save people a lot of grief by keeping a
  536. .Pa patchlevel.h
  537. file which is patched to increment the patch level as the first diff in the
  538. patch file you send out.
  539. If you put a
  540. .Qq Prereq:
  541. line in with the patch, it won't let them apply
  542. patches out of order without some warning.
  543. .Pp
  544. Second, make sure you've specified the file names right, either in a
  545. context diff header, or with an
  546. .Qq Index:
  547. line.
  548. If you are patching something in a subdirectory, be sure to tell the patch
  549. user to specify a
  550. .Fl p
  551. option as needed.
  552. .Pp
  553. Third, you can create a file by sending out a diff that compares a
  554. null file to the file you want to create.
  555. This will only work if the file you want to create doesn't exist already in
  556. the target directory.
  557. .Pp
  558. Fourth, take care not to send out reversed patches, since it makes people wonder
  559. whether they already applied the patch.
  560. .Pp
  561. Fifth, while you may be able to get away with putting 582 diff listings into
  562. one file, it is probably wiser to group related patches into separate files in
  563. case something goes haywire.
  564. .Sh ENVIRONMENT
  565. .Bl -tag -width "PATCH_VERSION_CONTROL" -compact
  566. .It Ev POSIXLY_CORRECT
  567. When set,
  568. .Nm
  569. behaves as if the
  570. .Fl Fl posix
  571. option has been specified.
  572. .It Ev SIMPLE_BACKUP_SUFFIX
  573. Extension to use for backup file names instead of
  574. .Qq .orig .
  575. .It Ev TMPDIR
  576. Directory to put temporary files in; default is
  577. .Pa /tmp .
  578. .It Ev PATCH_VERSION_CONTROL
  579. Selects when numbered backup files are made.
  580. .It Ev VERSION_CONTROL
  581. Same as
  582. .Ev PATCH_VERSION_CONTROL .
  583. .El
  584. .Sh FILES
  585. .Bl -tag -width "$TMPDIR/patch*" -compact
  586. .It Pa $TMPDIR/patch*
  587. .Nm
  588. temporary files
  589. .It Pa /dev/tty
  590. used to read input when
  591. .Nm
  592. prompts the user
  593. .El
  594. .Sh EXIT STATUS
  595. The
  596. .Nm
  597. utility exits with one of the following values:
  598. .Pp
  599. .Bl -tag -width Ds -offset indent -compact
  600. .It 0
  601. Successful completion.
  602. .It 1
  603. One or more lines were written to a reject file.
  604. .It \*(Gt1
  605. An error occurred.
  606. .El
  607. .Pp
  608. When applying a set of patches in a loop, it behooves you to check this
  609. exit status so you don't apply a later patch to a partially patched file.
  610. .Sh DIAGNOSTICS
  611. Too many to list here, but generally indicative that
  612. .Nm
  613. couldn't parse your patch file.
  614. .Pp
  615. The message
  616. .Qq Hmm...
  617. indicates that there is unprocessed text in the patch file and that
  618. .Nm
  619. is attempting to intuit whether there is a patch in that text and, if so,
  620. what kind of patch it is.
  621. .Sh SEE ALSO
  622. .Xr diff 1
  623. .Sh STANDARDS
  624. The
  625. .Nm
  626. utility is compliant with the
  627. .St -p1003.1-2008
  628. specification,
  629. except as detailed above for the
  630. .Fl -posix
  631. option.
  632. .Pp
  633. The flags
  634. .Op Fl BCEFfstVvxz
  635. and
  636. .Op Fl -posix
  637. are extensions to that specification.
  638. .Sh AUTHORS
  639. .An Larry Wall
  640. with many other contributors.
  641. .Sh CAVEATS
  642. .Nm
  643. cannot tell if the line numbers are off in an ed script, and can only detect
  644. bad line numbers in a normal diff when it finds a
  645. .Qq change
  646. or a
  647. .Qq delete
  648. command.
  649. A context diff using fuzz factor 3 may have the same problem.
  650. Until a suitable interactive interface is added, you should probably do
  651. a context diff in these cases to see if the changes made sense.
  652. Of course, compiling without errors is a pretty good indication that the patch
  653. worked, but not always.
  654. .Pp
  655. .Nm
  656. usually produces the correct results, even when it has to do a lot of
  657. guessing.
  658. However, the results are guaranteed to be correct only when the patch is
  659. applied to exactly the same version of the file that the patch was
  660. generated from.
  661. .Sh BUGS
  662. Could be smarter about partial matches, excessively deviant offsets and
  663. swapped code, but that would take an extra pass.
  664. .Pp
  665. Check patch mode
  666. .Pq Fl C
  667. will fail if you try to check several patches in succession that build on
  668. each other.
  669. The entire
  670. .Nm
  671. code would have to be restructured to keep temporary files around so that it
  672. can handle this situation.
  673. .Pp
  674. If code has been duplicated (for instance with #ifdef OLDCODE ... #else ...
  675. #endif),
  676. .Nm
  677. is incapable of patching both versions and, if it works at all, will likely
  678. patch the wrong one, and tell you that it succeeded to boot.
  679. .Pp
  680. If you apply a patch you've already applied,
  681. .Nm
  682. will think it is a reversed patch, and offer to un-apply the patch.
  683. This could be construed as a feature.