Difference between revisions of "Diff and patch"

From Noah.org
Jump to navigationJump to search
m
 
(5 intermediate revisions by the same user not shown)
Line 1: Line 1:
If you don't have svn access to a project and want to submit a
+
[[Category:Engineering]]
manual patch, the following notes should help.
 
You made changes to many files in a project and you want to
 
submit a patch to the maintainer of the project.
 
First, find out if they want Context or Unified diffs.
 
That will set the -c or -u option for diff.
 
I usually go with -c when in doubt. You will use the -r options
 
to recursively compare the ORIGINAL directory with the NEWER directory
 
(the one with your changes). You can add many more -x options to
 
exclude patterns of files that you do not want included in the patch.
 
Usually you don't want to compare binaries or files generated by
 
the build process (make).
 
  
 +
These notes cover creating manual patch files. These are used to communicate the differences between an original source tree and a tree to which changes have been made. This is what you would submit to the maintainer of a project.
 +
 +
You should find out of the maintainer prefers patch files formatted as '''Context''' or '''Unified''' diffs.
 +
This will decide decide between the '-c' or '-u' option for diff. Go with '-c 'when in doubt. You will use the -r option to recursively compare the '''ORIGINAL''' directory with the '''NEWER''' directory (the one with your changes). You can add multiple '-x' options to exclude patterns of files that you do not want included in the patch. Usually you don't want to compare binaries or files generated by the build process. This will generate a patch file that you can mail to the project maintainer.
 
<pre>
 
<pre>
 
cd /home/user/project-NEWER
 
cd /home/user/project-NEWER
 
diff -r -c -x"*.jpg" -x"*.png" -x"*.gif" -x"*.swp" \
 
diff -r -c -x"*.jpg" -x"*.png" -x"*.gif" -x"*.swp" \
 +
    -x"*.a" -x"*.so" -x"*.o" -x"*.pyc" -x"*.exe" -x"*.class" \
 +
    -x".svn" -x"CVS" -x"core" -x"a.out" \
 +
    "/home/user/project-ORIGINAL" "." > /tmp/changes.patch
 +
</pre>
 +
 +
The project maintainer will then apply the patch as follows:
 +
<pre>
 +
cd project-ORIGINAL
 +
patch -p0 < /tmp/changes.patch
 +
</pre>
 +
 +
Note the '-p0' option. Also note that the path to changes.patch will depend on where the maintainer stored it (/tmp/ is just an example).
 +
 +
Sometimes you and the maintainer will not be working from exactly the same '''ORIGINAL''' source tree. Patch can do a fuzzy search around an area of code and find where the context matches. In this case it can help to have more context for patch to work with. Use the "-C NUM" options instead of '-c':
 +
<pre>
 +
diff -r -C 7 -x"*.jpg" -x"*.png" -x"*.gif" -x"*.swp" \
 
-x"*.a" -x"*.so" -x"*.o" -x"*.pyc" -x"*.exe" -x"*.class" \
 
-x"*.a" -x"*.so" -x"*.o" -x"*.pyc" -x"*.exe" -x"*.class" \
 
-x".svn" -x"CVS" -x"core" -x"a.out"
 
-x".svn" -x"CVS" -x"core" -x"a.out"
Line 20: Line 29:
 
</pre>
 
</pre>
  
This will generate a patch file that you can mail to the project maintainer. They will then apply the patch as follows:
+
== diff two directory trees ==
  
 +
This will compare two directory trees for new, deleted, and modified files.
 
<pre>
 
<pre>
cd project-ORIGINAL
+
diff -u -r -N /home/noah/bsp/rootfs.theirs /home/noah/bsp/rootfs.mine
patch -p0 < /tmp/changes.patch
+
</pre>
 +
 
 +
If you are generating a patch between an old version and a new version then the results will be smaller and more clear if you use the '''--unidirectional-new-file''' option instead of the '''-N''' option. Note that you must make sure you specify the '''old''' directory first and the '''new''' directory second.
 +
<pre>
 +
<pre>
 +
diff -u -r --unidirectional-new-file /home/noah/bsp/rootfs.old /home/noah/bsp/rootfs.new     
 
</pre>
 
</pre>
  
Note the -p0 option. The path to changes.patch will depend on where the maintainer stored it.
+
=== Just looking for changed file, not the changes. ===
 +
 
 +
This is a work in progress. It does not handle very well files that are in one directory but not the other.
 +
<pre>
 +
find . -type f -exec md5sum "{}" \; | (cd /home/noah/piebox_setup/ && md5sum -c -)
 +
</pre>

Latest revision as of 16:09, 11 May 2011


These notes cover creating manual patch files. These are used to communicate the differences between an original source tree and a tree to which changes have been made. This is what you would submit to the maintainer of a project.

You should find out of the maintainer prefers patch files formatted as Context or Unified diffs. This will decide decide between the '-c' or '-u' option for diff. Go with '-c 'when in doubt. You will use the -r option to recursively compare the ORIGINAL directory with the NEWER directory (the one with your changes). You can add multiple '-x' options to exclude patterns of files that you do not want included in the patch. Usually you don't want to compare binaries or files generated by the build process. This will generate a patch file that you can mail to the project maintainer.

cd /home/user/project-NEWER
diff -r -c -x"*.jpg" -x"*.png" -x"*.gif" -x"*.swp" \
    -x"*.a" -x"*.so" -x"*.o" -x"*.pyc" -x"*.exe" -x"*.class" \
    -x".svn" -x"CVS" -x"core" -x"a.out" \
    "/home/user/project-ORIGINAL" "." > /tmp/changes.patch

The project maintainer will then apply the patch as follows:

cd project-ORIGINAL
patch -p0 < /tmp/changes.patch

Note the '-p0' option. Also note that the path to changes.patch will depend on where the maintainer stored it (/tmp/ is just an example).

Sometimes you and the maintainer will not be working from exactly the same ORIGINAL source tree. Patch can do a fuzzy search around an area of code and find where the context matches. In this case it can help to have more context for patch to work with. Use the "-C NUM" options instead of '-c':

diff -r -C 7 -x"*.jpg" -x"*.png" -x"*.gif" -x"*.swp" \
-x"*.a" -x"*.so" -x"*.o" -x"*.pyc" -x"*.exe" -x"*.class" \
-x".svn" -x"CVS" -x"core" -x"a.out"
"/home/user/project-ORIGINAL" "." > /tmp/changes.patch

diff two directory trees

This will compare two directory trees for new, deleted, and modified files.

diff -u -r -N /home/noah/bsp/rootfs.theirs /home/noah/bsp/rootfs.mine

If you are generating a patch between an old version and a new version then the results will be smaller and more clear if you use the --unidirectional-new-file option instead of the -N option. Note that you must make sure you specify the old directory first and the new directory second.

<pre>
diff -u -r --unidirectional-new-file /home/noah/bsp/rootfs.old /home/noah/bsp/rootfs.new       

Just looking for changed file, not the changes.

This is a work in progress. It does not handle very well files that are in one directory but not the other.

find . -type f -exec md5sum "{}" \; | (cd /home/noah/piebox_setup/ && md5sum -c -)