Что означает мета-линия "@@... @@" с знаками в svn diff или git diff?

Когда я использую svn diff или git diff, он показывает строки вроде:

@@ -1,5 +1,9 @@

Что они означают?

Ответ 1

Те называются (c) заголовками заголовков и содержат информацию о диапазоне.

Они окружены двойными знаками @@. Они имеют формат:

@@ -l,s +l,s @@

где l - номер стартовой строки, а s - количество строк, к которым применяется переменная (c) для каждого соответствующего файла. - указывает исходный файл, а + указывает новый (измененный) файл. Обратите внимание, что он не только отображает затронутые строки, но также и контекстные строки.

-1,5 находится в исходном файле (обозначается -). Он показывает, что первая строка - это начальная и 5 затронутые/контекстные строки

+1,9 находится в новом (измененном) файле (обозначается символом +), а первая строка - стартовая и 9 затронутых/контекстных строк.

Подробнее здесь: http://en.wikipedia.org/wiki/Diff#Unified_format

Ответ 2

Простой пример анализа

Формат в основном совпадает с унифицированным diff diff -u.

Например:

diff -u <(seq 16) <(seq 16 | grep -Ev '^(2|3|14|15)$')

Здесь мы удалили строки 2, 3, 14 и 15. Вывод:

@@ -1,6 +1,4 @@
 1
-2
-3
 4
 5
 6
@@ -11,6 +9,4 @@
 11
 12
 13
-14
-15
 16

@@ -1,6 +1,4 @@ означает:

  • -1,6 означает, что этот фрагмент первого файла начинается со строки 1 и показывает всего 6 строк. Поэтому он показывает строки с 1 по 6.

    1
    2
    3
    4
    5
    6
    

    - означает "старый", так как мы обычно называем его diff -u old new.

  • +1,4 означает, что этот фрагмент второго файла начинается со строки 1 и показывает всего 4 строки. Поэтому он показывает строки с 1 по 4.

    + означает "новый".

    У нас только 4 строки вместо 6, потому что 2 строки были удалены! Новый кусок просто:

    1
    4
    5
    6
    

@@ -11,6 +9,4 @@ для второго блока аналогичен:

  • в старом файле у нас есть 6 строк, начиная со строки 11 старого файла:

    11
    12
    13
    14
    15
    16
    
  • в новом файле у нас есть 4 строки, начиная с 9 строки нового файла:

    11
    12
    13
    16
    

    Обратите внимание, что строка 11 является 9-й строкой нового файла, поскольку мы уже удалили 2 строки в предыдущем блоке: 2 и 3.

Заголовок куска

В зависимости от вашей версии и конфигурации git вы также можете получить строку кода рядом со строкой @@, например, func1() { в:

@@ -4,7 +4,6 @@ func1() {

Это также можно получить с флагом -p обычного diff.

Пример: старый файл:

func1() {
    1;
    2;
    3;
    4;
    5;
    6;
    7;
    8;
    9;
}

Если мы уберем строку 6, разница показывает:

@@ -4,7 +4,6 @@ func1() {
     3;
     4;
     5;
-    6;
     7;
     8;
     9;

Обратите внимание, что это неправильная строка для func1: пропущены строки 1 и 2.

Эта удивительная функция часто говорит точно, к какой функции или классу относится каждый кусок, что очень полезно для интерпретации различий.

Как именно работает алгоритм выбора заголовка, обсуждается на: Откуда взята выдержка из заголовка git diff?

Ответ 3

Они описывают строки, затронутые diff hunk. В вашем случае это означает, что hunk влияет на 5 строк, начиная с строки 1, в результате чего начинается замещение в строке 1 длиной 9 строк.

Обратите внимание, что это формат, используемый унифицированным форматом diff. В классическом формате diff используется другая модель (но кто использует классическую разницу в эти дни?).