I am writing this blog to share my experience when i was asked to apply a patch which was written by some other person. When we applying patches, sometimes we may get some errors in the patch command. This blog post will help you to understand the format of the patch file and from that you can identify the reasons which caused your patch to fail and enable you to apply patch manually if required.
Patch or diff files are just text files, so you can look at them with less or a text editor.
If you prefer to use a terminal, colordiff (in the colordiff package) provides syntax highlighting. If the patch is long, you may want to use less to look at it. You need the -R option for less, or else the colors won’t show. I also always use -S, which will enable horizontal scrolling in less instead of wrapping long lines. The whole command to view a patch with syntax highlighting through less in a terminal is:
~$ cat file.patch | colordiff | less -RS
Patch formats
Each patch file comes in , called normal, context and unified diff. You can identify them by looking at the contents of the patch file.
Normal diffs have a lot of lines that start with > or <:
...
51
< background-color: red;
---
> background-color: blue;
...
Context diffs have a lot of lines with stars ***** in them and lines starting with !, + and -:
...
***************
*** 44,54 ****
html, body { color: #242626; }
html {
! background-color: red;
height: 100%;
margin-bottom:;
overflow-y: scroll;
--- 44,54 ----
html, body { color: #242626; }
html {
! background-color: blue;
height: 100%;
margin-bottom:;
overflow-y: scroll;
...
And finally unified diffs have a lot of lines with two @@s in them and lines starting with + and -:
...
@@ -44,11 +44,11 @@
html, body { color: #242626; }
html {
- background-color: red;
+ background-color: blue;
height: 100%;
margin-bottom:;
overflow-y: scroll;
...
How to read a normal diff
The patch file contains a section for each file that should be changed. That section starts with a line identifying the file. That line has the file name and path of first the old and then the new version in it:
diff violet-park-2.orig/style.css violet-park-2/style.css
Then follow sets of changes, called hunks. The first line of each hunk contains
the line or line range from,to in the file before the changes
a letter indicating a change (c), an addition (a) or a deletion (d)
the line or line range in the file after the changes
all without spaces in between.
A change looks like this:
73
< red
---
> blue
That means, change line 73, which contains red, to blue. The new line is line after all changes.
The new line number could also have been, say, 75. In that case all additions, deletions and changes before that line added up to the file after all changes.
Instead of single line numbers, a line range can be specified, for example:
90,94
...
That means, change lines file to the following, which will be lines file. The same applies for additions and deletions.
An addition looks like this:
80,81
> line1
> line2
That means, in the original file after line. These will be lines.
And finally, a deletion looks like this:
77
< line1
That means, delete line file. The line, that preceded line file will be line file.
How to read a context diff
The patch file contains a section for each file that should be changed. That section starts with the file name and path of first the old and then the new version and some additional information:
diff -c violet-park-2.orig/archive.php violet-park-2/archive.php
*** violet-park-2.orig/archive.php 2009-10-10 07:37:43.000000000 +0200
--- violet-park-2/archive.php 2009-10-10 09:05:58.000000000 +0200
patch is pretty lax about the format of these lines, as long as it can find out the file names. In patches generated by version control systems like cvs, svn or git these little different.
Then follow sets of changes, called hunks. Each hunk starts with a line with ****. Then comes a line with the line range from,to and the lines from file before the changes. Lines that start with an ! are changed, lines that start with a - are deleted. Then comes the line range and the lines in the file after all changes. Lines that start with a ! are, again, changed, and lines that start with a + are added. Each line modified by the patch is surrounded with before and after.
A change looks like this:
***************
*** 70,76 ****
foo
bar
baz
! red
more context
and more
still context
--- 70,76 ----
foo
bar
baz
! blue
more context
and more
still context
That means, change line 73 (= 70 + in the file before all changes, which contains red to blue. The changed line is also line 73 (= 70 + in the file after all changes.
Here’s an example for an addition:
***************
*** 75,80 ****
--- 77,84 ----
foo
bar
baz
+ line1
+ linemore
and still context
That means, in the original file after line 78 (= 75 + add . These will be lines 80 (= 77 + through.
And that’s how a deletion looks like:
***************
*** 75,81 ****
foo
bar
baz
- linemore
and still context
--- 75,80 ----
That means, delete line 78 (= 75 + in the original file. The unchanged context will be on lines.
How to read a unified diff
The patch file contains a section for each file that should be changed. That section starts with the file name and path of first the old and then the new version and some additional information:
diff -u violet-park-2.orig/archive.php violet-park-2/archive.php
--- violet-park-2.orig/archive.php 2009-10-10 07:37:43.000000000 +0200
+++ violet-park-2/archive.php 2009-10-10 09:05:58.000000000 +0200
patch is pretty lax about the format of these lines, as long as it can find out the file names. In patches generated by version control systems like cvs, svn or git these little different.
Then follow sets of changes, called hunks. Each hunk starts with a line that contains, enclosed in @@, the line or line range from,no-of-lines in the file before (with a -) and after (with a +) the changes. After that come the lines from the file. Lines starting with a - are deleted, lines starting with a + are added. Each line modified by the patch is surrounded with @@ before and after.
An addition looks like this:
@@ -75,6 +77,8 @@
foo
bar
baz
+line1
+linemore
and still context
That means, in the original file after line 78 (= 75 + add . These will be lines 80 (= 77 + through.
A deletion looks like this:
@@ -75,7 +75,6 @@
foo
bar
baz
-linemore
and still context
That means, delete line 78 (= 75 + in the original file. The unchanged context will be on lines.
Finally, a change looks like this:
@@ -70,7 +70,7 @@
foo
bar
baz
-red
+blue
more context
and more
still context
That means, change line 73 (= 70 + in the file before all changes, which contains red to blue. The changed line is also line 73 (= 70 + in the file after all changes.
Comments
Post a Comment