Diff and Patch

  • The commands diff and patch form a powerful combination. They are widely used to get differences between original files and updated files in such a way that other people who only have the original files can turn them into the updated files with just a single patch file that contains only the differences.
  • There should be some basic Linux and command line knowledge, like changing directories, copying files and editing text files.
  • Using diff to create a simple patch:  The most simple way of using diff is getting the differences between two files, an original file and an updated file. For example, write a few words in a normal text file, make some modifications, and then save the modified content to a second file. Then, you could compare these files with diff, like this:
     diff originalfile updatedfile
  • You will most probably get an output like this:
1c1
< These are a few words.
\ No newline at end of file 
--- 
> These still are just a few words. 
\ No newline at end of file
  • To demonstrate the creation of a simple patch, I used the file originalfile with the content “These are a few words.” and the file updatedfile with the content “These still are just a few words.”. You can create these files yourself.
  • The 1c1 is a way of indicating line numbers and specifying what should be done. Note that those line numbers can also be line ranges (12,15 means line 12 to line 15). The “c” tells patch to replace the content of the lines. Two other characters with a meaning exist: “a” and “d”, with “a” meaning “add” or “append” and “d” meaning “delete”. The syntax is (line number or range)(c, a or d)(line number or range), although when using “a” or “d”, one of the (line number or range) parts may only contain a single line number.
  • When using “c”, the line numbers left of it are the lines in the original file that should be replaced with text contained in the patch, and the line numbers right of it are the lines the content should be in in the patched version of the file.
  • When using “a”, the line number on the left may only be a single number, meaning where to add the lines in the patched version of the file, and the line numbers right of it are the lines the content should be in in the patched version of the file.
  • When using “d”, the line numbers left of it are the lines that should be deleted to create the patched version of the file, and the line number on the right may only be a single number, telling where the lines would have been in the patched version of the file if they wouldn’t have been deleted.
  • The “<“ means that patch should remove the characters after this sign, and the “>” means that the characters after this sign should be added. When replacing content (a “c” between the line numbers), you will see both the < and the > sign. When adding content (an “a” between the line numbers), you’ll only see the > sign, and when deleting content (a “d” between the line numbers), only the < sign.
  • The “\”, followed by “No newline at end of file”, is only there because I didn’t press enter after typing the words. Generally, it always is good practice to add a final newline to every text file you create. Certain pieces of software can’t do without them. Therefore, the absence of a final newline is reported so explicit by diff. Adding final newlines to the files makes the output a lot shorter:
1c1
< These are a few words.
---
> These still are just a few words.
  • indicate the end of the lines that should be replaced and the beginning of the lines that should replace them. They separate the old and the new lines. You will only see these when replacing content (a “c” between the line numbers).
  • If we want to create a patch, we should put the output of diff into a file. Of course, you could do this by copying the output from your console and, after pasting it in your favourite text editor, saving the file, but there is a shorter way. We can let bash write diff’s output to a file for us this way:
    diff originalfile updatedfile > patchfile.patch
  • Again, replace the filenames with the ones appropriate in your case. You might like to know that telling bash to write a command’s output to a file using > works with every command. This can be very useful to save to output of a command to a (log) file.
  • Applying the simple patch we created: We can use the patchfile to change a copy of originalfile to a copy of updatedfile. Of course, it wouldn’t make that much sense to apply the patch on the files we created the patch from. Therefore, copy the original file and the patchfile to an other place, and go to that place. Then, try applying the patch this way:
    patch originalfile -i patchfile.patch -o updatedfile
  • Again, replace the filenames where necessary. If all went well, the file updatedfile just created by patch should be identical to the one you had at first, when creating the patch with diff. You can check this using diff’s -s option:
    diff -s updatedfile [/path/to/the/original/updatedfile]/updatefile
  • Replace the part between [ and ] with the path to the original update file. For example, if the updatedfile you used when creating the patch is located in the parent directory of your current directory, replace “[/path/to/the/original/updatedfile]” with “..” (bash understands this as the parent directory of the current working directory). And of course, also replace the filenames again where appropriate.
  • If diff reported the files to be equal, you just successfully created and used a patch.
This entry was posted in Uncategorized. Bookmark the permalink.

Leave a comment