What do the numbers on a Git Diff header mean?
Summary:
- Assume
git diff
will output [0-3] lines of context [before/after] [first/last] changes
@@ -[original file's number of first line displayed
],[context lines + removed lines
] +[changed file's number of first line displayed
],[context lines + added lines
] @@
This header is called set of change, or hunk. 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 3 lines of context before and after.
An addition looks like this:
@@ -75,6 +103,8 @@
foo
bar
baz
+line1
+line2
more context
and more
and still context
That means, in the original file before line 78 (= 75 + 3 lines of context) add two lines. These will be lines 106 (= 103 + 3 lines of context) through 107 after all changes.
Note the difference in from
numbers (-75 vs +103), this means that there were other changes in this file before this particular hunk, that added 28 (103 - 75) lines of code.
A deletion looks like this:
@@ -75,7 +75,6 @@
foo
bar
baz
-line1
more context
and more
and still context
That means, delete line 78 (= 75 + 3 lines of context) in the original file. The unchanged context will be on lines 75 to 80 after all changes.
Note that from
numbers in this hunk are equal (-75 and +75), this means that either there were no changes before this hunk, or amount of added and deleted lines in previous changes are the same.
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 + 3 lines of context) in the file before all changes, which contains red to blue. The changed line is also line 73 (= 70 + 3 lines of context) in the file after all changes.
I wonder what does the four numbers mean?
Let's analyze a simple example
The format is basically the same the diff -u
unified diff.
We start with numbers from 1 to 16 and remove 2, 3, 14 and 15:
diff -u <(seq 16) <(seq 16 | grep -Ev '^(2|3|14|15)$')
Output:
@@ -1,6 +1,4 @@
1
-2
-3
4
5
6
@@ -11,6 +9,4 @@
11
12
13
-14
-15
16
@@ -1,6 +1,4 @@
means:
-1,6
means that this piece of the first file starts at line 1 and shows a total of 6 lines. Therefore it shows lines 1 to 6.1 2 3 4 5 6
-
means "old", as we usually invoke it asdiff -u old new
.+1,4
means that this piece of the second file starts at line 1 and shows a total of 4 lines. Therefore it shows lines 1 to 4.+
means "new".We only have 4 lines instead of 6 because 2 lines were removed! The new hunk is just:
1 4 5 6
@@ -11,6 +9,4 @@
for the second hunk is analogous:
on the old file, we have 6 lines, starting at line 11 of the old file:
11 12 13 14 15 16
on the new file, we have 4 lines, starting at line 9 of the new file:
11 12 13 16
Note that line
11
is the 9th line of the new file because we have already removed 2 lines on the previous hunk: 2 and 3.