Что означает «@@ -1 +1 @@» в выводе Git diff?

104

Я собирал данные из информации, полученной из

git diff <commitId>..<commitId>

и я столкнулся с @@ -1 +1 @@

Я не могу понять, о чем это мне говорит. Я немного искал в Google, но безрезультатно.

SSEMember
источник
Вы можете описать, в каком файле получается такой заголовок?
kworr 08
@kworr, это какой-то глупый вопрос, любой diff в едином формате имеет заголовки диапазона.
Yuval Adam
@YuvalAdam: на самом деле в унифицированном формате diff есть больше полей, которые нужно заполнить, например [- +] <position>, <lines>, и здесь у нас нет никаких изменений, но эти изменения касаются первой строки файла.
kworr 08

Ответы:

69

Это унифицированный идентификатор блока различий. Это задокументировано GNU Diffutils.

Унифицированный выходной формат начинается с двухстрочного заголовка, который выглядит следующим образом:

--- от-файла от-файла-времени-модификации 
+++ к-файлу к-времени-модификации-файла

Метка времени выглядит так, 2002-02-21 23:30:39.942229878 -0800чтобы указывать дату, время с долями в секундах и часовой пояс. Дробные секунды опускаются на хостах, которые не поддерживают дробные метки времени.

Вы можете изменить содержимое заголовка с помощью --label=labelопции; см. раздел « Альтернативные имена» .

Затем следуют одна или несколько частей различий; каждый кусок показывает одну область, в которой файлы различаются. Блоки унифицированного формата выглядят так:

@@ номера-строк из файла в номера строк в файле @@
  строка-из-любого-файла 
 строка-из-любого-файла ...

Если блок содержит только одну строку, отображается только номер его начальной строки. В противном случае его номера строк выглядят так . Считается, что пустой блок начинается со строки, следующей за блоком.start,count

Если кусок и его контекст содержат две или более строк, номера его строк выглядят так . В противном случае отображается только номер его конечной строки. Считается, что пустой блок заканчивается на строке, предшествующей блоку.start,count

Строки, общие для обоих файлов, начинаются с пробела. Строки, которые фактически различаются между двумя файлами, имеют один из следующих символов индикатора в левом столбце печати:

  • +
    Здесь к первому файлу добавлена ​​строчка.
  • -
    Из первого файла здесь убрана строчка.
Тодд А. Джейкобс
источник
71

Анализ простого примера

Формат в основном такой же, как и у diff -uунифицированного diff.

Например:

diff -u <(seq -w 16) <(seq -w 16 | grep -Ev '^(02|03|14|15)$')

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

@@ -1,6 +1,4 @@
 01
-02
-03
 04
 05
 06
@@ -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 строки были удалены! Новый кусок просто:

    01
    04
    05
    06
    

@@ -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() {in:

@@ -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 hunk?

Чиро Сантилли 郝海东 冠状 病 六四 事件 法轮功
источник
Ах, поэтому я бы прочитал @@ -1,6 +1,4 @@как «Начиная со строки 1, старое количество строк было 6, а новое - 4»
Cloud
1
@Cloud, да вот и все :-)
Чиро Сантилли 郝海东 冠状 病 六四 事件 法轮功
6

Это информация о текущем диапазоне фрагментов, указывающая, на каких номерах строк начинается и заканчивается этот фрагмент различий.

Прочтите http://en.wikipedia.org/wiki/Diff#Unified_format для более подробного объяснения.

Юваль Адам
источник
Спасибо. Выручил. Если нет конечной запятой и s, по умолчанию используется 1.
SSEMember