diff --git a/builtin-http-fetch.c b/http-fetch.c
similarity index 95%
rename from builtin-http-fetch.c
rename to http-fetch.c
index f3e63d7..e8f44ba 100644
--- a/builtin-http-fetch.c
+++ b/http-fetch.c
@@ -1,8 +1,9 @@
#include "cache.h"
#include "walker.h"
-int cmd_http_fetch(int argc, const char **argv, const char *prefix)
+int main(int argc, const char **argv)
{
+ const char *prefix;
struct walker *walker;
int commits_on_stdin = 0;
int commits;
@@ -18,6 +19,8 @@ int cmd_http_fetch(int argc, const char **argv, const char *prefix)
int get_verbosely = 0;
int get_recover = 0;
+ prefix = setup_git_directory();
+
git_config(git_default_config, NULL);
while (arg < argc && argv[arg][0] == '-') {
Vamos analisar esse patch linha por linha.
A primeira linha
diff --git a / builtin-http-fetch.cb / http-fetch.c
é um cabeçalho "git diff" no formulário diff --git a/file1 b/file2. Os nomes de arquivo a/e b/são os mesmos, a menos que renomear / copiar esteja envolvido (como no nosso caso). A --gité para significar que diff está no formato diff "git".
A seguir, estão uma ou mais linhas de cabeçalho estendidas. Os três primeiros
índice de similaridade 95%
renomeie de builtin-http-fetch.c
renomeie para http-fetch.c
diga-nos que o arquivo foi renomeado de builtin-http-fetch.cpara http-fetch.ce que esses dois arquivos são 95% idênticos (que foram usados para detectar essa renomeação).
A última linha no cabeçalho diff estendido, que é
índice f3e63d7..e8f44ba 100644
informe-nos sobre o modo de um determinado arquivo ( 100644significa que ele é um arquivo comum e não, por exemplo, link simbólico, e que não possui um bit de permissão executável) e sobre um hash reduzido de pré-imagem (a versão do arquivo antes da alteração) e a pós-imagem (a versão do arquivo após a alteração). Essa linha é usada git am --3waypara tentar fazer uma mesclagem de 3 vias se o patch não puder ser aplicado.
Em seguida é o cabeçalho diff unificado de duas linhas
--- a / builtin-http-fetch.c
+++ b / http-fetch.c
Comparado ao diff -Uresultado, ele não possui nomes de arquivo de tempo de modificação de arquivo nem de tempo de modificação de arquivo após os nomes dos arquivos de origem (pré-imagem) e de destino (pós-imagem). Se o arquivo foi criado, a fonte é /dev/null; se o arquivo foi excluído, o destino é /dev/null. Se você definir diff.mnemonicPrefixvariável de configuração para true, no lugar de a/e b/prefixos neste cabeçalho de duas linhas que você pode ter ao invés c/, i/, w/e o/como prefixos, respectivamente para o que você comparar; veja git-config (1)
Em seguida, vêm um ou mais pedaços de diferenças; cada pedaço mostra uma área em que os arquivos diferem. Pedaços de formato unificado começam com linhas como
É no formato @@ from-file-range to-file-range @@ [header]. O intervalo from-file está no formato -<start line>,<number of lines>e to-file-range +<start line>,<number of lines>. Tanto a linha inicial quanto o número de linhas referem-se à posição e comprimento do pedaço na pré-imagem e pós-imagem, respectivamente. Se o número de linhas não mostrado, significa que é 0.
O cabeçalho opcional mostra a função C em que cada alteração ocorre, se for um arquivo C (como -popção no GNU diff) ou o equivalente, se houver, para outros tipos de arquivos.
Em seguida, vem a descrição de onde os arquivos diferem. As linhas comuns aos dois 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.
@ Geremia: O Git usa heurísticas baseadas em similaridade para renomear a detecção ... e também para mover código e detectar cópias git blame -C -C, é assim que funciona; é uma decisão de design do Git. O formato git diff mostra apenas o índice de semelhança (ou dissimilaridade) com o usuário.
Jakub Narębski
1
@ Geremia: Para ser mais exato, [header]é o precedente mais próximo, como no início da função que precede um pedaço. Na maioria dos casos, essa linha inclui o nome da função na qual está o pedaço de diff. Isso é configurável com o diffgitattribute definido como driver diff, e driver diff incluindo a xfuncnamevariável de configuração.
Jakub Narębski
1
@AnthonyGeoghegan: as linhas podem ser excluídas (o número de linhas na pós-imagem é 0) ou adicionadas (o número de linhas na pré-imagem é 0).
@ JakubNarębski: O número de linhas padrão é 1, e não 0. É tão simples quanto isso. Na prática, ele aparece apenas como "-1" e / ou "+1" para arquivos de linha única porque não há contexto para exibição.
precisa
68
@@ -1,2 +3,4 @@ parte do diff
Essa parte demorou um pouco para entender, então criei um exemplo mínimo.
O formato é basicamente o mesmo que o diff -udiff unificado.
Isso é para quem ainda não entendeu direito. Em @@ -1,6 +1,4 @@pls, não leia -1como minus oneou, +1em plus onevez disso, leia isso como line 1 to 6no antigo (primeiro) arquivo. Observe aqui - implies "old"não menos. BTW, obrigado pelo esclarecimento ... haash.
Dkjain 2/07
a partir disso @@ -1,8 +1,9 @@ é possível interpretar o que realmente aconteceu. por exemplo 1) uma linha foi adicionada 2) uma linha está sendo modificada e uma linha está sendo adicionada e assim por diante. Ou é de outra maneira, como deve haver uma maneira de obtê-los, já que o git diff corretamente identifica quais linhas foram modificadas no código. Por favor me ajude como eu realmente preciso resolver isso
Kasun Siyambalapitiya
Observe que esta declaração é incorreta e muito enganadora na resposta acima: " +1,4diz que esta peça corresponde à linha 1 a 4 do segundo arquivo ". Isso ocorre porque +1,4pode se referir a linhas de contexto não contingentes. Pelo contrário, o que " +1,4" realmente significa é que " existem 4linhas (isto é, linhas de contexto) nessa 'versão' do arquivo ". É importante compreender o significado do +, -e <whitespace>no início dessas linhas, que se aplica à interpretação dos pedaços. Um exemplo mais visual: youtube.com/watch?v=1tqMjJeyKpw
Damilola Olowookere
23
Aqui está o exemplo simples.
diff --git a/file b/file
index 10ff2df..84d4fa2 100644
--- a/file
+++ b/file
@@ -1,5 +1,5 @@
line1
line2
-this line will be deleted
line4
line5
+this line is added
--git não é um comando, isso significa que é uma versão git do diff (não unix)
a/ b/são diretórios, eles não são reais. é apenas uma conveniência quando lidamos com o mesmo arquivo (no meu caso, a / está no índice eb / está no diretório de trabalho)
10ff2df..84d4fa2 são IDs de blob desses 2 arquivos
100644 são os "bits de modo", indicando que este é um arquivo comum (não executável e não um link simbólico)
--- a/file +++ b/filesinais de menos mostra linhas na versão a / mas ausentes na versão b /; e sinais de mais mostram linhas ausentes em a / mas presentes em b / (no meu caso --- significa linhas excluídas e +++ significa linhas adicionadas em b / e este é o arquivo no diretório de trabalho)
@@ -1,5 +1,5 @@para entender isso, é melhor trabalhar com um arquivo grande; se você tiver duas alterações em lugares diferentes, receberá duas entradas como @@ -1,5 +1,5 @@; suponha que você tenha o arquivo line1 ... line100 e excluiu a line10 e adicione a nova line100 - você receberá:
@@ -7,7 +7,6 @@ line6
line7
line8
line9
-this line10 to be deleted
line11
line12
line13
@@ -98,3 +97,4 @@ line97
line98
line99
line100
+this is new line100
Obrigado. "100644 são os bits de modo, indicando que este é um arquivo regular (não executável e não um link simbólico)". "Mode bits" é um conceito no Linux ou apenas no Git?
Tim
@ Tim Não é específico para o git. Os 3 dígitos corretos ( 644) devem ser lidos em octal (valores: 1, 2, 4 respectivamente, permissão eXecute, Write e Read) e correspondem nessa ordem a Proprietário (Usuário), Grupo e Outras permissões. Então, resumindo 644, se escrito simbolicamente u=rw,og=r, é legível para todos, mas é gravável apenas pelo proprietário. Os outros dígitos à esquerda codificam outras informações, como se fosse um link simbólico, etc. Os valores podem ser vistos em github.com/git/git/blob/… , o primeiro 1 nesta posição é "arquivo regular".
Patrick Mevzek 30/08/19
15
O formato de saída padrão (originalmente proveniente de um programa conhecido como diffse você deseja procurar mais informações) é conhecido como "diff unificado". Ele contém essencialmente 4 tipos diferentes de linhas:
linhas de contexto, que começam com um único espaço,
linhas de inserção que mostram uma linha que foi inserida, que começam com um +,
linhas de deleção, que começam com um -, e
linhas de metadados que descrevem coisas de nível superior, como qual arquivo está falando, quais opções foram usadas para gerar o diff, se o arquivo alterou suas permissões etc.
Aconselho que você pratique a leitura de diferenças entre duas versões de um arquivo em que você sabe exatamente o que mudou. Assim, você reconhecerá exatamente o que está acontecendo quando o vir.
As linhas comuns aos dois 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.
Observe que o git não imprime a parte 'XXX-FILE-MODIFICATION-TIME', pois não faz sentido para o sistema de controle de versão. Para comparar arquivos nos arquivos de data e hora do sistema de arquivos, pode funcionar como controle de versão "pobre homem".
Jakub Narębski 27/03
3
Não está claro em sua pergunta qual parte das diferenças você considera confusa: as informações realmente diff ou extra, que o git imprime. Apenas no caso, aqui está uma rápida visão geral do cabeçalho.
A primeira linha é algo como diff --git a/path/to/file b/path/to/file- obviamente, está apenas dizendo a você para qual arquivo esta seção do diff é. Se você definir a variável de configuração booleana diff.mnemonic prefix, o ae bserá alterado para letras mais descritivas como ce w(confirmação e árvore de trabalho).
Em seguida, existem "linhas de modo" - linhas que fornecem uma descrição de quaisquer alterações que não envolvam a alteração do conteúdo do arquivo. Isso inclui arquivos novos / excluídos, arquivos renomeados / copiados e alterações nas permissões.
Finalmente, há uma linha como index 789bd4..0afb621 100644. Você provavelmente nunca se importará com isso, mas esses números hexadecimais de 6 dígitos são os hashes SHA1 abreviados dos blobs antigos e novos desse arquivo (um blob é um objeto git que armazena dados brutos como o conteúdo de um arquivo). E, claro, esse 100644é o modo do arquivo - os três últimos dígitos são obviamente permissões; os três primeiros fornecem informações extras sobre metadados de arquivos ( publicação SO descrevendo isso ).
Depois disso, você estará na saída diff unificada padrão (como no clássico diff -U). Ele é dividido em pedaços - um pedaço é uma seção do arquivo que contém alterações e seu contexto. Cada pedaço é precedido por um par de ---e +++linhas que indicam o arquivo em questão; o diff real é (por padrão) três linhas de contexto em ambos os lados das linhas -e +mostrando as linhas removidas / adicionadas.
Respostas:
Vamos dar uma olhada no exemplo diff avançado do histórico do git (no commit 1088261f no repositório git.git ):
Vamos analisar esse patch linha por linha.
A primeira linha
é um cabeçalho "git diff" no formuláriodiff --git a/file1 b/file2
. Os nomes de arquivoa/
eb/
são os mesmos, a menos que renomear / copiar esteja envolvido (como no nosso caso). A--git
é para significar que diff está no formato diff "git".A seguir, estão uma ou mais linhas de cabeçalho estendidas. Os três primeiros
diga-nos que o arquivo foi renomeado debuiltin-http-fetch.c
parahttp-fetch.c
e que esses dois arquivos são 95% idênticos (que foram usados para detectar essa renomeação).A última linha no cabeçalho diff estendido, que é informe-nos sobre o modo de um determinado arquivo (
100644
significa que ele é um arquivo comum e não, por exemplo, link simbólico, e que não possui um bit de permissão executável) e sobre um hash reduzido de pré-imagem (a versão do arquivo antes da alteração) e a pós-imagem (a versão do arquivo após a alteração). Essa linha é usadagit am --3way
para tentar fazer uma mesclagem de 3 vias se o patch não puder ser aplicado.Em seguida é o cabeçalho diff unificado de duas linhas
Comparado aodiff -U
resultado, ele não possui nomes de arquivo de tempo de modificação de arquivo nem de tempo de modificação de arquivo após os nomes dos arquivos de origem (pré-imagem) e de destino (pós-imagem). Se o arquivo foi criado, a fonte é/dev/null
; se o arquivo foi excluído, o destino é/dev/null
.Se você definir
diff.mnemonicPrefix
variável de configuração para true, no lugar dea/
eb/
prefixos neste cabeçalho de duas linhas que você pode ter ao invésc/
,i/
,w/
eo/
como prefixos, respectivamente para o que você comparar; veja git-config (1)Em seguida, vêm um ou mais pedaços de diferenças; cada pedaço mostra uma área em que os arquivos diferem. Pedaços de formato unificado começam com linhas como
ou É no formato@@ from-file-range to-file-range @@ [header]
. O intervalo from-file está no formato-<start line>,<number of lines>
e to-file-range+<start line>,<number of lines>
. Tanto a linha inicial quanto o número de linhas referem-se à posição e comprimento do pedaço na pré-imagem e pós-imagem, respectivamente. Se o número de linhas não mostrado, significa que é 0.O cabeçalho opcional mostra a função C em que cada alteração ocorre, se for um arquivo C (como
-p
opção no GNU diff) ou o equivalente, se houver, para outros tipos de arquivos.Em seguida, vem a descrição de onde os arquivos diferem. As linhas comuns aos dois 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:
Então, por exemplo, primeiro pedaço
significa que
cmd_http_fetch
foi substituído pormain
e essaconst char *prefix;
linha foi adicionada.Em outras palavras, antes da mudança, o fragmento apropriado do arquivo 'builtin-http-fetch.c' era assim:
Após a alteração, este fragmento do arquivo 'http-fetch.c' se parece com o seguinte:
Pode haver
linha presente (não é no exemplo diff).Como Donal Fellows disse , é melhor praticar a leitura de diferenças em exemplos da vida real, onde você sabe o que mudou.
Referências:
fonte
git blame -C -C
, é assim que funciona; é uma decisão de design do Git. O formato git diff mostra apenas o índice de semelhança (ou dissimilaridade) com o usuário.[header]
é o precedente mais próximo, como no início da função que precede um pedaço. Na maioria dos casos, essa linha inclui o nome da função na qual está o pedaço de diff. Isso é configurável com odiff
gitattribute definido como driver diff, e driver diff incluindo axfuncname
variável de configuração.@@ -1,2 +3,4 @@
parte do diffEssa parte demorou um pouco para entender, então criei um exemplo mínimo.
O formato é basicamente o mesmo que o
diff -u
diff unificado.Por exemplo:
Aqui removemos as linhas 2, 3, 14 e 15. Saída:
@@ -1,6 +1,4 @@
significa:-1,6
significa 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.-
significa "antigo", como normalmente chamamosdiff -u old new
.+1,4
significa que esta parte do segundo arquivo começa na linha 1 e mostra um total de 4 linhas. Portanto, 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:
@@ -11,6 +9,4 @@
para o segundo pedaço é análogo:no arquivo antigo, temos 6 linhas, começando na linha 11 do arquivo antigo:
no novo arquivo, temos 4 linhas, começando na linha 9 do novo arquivo:
Observe que a linha
11
é a 9a linha do novo arquivo, porque já removemos duas linhas no pedaço anterior: 2 e 3.Cabeçalho do pedaço
Dependendo da versão e configuração do git, você também pode obter uma linha de código próxima à
@@
linha, por exemplo,func1() {
in:Isso também pode ser obtido com a
-p
bandeira da planíciediff
.Exemplo: arquivo antigo:
Se removermos a linha
6
, o diff mostrará:Observe que esta não é a linha correta para
func1
: pulou as linhas1
e2
.Esse recurso impressionante geralmente informa 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 do cabeçalho do git diff hunk?
fonte
@@ -1,6 +1,4 @@
pls, não leia-1
comominus one
ou,+1
emplus one
vez disso, leia isso comoline 1 to 6
no antigo (primeiro) arquivo. Observe aqui- implies "old"
não menos. BTW, obrigado pelo esclarecimento ... haash.+1,4
diz que esta peça corresponde à linha 1 a 4 do segundo arquivo ". Isso ocorre porque+1,4
pode se referir a linhas de contexto não contingentes. Pelo contrário, o que "+1,4
" realmente significa é que " existem4
linhas (isto é, linhas de contexto) nessa 'versão' do arquivo ". É importante compreender o significado do+
,-
e<whitespace>
no início dessas linhas, que se aplica à interpretação dos pedaços. Um exemplo mais visual: youtube.com/watch?v=1tqMjJeyKpwAqui está o exemplo simples.
Aqui está uma explicação (veja detalhes aqui ).
--git
não é um comando, isso significa que é uma versão git do diff (não unix)a/ b/
são diretórios, eles não são reais. é apenas uma conveniência quando lidamos com o mesmo arquivo (no meu caso, a / está no índice eb / está no diretório de trabalho)10ff2df..84d4fa2
são IDs de blob desses 2 arquivos100644
são os "bits de modo", indicando que este é um arquivo comum (não executável e não um link simbólico)--- a/file +++ b/file
sinais de menos mostra linhas na versão a / mas ausentes na versão b /; e sinais de mais mostram linhas ausentes em a / mas presentes em b / (no meu caso --- significa linhas excluídas e +++ significa linhas adicionadas em b / e este é o arquivo no diretório de trabalho)@@ -1,5 +1,5 @@
para entender isso, é melhor trabalhar com um arquivo grande; se você tiver duas alterações em lugares diferentes, receberá duas entradas como@@ -1,5 +1,5 @@
; suponha que você tenha o arquivo line1 ... line100 e excluiu a line10 e adicione a nova line100 - você receberá:fonte
644
) devem ser lidos em octal (valores: 1, 2, 4 respectivamente, permissão eXecute, Write e Read) e correspondem nessa ordem a Proprietário (Usuário), Grupo e Outras permissões. Então, resumindo644
, se escrito simbolicamenteu=rw,og=r
, é legível para todos, mas é gravável apenas pelo proprietário. Os outros dígitos à esquerda codificam outras informações, como se fosse um link simbólico, etc. Os valores podem ser vistos em github.com/git/git/blob/… , o primeiro 1 nesta posição é "arquivo regular".O formato de saída padrão (originalmente proveniente de um programa conhecido como
diff
se você deseja procurar mais informações) é conhecido como "diff unificado". Ele contém essencialmente 4 tipos diferentes de linhas:+
,-
, eAconselho que você pratique a leitura de diferenças entre duas versões de um arquivo em que você sabe exatamente o que mudou. Assim, você reconhecerá exatamente o que está acontecendo quando o vir.
fonte
No meu mac:
info diff
depois selecione:Output formats
->Context
->Unified format
->Detailed Unified
:Ou o homem online difere no gnu seguindo o mesmo caminho para a mesma seção:
fonte
Não está claro em sua pergunta qual parte das diferenças você considera confusa: as informações realmente diff ou extra, que o git imprime. Apenas no caso, aqui está uma rápida visão geral do cabeçalho.
A primeira linha é algo como
diff --git a/path/to/file b/path/to/file
- obviamente, está apenas dizendo a você para qual arquivo esta seção do diff é. Se você definir a variável de configuração booleanadiff.mnemonic prefix
, oa
eb
será alterado para letras mais descritivas comoc
ew
(confirmação e árvore de trabalho).Em seguida, existem "linhas de modo" - linhas que fornecem uma descrição de quaisquer alterações que não envolvam a alteração do conteúdo do arquivo. Isso inclui arquivos novos / excluídos, arquivos renomeados / copiados e alterações nas permissões.
Finalmente, há uma linha como
index 789bd4..0afb621 100644
. Você provavelmente nunca se importará com isso, mas esses números hexadecimais de 6 dígitos são os hashes SHA1 abreviados dos blobs antigos e novos desse arquivo (um blob é um objeto git que armazena dados brutos como o conteúdo de um arquivo). E, claro, esse100644
é o modo do arquivo - os três últimos dígitos são obviamente permissões; os três primeiros fornecem informações extras sobre metadados de arquivos ( publicação SO descrevendo isso ).Depois disso, você estará na saída diff unificada padrão (como no clássico
diff -U
). Ele é dividido em pedaços - um pedaço é uma seção do arquivo que contém alterações e seu contexto. Cada pedaço é precedido por um par de---
e+++
linhas que indicam o arquivo em questão; o diff real é (por padrão) três linhas de contexto em ambos os lados das linhas-
e+
mostrando as linhas removidas / adicionadas.fonte
index
linha. Confirmado comgit hash-object ./file