Subject: [Dev] embarrassing patch question

From: "John F Davis" <[email-masked]>
Date: Thu, 28 Feb 2002 11:28:30 -0500

Hello

Ok.  I've been using patch and I've asked some questions about it on IRC,
but I'm still not
sure about how to use it "CORRECTLY" or in the "PRESCRIBED-METHOD".  So,
please correct me.

I want to create a patch file to give to my co-workers and instructions on
how to use it.

With that said, here is the scenario:

I have a original directory called foo.orig and a "up-to-date" directory
called foo.latest.
So, I created a patch file using this syntax:
diff -Naur foo.orig foo.latest > foo.patch

Then to apply the patch, I did:
patch -p1 foo < foo.patch
or
patch -p1 foo.orig < foo.patch
I can't remember which one I did.

I think this is right.  However, it would be great if someone would clear
up the bit
about the target directory.  Does the target directory have to called the
same as the
"patched" or "orig" directory?  Is there a way to specify or edit the patch
file so
that the end user can have their own custom directory name.  For instance,
I used foo and foo.orig, but the end user might have directory names
like foo2 or foo.nfs, etc.

JD

---

From: David Filion <[email-masked]>
Date: Thu, 28 Feb 2002 11:39:42 -0500

John F Davis wrote:
> --
> Kernelnewbies: Help each other learn about the Linux kernel.
> Archive:       http://mail.nl.linux.org/kernelnewbies/
> IRC Channel:   irc.openprojects.net / #kernelnewbies
> Web Page:      http://www.kernelnewbies.org/

I threw together something a while ago when I was in the same 
situation, I've included it below.  Because we are using Solaris
at work, it covers the older and newer versions of diff/patch.

HTH
David Filion

--- Start of doc ---

Creating a patch

Below is a cheat sheet for creating and applying patch files.  For more
details about each command, check the commands manpage, info document or
try "command --help".

1.0 Using older versions of diff/patch.
	The older diff/patch utilities don't understand the newer unified 
	format.  Thus, the older conext format must be used. Thus the -c 
	option that appears.

1.1 Create the patch
	diff -c -b -r /original /new > filename.patch

diff options:
	-c  Produces a listing of differences with three lines of context.
	-b  Ignores trailing blanks (spaces and tabs) and treats other strings
	    of blanks as equivalent.
	-r  Applies diff recursively to common subdirectories encountered.

1.2 Apply the patch
	patch -c -l -p1 -d /original < filename.patch

patch options:
	-c  Interpret the patch file as a context difference (the output of
	    the command diff when the -c or -C options are specified).
	-l  Cause any sequence of blank characters in the difference script
	    to match any sequence of blank characters in the input file.  
	    Other characters will be matched exactly.
  	-d  Change the current directory  to  dir  before processing.
	-p NUM  Strip NUM leading components from file names.

2.0 Using newer/GNU diff and patch utilities.
	Unlike their older counterparts, the newer/GNU versions of diff 
	understand the unified format of patch file.  This is the format used
	by the Linux kernel developers.

2.1 Create the patch
	   diff -u oldfile newfile > filename.patch
	or diff -urN /olddir /newdir > filename.patch
	or diff -urN -X excludes /olddir /newdir > filename.patch

diff options:
	-u  Output (default 2) lines of unified context.
	-r  Recursively compare any subdirectories found.
	-N  Treat absent files as empty.
	-X FILE  Exclude files that match any pattern in FILE.

Note: The -u options can be replaced with -c to create a context format diff
      file with a setting of two lines.

2.2 Apply the patch
	   gzip -cd patch.gz | patch -p0
	or bzip2 -dc patch.bz2 | patch -p0
	or patch -p0 < filename.patch

patch options:
	-p NUM  Strip NUM leading components from file names.

3.0 Creating a patch using CVS.
	A patch is created in CVS using the rdiff cvs command.

3.1 Create the patch.
	
	o Create a context (default) format diff of release tags rel1 and 
	  rel2 for module.
	cvs rdiff -r rel1 -r rel2 module

	o Create a unidiff format diff of release tags rel1 and rel2 
	for module.
	cvs rdiff -u -r rel1 -r rel2 module

cvs rdiff options:
	-r tag  Use revision <tag>
	-u  Use the unidiff format.
	-c  Use the context format (default).

Copyright (c) David Filion ([email-masked])
Created 2001/09/12.

---

From: James Manning <[email-masked]>
Date: Thu, 28 Feb 2002 12:32:32 -0500

[David Filion]
> 	patch -c -l -p1 -d /original < filename.patch

I'd leave out this section personally - mainly just cuz I'm a big
fan of unified diffs and anything that helps ppl avoid the older
versions is a Good Thing IMHO :)

> 	by the Linux kernel developers.

... and most other Free Software projects, AFAICT :)

> 	-u  Output (default 2) lines of unified context.

default's been 3 for as long as I can remember - prob. just a typo?

> 	-p NUM  Strip NUM leading components from file names.

This is really the key point ppl need to understand in my exp.

> 	A patch is created in CVS using the rdiff cvs command.

"cvs diff" works well for local mods, like for checking before
a commit (to make sure you're not commit'ing things you don't
want to).  In many cases you don't want to diff against two
things that are checked in, but against local mods to a branch.

> 	cvs rdiff -u -r rel1 -r rel2 module

Pedantic, but for the sake of consistency it's prob. woth including
the "> filename.patch" part for clarity.

Great doc!  Wish I had it around back when I was learning diff/patch :)

James
-- 
James Manning <[email-masked]>
GPG Key fingerprint = B913 2FBD 14A9 CE18 B2B7  9C8E A0BF B026 EEBB F6E4