O que “@@ -1 +1 @@” significa na saída de diff do Git?

104

Tenho coletado dados das informações retornadas de

git diff <commitId>..<commitId>

e eu corri para @@ -1 +1 @@

Não consigo descobrir o que isso está me dizendo. Pesquisei um pouco no Google, mas não adiantou.

SSEMember
fonte
Você pode descrever o arquivo que resulta em tal cabeçalho?
kworr
@kworr essa é uma pergunta meio boba, qualquer diff no formato unificado tem cabeçalhos de intervalo.
Yuval Adam
@YuvalAdam: na verdade, o formato unificado diff tem mais campos que devem ser preenchidos como [- +] <posição>, <linhas> e aqui não temos alterações exibidas, mas essas alterações tocam a primeira linha do arquivo.
kworr

Respostas:

69

É um identificador de bloco diff unificado. Isso é documentado pelo GNU Diffutils.

O formato de saída unificado começa com um cabeçalho de duas linhas, que se parece com isto:

--- from-file from-file-mod-time 
+++ para-file to-file-mod-time-time

O carimbo de hora parece 2002-02-21 23:30:39.942229878 -0800indicar a data, hora com segundos fracionários e fuso horário. Os segundos fracionários são omitidos em hosts que não oferecem suporte a carimbos de data / hora fracionários.

Você pode alterar o conteúdo do cabeçalho com a --label=labelopção; consulte Ver nomes alternativos .

Em seguida, vêm um ou mais blocos de diferenças; cada pedaço mostra uma área onde os arquivos são diferentes. Os pedaços de formato unificado são assim:

@@ números-de-linha-de-arquivo-para-arquivo-números -de-linha
  @@-
  linha-de-qualquer-arquivo -linha-de-qualquer-arquivo ...

Se um pedaço contém apenas uma linha, apenas o número da linha inicial aparece. Caso contrário, seus números de linha serão semelhantes . Um pedaço vazio é considerado como começando na linha que segue o pedaço.start,count

Se um pedaço e seu contexto contiverem duas ou mais linhas, seus números de linha serão semelhantes . Caso contrário, apenas o número da linha final aparece. Um pedaço vazio é considerado como terminando na linha que precede o pedaço.start,count

As linhas comuns a ambos os arquivos começam com um caractere de espaço. As linhas que realmente diferem entre os dois arquivos têm um dos seguintes caracteres indicadores na coluna de impressão à esquerda:

  • +
    Uma linha foi adicionada aqui ao primeiro arquivo.
  • -
    Uma linha foi removida aqui do primeiro arquivo.
Todd A. Jacobs
fonte
69

Análise de exemplo simples

O formato é basicamente o mesmo do diff -udiff unificado.

Por exemplo:

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

Aqui removemos as linhas 2, 3, 14 e 15. Resultado:

@@ -1,6 +1,4 @@
 01
-02
-03
 04
 05
 06
@@ -11,6 +9,4 @@
 11
 12
 13
-14
-15
 16

@@ -1,6 +1,4 @@ significa:

  • -1,6significa que esta parte do primeiro arquivo começa na linha 1 e mostra um total de 6 linhas. Portanto, mostra as linhas 1 a 6.

    1
    2
    3
    4
    5
    6
    

    -significa "antigo", como normalmente o chamamos diff -u old new.

  • +1,4significa que esta parte do segundo arquivo começa na linha 1 e mostra um total de 4 linhas. Portanto, ele mostra as linhas 1 a 4.

    + significa "novo".

    Temos apenas 4 linhas em vez de 6 porque 2 linhas foram removidas! O novo pedaço é apenas:

    01
    04
    05
    06
    

@@ -11,6 +9,4 @@ pois o segundo pedaço é análogo:

  • no arquivo antigo, temos 6 linhas, começando na linha 11 do arquivo antigo:

    11
    12
    13
    14
    15
    16
    
  • no novo arquivo, temos 4 linhas, começando na linha 9 do novo arquivo:

    11
    12
    13
    16
    

    Observe que a linha 11é a 9ª linha do novo arquivo porque já removemos 2 linhas no trecho anterior: 2 e 3.

Cabeçalho Hunk

Dependendo da sua versão e configuração do git, você também pode obter uma linha de código ao lado da @@linha, por exemplo, func1() {em:

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

Isso também pode ser obtido com a -pbandeira da planície diff.

Exemplo: arquivo antigo:

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

Se removermos a linha 6, o diff mostra:

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

Observe que esta não é a linha correta para func1: ela pulou linhas 1e 2.

Esse recurso incrível geralmente diz exatamente a qual função ou classe cada pedaço pertence, o que é muito útil para interpretar o diff.

Como o algoritmo para escolher o cabeçalho funciona exatamente é discutido em: De onde vem o trecho no cabeçalho git diff hunk?

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
fonte
Ah, então eu leria @@ -1,6 +1,4 @@como "Começando na linha 1, a contagem de linha antiga era 6, mas a contagem de nova linha é 4"
Nuvem de
1
@Cloud yup é isso :-)
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
6

É a informação do intervalo do pedaço atual que indica em quais números de linha esse pedaço diff começa e termina.

Leia http://en.wikipedia.org/wiki/Diff#Unified_format para obter uma explicação detalhada.

Yuval Adam
fonte
Obrigado. Ajudou. Quando não há vírgulas finais e s, o padrão é 1.
SSEMembro de