git reflog

Questa pagina fornisce una discussione dettagliata del comando git reflog. Git tiene traccia degli aggiornamenti alla punta dei branch utilizzando un meccanismo chiamato log di riferimento o "reflog. " Molti comandi Git accettano un parametro per specificare un riferimento o un "ref", che è un puntatore a un commit. Gli esempi più comuni includono:

  • Git checkout

  • git reset

  • git merge <ref>

Reflog tiene traccia di quando i riferimenti di Git sono stati aggiornati nel repository locale. Oltre ai reflog delle punte dei branch, viene mantenuto un reflog speciale per lo stash Git. I reflog sono archiviati nelle directory della directory .gitĀ del repository locale. Le directory git reflog possono essere trovate all'indirizzo .git/logs/refs/heads/., .git/logs/HEAD, e anche .git/logs/refs/stash se git stash ĆØ stato utilizzato nel repository.

Abbiamo parlato di git reflog in generale nella pagina della riscrittura della cronologia. Questo documento tratterĆ : opzioni di configurazione estese di git reflog, casi d'uso comuni e insidie di git reflog, come annullare le modifiche con git reflog e altro ancora.

Utilizzo di base

Il caso d'uso più semplice di Reflog è il richiamo:

git reflog

Questa ĆØ essenzialmente una scorciatoia che equivale a:

git reflog show HEAD

VerrĆ  emesso il reflog HEAD. Dovresti vedere un output simile a:

eff544f HEAD@{0}: commit: migrate existing content
bf871fd HEAD@{1}: commit: Add Git Reflog outline
9a4491f HEAD@{2}: checkout: moving from main to git_reflog
9a4491f HEAD@{3}: checkout: moving from Git_Config to main
39b159a HEAD@{4}: commit: expand on git context 
9b3aa71 HEAD@{5}: commit: more color clarification
f34388b HEAD@{6}: commit: expand on color support 
9962aed HEAD@{7}: commit: a git editor -> the Git editor

Visita la pagina della riscrittura della cronologia per un altro esempio di accesso reflog comune.

Riferimenti Reflog

Per impostazione predefinita, git reflog emetterĆ  il reflog del riferimento HEAD. HEAD ĆØ un riferimento simbolico al branch attualmente attivo. I reflog sono disponibili anche per altri riferimenti. La sintassi per accedere a un git ref ĆØ name@{qualifier}. Oltre che a HEAD, ĆØ possibile fare riferimento anche ad altri branch, tag e remoti e allo stash Git.

Puoi ottenere un reflog completo di tutti i riferimenti eseguendo:

git reflog show --all

Per vedere il reflog per un branch specifico, passa il nome del branch a git reflog show

In Bitbucket, viene visualizzata la paginaĀ Create a new repository (Crea un nuovo repository). Leggi con attenzione il contenuto della finestra di dialogo. Puoi modificare in un secondo momento tutte le informazioni che inserisci in questa pagina, a eccezione del campoĀ Repository type (Tipo di repository).

git reflog show otherbranch

9a4491f otherbranch@{0}: commit: seperate articles into branch PRs
35aee4a otherbranch{1}: commit (initial): initial commit add git-init and setting-up-a-repo docs

L'esecuzione di questo esempio mostrerĆ  un reflog per il branch otherbranch. L'esempio seguente presuppone che tu abbia precedentemente nascosto alcune modifiche utilizzando il comando git stash.

git reflog stash

0d44de3 stash@{0}: WIP on git_reflog: c492574 flesh out intro

VerrĆ  generato un reflog per lo stash Git. I puntatori di riferimento restituiti possono essere passati ad altri comandi Git:

git diff stash@{0} otherbranch@{0}

Se eseguito, questo codice di esempio mostrerĆ  l'output Git diff confrontando le modifiche di stash@{0} con il riferimento otherbranch@{0}.

Reflog temporizzati

A ogni voce di reflog è associato un timestamp. Questi timestamp possono essere utilizzati come token qualificatore della sintassi del puntatore di riferimento Git. Ciò consente di filtrare i reflog Git in base al tempo. Di seguito sono riportati alcuni esempi di qualificatori temporali disponibili:

  • 1.minute.ago

  • 1.hour.ago

  • 1.day.ago

  • Ieri

  • 1.week.ago

  • 1.month.ago

  • 1.year.ago

  • 17/05/2011:09:00:00

    Ā 

I qualificatori temporali possono essere combinati (ad es. 1.day.2.hours.ago), Inoltre sono accettate forme plurali (ad es. 5.minutes.ago).

I riferimenti ai qualificatori temporali possono essere passati ad altri comandi git.

git diff main@{0} main@{1.day.ago}

Questo esempio differenzia l'attuale branchĀ principale da quello principaleĀ di 1 giorno fa. Questo esempio ĆØ molto utile se vuoi conoscere i cambiamenti che sono avvenuti in un periodo di tempo.

Sottocomandi e opzioni di configurazione

git reflog accetta alcuni argomenti aggiuntivi che sono considerati sottocomandi.

Mostra:git reflog show

show ĆØ passato implicitamente per impostazione predefinita. Ad esempio, il comando:

git reflog main@{0}

ĆØ equivalente al comando:

git reflog show main@{0}

Inoltre,Ā git reflog show ĆØ un alias di git log -g --abbrev-commit --pretty=oneline. L'esecuzione di git reflog show <refid> mostrerĆ  il log relativo al <refid> passato.

Scadenza -git reflog expire

Il sottocomando expire pulisce le voci di reflog vecchie o irraggiungibili. Il sottocomando expire potrebbe causare la perdita di dati. Questo sottocomando non ĆØ in genere utilizzato dagli utenti finali, ma viene utilizzato internamente da git. Passare un'opzione -n o —dry-run a git reflog expire eseguirĆ  un "dry run" che mostrerĆ  quali voci di reflog sono contrassegnate per essere eliminate, ma non le eliminerĆ  effettivamente.

Per impostazione predefinita, la data di scadenza del reflog ĆØ impostata su 90 giorni. ƈ possibile specificare una data di scadenza passando l'argomento della riga di comando —expire=time a git reflog expire o impostando il nome di configurazione git gc.reflogExpire.

Elimina:git reflog delete

Il sottocomando delete si spiega da sƩ e eliminerƠ una voce di reflog passata. Come per expire, delete potrebbe causare la perdita di dati e non viene comunemente richiamato dagli utenti finali.

Recupero dei commit persi

Git non perde mai davvero nulla, anche quando esegue operazioni di riscrittura della cronologia come rebase o modifica dei commit. Per il prossimo esempio supponiamo di aver apportato alcune nuove modifiche al nostro repository. Il nostro git log —pretty=oneline ha il seguente aspetto:

338fbcb41de10f7f2e54095f5649426cb4bf2458 extended content
1e63ceab309da94256db8fb1f35b1678fb74abd4 bunch of content
c49257493a95185997c87e0bc3a9481715270086 flesh out intro
eff544f986d270d7f97c77618314a06f024c7916 migrate existing content
bf871fd762d8ef2e146d7f0226e81a92f91975ad Add Git Reflog outline
35aee4a4404c42128bee8468a9517418ed0eb3dc initial commit add git-init and setting-up-a-repo docs

Quindi apportiamo le modifiche ed eseguiamo quanto segue:

#make changes to HEAD
git commit -am "some WIP changes"

Con l'aggiunta del nuovo commit. Il registro ora ha il seguente aspetto:

$ git clone

https://emmap1@bitbucket.org/emmap1/bitbucketstationlocations.git 

Cloning into 'bitbucketspacestation'...

fatal: could not read

Password for 'https://emmap1@bitbucket.org': No such file or directory

Se ricevi questo errore, inserisci quanto segue nella riga di comando:

37656e19d4e4f1a9b419f57850c8f1974f871b07 some WIP changes
338fbcb41de10f7f2e54095f5649426cb4bf2458 extended content
1e63ceab309da94256db8fb1f35b1678fb74abd4 bunch of content
c49257493a95185997c87e0bc3a9481715270086 flesh out intro
eff544f986d270d7f97c77618314a06f024c7916 migrate existing content
bf871fd762d8ef2e146d7f0226e81a92f91975ad Add Git Reflog outline
35aee4a4404c42128bee8468a9517418ed0eb3dc initial commit add git-init and setting-up-a-repo docs

A questo punto eseguiamo un rebase interattivo sul branchĀ principale eseguendo...

git rebase -i origin/main

Durante il rebase contrassegniamo i commit per squash con il sottocomando s di rebase. Durante il rebase, aggiungiamo alcuni commit ai commit più recenti di "alcune modifiche WIP".

PoichƩ abbiamo eliminato i commit, l'output del log di git ora ha il seguente aspetto:

40dhsoi37656e19d4e4f1a9b419f57850ch87dah987698hs some WIP changes
35aee4a4404c42128bee8468a9517418ed0eb3dc initial commit add git-init and setting-up-a-repo docs

Se esaminiamo git log a questo punto sembra che non abbiamo più i commit contrassegnati per lo squashing. E se volessimo operare su uno dei commit sottoposti a squash? Magari per rimuovere le modifiche dalla cronologia? Questa è un'opportunità per sfruttare reflog.

git reflog
37656e1 HEAD@{0}: rebase -i (finish): returning to refs/heads/git_reflog
37656e1 HEAD@{1}: rebase -i (start): checkout origin/main
37656e1 HEAD@{2}: commit: some WIP changes

Possiamo vedere che ci sono voci di reflog per l'inizio e la fine del rebase e prima di queste c'ĆØ il nostro commit per le "modifiche WIP". Possiamo passare il ref reflog a git reset e resettare a un commit precedente al rebase.

git reset HEAD@{2}

L'esecuzione di questo comando di ripristino sposterĆ  HEAD nel commit in cui sono state aggiunte "alcune modifiche WIP", essenzialmente ripristinando gli altri commit sottoposti a squash.

Riepilogo

In questo tutorial abbiamo discusso del comando git reflog. Alcuni punti chiave trattati sono stati:

  • Come visualizzare i reflog per branch specifici

  • Come annullare un rebase git usando reflog

  • Come specificare e visualizzare i reflog in base al tempo

Abbiamo accennato brevemente al fatto che git reflog può essere usato con altri comandi git come git checkout, git reset e git merge. Per saperne di più visita le rispettive pagine. Per ulteriori discussioni su riferimenti e reflog, scopri di più qui.

Consigliata per te

Blog di Bitbucket

Percorso di apprendimento DevOps

Scopri di più su Git

Trova altre guide e risorse su Git in questo hub.