Ver confirmaciones de Git no apresuradas

1752

¿Cómo puedo ver las confirmaciones locales que he realizado y que aún no se han enviado al repositorio remoto? Ocasionalmente, git statusimprimirá que mi rama es X confirma antes origin/master, pero no siempre.

¿Es esto un error con mi instalación de Git o me falta algo?

Josh Buhler
fuente
18
Comenzando con Git 2.5+ (Q2 2015), la respuesta real sería git log @{push}... Vea ese nuevo acceso directo @{push}(haciendo referencia a la rama de seguimiento remoto que está presionando) en mi respuesta a continuación
VonC
59
@Torek: otra tarea sencilla que Git dificulta. Cada vez que aparece una pregunta de Git con cientos o miles de votos a favor y millones de visitas, alguien debería pensar: Wow, realmente arruinamos ese flujo de trabajo. Por desgracia, los desarrolladores de Git han omitido el paso de retroalimentación en el ciclo de vida del desarrollo, por lo que la retroalimentación no se incorpora. En cambio, siguen cometiendo los mismos errores una y otra vez. Para esta pregunta, git status --alldebería haber aparecido en 2010; o git status -vdebería proporcionar el resultado detallado que incluye la información adicional.
jww
44
No estoy de acuerdo con que "git status -v" debería proporcionar esta información porque está destinada a proporcionar un estado sobre el árbol de trabajo, ya que solo se relaciona con la rama desprotegida. Sin embargo, vea la respuesta a continuación sobre "git branch -v", que creo que debería ser la respuesta aceptada
JoelFan
13
Esta pregunta particular de StackOverflow tiene el mayor número de respuestas correctas que todo funciona pero que no tiene ningún sentido.
Pete Alvin el
@ josh-buhler Lo siento, voté en contra accidentalmente ... mientras intentaba hacer clic en 'ESTRELLA'. Volvió a intentar votar, pero no funcionó.
RafiAlhamd

Respuestas:

1828
git log origin/master..HEAD

También puede ver la diferencia usando la misma sintaxis

git diff origin/master..HEAD
Peter B
fuente
3
Esto lo hizo por mí, por alguna razón git log origin .. por sí solo arrojaba un error. Parece que también tuve un problema con la forma en que se configuró mi sucursal local: una vez que hice los cambios que encontré aquí: wincent.com/blog/… ... el problema se resolvió y pude usar el estado de git nuevamente para ver lo que quería .
Josh Buhler
66
Invaluable: tanto que lo hice git config --global alias.ahead "log origin/master..HEAD --oneline"para poder averiguar rápidamente dónde estoy. Aún más dulces:for i in *; do echo $i && git ahead 2>/dev/null; done
Jamie
15
git log --stat origin/master..HEADpor un poco de asombro extra
Cory Danielson
141
Esta no es la mejor solución. Origen / maestro puede no siempre la rama ascendente. Una mejor solución es utilizar @ {u} en lugar de "origen / maestro" para indicar la rama ascendente. Dado que HEAD está implícito por defecto, también se puede omitir eso. Ver la respuesta de @Ben Ling. Cambios salientes: git log @ {u} .. Cambios entrantes: git log .. @ {u}
PlagueHammer
12
@Nocturne Solo quiero señalar que cuando se publicó esta respuesta, la @{u}sintaxis aún no estaba disponible, solo estuvo disponible el 12 de febrero de 2010 . Además, @{u}no funcionará si la rama local no está configurada con un flujo ascendente. Finalmente, @{u}actualmente no tiene soporte para completar pestañas, <remote>/<branch>con la finalización de pestañas sigue siendo una de las formas más rápidas de obtener esta información, y funcionará si se configura un flujo ascendente o no.
703

Si desea ver todas las confirmaciones en todas las ramas que aún no se han enviado, es posible que esté buscando algo como esto:

git log --branches --not --remotes

Y si solo desea ver la confirmación más reciente en cada rama, y ​​los nombres de las ramas, esto:

git log --branches --not --remotes --simplify-by-decoration --decorate --oneline
cxreg
fuente
8
Esto es asombroso En un escenario relacionado, tenía dos sucursales locales con dos sucursales aguas arriba, y una mano local se fusionó con la otra. Quería saber qué commits eran seguros para rebase, pero lo normal git log master..HEADno funcionaría ya que había múltiples upstreams. Esta publicación me llevó git log MyBranch --not --remotesa mostrar todas las confirmaciones que no se han enviado a ninguna cadena en una sola rama.
Pavón
Esto fue tan útil que lo alias en mi configuración de zsh. Gracias.
Scotty C.
Entiendo que su segundo comando también enumera las confirmaciones que aún no se han enviado, solo muestra una por rama.
Stephane
--decoratemuestra las ramas también. --graphlo hace aún más obvio.
Ray
Tenga en cuenta que estos comandos solo enumeran confirmaciones que no se han introducido en ninguna rama. Ejemplo: supongamos que tiene una rama desarrollada con branch feat-NewThing. Realiza cambios localmente en feat-NewThing. (El registro tiene cambios.) Luego empujas feat-newThing a su rama remota. (El registro está vacío). Fusionas local feat-newThing para desarrollar localmente. Suponiendo un avance rápido, el registro aún no tiene cambios.
Patrick W
325

Puede mostrar todas las confirmaciones que tiene localmente pero no en sentido ascendente con

git log @{u}..

@{u}o @{upstream}significa la rama ascendente de la rama actual (ver git rev-parse --helpo git help revisionspara más detalles).

Ben Lings
fuente
17
En Windows, necesitaba encerrar el argumento final entre comillas, como: git log "@ {u} .."
Jon Schneider
git log @{u}.. -p Una de las opciones más útiles es -p , que muestra las diferencias introducidas en cada confirmación.
mQuiroz
Posiblemente mejor git log @ {push} .., vea otra respuesta .
Hans-Peter Störr el
183

Esto funcionó para mí:

git cherry -v 

Como se indica en Git: vea todas las confirmaciones no confirmadas o confirmaciones que no están en otra rama .

Christian Vielma
fuente
21
¡Creo que esta debería ser la respuesta principal, ya que esta proporciona la lista más sucinta de confirmaciones en lugar de una diferencia detallada, difícil de leer, en todos los archivos!
ViFI
1
git-cherry - "Buscar confirmaciones que aún no se han aplicado a la parte superior" parece proporcionar lo que el OP estaba pidiendo, pero solo con el asunto de la confirmación en lugar de todo el mensaje de confirmación.
Eido95
2
Vale la pena señalar que esto solo le dirá si hay confirmaciones no apresuradas en la rama que ha verificado actualmente. No le dirá si tiene una sucursal local (actualmente no desprotegida) con confirmaciones no ajustadas.
Dave Yarwood
66

Puedes hacer esto con git log:

git log origin..

Asumiendo que ese origines el nombre de su flujo ascendente, omita cualquier nombre de revisión después de ..implica HEAD, que enumera las nuevas confirmaciones que no se han enviado.

Greg Hewgill
fuente
1
Cada vez que veo una respuesta con git logy "2-dots-not-3", siempre me recuerda a stackoverflow.com/questions/53569/… ;)
VonC
1
Solo para agregarlo a la respuesta: si no hay una configuración ascendente, este comando da como resultado que no se haya configurado ninguna ascendente. Ejecute git branch --set-upstream master origin/<branch>para configurar en sentido ascendente si está dispuesto a usar este comando para ver las confirmaciones que se organizan por etapas.
asyncwait
Esto se comparará con la rama predeterminada en origen, no con la rama remota actual.
greuze
43

Todas las otras respuestas hablan de "aguas arriba" (la rama de la que extrae).
Pero una rama local puede empujar a una rama diferente de la que extrae.

masterpodría no empujar a la rama de seguimiento remoto " origin/master".
La rama ascendentemaster podría ser origin/master, pero podría empujar a la rama de seguimiento remoto origin/xxxo incluso anotherUpstreamRepo/yyy.
Estos se establecen branch.*.pushremotepara la rama actual junto con el global remote.pushDefaultvalor.

Es esa rama de seguimiento remoto la que cuenta cuando se buscan confirmaciones no apresuradas: la que rastrea el lugar branch at the remotedonde se empujaría la rama local .
El branch at the remotepuede ser, de nuevo, origin/xxxo incluso anotherUpstreamRepo/yyy.

Git 2.5+ (Q2 2015) presenta un nuevo atajo para eso: <branch>@{push}

Ver cometer 29bc885 , comprometerse 3dbe9db , cometen adfe5d0 , comprometerse 48c5847 , comprometerse a1ad0eb , comprometerse e291c75 , comprometerse 979cb24 , comprometerse 1ca41a1 , comprometerse 3a429d0 , comprometerse a9f9f8c , comprometerse 8770e6f , comprometerse da66b27 , comprometerse f052154 , comprometerse 9e3751d , comprometerse ee2499f [todos del 21 de mayo 2015], y cometer e41bf35 [01 de mayo de 2015] por Jeff King ( peff) .
(Fusionada por Junio ​​C Hamano - gitster-en commit c4a8354 , 05 jun 2015)

Comprometer adfe5d0 explica:

sha1_name: implementar @{push}taquigrafía

En un flujo de trabajo triangular, cada rama puede tener dos puntos de interés distintos: el @{upstream}que normalmente extrae y el destino al que normalmente empuja. No hay una taquigrafía para este último, pero es útil tenerlo.

Por ejemplo, es posible que desee saber qué compromisos aún no ha presionado :

git log @{push}..

O como un ejemplo más complicado, imagine que normalmente extrae los cambios origin/master(que configura como su @{upstream}), y empuja los cambios a su propio tenedor personal (por ejemplo, como myfork/topic).
Puede empujar a su tenedor desde múltiples máquinas, lo que requiere que integre los cambios desde el destino de empuje, en lugar de hacia arriba .
Con este parche, puedes hacer:

git rebase @{push}

en lugar de escribir el nombre completo.

Commit 29bc885 agrega:

for-each-ref: aceptar el %(push)formato " "

Así como tenemos " %(upstream)" para informar el " @{upstream}" para cada referencia, este parche agrega " %(push)" para que coincida " @{push}".
Admite los mismos modificadores de formato de seguimiento que en sentido ascendente (porque es posible que desee saber, por ejemplo, qué ramas tienen compromisos para impulsar ).

Si desea ver cuántos compromisos sus sucursales locales están adelante / atrás en comparación con la sucursal a la que está presionando:

git for-each-ref --format="%(refname:short) %(push:track)" refs/heads
VonC
fuente
42

Práctico alias de git para buscar confirmaciones sin empujar en la rama actual :

alias unpushed = !GIT_CURRENT_BRANCH=$(git name-rev --name-only HEAD) && git log origin/$GIT_CURRENT_BRANCH..$GIT_CURRENT_BRANCH --oneline

Lo que esto básicamente hace:

git log origin/branch..branch

pero también determina el nombre actual de la sucursal.

tomashin
fuente
8
¡Esto es asombroso! Para aquellos que no están familiarizados con los alias, simplemente agréguelos a su archivo ~ / .gitconfig en la sección [alias].
Gary Haran
1
Copiar / pegar en bash no funciona, pero el script es bastante útil y comprensible
greuze
Este no es un alias bash, como señala @GaryHaran. También hay un comando git para agregar alias: git alias <alias-name> <command>en este caso, el comando debe estar rodeado de comillas simples, para escapar de caracteres especiales del shell.
Dag Høidahl
44
Eso sería:git config --global alias.unpushed '!GIT_CURRENT_BRANCH=$(git name-rev --name-only HEAD) && git log origin/$GIT_CURRENT_BRANCH..$GIT_CURRENT_BRANCH --oneline'
Ricky Levi
Eso parece básicamente lo mismo que git log @ {u} .., sin embargo, vea otra respuesta .
Hans-Peter Störr
35

Tu podrías intentar....

gitk

Sé que no es una opción de línea de comandos pura, pero si la tiene instalada y está en un sistema GUI, es una excelente manera de ver exactamente lo que está buscando y mucho más.

(De hecho, estoy un poco sorprendido de que nadie lo haya mencionado hasta ahora).

Justin Ohms
fuente
3
gitk --allpara ver todas las ramas.
Ray
3
tigEs la alternativa ncurses.
Ray
@ justin-ohms gitkes genial! ¡Nunca supe que esto existe! Práctico para navegar a través de los cambios en una interfaz de usuario agradable.
RafiAlhamd
@ray tiges más útil en una situación de 'solo terminal', en la que no obtiene acceso a la GUI de escritorio. ¡Aprendiendo sobre esto por primera vez! INTERESANTE: tiges al revés de git!
RafiAlhamd
30

git branch -v mostrará, para cada sucursal local, si está "adelantado" o no.

Aurelien
fuente
2
Sí, en caso de que haya una confirmación no acelerada en la rama devel, la línea correspondiente será * devel 8a12fc0 [ahead 1] commit msg( *solo estará en la línea correspondiente a la rama desprotegida). ahead 1significa "adelante por un compromiso", es decir, hay un compromiso no apresurado.
Aurelien
2
¿No es así git branch -vv? Cf. docs: "Si se da dos veces, imprima el nombre de la rama ascendente también (vea también git remote show <remote>)".
Dirty Henry
No se trata de imprimir el nombre de la rama ascendente, sino de imprimir behindy / o aheadpara cada rama local, lo cual es suficiente para resolver el problema de OP (detectar confirmaciones no enviadas). git branch -ves suficiente para eso, acabo de probar nuevamente con Git 2.16.2 :)
Aurelien
El -vv es útil porque muestra una diferencia entre las ramas que están actualizadas con el control remoto y las que no se han presionado en absoluto. (Con solo una -v, aparecen idénticamente en la pantalla)
RM
30

Tuve una confirmación realizada anteriormente, no empujada a ninguna rama, ni remota ni local. Solo el compromiso. Nada de otras respuestas funcionó para mí, pero con:

git reflog

Allí encontré mi compromiso.

Olaia
fuente
Como se indica en este enlace git-scm.com/docs/git-reflog , registros de referencia o "reflogs", registre cuándo se actualizaron las sugerencias de ramas y otras referencias en el repositorio local. En mi caso, cloné un repositorio, creé una nueva rama, eliminé la rama, creé una nueva, creé una confirmación y cambié la confirmación. Todos estos pasos se registraron como HEAD @ {0}: commit (modificar): .. HEAD @ {1}: commit: ... HEAD @ {2}: desprotegido: moviéndose de ... a ... HEAD @ { 3}: desprotegido: moviéndose de ... a ... HEAD @ {4}: clone: ​​de #sorry para el formato SO no permite líneas múltiples en comentarios aparentemente
velocidad
esto también incluye las confirmaciones de origen, la mejor solución sería usar el comando proporcionado por @PlagueHammer ( stackoverflow.com/a/2016954/624048 )
Lincoln
20

Utilizo el siguiente alias para obtener solo la lista de archivos (y el estado) que se han confirmado pero no se han enviado (para la rama actual)

git config --global alias.unpushed \
"diff origin/$(git name-rev --name-only HEAD)..HEAD --name-status"

entonces solo haz:

git unpushed
CCC
fuente
parece interesante, pero $ (git name-rev --name-only HEAD) está "indefinido" en mi caso
vak
13

Creo que la forma más típica de hacer esto es ejecutar algo como:

git cherry --abbrev=7 -v @{upstream}

Sin embargo, personalmente prefiero ejecutar:

git log --graph --decorate --pretty=oneline --abbrev-commit --all @{upstream}^..

que muestra los commits de todas las ramas que no están fusionadas en sentido ascendente, más el último commit en sentido ascendente (que se muestra como un nodo raíz para todos los otros commits). Lo uso con tanta frecuencia que he creado un alias nouppara él.

git config --global alias.noup \
'log --graph --decorate --pretty=oneline --abbrev-commit --all @{upstream}^..'
Giorgos Kylafas
fuente
11

Le sugiero que vaya a ver el script https://github.com/badele/gitcheck , he codificado este script para verificar de una sola vez todos sus repositorios git, y muestra quién no se ha comprometido y quién no ha empujado / tirado.

Aquí un resultado de muestra ingrese la descripción de la imagen aquí

Bruno Adelé
fuente
1
¿Podría explicar cómo hacer que este complemento funcione en la máquina Windows? Estoy tratando de ejecutar pip, pero falta el comando en la línea de comando. Instalé Python, pero no estoy seguro de si es suficiente.
Konrad Szałwiński
@ KonradSzałwiński No tengo máquina de Windows, pero en este tema ( stackoverflow.com/questions/4750806/… ), el usuario parece responder a su pregunta :). Pero no lo he probado en Windows y no estoy seguro de que funcione.
Bruno Adelé
@ KonradSzałwiński, el colaborador de ChristianTremblay github ha agregado un soporte para Windows. Ahora el gitcheck funciona en windows. Puede descargarlo en github.com/badele/gitcheck
Bruno Adelé
Ahora, también puede usar gitcheck directamente desde un contenedor acoplable (con sus archivos en su host). Para obtener más información, consulte el proyecto gitcheck github
Bruno Adelé,
Gracias por publicar esto, parece realmente útil. Intenté instalar pero después de la instalación no puedo encontrar la ubicación del script para ejecutarlo. $ pip install git + git: //github.com/badele/gitcheck.git Recopilación de git + git: //github.com/badele/gitcheck.git Clonación git: //github.com/badele/gitcheck.git a c : \ users \ u6041501 \ appdata \ local \ temp \ pip-bxt472z_-build Instalación de paquetes recopilados: gitcheck Ejecutando setup.py install para gitcheck: comenzó a ejecutar setup.py install para gitcheck: finalizado con el estado 'hecho' Instalado con éxito gitcheck-0.3 .22
Lauren Fitch
9

No es un error Lo que probablemente esté viendo es el estado de git después de una fusión automática fallida donde se recuperan los cambios desde el control remoto pero aún no se fusionan.

Para ver las confirmaciones entre el repositorio local y el remoto, haga esto:

git fetch

Esto es 100% seguro y no imitará su copia de trabajo. Si hubo cambios se git statusmostrará X commits ahead of origin/master.

Ahora puede mostrar el registro de confirmaciones que están en el remoto pero no en el local:

git log HEAD..origin
Igor Zevaka
fuente
8

Esto funcionó mejor para mí:

git log --oneline @{upstream}..

o:

git log --oneline origin/(remotebranch)..
VaTo
fuente
2
Para cualquiera que se pregunte, @{upstream}es literal ( upstreames una palabra mágica), mientras que remotebranches solo el nombre de su rama.
Steve Bennett
7

Hay una herramienta llamada no apresurada que escanea todos los repositorios de Git, Mercurial y Subversion en el directorio de trabajo especificado y muestra la lista de archivos comprometidos y confirmaciones no apresuradas. La instalación es simple bajo Linux:

$ easy_install --user unpushed

o

$ sudo easy_install unpushed

para instalar en todo el sistema.

El uso también es simple:

$ unpushed ~/workspace
* /home/nailgun/workspace/unpushed uncommitted (Git)
* /home/nailgun/workspace/unpushed:master unpushed (Git)
* /home/nailgun/workspace/python:new-syntax unpushed (Git)

Ver unpushed --helpo descripción oficial para más información. También tiene un script cronjob unpushed-notifypara la notificación en pantalla de cambios no confirmados y no confirmados.

Pistola de clavos
fuente
5

Para enumerar fácilmente todas las confirmaciones sin empujar en todas las ramas , puede usar este comando:

 git log --branches  @{u}..
Mohsen Kashi
fuente
4

Similar: para ver ramas no fusionadas:

git branch --all --no-merged

Esos pueden ser sospechosos, pero recomiendo la respuesta de cxreg

Christophe Roussy
fuente
3

Si el número de confirmaciones que no se han eliminado es un número de un solo dígito, que a menudo es, la forma más fácil es:

$ git checkout

git responde diciéndole que está "adelantado N commits" en relación con su origen. Así que ahora solo tenga en cuenta ese número cuando vea los registros. Si está "adelantado por 3 confirmaciones", las 3 confirmaciones más importantes de la historia siguen siendo privadas.

Kaz
fuente
2

Una forma de hacer las cosas es enumerar los commits que están disponibles en una rama pero no en otra.

git log ^origin/master master
Alex
fuente
¿Qué hace el personaje '^'?
Aran Mulholland
@AranMulholland significa que no está aquí.
Alex
1

Como se dijo anteriormente:

git diff origin / master..HEAD

Pero si estás usando git gui

Después de abrir la interfaz gui, seleccione "Repositorio" -> debajo de " Visualizar historial "

Nota: A algunas personas les gusta usar CMD Prompt / Terminal mientras que a otras les gusta usar Git GUI (por simplicidad)

vrnair24
fuente
La opción de visualización en git gui es la indicada.
Rajesh Kolhapure
-2

Aquí está mi solución portátil (script de shell que también funciona en Windows sin instalación adicional) que muestra las diferencias de origen para todas las ramas: git-fetch-log

Un ejemplo de salida:

==== branch [behind 1]

> commit 652b883 (origin/branch)
| Author: BimbaLaszlo <[email protected]>
| Date:   2016-03-10 09:11:11 +0100
|
|     Commit on remote
|
o commit 2304667 (branch)
  Author: BimbaLaszlo <[email protected]>
  Date:   2015-08-28 13:21:13 +0200

      Commit on local

==== master [ahead 1]

< commit 280ccf8 (master)
| Author: BimbaLaszlo <[email protected]>
| Date:   2016-03-25 21:42:55 +0100
|
|     Commit on local
|
o commit 2369465 (origin/master, origin/HEAD)
  Author: BimbaLaszlo <[email protected]>
  Date:   2016-03-10 09:02:52 +0100

      Commit on remote

==== test [ahead 1, behind 1]

< commit 83a3161 (test)
| Author: BimbaLaszlo <[email protected]>
| Date:   2016-03-25 22:50:00 +0100
|
|     Diverged from remote
|
| > commit 4aafec7 (origin/test)
|/  Author: BimbaLaszlo <[email protected]>
|   Date:   2016-03-14 10:34:28 +0100
|
|       Pushed remote
|
o commit 0fccef3
  Author: BimbaLaszlo <[email protected]>
  Date:   2015-09-03 10:33:39 +0200

      Last common commit

Parámetros pasados ​​para el registro, por ejemplo, --onelineo --patchse pueden usar.

bimlas
fuente
-3
git show

mostrará todas las diferencias en sus confirmaciones locales.

git show --name-only

mostrará la identificación de confirmación local y el nombre de la confirmación.

usuario2387567
fuente
3
git showsolo muestra la confirmación más reciente, ya sea que se haya enviado al control remoto o no, no le mostrará todas sus confirmaciones no eliminadas.
-6
git diff origin

Suponiendo que su rama esté configurada para rastrear el origen, eso debería mostrarle las diferencias.

git log origin

Te daré un resumen de los commits.

mopoke
fuente
3
git log originle mostrará los compromisos que ya se han enviado , pero no mostrará los compromisos que no se han enviado , lo que se parece más a lo que pedía el póster original.