Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Re: submitting a patch for a directory (mini diff/patch tutorial)

by Anonymous Monk
on Aug 16, 2012 at 16:26 UTC ( #987814=note: print w/ replies, xml ) Need Help??


in reply to submitting a patch for a directory

The situation ( file/directory tree )

$ tree -f -a . . |-- ./Foo | `-- ./Foo/one.txt |-- ./Foo-new | |-- ./Foo-new/one.txt | `-- ./Foo-new/two.txt `-- ./Foo-old `-- ./Foo-old/one.txt 3 directories, 4 files

Foo is the original directory (CGI.pm-3.59)

Foo-old is the backup pristine copy (CGI.pm-3.59-old)

Foo-new is thing you've edited that you generate the patch from (CGI.pm-3.59-new)

Creating a new patch ( Foo-new.patch, CGI.pm-3.59-new.patch )

$ diff -Npurd Foo-old Foo-new > Foo-new.patch

What the switches mean

  • -N => --new-file Treat absent files as empty.
  • -p => --show-c-function Show which C function each change is in.
  • -u => -U NUM --unified=NUM Output NUM (default 3) lines of unified context.
  • -r => --recursive Recursively compare any subdirectories found.
  • -d => --minimal Try hard to find a smaller set of changes.

NOTE: If you're making a patch from a directory like CGI.pm-3.59, where you've used perl Makefile.PL && make, esp if using -N, you should clean up before making a patch, you should make realclean

What a patch looks like

$ cat Foo-new.patch diff -Npurd Foo-old/one.txt Foo-new/one.txt --- Foo-old/one.txt 2012-08-16 08:21:35.609375000 -0700 +++ Foo-new/one.txt 2012-08-16 08:19:45.859375000 -0700 @@ -1 +1 @@ -hi there +hello there diff -Npurd Foo-old/two.txt Foo-new/two.txt --- Foo-old/two.txt 1969-12-31 16:00:00.000000000 -0800 +++ Foo-new/two.txt 2012-08-16 08:19:25.500000000 -0700 @@ -0,0 +1 @@ +new file

Applying your new patch to Foo (CGI.pm-3.59), what the recipient of that patch would do, is first change working directory, then call patch

$ cd Foo

$ patch -p1 -i../Foo-new.patch

$ cd Foo $ patch -p1 -i../Foo-new.patch patching file one.txt patching file two.txt

-p1 means ignore the first path part, ignore the bold parts

--- Foo-old/two.txt 1969-12-31 16:00:00.000000000 -0800

+++ Foo-new/two.txt 2012-08-16 08:19:25.500000000 -0700

It also means don't create a Foo-new directory :)

If you used -p0 (ignore no path parts) the patching would fail in two ways, it wouldn't find one.txt, and it would create a Foo-new directory

$ patch -p0 -i../Foo-new.patch can't find file to patch at input line 4 Perhaps you used the wrong -p or --strip option? The text leading up to this was: -------------------------- |diff -Npurd Foo-old/one.txt Foo-new/one.txt |--- Foo-old/one.txt 2012-08-16 08:21:35.609375000 -0700 |+++ Foo-new/one.txt 2012-08-16 08:19:45.859375000 -0700 -------------------------- File to patch: Skip this patch? [y] Skipping patch. 1 out of 1 hunk ignored patching file Foo-old/two.txt $ tree -f -a . . |-- ./Foo-old | `-- ./Foo-old/two.txt `-- ./one.txt 1 directory, 2 files

For best patching experience

Always use relative paths for diff -Npurd diffolddir newdir

Always use the p1 or p0 option, otherwise patch will ignore all directories/patch the wrong file

 

To re-create my original situation, to create files and directories out of a patch, first produce the patch

diff -Npurd emptyDir tmpFoo > tmpFoo.patch

The new patch tmpFoo.patch looks like

diff -Npurd emptyDir/Foo/one.txt tmpFoo/Foo/one.txt --- emptyDir/Foo/one.txt 1969-12-31 16:00:00.000000000 -0800 +++ tmpFoo/Foo/one.txt 2012-08-16 08:21:35.609375000 -0700 @@ -0,0 +1 @@ +hi there diff -Npurd emptyDir/Foo-new/one.txt tmpFoo/Foo-new/one.txt --- emptyDir/Foo-new/one.txt 1969-12-31 16:00:00.000000000 -0800 +++ tmpFoo/Foo-new/one.txt 2012-08-16 08:19:45.859375000 -0700 @@ -0,0 +1 @@ +hello there diff -Npurd emptyDir/Foo-new/two.txt tmpFoo/Foo-new/two.txt --- emptyDir/Foo-new/two.txt 1969-12-31 16:00:00.000000000 -0800 +++ tmpFoo/Foo-new/two.txt 2012-08-16 08:19:25.500000000 -0700 @@ -0,0 +1 @@ +new file diff -Npurd emptyDir/Foo-old/one.txt tmpFoo/Foo-old/one.txt --- emptyDir/Foo-old/one.txt 1969-12-31 16:00:00.000000000 -0800 +++ tmpFoo/Foo-old/one.txt 2012-08-16 08:21:35.609375000 -0700 @@ -0,0 +1 @@ +hi there

Then apply the patch in your new working directory tmp2Foo

$ cd tmp2Foo $ patch -i ../tmpFoo.patch The next patch would create the file one.txt, which already exists! Assume -R? [n] Apply anyway? [n] Skipping patch. 1 out of 1 hunk ignored -- saving rejects to file one.txt.rej The next patch would create the file one.txt, which already exists! Assume -R? [n] Apply anyway? [n] Skipping patch. 1 out of 1 hunk ignored -- saving rejects to file one.txt.rej The next patch would create the file two.txt, which already exists! Assume -R? [n] Apply anyway? [n] Skipping patch. 1 out of 1 hunk ignored -- saving rejects to file two.txt.rej The next patch would create the file one.txt, which already exists! Assume -R? [n] Apply anyway? [n] Skipping patch. 1 out of 1 hunk ignored -- saving rejects to file one.txt.rej $ tree -f -a . . |-- ./one.txt |-- ./one.txt.rej |-- ./two.txt `-- ./two.txt.rej 0 directories, 4 files

Oh noes, a mistake! I forgot to include the -p1 switch, and no directories were created! Trying again with -p1

$ patch -p1 -i ../tmpFoo.patch patching file Foo/one.txt patching file Foo-new/one.txt patching file Foo-new/two.txt patching file Foo-old/one.txt $ tree -f -a . . |-- ./Foo | `-- ./Foo/one.txt |-- ./Foo-new | |-- ./Foo-new/one.txt | `-- ./Foo-new/two.txt `-- ./Foo-old `-- ./Foo-old/one.txt 3 directories, 4 files

Hooray! Hmm, I'll try p0 in the same directory

$ patch -p0 -i ../tmpFoo.patch patching file tmpFoo/Foo/one.txt patching file tmpFoo/Foo-new/one.txt patching file tmpFoo/Foo-new/two.txt patching file tmpFoo/Foo-old/one.txt $ tree -f -a . |-- ./Foo | `-- ./Foo/one.txt |-- ./Foo-new | |-- ./Foo-new/one.txt | `-- ./Foo-new/two.txt |-- ./Foo-old | `-- ./Foo-old/one.txt `-- ./tmpFoo |-- ./tmpFoo/Foo | `-- ./tmpFoo/Foo/one.txt |-- ./tmpFoo/Foo-new | |-- ./tmpFoo/Foo-new/one.txt | `-- ./tmpFoo/Foo-new/two.txt `-- ./tmpFoo/Foo-old `-- ./tmpFoo/Foo-old/one.txt 7 directories, 8 files

Whoa, that worked also and it didn't interfere :) but I don't really need that extra tmpFoo, now to get rid of it without rm -rfv -- from the same working directory

-Reversing a patch (just add -R to the command you used to apply the patch)

$ patch -p0 -R -i ../tmpFoo.patch patching file tmpFoo/Foo/one.txt patching file tmpFoo/Foo-new/one.txt patching file tmpFoo/Foo-new/two.txt patching file tmpFoo/Foo-old/one.txt $ tree -f -a . |-- ./Foo | `-- ./Foo/one.txt |-- ./Foo-new | |-- ./Foo-new/one.txt | `-- ./Foo-new/two.txt `-- ./Foo-old `-- ./Foo-old/one.txt 3 directories, 4 files

 

See also http://perldoc.perl.org/5.14.0/perlhack.html#Patching, http://perldoc.perl.org/5.10.0/perlhack.html#Patching


Comment on Re: submitting a patch for a directory (mini diff/patch tutorial)
Select or Download Code

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://987814]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (12)
As of 2015-07-03 13:23 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (53 votes), past polls