66

Every time I run git diff, for each single changes I made, I get some sort of header with numbers, for example:

@@ -169,14 +167,12 @@ function Browser(window, document, body, XHR, $log) {.....

I wonder what does the four numbers mean? I guess -169 means that this particular line of code that follows was originally in line 169 but now is in 167? And what do 14 and 12 mean?

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
Codier
  • 2,126
  • 3
  • 22
  • 33

3 Answers3

70

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.

Andrejs Cainikovs
  • 27,428
  • 2
  • 75
  • 95
  • 10
    Short answer: 14 in your case is amount of lines in hunk before applying the changes, 12 - after. – Andrejs Cainikovs Jun 28 '11 at 15:31
  • 6
    The `no-of-lines` values may not be immediately obvious. The 'before' value is the sum of the 3 lead context lines, the number of `-` lines, and the 3 trailing context lines, while the 'after' values is the sum of 3 lead context lines, the number of `+` lines and the 3 trailing lines. In some cases there are additional intermediate context lines which are also added to those numbers. So the total number of lines displayed is commonly neither of the `no-of-lines` values! – Philip Oakley Mar 25 '13 at 21:35
  • 4
    There's a red herring in the first example of adding 2 lines: `@@ -75,6 +77,8 @@`. The 75 and 77 may confuse newbie to think that was related to adding 2 lines. Actually, a simpler example would just have `@@ -75,6 +75,8 @@`. The +77 would only be if there were other edits higher up that added a net of 2 lines. – wisbucky Aug 28 '13 at 04:31
  • @AndrejsCainikovs Is there a reason for the 75/77 difference in the first example? – Holloway Oct 14 '14 at 14:40
  • @Trengot Yes. I wanted to show that those numbers are not always equal. `from` numbers can be different in case if there were other changes before. I will update my answer with that. – Andrejs Cainikovs Oct 15 '14 at 08:34
  • 2
    Because this is such a great answer, I want to point out one subtle mistake, if I may be so pedantic. Where you say, "That means, in the original file after line 78 (= 75 + 3 lines of context) add two lines.", you should say "after line 77", because line 75 is itself one of the 3 lines of context, i.e. lines 75, 76 and 77 are the context. So it is actually immediately after line 77 (=75+2) where the new code will be added. So the new text "line1" will be on line 78 (if those 2 new lines were the only changes/diffs.) You get the point I'm sure. – Will Dec 05 '17 at 14:03
  • @Will, thanks, fixed. – Andrejs Cainikovs Dec 05 '17 at 14:10
  • This is called a diff unified format. One should not rely on the contextual lines, before/after since it's not always 3, it can be any number. In [wikipedia's](https://en.wikipedia.org/wiki/Diff) opinion this can be summerized as: `@@ -l,s +l,s @@`: this is a **hunk range information** which contains **2 hunk ranges**. The one with `-` is the original file. The one with `+` is the new file. `l` indicates the starting line number, `s` is the sum of the contextual lines and deleted lines (for the first hunk) and the contextual lines and addition lines (for the second hunk). That's it. – Marius Mucenicu Oct 03 '18 at 12:11
  • Also, as mentioned in the Wikipedia article, the `,s` parts can be omitted in which case they mean just one line, so `@@ 1 1,20 @@` is equivalent of `@@ 1,1 1,20 @@` – Łukasz Nojek Jan 15 '19 at 22:08
22

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 as diff -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.

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
4

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] @@

Jose Alban
  • 7,286
  • 2
  • 34
  • 19