git reflog

Deze pagina bevat een gedetailleerde beschrijving van de opdracht git reflog. Git houdt updates van het uiteinde van branches bij met behulp van een mechanisme dat referentielogs of 'reflogs' wordt genoemd. Veel Git-opdrachten accepteren een parameter voor het specificeren van een referentie of 'ref', wat een pointer naar een commit is. Gangbare voorbeelden zijn:

  • Git Checkout
  • git reset
  • git merge

Reflogs houden bij wanneer Git-refs zijn bijgewerkt in de lokale repository. Naast reflogs voor branchuiteinden wordt er een speciale reflog bijgehouden voor de Git stash. Reflogs worden opgeslagen in mappen onder de map .git van de lokale repository. De git reflog-mappen zijn te vinden in .git/logs/refs/heads/., .git/logs/HEAD en ook in .git/logs/refs/stash als de git stash is gebruikt in de repo.

We hebben git reflog op hoog niveau besproken op de pagina Geschiedenis herschrijven. Dit document behandelt: uitgebreide configuratieopties voor git reflog, veelvoorkomende usecases en valkuilen van git reflog, hoe je wijzigingen ongedaan kunt maken met git reflog en meer.

Basisgebruik

De meest elementaire usecase van Reflog is het aanroepen van:

git reflog

Dit is in wezen een snelkoppeling die gelijk is aan:

git reflog show HEAD

Hiermee wordt de HEAD-reflog weergeven. Je zou ongeveer de volgende output moeten zien:

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

Ga naar de pagina Geschiedenis herschrijven voor nog een voorbeeld van veelvoorkomende gebruik van reflog.

Reflog-referenties

Met git reflog wordt standaard de reflog van de HEAD-ref weergegeven. HEAD is een symbolische verwijzing naar de momenteel actieve branch. Reflogs zijn ook beschikbaar voor andere refs. De syntaxis voor toegang tot een git ref is name@{qualifier}. Naast HEAD-refs kunnen ook andere branches, tags, remotes en de Git-stash worden geraadpleegd.

Je kunt een volledige reflog van alle refs verkrijgen door de volgende opdracht uit te voeren:

  git reflog show --all 

Om de reflog voor een specifieke branch te zien, geef je de naam van die branch door aan git reflog show

 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 

Als je dit voorbeeld uitvoert, krijg je een reflog voor de branch otherbranch. In het volgende voorbeeld wordt ervan uitgegaan dat je eerder enkele wijzigingen hebt opgeslagen met de opdracht git stash.

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

Dit levert een reflog op voor de Git-stash. De geretourneerde ref pointers kunnen worden doorgegeven aan andere Git-opdrachten:

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

Wanneer deze voorbeeldcode wordt uitgevoerd, geeft deze de diff-uitvoer van Git weer, waarbij de stash@{0}-wijzigingen worden vergeleken met de otherbranch@{0}-ref.

Getimede reflogs

Aan elk reflog-item is een tijdstempel gekoppeld. Deze tijdstempels kunnen worden gebruikt als qualifier-token voor de Git ref-pointersyntaxis. Hiermee kunnen Git-reflogs op tijd worden gefilterd. Hieronder volgen een paar voorbeelden van beschikbare tijdkwalificaties:

  • 1.minute.ago
  • 1.hour.ago
  • 1.day.ago
  • Gisteren
  • 1.week.ago
  • 1.month.ago
  • 1.year.ago
  • 2011-05-17.09:00:00

Tijdrukkwalificaties kunnen gecombineerd worden (bijv. 1.day.2.hours.ago), Daarnaast worden meervoudige vormen geaccepteerd (bijv. 5.minutes.ago).

Tijdkwalificatiereferenties kunnen worden doorgegeven aan andere Git-opdrachten.

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

In dit voorbeeld wordt een diff gemaakt van de huidige main-branch ten opzichte van die van 1 dag geleden. Dit voorbeeld is erg nuttig als je wilt weten welke veranderingen er binnen een bepaald tijdsbestek zijn opgetreden.

Subopdrachten en configuratieopties

git reflog accepteert enkele aanvullende argumenten die als subopdrachten worden beschouwd.

Show - git reflog show

show wordt standaard impliciet doorgegeven. Bijvoorbeeld de opdracht:

 git reflog main@{0} 

is gelijk aan de opdracht:

 git reflog show main@{0} 

Bovendien is git reflog show een alias voor git log -g --abbrev-commit --pretty=oneline. Executing git reflog show geeft het log weer voor de doorgegeven .

Expire - git reflog expire

De subopdracht expire ruimt oude of onbereikbare reflog-vermeldingen op. De subopdracht expire kan leiden tot gegevensverlies. Deze subopdracht wordt doorgaans niet gebruikt door eindgebruikers, maar intern door Git. Wanneer je de optie -n of --dry-run doorgeeft aan git reflog expire, wordt er een 'dry run' uitgevoerd die in de output aangeeft welke reflog-vermeldingen zijn gemarkeerd om te worden opgeschoond, zonder ze daadwerkelijk op te schonen.

De vervaldatum van de reflog is standaard ingesteld op 90 dagen. Een vervaltijd kan worden opgegeven door een opdrachtregelargument --expire=time door te geven aan git reflog expire of door de Git-configuratienaam in te stellen op gc.reflogExpire.

Delete - git reflog delete

De subopdracht delete spreekt voor zich en verwijdert een doorgegeven element in een reflog-vermelding. Net als bij de expire kunnen met delete gegevens verloren gaan en wordt deze opdracht niet vaak aangeroepen door eindgebruikers.

Verloren commits herstellen

Git verliest eigenlijk nooit iets, zelfs niet bij operaties om de geschiedenis te herschrijven, zoals rebasen of commit-wijzigingen. Laten we voor het volgende voorbeeld aannemen dat we een aantal nieuwe wijzigingen hebben aangebracht in onze repo. Onze git-log --pretty=oneline ziet er als volgt uit:

 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 

Vervolgens committen we die veranderingen en voeren we het volgende uit:

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

Met de toevoeging van de nieuwe commit ziet het log er nu zo uit:

 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 

Op dit punt voeren we een interactieve rebase uit tegen de main-branch door de volgende opdracht uit te voeren ...

 git rebase -i origin/main 

Tijdens de rebase markeren we commits voor squash met de rebase-subopdracht s. Tijdens de rebase squashen we een paar commits in de meest recente commit 'some WIP changes'.

Omdat we commits hebben gesquasht, ziet de git log-output er nu als volgt uit:

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

Als we nu git log bekijken, blijkt dat we niet langer de commits hebben die gemarkeerd waren voor squashing. Wat als we iets willen doen met een van de gesquashte commits? Misschien om de wijzigingen uit de geschiedenis te verwijderen? Dit is een kans om gebruik te maken van de 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 

We kunnen zien dat er reflog-vermeldingen zijn voor het begin en einde van de rebase, en daarvoor is onze 'some WIP changes' uitgevoerd. We kunnen de reflog-referentie doorgeven aan git reset en resetten naar een commit vóór de rebase.

 git reset HEAD@{2} 

Als je deze reset-opdracht uitvoert, wordt HEAD naar de commit verplaatst waar 'some WIP changes' is toegevoegd, waardoor in feite de andere gesquashte commits worden hersteld.

Samenvatting

In deze tutorial hebben we de opdracht git reflog besproken. Enkele belangrijke punten die aan bod kwamen waren:

  • reflog voor specifieke branches weergeven
  • Een Git-rebase ongedaan maken met de reflog
  • Op tijd gebaseerde reflog-vermeldingen specificeren en weergeven

We hebben kort vermeld dat git reflog kan worden gebruikt met andere git-opdrachten zoals git checkout, git reset en git merge. Meer informatie vind je op hun respectievelijke pagina's. Voor een verdere bespreking van refs en de reflog, vind je hier meer informatie.

Klaar om Git te leren?

Probeer deze interactieve tutorial.

Nu aan de slag