makepatch - create script to update a source tree
makepatch [
options ]
old-src new-src
Traditionally, source trees are updated with the
patch program,
processing patch information that is generated by the
diff program.
Although
diff and
patch do a very good job at patching file
contents, most versions do not handle creating and deleting files and
directories, and adjusting of file modes and time stamps. Newer versions of
diff and
patch seem to be able to create files, and very new
versions of
patch can remove files. But that's about it.
Another typical problem is that patch kits are typically downloaded from the
Internet, or transmitted via electronic mail. It is often desirable to verify
the correctness of a patch kit before even attempting to apply it.
The
makepatch package is designed to overcome these limitations.
The
makepatch package contains two Perl programs:
makepatch and
applypatch.
makepatch will generate a patch kit from two source trees. It traverses
the source directory and runs a
diff on each pair of corresponding
files, accumulating the output into a patch kit. It knows about the
conventions for patch kits: if a file named "patchlevel.h" exists,
it is handled first, so
patch can check the version of the source tree.
Also, to deal with the non-perfect versions of
patch that are in use,
it supplies ""Index:"" and ""Prereq:""
lines, so
patch can correctly locate the files to patch, and it
relocates the patch to the current directory to avoid problems with creating
new files.
The list of files can be specified in a so called
MANIFEST file, but it
can also be generated by recursively traversing the source tree. Files can be
excluded using shell style wildcards and Perl regex patterns.
But that is not it!
makepatch also inserts some additional information in
the patch kit for use by the
applypatch program.
It is important to emphasize that the generated patch kit is still valid input
for
patch. When used with
patch, there are no verifications and
problems may arise when new files need to be created.
makepatch
prepends a small shell script in front of the patch kit that creates the
necessary files and directories for the patch process. If you can not run
applypatch for some reason, you can run the patch kit
as a shell
script to prepare the source directory for the patching process.
The
applypatch program will do the following:
- •
- It will extensively verify that the patch kit is complete
and not corrupted during transfer.
- •
- It will apply some heuristics to verify that the directory
in which the patch will be applied does indeed contain the expected
sources.
- •
- It creates files and directories as necessary.
- •
- It applies the patch by running the patch
program.
- •
- Upon completion, obsolete files, directories and
".orig" files are removed, file modes of new files are set, and
the timestamps of all patched files are adjusted.
Note that
applypatch only requires the
patch program. It does not
rely on a shell or shell tools. This makes it possible to apply patches on
non-Unix systems.
Suppose you have an archive `"pkg-1.6.tar.gz"' containing the sources
for package `"pkg"' version 1.6, and a directory tree
`"pkg-1.7"' containing the sources for version 1.7. The following
command will generate a patch kit that updates the 1.6 sources into their 1.7
versions:
makepatch pkg-1.6.tar.gz pkg-1.7 > pkg-1.6-1.7.patch
To apply this script, go to the directory containing the 1.6 sources and feed
the script to
applypatch:
cd old/pkg-1.6
applypatch pkg-1.6-1.7.patch
applypatch will verify that it is executing in the right place and make
all necessary updates.
By default,
makepatch will provide a few lines of progress information,
for example:
Extracting pkg-1.6.tar.gz to /tmp/mp21575.d/old...
Manifest MANIFEST for pkg-1.6 contains 1083 files.
Manifest MANIFEST for pkg-1.7 contains 1292 files.
Processing the filelists ...
Collecting patches ...
266 files need to be patched.
216 files and 8 directories need to be created.
7 files need to be removed.
applypatch will provide no feedback information by default.
makepatch requires two arguments:
old_src and
new_src.
- old-src
- This is the name of either a single file or a directory
that contains copies of the older version of the target files; in other
words, copies of the files prior to any modifications.
Alternatively, it may be the name of an archive that holds the files to be
processed. Allowable archive formats are gzipped tar (name ends in
"".tar.gz"" or "".tgz""), bzipped
tar (name ends in "".tar.bz2""), plain tar (name ends
in "".tar"" and zip (name ends in
"".zip"").
- new-src
- This is the name of either a single file or a directory
that contains copies of the newer version of the target files; in other
words, copies of the files after the modifications have been made.
Alternatively, it may be the name of an archive that holds the files to be
processed.
The patch script generated by
makepatch will take care of creating new
files and directories, update existing files, and remove files and directories
that are no longer present in the
new-src directory.
The purpose of a manifest file is to provide the list of files that constitute a
package. Manifest files are traditionally called
""MANIFEST"" and reside in the top level directory of the
package.
Although there is no formal standard for the contents of manifest files,
makepatch uses the following rules:
- •
- If the second line from the manifest file looks like a
separator line (e.g. it is empty, or contains only dashes), it is
discarded and so is the first line.
- •
- Empty lines and lines that start with a "#" are
ignored.
- •
- If there are multiple space-separated "words" on
a line, the first word is considered to be the filename.
By default,
makepatch looks for files named
""MANIFEST"" in the top level directories of the old and
the new source trees. If these files (or one of them) are found, they are
used. If no manifest file could be found, the package is assumed to consist of
all files in the directory.
The default name of the default manifest file can be modified with the command
line option ""-automanifest"", see Section "Command
line options".
Command line options ""-oldmanifest"" and
""-newmanifest"" can be used to explicitly designate old
and new manifest files. Option ""-manifest"" is a short
way to set one manifest file for both the old and new source trees.
Command line option ""-nomanifest"" can be used to suppress
all manifest file processing. The package is assumed to consist of all files
in the source directories.
makepatch takes several options to control its behaviour. Options are
usually specified on the command line, but
makepatch can take options
from three sources in the following order:
- •
- Environment variable MAKEPATCHINIT.
When this environment variable is set its contents are considered to be
command line options that are processed upon startup. All normal options
are allowed, plus one: -rcfile filename. Option
-rcfile can be used to specify an alternate option file, see
below.
- •
- Options files.
makepatch first tries to process a file named
/etc/makepatchrc. (This is a Unix-ism.) It is okay if this file is
missing.
Next, makepatch will process a file named .makepatchrc in the
user's home directory, if it exists.
After processing this file, makepatch will process a file named
.makepatchrc in the current directory, if it exists. An alternative
name for this file can be specified with option -rcfile in
environment variable MAKEPATCHINIT. This is the only way to specify
an alternative options file name.
In all option files, empty lines and lines starting with ";" or
"#" are ignored. All other lines are considered to contain
options exactly as if they had been supplied on the command line.
- •
- The command line.
Options are matched case insensitive, and may be abbreviated to uniqueness.
-
-description text
- Provide a descriptive text for this patch. Multiple
-description options may be supplied.
If no description is provided, the program try to guess one. This is usually
possible if both directories are simple names, e.g.
'"pkg-1.16"'. If no description can be determined, the program
will ask for one.
-
-diff cmd
- If specified, cmd is the command to be used to
generate the differences between the two versions of the files. If not
specified, this command defaults to ""diff -c"".
For best results, only use ""diff -c"" or
""diff -u"". In any case, it must produce
either context or unified diff output.
-
-patchlevel pfile
- If specified, pfile indicates an alternate file that
is to be used in lieu of " patchlevel.h".
-
-automanifest mfile
-
makepatch will automatically use manifest files of
the given name if they appear in the directories. The default name is
" MANIFEST".
- -nomanifest
- Suppress using manifest files.
-
-manifest mfile
- If specified, mfile indicates the name of the
manifest file which consists of a list of the files contained in both the
old and the new directories.
-
-oldmanifest omfile
- If specified, omfile indicates the name of the
manifest file which consists of a list of the files contained in the
old directory. This option is designed to be used in conjunction
with the -newmanifest option. Note that the old and
new directories must still be indicated.
-
-newmanifest nmfile
- If specified, nmfile indicates the name of the
manifest file which consists of a list of the files contained in the
new directory. This option is designed to be used in conjunction
with the -oldmanifest option. Note that the old and
new directories must still be indicated.
-
-[no]recurse
-
makepatch recurses through directories by default.
Option -norecurse prevents recursion beyond the initial
directories.
-
-[no]follow
- If set, symbolic links to directories are traversed as if
they were real directories.
-
-infocmd command
- If specified, the output of running command will be
added before each patch chunk. command will undergo the following
substitutions first: %oP will be replaced by the name of the old file, %nP
will be replaced by the name of the new file. "%%" will be
replaced by a single "%"; other "%" sequences may be
added in future versions. When a new file is being created, the name of
the new file will be supplied for both %oP and %nP.
Note that %oP and %nP are modeled after the "%" sequences of
find -printf.
-
-exclude pattern
- If specified, files that match the shell pattern
pattern will be excluded. Only wildcard characters "*"
and "?", and character classes "[...]" are handled.
Multiple -exclude options may be supplied.
-
-exclude-regex pattern
- If specified, files and directories that match the Perl
regular expression pattern pattern will be excluded. Multiple
-exclude-regex options may be supplied.
-
-[no]exclude-standard
- Set by default. If set, a common set of files and
directories are ignored.
See also section "Standard Exclude Patterns".
-
-[no]exclude-cvs
- If set, files and directories that are usually part of
version control system CVS are excluded.
Also, ".cvsignore" files are honoured just like CVS does it.
See also section "Standard Exclude Patterns".
-
-[no]exclude-rcs
- If set, files and directories that are usually part of
version control system RCS are excluded.
See also section "Standard Exclude Patterns".
-
-[no]exclude-sccs
- If set, files and directories that are usually part of
version control system SCCS are excluded.
See also section "Standard Exclude Patterns".
-
-[no]exclude-vc
- Short for (re)setting -exclude-rcs,
-exclude-cvs, and -exclude-sccs.
-
-[no]ignore-cvs-keywords
- Differences in CVS keyword data (e.g. "Id",
"Header", "Revision") are ignored, provided there are
no other differences in the same hunk. This option passes a very hairy
regex to the --ignore-matching-lines option of the diff
program, and hence requires GNU diff. This restriction may be
lifted in a future version.
-
-[no]ignore-rcs-keywords
- Same as -[no]ignore-cvs-keywords.
-
-extract pattern=command
- Define additional extraction rules for archives. If the
name of the source or destination matches the Perl pattern, the
command is executed with the archive on standard input and the
current directory set to the location where the files must be extracted.
Multiple -extract options may be supplied. User defined rules
override built-in rules.
Builtin rules are:
.+\.(tar\.gz|tgz) => "gzip -d | tar xpf -"
.+\.(tar\.bz2) => "bzip2 -d | tar xpf -"
.+\.tar => "tar xf -"
.+\.zip => "unzip -"
The patterns are implicitly anchored to the begin and end of the
filename.
-
-[no]ident
- If set, the program name and version is reported.
-
-[no]verbose
- This is set by default, making makepatch display
information concerning its activity to stderr.
-
-[no]quiet
- The opposite of -verbose. If set, this instructs
makepatch to suppress the display of activity information.
-
-[no]help
- If set, this causes a short help message to be displayed,
after which the program immediately exits.
The following file patterns are always excluded:
*~ *.a *.bak *.BAK *.elc *.exe *.gz *.ln *.o *.obj
*.olb *.old *.orig *.rej *.so *.Z
.del-* .make.state .nse_depinfo core
tags TAGS
Option
-exclude-sccs adds:
p.* s.* SCCS
Option
-exclude-rcs adds:
,* *,v RCS RCSLOG
Option
-exclude-cvs adds ".cvsignore" patterns, and:
.#* #* _$* *$ CVS CVS.adm cvslog.*
Please let me know if I missed some.
- MAKEPATCHINIT
- When this environment variable is set its contents is
considered to be command line options that are processed upon startup. All
normal options are allowed, plus one: -rcfile filename. If
-rcfile is specified, the file is read and all lines of it are
considered to contain option settings as described in section
"Makepatch options".
- TMPDIR
- "TMPDIR" can be used to designate the area where
temporary files are placed. It defaults to "/tmp".
- TEMP
- "TEMP" can be used as an alternative to
"TMPDIR".
Suppose you have a directory tree `"pkg-1.6"' containing the sources
for package `"pkg"' version 1.6, and a directory tree
`"pkg-1.7"' containing the sources for version 1.7. The following
command will generate a patch kit that updates the 1.6 sources into their 1.7
versions:
makepatch pkg-1.6 pkg-1.7 > pkg-1.6-1.7.patch
To apply this script, go to the pkg-1.6 directory and feed the script to
applypatch:
cd old/pkg-1.6
applypatch pkg-1.6-1.7.patch
applypatch will verify that it is executing in the right place and make
all necessary updates.
This is one way to generate and use manifest files:
(cd pkg-1.6; find . -type f -print > OLDMANIFEST)
(cd pkg-1.7; find . -type f -print > NEWMANIFEST)
makepatch \
-oldmanifest pkg-1.6/OLDMANIFEST \
-newmanifest pkg-1.7/NEWMANIFEST \
pkg-1.6 pkg-1.7 > pkg-1.6-1.7.diff
Much of the job of
makepatch is processing file names.
makepatch
has been tested extensively on Unix systems, but it is not guaranteed to work
on other systems.
applypatch is repeatedly reported to correctly process
makepatch
generated patch kits on modern 32-bit Windows systems as well.
makepatch does not know about symbolic links. These will be treated like
plain files.
Wrong results can be generated if the file lists that are used or generated use
different path separators.
applypatch(1),
diff(1),
patch(1),
perl(1),
rm(1).
Johan Vromans (
[email protected]) wrote the program, with a little help and
inspiration from: Jeffery Small, Ulrich Pfeifer, Nigel Metheringham, Julian
Yip, Tim Bunce, Gurusamy Sarathy, Hugo van der Sanden, Rob Browning, Joshua
Pritikin, and others.
This program is Copyright 1992,2004,2006 by Squirrel Consultancy. All rights
reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of either: a) the GNU General Public License as published by the
Free Software Foundation; either version 1, or (at your option) any later
version, or b) the "Artistic License" which comes with Perl.
This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See either the GNU General Public License or the
Artistic License for more details.