Patch Generation Assistant

Overview

The patchgen script is a simple shell script to assist in the creation of source patches for collections of text files. Developed for the InterWorks FAST project, the scripts in this package are general enough to be used for various purposes besides just computer source code.

The general idea is to start with a collection of text files (such as the source code of an open-source software package), modify them by various means, then generate a single patch file which incorporates the changes made to all the files.

To implement the mechanism, you should use the ednew script to create an editable copy of a file before you alter it. This will create a copy of the file for editing, and stash the original text in a file with a ".original" suffix. The patchgen script then traverses the directory tree, performing a diff operation on all ".original" files, and concatenating the patches into a single file.

The ednew script

Run the ednew script with a file name, or list of file names, to be edited. It will guard against multiple invocations by checking for "file.original" for each file it is asked to copy. It also sets the "write" permission for the copy. By renaming the original and creating a copy, ednew preserves the original timestamp of the file. An example:

ednew Makefile config.h

This will move Makefile to Makefile.original, and create a writeable copy of it called Makefile. It will also move config.h to config.h.original and create an editable config.h. The filenames can actually be pathnames, eg.:

ednew src/fumble.c

In this case, the copies are placed in the same directories as the originals, so the above would move src/fumble.c to src/fumble.c.original and create an editable copy src/fumble.c.

The patchgen script

Run the patchgen script by changing your current working directory to the "top" of the source tree for which you wish to generate a patch file. In FAST terms, this would be the src subdirectory under the application directory in /opt tree. Then, run it by giving it the name of the patch file to be generated. Again in FAST terms, it would called in this way:

patchgen FAST.patch

This will traverse the src directory tree, which includes the modified sources that you have created during the porting of the package, looking for files with the ".original" suffix. For each such file it finds, it will append a unified context diff patch to the FAST.patch file. Note that this requires the GNU diff program--the standard HP-UX diff program does not accept the appropriate -u option. This can actually be fiddled around--the patch program accepts numerous input formats, but the unified context diff is usually best. The GNU diff program is provided as a FAST package, so install it first!

The resulting patch file can be used by unpacking the original source into a directory, then running patch <patchfile. This will apply all the differences given in the patch file. Presuming that you have been religious in your use of ednew, this should duplicate the modified source tree that you produced through editing. Note that patch uses ".orig" as its "original file" suffix, so the resulting tree won't have the same filenames, but should have the same contents. Any build operations should then work as they did with your modified sources.

The checkeds script

In a section above, we said "Presuming that you have been religious in your use of ednew ...". This isn't a totally realistic expectation all the time, so the checkeds script has been provided to give a bit of help in this area. If you use an editor which creates recognizable backup files by appending a suffix to them, such as ".bak" or "~" (tilde), the checkeds script will look to see if any files have been edited (that is, if any files have backups) which do not have a corresponding "file.original". This process is not perfect, and won't work at all if your editor is like pico and doesn't create backups, but it can help in some cases.

The intent is that you run checkeds immediately prior to running patchgen, and from the same working directory. It traverses the directory tree looking for files with ".bak" or "~" suffixes, and checks to see if there is a properly named ".original" for that file also. It takes an optional -v argument, which means run in "verbose" mode. Without the -v, checkeds only prints a message for files without a corresponding ".original". Ideally, then, it would produce no output. With -v, it also prints a message for all backup files, even those which pass muster. So, call it like this:

checkeds

Or else like this:

checkeds -v

Note that checkeds does not attempt to create a ".original" file from the backup file. It has no way of knowing whether you have done multiple edits to the file, thus rendering the backup different from the original. If you detect any rogue edits using checkeds, you should unpack the original file(s) from their source distribution package, and manually rename them with the ".original" suffix.

If your editor uses a backup suffix other than ".bak" or "~" (tilde), you can add your editor's backup-file suffix to the list given in the "backups" variable at the top of the checkeds script.


Chip Richards
Last modified: Sat Oct 31 12:59:23 MST 1998