Usando Git, ¿cómo encuentro cambios entre local y remoto?

152

Aquí hay dos preguntas diferentes, pero creo que están relacionadas.

  1. Cuando uso Git, ¿cómo encuentro qué cambios he comprometido localmente, pero aún no he enviado a una sucursal remota? Estoy buscando algo similar al comando Mercurial hg outgoing.

  2. Cuando uso Git, ¿cómo encuentro qué cambios tiene una rama remota antes de hacer un pull? Estoy buscando algo similar al comando Mercurial hg incoming.

Para el segundo: ¿hay alguna forma de ver lo que está disponible y luego elegir los cambios que quiero obtener?

ejunker
fuente
11
Al mirar las respuestas, parece haber cierta confusión sobre qué hg incomingy qué hg outgoinghacer realmente. El equivalente de Git más cercano que encontré es la --dry-runopción. Justo git pull --dry-runy verás una lista de todas las cosas que deben suceder.
Roman Starkov

Respuestas:

97

Git no puede enviar ese tipo de información a través de la red, como puede hacer Hg. Pero puede ejecutar git fetch(que es más parecido hg pulla hg fetch) para obtener nuevas confirmaciones de sus servidores remotos.

Entonces, si tiene una rama llamada mastery una remota llamada origin, después de ejecutar git fetch, también debe tener una rama llamada origin/master. A continuación, puede obtener git logtodos los commits que masterdeben ser un superconjunto origin/masteral hacer git log master..origin/master. Invierta esos dos para obtener lo contrario.

Un amigo mío, David Dollar, ha creado un par de scripts de git shell para simular hg incoming/outgoing. Puede encontrarlos en http://github.com/ddollar/git-utils .

Jordi Bunster
fuente
113

Comenzando con Git 1.7.0, hay una sintaxis especial que le permite referirse genéricamente a la rama ascendente: @{u}o @{upstream}.

Para imitar hg incoming:

git log ..@{u}

Para imitar hg outgoing:

git log @{u}..

Uso lo siguiente incomingy los outgoingalias para hacer que lo anterior sea más fácil de usar:

git config --global alias.incoming '!git remote update -p; git log ..@{u}'
git config --global alias.outgoing 'log @{u}..'
Richard Hansen
fuente
git log .. @ {u} me da estos errores. (Tengo tanto el origen como un repositorio ascendente en mi configuración de git). error: no se encontró una rama ascendente para '' error: no se encontró una rama ascendente para '..' error: no se encontró una rama ascendente para '..' fatal: argumento ambiguo '.. @ {u}': revisión desconocida o ruta no en El árbol de trabajo. Use '-' para separar las rutas de las revisiones
Henrik
66
Obtendrá esos errores si su sucursal local no está configurada con un flujo ascendente. Para arreglarlo, corre git branch --set-upstream foo origin/foo.
Richard Hansen el
git log @{u}..enumera cada cambio en el repositorio para mí. No hay forma de que aún no existan.
Roman Starkov
@romkyns: es posible que su sucursal local tenga la sucursal remota incorrecta configurada como ascendente. Asegúrese de git rev-parse --symbolic-full-name @{u}imprimir la referencia remota adecuada. Además, git log @{u}..muestra las confirmaciones a las que la rama ascendente no puede acceder, que pueden incluir confirmaciones que ya están en el repositorio remoto (si se puede acceder a ellas mediante una referencia diferente). Esto sucederá justo después de fusionarse en una rama ya empujada.
Richard Hansen
@RichardHansen Me temo que soy demasiado novato para saber qué sería apropiado para una referencia remota, sin embargo, este fue un repositorio recién clonado en el que hice solo un checkout <somebranch>y merge <otherbranch>. En este punto, hice el log @{u}..y vi todos los cambios enumerados.
Roman Starkov
42

No es una respuesta completa, pero git fetch extraerá el repositorio remoto y no hará una fusión. Entonces puedes hacer un

git diff maestro origen / maestro

Martin Redmond
fuente
1
Trabajó para mí (pero al revés) -git diff origin/master master
Nick Grealy
34
  1. Use "git log origin..HEAD"

  2. Utilice "git fetch" seguido de "git log HEAD..origin". Puede seleccionar confirmaciones individuales utilizando los ID de confirmación enumerados.

Lo anterior supone, por supuesto, que "origen" es el nombre de su rama de seguimiento remoto (que es si ha utilizado clonar con opciones predeterminadas).

Greg Hewgill
fuente
3
(Y si no está rastreando la rama remota, es "git log origin / master..HEAD".)
plindberg
44
"origen" no es el nombre de la rama de seguimiento remoto, es el nombre del control remoto. Y solo especificar el nombre remoto no funciona, debe especificar la rama de seguimiento remoto, que sería origen / maestro.
robinst
22

También hay esto, para comparar todas las ramas:

git log --branches --not --remotes=origin

Esto es lo que dice la página de manual de git log sobre esto:

Muestra todas las confirmaciones que se encuentran en cualquiera de las sucursales locales pero no en ninguna de las sucursales de seguimiento remoto para el origen (lo que tiene ese origen no).

Lo anterior es para outgoing. Para incoming, simplemente intercambiar:

git log --remotes=origin --not --branches
robinst
fuente
8

yo lo haría

$ git fetch --dry-run

para hg incomingy

$ git push --dry-run

para hg outgoing.

Chris
fuente
Lo siento, pasé por alto que esto ya se dijo como un comentario al OP.
Chris
1

git-out es un script que emula con hg outgoingbastante precisión. Se analiza en la salida "push -n", por lo que produce una salida precisa si necesita especificar argumentos adicionales para empujar.

stepancheg
fuente
0

git entrante

$ git fetch && git log ..origin/master --stat
OR
$ git fetch && git log ..origin/master --patch

git saliente

$ git fetch && git log origin/master.. --stat
OR
$ git fetch && git log origin/master.. --patch
prayagupd
fuente
0

Cuando las respuestas "git log" y @ {u} inicialmente me dieron errores de "revisión desconocida", probé la sugerencia de Chris / romkyns de git push --dry-run.

Obtendrá una salida como "5905..4878 master-> master". 5905 es la última confirmación que tiene el control remoto y los compromisos a través de (e incluyendo) 4878 se aplicarán al control remoto.

Luego puede usar 5905..4878 como argumentos para varios otros comandos git para obtener más detalles:

git diff 5905..4878 # Gives full code changes in diff style

git log --online 5905..4878 # Displays each commit's comment
pierce.jason
fuente
-1

Cuando hace git fetch, todo el contenido, incluidas las ramas, las etiquetas (referencias) se almacenan temporalmente en .git / FETCH_HEAD cuyo contenido se puede ver con el comando: git log FETCH_HEAD Si no usa el sufijo -a con git fetch, entonces de manera predeterminada , El contenido de FETCH_HEAD se sobrescribirá con nuevos contenidos. A partir de estos contenidos, puede ver y decidir a qué rama desea fusionarlos si lo hace, o puede elegir simplemente si desea solo unas pocas confirmaciones de lo que se ha traído por fetch.

AMIT PRAKASH PANDEY
fuente