Obtenga una lista de todos los git commits, incluidos los 'perdidos'

139

Digamos que tengo un gráfico como este:

A---B---C---D (master)
     \
      \-E---F (HEAD)

Si lo hago git log --all --oneline, obtendré los seis compromisos.

Pero si el gráfico es

A---B---C---D (master, HEAD)
     \
      \-E---F

No veré E y F. ¿Puedo hacer que git me diga todas las confirmaciones, incluidas las de las ramas que no tienen nombre?

Gracias

Amadan
fuente

Respuestas:

63

No es particularmente fácil: si ha perdido el puntero en la punta de una rama, es como encontrar una aguja en un pajar. Puede encontrar todas las confirmaciones que ya no parecen estar referenciadas, git fsck --unreachablelo harán por usted, pero eso incluirá las confirmaciones que descartó después de una git commit --amendconfirmación anterior en las ramas que ha modificado, etc., así que ver todas estas confirmaciones a la vez es muy probable que haya demasiada información para pasar.

Entonces, la respuesta impertinente es: no pierdas el rastro de las cosas que te interesan. Más en serio, los reflogs mantendrán referencias a todos los commits que has usado durante los últimos 60 días más o menos de forma predeterminada. Más importante aún, darán un contexto sobre cuáles son esos compromisos .

araqnid
fuente
77
+1: No hay absolutamente ninguna diferencia entre un commit huérfano deliberadamente por commit --amendo rebasey uno huérfano accidentalmente trabajando con un HEAD separado, por ejemplo.
Cascabel
3
en efecto. Probablemente la forma más fácil de recuperarse de esa situación será mirar el registro de HEAD.
araqnid
@Jefromi: Gran punto sobre git commit --amendetc. dejando compromisos sin salida, perdidos. Hice un poco de rebase y otras cosas y terminé con algunos commits a los que no se podía acceder desde ninguna rama, y ​​me sentí un poco sucio dejándolos en el repositorio. Ahora el pensamiento ya no es tan inquietante. :)
Emil Lundberg
2
@araqnid Me metí en el mismo aprieto que el póster original y tu sugerencia para mirar el registro fue lo que había que hacer.
Ignazio
77
Estoy de acuerdo con esta respuesta, pero en el caso de que alguien necesite ver todas las confirmaciones, incluidas las huérfanas, ya sean deliberadas o accidentales, git fsck --unreachableno proporciona eso. Solo lo intenté. El mejor enfoque es la --reflogopción para git log, como respondió Kenorb . Lo que es especialmente bueno de esto es que, combinado con --graph, obtienes un contexto visual fácil de analizar, muy similar al ilustrado en la pregunta original. Por ejemplo, intente:git log --graph --all --oneline --reflog
Iñigo
111

Tratar:

git log --reflog

que enumera todas las confirmaciones de git pretendiendo que todos los objetos mencionados por reflogs ( git reflog) se enumeran en la línea de comando como <commit>.

kenorb
fuente
1
Esto es lo que estaba buscando: la funcionalidad del argumento --reflog.
Anomalía
3
Por cierto, gitk también es compatible con eso: gitk --reflog.
ald.li
50

Cuando abordo este problema, uso el siguiente comando:

git reflog |  awk '{ print $1 }' | xargs gitk

Esto me permite visualizar confirmaciones recientes que se han vuelto sin cabeza.

Tengo esto envuelto en un asistente de script llamado ~/bin/git-reflog-gitk.

Kieran
fuente
1
Esto me AHORRÓ a lo grande ... ¡GRACIAS!
Bret Royster
esto es asombroso! ¡gracias! Realmente visualiza las partes importantes del árbol.
Mladen B.
Solo un consejo: esto solo funcionará para su trabajo local como registros de reflog when the tips of branches and other references were updated in the *local repository*. Es posible que desee utilizar git log --reflogsi desea hacer esto para cambios de referencia no locales
Krishna Gupta
29

Lo que me salvó la vida fue el siguiente comando:

git reflog

Allí encontrarás una pantalla con confirmaciones de historial hechas para git como esta:

ingrese la descripción de la imagen aquí

En este punto, solo tiene que encontrar lo HEAD@{X}que necesita, crear una rama temporal y pasar a ella de esta manera:

git checkout -b temp_branch HEAD@{X}

De esa manera, tendrá una rama temporal con su confirmación perdida sin rebajar ni romper aún más su repositorio git.

Espero que esto ayude...

Sonhja
fuente
26

Me gusta la respuesta de @Kieran, pero para la consola: git log --oneline --all --graph --decorate $(git reflog | awk '{print $1}')

Florian Fida
fuente
¿Necesita incluir la última parte: $ (git reflog | awk '{print $ 1}')? ¿Qué hace esto? Después de probar su solución, parece que produce la misma salida incluso sin esa última parte.
wmock
Si mueve el puntero de su rama y deja algunos commits sin una referencia (como lo hizo OP), ya no aparecerán git log --all. Un ejemplo rápido: después de una git reset --hard @^confirmación HEAD @ {0} solo estará en el registro, y dado que git reflogno es compatible --graph, debe pasar las confirmaciones git log --graphpara obtener una representación visual.
Florian Fida
55
puede usar en --refloglugar de $(git reflog | awk '{print $1}')
Sild
Comparado git log --oneline --all --graph --decorate $(git reflog | awk '{print $1}')con git log --oneline --all --graph --decorate --reflog, son casi idénticos, excepto que el registro incluye detalles como entradas WIP.
Script Wolf
@FlorianFida, en lugar de reflog¿ por qué no usar log --reflogen su lugar?
Pacerier
9

¿Cómo resuelvo este problema? Uso git fscky registro!

Primero cree un archivo que contenga confirmaciones y blobs perdidos (inalcanzables). (NOTA: si hiciste algo así, git gcentonces recolectará basura todos los compromisos y ¡no los encontrarás aquí!)

$git fsck --lost-found > lost_found.commits

Eso te da un archivo como este:

colgando cometer dec2c5e72a81ef06963397a49c4b068540fc0dc3
colgando burbuja f8c2579e6cbfe022f08345fa7553feb08d60a975
colgando burbuja 0eb3e86dc112332ceadf9bc826c49bd371acc194
colgando burbuja 11cbd8eba79e01f4fd7f496b1750953146a09502
colgando cometer 18733e44097d2c7a800650cea442febc5344f9b3
colgando burbuja 1e53a5cdb3ecdde27081ec6e8b31e4070106ee05

Luego puede abrir este archivo con su editor de texto favorito para copiar los hash de confirmación / blog desde allí. (* tos * vim macros funciona muy bien para esto * tos *)

Ahora puede volver a iniciar sesión desde este commit con algo como git log --oneline <commit hash>. Alternativamente, gitk, tig o cualquier otro visor de git deberían funcionar.

En su caso, si encuentra el hash para commit F, el registro le mostrará algo como esto,

A---B---E---F

¡Rapido y Facil! Ahora puede encontrar el contexto detrás de todas esas confirmaciones pendientes.

PD Sí, lo sé, publicación tardía, pero bueno, alguien podría encontrarlo aquí y encontrarlo útil. (Lo más probable es que yo en 6 meses cuando vuelva a googlear esto)

bsimmons
fuente
5

Tuve suerte recuperando el commit mirando el reflog, que estaba ubicado en .git/logs/HEAD

Luego tuve que desplazarme hasta el final del archivo , y encontré la confirmación que acabo de perder.

GameScripting
fuente
Esto es lo que terminó haciendo cuando arruiné algo. Intenté comprometerme con el maestro y Stash se resistió cuando empujé. Reajusté --duro, luego me di cuenta de mi error. El commit estaba en el registro, así que lo revisé, hice una ramificación y luego lo presioné. Todo funcionó al final.
David
5

A git logveces no es bueno obtener todos los detalles de las confirmaciones, así que para ver esto ...

Para Mac: entre en su proyecto git y escriba:

$ nano .git/logs/HEAD

para verlos a todos los comprometidos en eso, o:

$ gedit .git/logs/HEAD

para ver a todos ustedes se compromete en eso,

entonces puedes editar en cualquiera de tus navegadores favoritos.

Vinod Joshi
fuente
3

@bsimmons

git fsck --lost-found | grep commit

Luego crea una rama para cada uno:

$ git fsck --lost-found | grep commit
Checking object directories: 100% (256/256), done.
dangling commit 2806a32af04d1bbd7803fb899071fcf247a2b9b0
dangling commit 6d0e49efd0c1a4b5bea1235c6286f0b64c4c8de1
dangling commit 91ca9b2482a96b20dc31d2af4818d69606a229d4

$ git branch  branch_2806a3 2806a3
$ git branch  branch_6d0e49 6d0e49
$ git branch  branch_91ca9b 91ca9b

Ahora, muchas herramientas le mostrarán una visualización gráfica de esas confirmaciones perdidas.

yakoda
fuente
2

Si utiliza la GUI de Git Extensions, puede mostrarle una visualización gráfica de las confirmaciones colgantes si marca "Ver -> Mostrar referencias de reflog". Esto mostrará confirmaciones colgantes en el árbol, al igual que todas las demás referencias. De esta manera, es mucho más fácil encontrar lo que está buscando.

Ver esta imagen para demostración. Los commits C2, C3, C4 y C5 en la imagen están colgando pero aún son visibles.

Zdovc
fuente
2
git log --reflog

¡me salvó! ¡Perdí mi fusión de HEAD y no pude encontrar mis últimos compromisos! No se muestra en el árbol de origen pero git log --reflogmuestra todas mis confirmaciones locales

Sultanmyrza Kasymbekov
fuente