Como devo entender o formato unificado da saída do diff?

0

De manual do diffutils

Next come one or more hunks of diff erences; each hunk shows one area where the files differ. Unified format hunks look like this:

@@ from-file-line-numbers to-file-line-numbers @@
line-from-either-file
line-from-either-file...

If a hunk contains just one line, only its start line number appears. Otherwise its line numbers look like ‘start,count’. An empty hunk is considered to start at the line that follows the hunk.

If a hunk and its context contain two or more lines, its line numbers look like ‘start,count’. Otherwise only its end line number appears. An empty hunk is considered to end at the line that precedes the hunk.

O que eles querem dizer? Você poderia também dar alguns exemplos para mostrar o que eles significam?

Em particular, não consegui identificar as diferenças entre os casos nos dois últimos parágrafos. Eles parecem falar sobre os mesmos casos, mas eu suspeito que não.

  • Qual é a diferença entre o caso "if" no primeiro parágrafo e o caso "caso contrário" no segundo?

  • Qual é a diferença entre o caso "caso contrário" no primeiro parágrafo e o caso "se" no segundo?

por Tim 07.11.2018 / 21:07

1 resposta

3

Eu suspeito que o primeiro parágrafo (dos dois que você destaca) tenta explicar from-file-line-numbers , enquanto o segundo tenta explicar to-file-line-numbers .

Ignorarei o texto, que é obscuro, e explique como o diff do GNU implementa diff s unificado (endereçando o título da sua pergunta).

diff -u <(printf "a\nb\nc\n") <(printf "a\n")

produz o seguinte:

--- /proc/self/fd/11    2018-11-08 11:16:09.183611033 +0100
+++ /proc/self/fd/12    2018-11-08 11:16:09.184611029 +0100
@@ -1,3 +1 @@
 a
-b
-c

(omitirei as duas primeiras linhas dos exemplos subsequentes, pois elas não precisam de muita explicação).

Isso mostra que nossos dois "arquivos" diferem, com um conjunto de diferenças ("hunk"). Em um patch unificado, cada comparação de arquivo é introduzida por um par de linhas iniciando com --- (o arquivo “de”) e +++ (o arquivo “para”). Dentro de cada comparação de arquivo, cada pedaço é introduzido com uma linha começando e terminando com @@ . Esta linha identifica a localização da alteração nos arquivos de e para. A partir da localização começa com - (que não faz parte do número que se segue), a localização para começa com + . Locais são um par de números: a linha de partida e o comprimento (que é omitido se for 1). Portanto, no patch acima, temos uma alteração que transforma as três linhas começando na linha 1 do arquivo para a linha única começando na linha 1 no arquivo para.

Os itens podem incluir o contexto, que é o caso acima. Por padrão, diff inclui três linhas de contexto, se disponíveis; Ele também mesclará pedaços cujo contexto se sobrepõe. Se não houver três linhas de contexto antes e / ou após a alteração, o contexto será reduzido; portanto, acima, temos apenas uma linha de contexto antes da mudança e nenhuma depois. Este contexto é contado como parte da mudança dada no hunk, por isso contribui para a linha de partida e comprimento.

diff -u0 <(printf "a\nb\nc\n") <(printf "a\n")

ilustra isso:

@@ -2,2 +1,0 @@
-b
-c

Esta é a mesma alteração, mas sem contexto: é, portanto, reduzida a uma mudança, transformando as duas linhas, começando na linha 2, em nenhuma linha, começando na linha 1.

Os locais mais simples correspondem a patches que alteram uma única linha, sem contexto:

$ diff -u0 <(printf "a\nb\nc\n") <(printf "a\nb\nd\n")
@@ -3 +3 @@
-c
+d

Com contexto, isso seria

@@ -1,3 +1,3 @@
 a
 b
-c
+d

(A utilidade do contexto é permitir que os patches permaneçam úteis com arquivos "de" que não combinam com o original. patch aplicará patches "indistintos" nos quais os números de linha não coincidem, se ele encontra o contexto dentro de uma certa distância do local original.)

    
por 08.11.2018 / 11:36