Obteniendo la diferencia entre dos repositorios

184

¿Cómo podemos obtener la diferencia entre dos repositorios git?

El escenario: tenemos un repo_a y repo_b. Este último fue creado como una copia de repo_a. Ha habido un desarrollo paralelo en ambos repositorios después. ¿Hay alguna manera de enumerar las diferencias de las versiones actuales de estos dos repositorios?

sanjayav
fuente
2
posible duplicado de ¿Cómo comparo dos repositorios git?
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Respuestas:

250

En 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
iamamac
fuente
3
¿Qué sucede si necesita comparar repo_a / master con una etiqueta específica de repo_b?
David Torres
2
no funciona para mí, está arrojando: fatal: argumento ambiguo 'remotes / b / master': revisión desconocida o ruta no en el árbol de trabajo. Use '-' para separar las rutas de las revisiones, así: 'git <comando> [<revisión> ...] - [<archivo> ...]' ¿Alguna idea aquí?
Andrew Heekin
2
Estoy obteniendo lo mismo que @AndrewHeekin. ¿Alguien tiene una solución?
Parlamento
44
Parece que necesito especificar en origin/masterlugar de un simple master. Además, esto encuentra la diferencia entre las ramas maestras, entonces, ¿qué pasa si desea encontrar todas las ramas que son diferentes? Por ejemplo, para verificar el estado de una copia de seguridad del repositorio?
davidA
1
¿Puedes explicar qué está haciendo cada línea? Gracias !
Enrique
34

Meld puede comparar directorios:

meld directory1 directory2

Simplemente use los directorios de los dos repositorios git y obtendrá una buena comparación gráfica:

ingrese la descripción de la imagen aquí

Cuando hace clic en uno de los elementos azules, puede ver qué cambió.

Martin Thoma
fuente
1
Meld se congela mientras comparo proyectos en mi solución VS, BeyondCompare no lo es.
Sasha Bond
44
en OSX: diff -rq folder1 folder2
Mark
1
Maravilloso enlace! Programa muy simple, ahora estoy usando esto como mi programa diff para OSX.
dmanexe
1
¡Esto es absolutamente encantador! Gracias por compartir.
Shihab Khan
No estoy seguro de si meld es capaz de manejar archivos que git ignora, debería considerar esto mientras lo usa
noamgot
11

Puede agregar otro repositorio primero como control remoto a su repositorio actual:

git remote add other_name PATH_TO_OTHER_REPO

luego busque brach desde ese control remoto:

git fetch other_name branch_name:branch_name

esto crea esa rama como una nueva rama en su repositorio actual, luego puede diferenciar esa rama con cualquiera de sus ramas, por ejemplo, para comparar la rama actual con la nueva rama (nombre_sucursal):

git diff branch_name
M.Kouchi
fuente
8

Una vez que tenga ambas ramas en un repositorio, puede hacer una git diff. Y ponerlos en un repositorio es tan fácil como

git fetch /the/other/repo/.git refs/heads/*:refs/remotes/other/*
Michael Krelin - hacker
fuente
¿Hay alguna manera de seleccionar el historial con un pequeño cambio: por ejemplo, el archivo de repositorio remoto se coloca en un directorio, pero quiero aplicar los cambios al mismo archivo pero que se coloca en un directorio diferente en el repositorio local?
Eugen Konkov
Si está hablando de un pequeño cambio, creo que lo más fácil sería simplemente hacer una diferencia y luego volver a aplicarla al otro archivo usando el parche.
Michael Krelin - pirata informático
El parche no se aplica debido a diferentes nombres de archivo a pesar de que esos son los mismos archivos
Eugen Konkov
Oh, solo estaba pensando en diferentes directorios, no en nombres de archivos (los directorios se pueden manejar fácilmente a través de las opciones de parche). Bueno, para los nombres de archivo, simplemente los cambiaría manualmente o mediante el script. Dicho esto, no estoy diciendo que no haya una mejor solución, solo lo que se me ocurre sin excavar en ningún lado.
Michael Krelin - hacker
¿Qué pasa si quiero comparar todas las ramas?
endolito
7
git diff master remotes/b

Eso es incorrecto remotes/bes un control remoto, pero no una rama.

Para que funcione, tuve que hacer:

git diff master remotes/b/master
James
fuente
2
Esto realmente debería ser un comentario sobre la respuesta relevante.
EntangledLoops
6

Consulte http://git.or.cz/gitwiki/GitTips , sección "Cómo comparar dos repositorios locales" en "General".

En resumen, está utilizando la variable de entorno GIT_ALTERNATE_OBJECT_DIRECTORIES para tener acceso a la base de datos de objetos del otro repositorio, y está usando git rev-parse con --git-dir/ GIT_DIR para convertir el nombre simbólico en otro repositorio al identificador SHA-1.

La versión moderna se vería así (suponiendo que se encuentre en 'repo_a'):

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

donde ../repo_b/.gitestá la ruta de acceso a la base de datos de objetos en repo_b (sería repo_b.git si fuera un repositorio simple). Por supuesto, puede comparar versiones arbitrarias, no solo HEADs.


Tenga en cuenta que si repo_a y repo_b son el mismo repositorio, podría tener más sentido colocarlos en el mismo repositorio, ya sea usando " git remote add -f ..." para crear apodos para el repositorio para actualizaciones repetidas, u obedeciendo " git fetch ..."; como se describe en otras respuestas.

Jakub Narębski
fuente
5

Yo uso PyCharm que tiene grandes capacidades para comparar entre carpetas y archivos.

Simplemente abra la carpeta principal para ambos repositorios y espere hasta que indexe. Luego, puede hacer clic derecho en una carpeta o archivo Compare to...y seleccionar la carpeta / archivo correspondiente en el otro lado.

Muestra no solo qué archivos son diferentes sino también su contenido. Mucho más fácil que la línea de comando.

MrE
fuente
2

Su mejor opción es tener ambos repositorios en su máquina local y usar el comando linux diff con los dos directorios como parámetros:

diff -r repo-A repo-B

Andrew Heekin
fuente
2
La única forma de hacer que esto sea utilizable es cambiar el nombre de uno de los directorios .git. Esto reduce a dos líneas páginas de diferencias que no importan. He estado allí, hecho eso, vine aquí buscando una mejor respuesta.
hildred
2

Una manera fácil de hacerlo sin tocar la configuración de sus controles remotos. Desde el repositorio A, en maestro (suponga que desea comparar ramas maestras):

git fetch path/to/repo_b.git master
git diff FETCH_HEAD
jorisv92
fuente
0

Puedes usar el siguiente comando:

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

o para el lado a lado puedes usar:

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

En caso de colorear todos los archivos diff, puede usar:

diff -x .git -W200 -y -r repo-A repo-B | sed -e "s/\(^diff .*\)/\x1b[31m\1\x1b[0m/"
Gerard
fuente
basado en la solución @ andrew-heekin
Gerard
0

Recordatorio para auto ... buscar primero, de lo contrario el repositorio no tiene hash local (supongo).

paso 1. Configura el control remoto ascendente y superior ^

diferenciar un solo archivo sigue este patrón:

git diff localBranch uptreamBranch --spacepath / singlefile

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

Hillsie
fuente