14

I have a directory with .patch files, generated using diff.

I would like to apply all those patches using patch -p1 to another directory.

But patch takes only one file, unless I cat.

What would the command be to apply multiple files using xargs or a similar tool.

3
  • 1
    Then why not upvote them?
    – womble
    Commented Jan 13, 2010 at 20:59
  • A reputation of 15 is required to upvote.
    – styts
    Commented Jan 16, 2010 at 9:55
  • 2
    ah, finally enough points.. both solutions upvoted!
    – styts
    Commented Jul 1, 2010 at 12:28

5 Answers 5

3

If cat works, why not use it?

To use find and xargs:

find dirname -name namespec -print0 | xargs -0 patch patchargs

Example:

find src/networking -type f -name 'network*.patch' -print0 | xargs -0 patch -p2
4
  • what is namespec?? could you put [] around what you should modify?
    – OZZIE
    Commented Sep 25, 2017 at 6:43
  • 1
    @OZZIE: "namespec" represents a file glob, for example 'network*'.patch. I've added an example. Commented Sep 25, 2017 at 13:32
  • do you need to sort the patch files? Commented May 31, 2018 at 3:54
  • @dementedhedgehog: You may need to sort them because find outputs them in the order it finds them. Use sort -z so it works with the null-terminated output Commented May 31, 2018 at 13:05
24

Assuming you're using bash/sh/zsh etc...

cd /path/to/source
for i in /path/to/patches/*.patch; do patch -p1 < $i; done
12

Accepted answer did not work for me, it seems to assume patch can take multiple patch files on one command line. My solution:

find /tmp/patches -type f -name '*.patch' -print0 | sort -z | xargs -t -0 -n 1 patch -p0 -i

Find: Finds patch files

  • /tmp/patches: The directory to search for patch files in
  • -type f: only files
  • -name '*.patch': files which end in .patch
  • -print0: output results to stdout as a list of null-terminated strings

Sort: Sorts patch files so order remains (e.g. 001 comes before 002)

  • -z: input is null terminated (since we used -print0)

xargs: Call patch using stdin as arguments

  • -t: Print command before running it, can remove it for less verbosity
  • -0: stdin is a list that is null terminated
  • -n 1: Call patch again for every 1 item in the list (e.g. call patch N times, instead of building a list and calling it once)
  • -i: argument to patch to tell it the argument will be the patchfile
2

This actually works (in Bash):

shopt -s globstar
for file in /path/to/patches/**/*.patch
do
    patch -p1 < "$file"
done
0

Debian uses a very nice tool called quilt for its package management.

On Debian/Ubuntu install it with

sudo apt install quilt

Take a look at this very nice tutorial from Shakthi Kannan: Quilt Tutorial, even it is a bit older.

To give an overview, take a look at the man page quilt (1):

Quilt is a tool to manage large sets of patches by keeping track of the changes each patch makes. Patches can be applied, un-ap- plied, refreshed, etc. The key philosophical concept is that your primary output is patches. With quilt, all work occurs within a single directory tree. Commands can be invoked from anywhere within the source tree.

Quilt manages a stack of patches. Patches are applied incrementally on top of the base tree plus all preceding patches. They can be pushed on top of the stack (quilt push), and popped off the stack (quilt pop).

Commands are available for querying the contents of the series file (quilt series, see below), the contents of the stack (quilt applied, quilt previous, quilt top), and the patches that are not applied at a particular moment (quilt next, quilt unapplied). By default, most commands apply to the top- most patch on the stack.

A file called series contains a list of patch file names that defines the order in which patches are applied. Unless there are means by which series files can be generated automatically, it is usually provided along with a set of patches. In this file, each patch file name is on a separate line. Patch files are identified by path names that are relative to the patches directory; patches may be in sub-directories below this directory. Lines in the series file that start with a hash character (#) are ignored.

When quilt adds, removes, or renames patches, it automatically updates the series file. Users of quilt can modify series files while some patches are applied, as long as the applied patches remain in their original order. Different series files can be used to assemble patches in different ways, corresponding for example to different development branches.

Before a patch is applied (or ``pushed on the stack''), copies of all files the patch modifies are saved to the .pc/patch directory. The patch is added to the list of currently applied patches (.pc/applied-patches). Later when a patch is regenerated (quilt refresh), the backup copies in .pc/patch are compared with the current versions of the files in the source tree using GNU diff.

To sum it up you can add patches to a file called series and manage it by several ways. You can add, remove patches, and get a list of applied patches, ...

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .