Ottieni un elenco di tutti i commit di git, inclusi quelli "persi"


139

Diciamo che ho un grafico come questo:

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

Se lo farò git log --all --oneline, otterrò tutti e sei i miei impegni.

Ma se il grafico lo è

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

Non vedrò E e F. Posso avere il coraggio di dirmi tutti gli commit, compresi quelli sui rami che non sono nominati?

Grazie

Risposte:


63

Non particolarmente facilmente: se hai perso il puntatore sulla punta di un ramo, è piuttosto come trovare un ago in un pagliaio. Puoi trovare tutti i commit che non sembrano essere più referenziati- git fsck --unreachablelo faranno per te- ma che includeranno i commit che hai gettato via dopo un git commit --amendvecchio commit sui rami che hai ribassato ecc. Ecc. Quindi vedendo tutti questi commit allo stesso tempo è probabilmente fin troppo troppa informazione per guadare.

Quindi la risposta impercettibile è, non perdere la traccia delle cose che ti interessano. Più seriamente, i reflog conterranno riferimenti a tutti i commit che hai usato negli ultimi 60 giorni circa per impostazione predefinita. Ancora più importante, forniranno un contesto su ciò che tali impegni sono .


7
+1: Non c'è assolutamente alcuna differenza tra un commit deliberatamente orfano di commit --amendo rebaseuno accidentalmente orfano lavorando con un HEAD distaccato, per esempio.
Cascabel,

3
infatti. probabilmente il modo più semplice per riprendersi da quella situazione sarà guardare il reflog per HEAD stesso.
araqnid,

@Jefromi: grande precisazione su git commit --amendecc. Che lascia il vicolo cieco, commessi persi. Ho fatto un po 'di rebasing e quant'altro e ho finito con alcuni commit non raggiungibili da nessun ramo e mi sono sentito un po' sporco lasciandoli nel repository. Ora il pensiero non è più così inquietante. :)
Emil Lundberg,

2
@araqnid Mi sono messo nello stesso sottaceto del poster originale e il tuo suggerimento di guardare il reflog era proprio la cosa da fare.
Ignazio,

7
Sono d'accordo con questa risposta, ma nel caso in cui qualcuno abbia bisogno di vedere tutti i commit, compresi quelli orfani, sia intenzionali che accidentali, git fsck --unreachablenon lo fornisce. L'ho appena provato. L'approccio migliore è l' --reflogopzione per git log, come ha risposto Kenen . Ciò che è particolarmente bello di questo è che, combinato con --graph, ottieni un contesto visivo facile da analizzare, molto simile a quello illustrato nella domanda originale. Ad esempio, prova:git log --graph --all --oneline --reflog
Inigo,

111

Provare:

git log --reflog

che elenca tutti i commit di git fingendo che tutti gli oggetti menzionati da reflogs ( git reflog) siano elencati nella riga di comando come <commit>.


1
Questo è quello che stavo cercando: la funzionalità dell'argomento --reflog.
Anomalia

3
A proposito, gitk supporta anche questo: gitk --reflog.
ald.li,

50

Quando affronto questo problema, utilizzo il seguente comando:

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

Questo mi permette di visualizzare i commit recenti che sono diventati senza testa.

L'ho racchiuso in un assistente di script chiamato ~/bin/git-reflog-gitk.


1
Questo mi ha appena salvato alla grande ... GRAZIE!
Bret Royster,

Questo e spettacolare! grazie! visualizza davvero le parti importanti dell'albero.
Mladen B.

Un consiglio: questo funzionerà solo per il tuo lavoro locale come record di reflog when the tips of branches and other references were updated in the *local repository*. Potresti voler utilizzare git log --reflogse desideri eseguire questa operazione per modifiche di riferimento non locali
Krishna Gupta,

29

Ciò che mi ha salvato la vita è stato il seguente comando:

git reflog

Qui trovi una schermata con i commit della cronologia fatti per git come questo:

inserisci qui la descrizione dell'immagine

A questo punto, devi solo trovare quello HEAD@{X}che ti serve, creare un ramo temporaneo e spostarti in questo modo:

git checkout -b temp_branch HEAD@{X}

In questo modo avrai una diramazione temporanea con il commit perduto senza dover reimpostare o interrompere ulteriormente il tuo repository git.

Spero che questo ti aiuti...


26

Come la risposta di @Kieran, ma per la console: git log --oneline --all --graph --decorate $(git reflog | awk '{print $1}')


Devi includere l'ultima parte: $ (git reflog | awk '{print $ 1}')? Cosa fa questo? Dopo aver provato la tua soluzione, sembra che produca lo stesso output anche senza quest'ultima parte.
wmock,

Se sposti il ​​puntatore della diramazione e lasci alcuni commit senza un riferimento (come ha fatto OP) non verranno più visualizzati git log --all. Un rapido esempio: dopo un git reset --hard @^commit HEAD @ {0} sarà solo nel reflog e poiché git reflognon supporta --graphè necessario passare i commit git log --graphper ottenere una rappresentazione visiva.
Florian Fida,

5
puoi usare --refloginvece di $(git reflog | awk '{print $1}')
Sild

Ho confrontato git log --oneline --all --graph --decorate $(git reflog | awk '{print $1}')con git log --oneline --all --graph --decorate --reflog, sono quasi identici tranne - il registro includeva dettagli come le voci WIP.
Script Wolf

@FlorianFida, invece di reflogperché non utilizzare log --refloginvece?
Pacerier

9

Come risolvo questo problema? Usa git fscke registra!

Creare innanzitutto un file contenente commit e BLOB persi (non raggiungibili). (NOTA: se hai fatto qualcosa del genere git gc, la spazzatura raccoglierà tutti i loro impegni e non li troverai qui!)

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

Questo ti dà un file come questo:

penzoloni commettere dec2c5e72a81ef06963397a49c4b068540fc0dc3
penzoloni blob f8c2579e6cbfe022f08345fa7553feb08d60a975
penzoloni blob 0eb3e86dc112332ceadf9bc826c49bd371acc194
penzoloni blob 11cbd8eba79e01f4fd7f496b1750953146a09502
penzoloni commettere 18733e44097d2c7a800650cea442febc5344f9b3
penzoloni blob 1e53a5cdb3ecdde27081ec6e8b31e4070106ee05

È quindi possibile aprire questo file con l'editor di testo preferito per copiare gli hash di commit / blog da lì. (* tosse * macro vim funziona alla grande per questo * tosse *)

Ora puoi tornare indietro da questo commit con qualcosa di simile git log --oneline <commit hash>. In alternativa, gitk, tig o qualsiasi altro visualizzatore git dovrebbe funzionare.

Nel tuo caso, se trovi l'hash per commit F, il registro ti mostrerà qualcosa del genere,

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

Facile e veloce! Ora puoi trovare il contesto dietro tutti questi commit penzolanti.

PS Sì, lo so, post in ritardo, ma vabbè, qualcuno potrebbe trovarlo qui e trovarlo utile. (Molto probabilmente io tra 6 mesi quando ricomincio a cercarlo su Google)


5

Ho avuto fortuna a recuperare il commit guardando il reflog, che si trovava in .git/logs/HEAD

Ho dovuto quindi scorrere fino alla fine del file e ho trovato il commit che avevo appena perso.


Questo è ciò che è appena finito quando ho rovinato qualcosa. Ho provato a impegnarmi con il maestro e Stash si è opposto quando ho spinto. Ho resettato --hard, poi ho capito il mio errore. Il commit era nel reflog, quindi l'ho verificato, ne ho creato un ramo, quindi l'ho spinto. Alla fine tutto ha funzionato.
David,

5

A git logvolte non è bene avere tutti i dettagli di commit, quindi per vedere questo ...

Per Mac: entra nel tuo progetto git e digita:

$ nano .git/logs/HEAD

per vederti tutti impegnati in questo, oppure:

$ gedit .git/logs/HEAD

per vederti tutti impegnati in questo,

quindi puoi modificarlo in uno dei tuoi browser preferiti.


3

@bsimmons

git fsck --lost-found | grep commit

Quindi creare un ramo per ognuno:

$ 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

Ora molti strumenti ti mostreranno una visualizzazione grafica di quei commit persi.


2

Se usi la GUI di Git Extensions può mostrarti una visualizzazione grafica dei commit penzolanti se selezioni "Visualizza -> Mostra riferimenti reflog". Questo mostrerà commit penzolanti nell'albero, proprio come tutti gli altri referenziati. In questo modo è molto più facile trovare quello che stai cercando.

Vedi questa immagine per la dimostrazione. I commit C2, C3, C4 e C5 sull'immagine sono penzolanti ma ancora visibili.


2
git log --reflog

mi ha salvato! Ho perso il mio mentre ho unito HEAD e non sono riuscito a trovare i miei compagni impegnati! Non mostrato nell'albero dei sorgenti ma git log --reflogmostra tutti i miei commit locali prima

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.