Obtendo a diferença entre dois repositórios


184

Como podemos obter a diferença entre dois repositórios git?

O cenário: temos um repo_a e repo_b. Este último foi criado como uma cópia de repo_a. Houve um desenvolvimento paralelo nos dois repositórios posteriormente. Existe uma maneira de listar as diferenças das versões atuais desses dois repositórios?


Respostas:


249

Em repo_a:

git remote add -f b path/to/repo_b.git
git remote update
git diff master remotes/b/master
git remote rm b

3
E se você precisar comparar repo_a / master com uma tag específica de repo_b?
David Torres

2
não está funcionando para mim, está jogando: fatal: argumento ambíguo 'remotes / b / master': revisão desconhecida ou caminho que não está na árvore de trabalho. Use '-' para separar caminhos das revisões, assim: 'git <comando> [<revisão> ...] - [<arquivo> ...]' Alguma idéia aqui?
Andrew Heekin 02/09/2015

2
Estou recebendo o mesmo que @AndrewHeekin. Alguém tem uma solução?
parliament

4
Parece que preciso especificar, em origin/mastervez de um simples master. Além disso, isso encontra a diferença entre os ramos principais, e se você quiser encontrar todos os ramos diferentes? Por exemplo, para verificar o status de um backup do repositório?
DavidA

1
Você pode explicar o que está fazendo em todas as linhas? Obrigado !
Enrique

34

Meld pode comparar diretórios:

meld directory1 directory2

Basta usar os diretórios dos dois repositórios git e você obterá uma boa comparação gráfica:

insira a descrição da imagem aqui

Quando você clica em um dos itens azuis, pode ver o que mudou.


1
O Meld congela enquanto compara projetos na minha solução VS, o BeyondCompare não.
Sasha de Bond

4
no OSX: diff -rq folder1 folder2
Mark

1
Link maravilhoso! Programa muito simples, agora estou usando isso como meu programa diff para OSX.
dmanexe 12/03/19

1
Isso é absolutamente adorável! Obrigado por compartilhar.
Shihab Khan

Não tenho certeza se o meld é capaz de manipular arquivos que são ignorados pelo git - você deve considerar isso enquanto o usa
noamgot

11

Você pode adicionar outro repo primeiro como controle remoto ao repo atual:

git remote add other_name PATH_TO_OTHER_REPO

Em seguida, busque o brach desse controle remoto:

git fetch other_name branch_name:branch_name

isso cria esse ramo como um novo ramo no seu repo atual, e você pode diferenciá-lo com qualquer um dos seus ramos, por exemplo, para comparar o ramo atual com o novo ramo (branch_name):

git diff branch_name

8

Depois de ter as duas ramificações em um repositório, você pode fazer a git diff. E colocá-los em um repositório é tão fácil quanto

git fetch /the/other/repo/.git refs/heads/*:refs/remotes/other/*

Existe uma maneira de escolher o histórico com uma pequena alteração: por exemplo, o arquivo de repo remoto é colocado em um diretório, mas eu quero aplicar as alterações no mesmo arquivo, mas que é colocado em um diretório diferente no repo local?
Eugen Konkov 22/02

Se você está falando de uma pequena alteração, acho que o mais fácil seria apenas fazer um diff e reaplicá-lo ao outro arquivo usando o patch.
Michael Krelin - hacker de

O patch não é aplicado devido a nomes de arquivos diferentes, apesar de serem os mesmos arquivos
Eugen Konkov

Ah, eu estava pensando apenas em diretórios diferentes, não em nomes de arquivos (os diretórios podem ser facilmente manipulados por meio de opções de patch). Bem, para os nomes de arquivos, eu os mudaria manualmente ou através do script. Dito isto, não estou dizendo que não há solução melhor, apenas o que posso criar sem cavar em lugar algum.
Michael Krelin - hacker de

e se eu quiser comparar todas as filiais?
endolith

7
git diff master remotes/b

Isso está incorreto. remotes/bé um controle remoto, mas não um ramo.

Para fazê-lo funcionar, eu tinha que fazer:

git diff master remotes/b/master

2
Este deve realmente ser um comentário sobre a resposta relevante.
EntangledLoops

6

Consulte http://git.or.cz/gitwiki/GitTips , seção "Como comparar dois repositórios locais" em "Geral".

Em resumo, você está usando a variável de ambiente GIT_ALTERNATE_OBJECT_DIRECTORIES para ter acesso ao banco de dados de objetos do outro repositório e usando git rev-parse com --git-dir/ GIT_DIR para converter o nome simbólico em outro repositório no identificador SHA-1.

A versão moderna ficaria assim (supondo que você esteja em 'repo_a'):

GIT_ALTERNATE_OBJECT_DIRECTORIES = .. / repo_b / .git / objects \
   git diff $ (git --git-dir = .. / repo_b / .git rev-parse --verify HEAD)

onde ../repo_b/.gitestá o caminho para o banco de dados de objetos no repo_b (seria repo_b.git se fosse um repositório vazio). Claro que você pode comparar versões arbitrárias, não apenas HEADs.


Observe que, se repo_a e repo_b forem o mesmo repositório, pode fazer mais sentido colocar os dois no mesmo repositório, usando " git remote add -f ..." para criar apelidos para o repositório para atualizações repetidas ou obedeça " git fetch ..."; conforme descrito em outras respostas.


5

Eu uso o PyCharm, que tem ótimos recursos para comparar entre pastas e arquivos.

Basta abrir a pasta pai para ambos os repositórios e aguarde até que seja indexada. Em seguida, você pode usar o botão direito do mouse em uma pasta ou arquivo Compare to...e escolher a pasta / arquivo correspondente do outro lado.

Ele mostra não apenas quais arquivos são diferentes, mas também seu conteúdo. Muito mais fácil que a linha de comando.


2

Sua melhor aposta é ter ambos os repositórios em sua máquina local e usar o comando linux diff com os dois diretórios como parâmetros:

diff -r repo-A repo-B


2
A única maneira de tornar isso utilizável é renomear um dos diretórios .git. isso reduz para duas linhas as páginas de diferenças que não importam. Estive lá, fiz isso, veio aqui procurando uma resposta melhor.
Hildred

2

Uma maneira fácil de fazer isso sem tocar na configuração dos controles remotos. No repositório A, no mestre (suponha que você queira comparar as ramificações principais):

git fetch path/to/repo_b.git master
git diff FETCH_HEAD

0

Você pode usar o seguinte comando:

diff -x .git -r repo-A repo-B

ou, lado a lado, você pode usar:

diff -x .git -W200 -y -r repo-A repo-B

No caso de Colorizing cada arquivo diff, você pode usar:

diff -x .git -W200 -y -r repo-A repo-B | sed -e "s/\(^diff .*\)/\x1b[31m\1\x1b[0m/"

solução no @ andrew-Heekin base
Gerard

0

Lembrete de auto ... buscar primeiro, caso contrário, o repositório não possui hash local (eu acho).

etapa 1. Configure o controle remoto acima e acima ^

a diferença de um único arquivo segue esse padrão:

git diff localBranch uptreamBranch --spacepath / singlefile

git diff master upstream/nameofrepo -- src/index.js

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.