Sfoglia i commit orfani in Git


102

Il mio repository git è in qualche modo traballante - ho caricato msysgit questa mattina e invece di mostrare il nome del ramo dopo la directory corrente, dice "((ref: re ...))", 'git status' riporta tutto come un nuovo file, 'git log' e 'git reflog' mi dicono "fatal: bad default revision 'HEAD'", e così via.

Fare "git reflog --all" o "gitk --all" mostra che il resto del repository è intatto, ma sembra che il ramo su cui stavo lavorando sia appena scomparso, il che spiega perché HEAD non sembra esistere / indicare qualsiasi cosa.

So che git conserva tutti i tipi di glob di informazioni, e presumo che i miei commit siano rimasti orfani in qualche modo, quindi c'è qualche comando che mi mostrerà quei commit in modo da poter reimpostare HEAD su di loro?

EDIT: Oh caro. Ho scoperto "git fsck", e "git fsck --full" riporta "fatal: object 03ca4 ... is danneggiato". Che diavolo posso fare a riguardo?

EDIT: Oh caro oh caro. Ho verificato un altro ramo, quindi ho provato a ricreare il ramo originale con lo stesso nome utilizzando "git checkout -b lostbranchname" e git dice "errore: impossibile risolvere riferimenti refs / heads / lostbranchname: nessun errore, fatale: non riuscito per bloccare ref per l'aggiornamento: Nessun errore ". "Nessun errore" deve essere un errore particolarmente fastidioso. Quindi sembra che sia ancora in giro, ma non può essere usato e non può essere ucciso.

EDIT: Super duper oh caro. Ho fatto un sacco di disimballaggio e reimballaggio e sostituzione di cose come suggerito qui: Come recuperare oggetti Git danneggiati da un guasto del disco rigido? , ma ora sto ricevendo un altro hash segnalato come corrotto, per qualcosa di innocuo come "git status". Penso che l'intera faccenda sia stata lavata. Git è adorabile e tutto, ma non dovrei avere a che fare con questo genere di cose.


Per quanto riguarda git checkout -b lostbranchname: se ti interessa solo il nome del ramo (non il contenuto di esso), puoi eliminare manualmente (o rinominare) .git/refs/heads/lostbranchname- si spera che faccia il trucco.
Antony Hatchkins

1
E non hai un upstream in cui spingere questa cartella git?
Lakshman Prasad

1
Purtroppo no, in realtà è una specie di repository sostitutivo per un sistema di controllo del codice inferiore, lo sto solo usando localmente per ottenere tutte le funzionalità e le sottigliezze di git senza il fastidio dell'altro sistema. Ma almeno l'altro sistema non si corrompe casualmente. Tuttavia, ciò significa che tutto ciò che ho perso sono le mie modifiche dall'ultima volta che ho effettuato il check-in sull'altro sistema, che ho già recuperato. È ora di avviare un nuovo repository!
Ben Hymers

7
Esiterei a dire che git ti ha fatto "affrontare questo genere di cose" o che si è corrotto da solo. Niente oltre a un backup può essere completamente stabile contro la perdita di dati.
Cascabel

1
Lo so davvero, sono solo (naturalmente) un po 'seccato di aver perso la mia bella storia. Non è colpa di git, qualsiasi altro sistema si comporterebbe con gli stessi errori di file system dati.
Ben Hymers

Risposte:


135

Piuttosto che lasciarlo aperto, penso che darò una risposta alla mia domanda. L'utilizzo git reflog --allè un buon modo per sfogliare i commit orfani e utilizzando gli hash SHA1 da cui è possibile ricostruire la cronologia.

Nel mio caso, però, il repository era danneggiato, quindi questo non ha aiutato; git fsckpuò aiutarti a trovare e talvolta correggere errori nel repository stesso.


3
Grazie. Questo è l'unico posto in cui ho trovato queste informazioni durante il tentativo di eseguire il pull di una richiesta pull orfana su GitHub. Ho risolto il mio problema.
SystemParadox

6
nel caso in cui qualcuno volesse tutto in gitk: [alias] orphank = !gitk --all --date-order ``git reflog | cut -c1-7``&(modifica: immagina quei doppi backtick in cui quelli singoli - l'escape non sembra funzionare qui)
mbx

1
Suggerimento fantastico @mbx! Molto utile per poter vedere graficamente i collegamenti tra commit orfani!
Ben Hymers

@BenHymers Sarebbe bello se potessimo ottenere linee tratteggiate anche per le relazioni di commit "rebase / squash". Non ho ancora trovato un modo per farlo.
mbx

Non sapevo di reflog quando ho scritto la risposta sopra. È uno strumento così utile!
Jamey Hicks

17

Con git 2.9.x / 2.10 (Q3 2016), non dovrai git reflog --allpiù usare , git reflogsarà sufficiente.

Vedere commit 71abeb7 (03 giugno 2016) di SZEDER Gábor ( szeder) .
(Fuso da Junio ​​C Hamano - gitster- in commit 7949837 , 06 luglio 2016)

reflog: continua a camminare sul reflogpassato root commit

Se un repository contiene più di un commit root, il suo reflog HEAD può contenere più "eventi di creazione", cioè voci il cui valore "da" è null sha1.
L'elenco di un reflog di questo tipo attualmente si interrompe prematuramente alla prima di tali voci, anche quando il reflog contiene ancora voci meno recenti.
Questo può spaventare gli utenti facendogli pensare che il loro reflog sia stato troncato dopo ' git checkout --orphan'.

Continua a camminare nel reflog oltre tali eventi di creazione in base al valore "nuovo" della voce di reflog precedente.


4

Una buona caratteristica di git è che rileva la corruzione. Tuttavia, non include la correzione degli errori per proteggere dalla corruzione.

Spero che tu abbia trasferito il contenuto di questo repository su un'altra macchina o che tu abbia backup per recuperare le parti danneggiate.

Non ho alcuna esperienza con git su Windows ma non ho mai visto questo tipo di comportamento con git su Linux o OS X.


3

In genere trovo che l' git reflogoutput sia confuso. È molto più facile per me capire un grafico di commit da git log --graph --reflog. L'override del formato per mostrare solo i riepiloghi dei commit può anche rendere il grafico più facile da seguire:

$ git alias graph "log --graph --all --format='%h %s%n        (%an, %ar)%d' --abbrev-commit
$ git graph --reflog

* f06abeb Add feature
|         (Sue Dakota, 4 days ago) (HEAD -> master)
* f126291 Fix the build
|         (Oski M. Wizard, 5 days ago) (origin/master, master)
* 3c4fb9c Break the build
|         (Alyssa P. Hacker, 5 days ago)
| * e3124bf fixup! More work for feature
| |         (Sue Dakota, 4 days ago)
| | * 6a7a52e Lost commit
| |/          (Sue Dakota, 4 days ago)
| * 69d9438 More work for feature
| |         (Sue Dakota, 2 weeks ago)
| * 8f69aba Initial work for feature
|/          (Sue Dakota, 3 weeks ago)
* d824fa9 Fix warnings from the linter
|         (Theo Ristudent, 4 weeks ago)
* 9f782b8 Fix tests flakes
|         (Tess Driven, 5 weeks ago)

Da ciò è chiaro che e3124bfe 6a7a52esono orfani non referenziati, e c'è il contesto dai loro impegni antenati.


Mi ha fatto risparmiare ore di lavoro perso proprio ora! ha cancellato accidentalmente un ramo locale che aveva annullato i commit su di esso, git reflog --allnon li mostra, git log --graph --reflogperché erano molto visibili ...
Adam.Er8
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.