git reflog

Ta strona zawiera dokładne omówienie polecenia git reflog. Git śledzi aktualizacje końcówek gałęzi za pomocą mechanizmu zwanego dziennikami referencji lub „reflogami”. Wiele poleceń systemu Git uwzględnia parametr pozwalający przekazać odniesienie, czyli wskaźnik do commitu. Często stosowane przykłady:

  • git checkout
  • git reset
  • git merge

Dzienniki referencji śledzą, kiedy odniesienia systemu Git zostały zaktualizowane w lokalnym repozytorium. Oprócz dzienników reflog końcówek gałęzi utrzymywany jest specjalny dziennik schowka Git. Dzienniki reflog są przechowywane w podkatalogach mieszczących się w katalogu .git lokalnego repozytorium. Katalogi git reflog można znaleźć w .git/logs/refs/heads/., .git/logs/HEAD, a także .git/logs/refs/stash, jeśli polecenia git stash użyto w repozytorium.

Polecenie git reflog ogólnie omówiliśmy na stronie dotyczącej przepisywania historii. Tutaj poruszymy kwestie, takie jak rozszerzone opcje konfiguracji git reflog, typowe przypadki użycia i pułapki w korzystaniu z reflog git, a także sposób cofania zmian za pomocą git reflog.

Podstawowe użycie

Najbardziej podstawowym przypadkiem użycia polecenia reflog jest zwykłe wywołanie:

git reflog

Zasadniczo jest to skrót odpowiadający poleceniu:

git reflog show HEAD

Spowoduje to wyświetlenie dziennika HEAD. Wynik powinien wyglądać mniej więcej następująco:

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

Aby zobaczyć inny przykład wykorzystania tego polecenia, odwiedź stronę dotyczącą przepisywania historii.

Odniesienia reflog

Domyślnie polecenie git reflog wyświetla odniesienie HEAD. HEAD to symboliczne odniesienie do aktualnie aktywnej gałęzi. Reflogi są również dostępne dla innych odwołań. Składnia polecenia dostępu do odwołania systemu Git to nazwa@{kwalifikator}. Oprócz odniesień HEAD można się również odwoływać do innych gałęzi, tagów, zdalnych repozytoriów i schowka Git.

Można też wywołać kompletny dziennik wszystkich odwołań, wykonując polecenie:

  git reflog show --all 

Aby wyświetlić reflog dla określonej gałęzi, należy przekazać jej nazwę do 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 

Zastosowanie tego przykładu spowoduje wyświetlenie dziennika dla gałęzi otherbranch. W poniższym przykładzie założono, że niektóre zmiany zostały wcześniej zapisane w schowku za pomocą polecenia git stash.

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

Spowoduje to wyświetlenie dziennika schowka Git. Zwracane wskaźniki mogą być przekazywane do innych poleceń Git:

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

Zastosowanie tego przykładowego kodu spowoduje wyświetlenie zakresu różnic między zmianami w stash@{0} a odwołaniem otherbranch@{0}.

Dzienniki reflog ze znacznikami czasu

Każdy wpis w dzienniku ma przypisany znacznik czasu. Znaczniki te można wykorzystać w roli kwalifikatora w składni wskaźnika odniesienia Git. Umożliwia to filtrowanie dzienników reflog według czasu. Oto kilka przykładów dostępnych kwalifikatorów czasowych:

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

Kwalifikatory czasowe można ze sobą łączyć (np. 1.day.2.hours.ago), Dodatkowo akceptowane są formy mnogie (np. 5.minutes.ago).

Odniesienia z kwalifikatorami czasu można przekazywać do innych poleceń git.

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

Efektem powyższego przykładowego polecenia będzie wykaz zmian w bieżącej gałęzi głównej względem jej stanu z dnia poprzedniego. To przydatne rozwiązanie do sprawdzenia zmian, które zaszły w danym okresie.

Podpolecenia i opcje konfiguracyjne

Polecenie git reflog dopuszcza kilka dodatkowych argumentów, które są traktowane jako podpolecenia.

Pokaż — git reflog show

Argument show domyślnie przekazywany jest w sposób niejawny. Na przykład polecenie:

 git reflog main@{0} 

jest równoważne poleceniu:

 git reflog show main@{0} 

Ponadto git reflog show to alias git log -g --abbrev-commit --pretty=oneline. Wykonanie git reflog show wyświetli dziennik dla przekazanych .

Wygaś — git reflog expire

Podpolecenie wygaszania czyści stare lub nieosiągalne wpisy dziennika reflog. Podpolecenie expire może prowadzić do utraty danych. Nie jest zwykle używane przez użytkowników końcowych git, a raczej wewnętrznie przez sam system. Przekazanie opcji -n lub --dry-run do git reflog expire spowoduje wykonanie „przebiegu próbnego”, w ramach którego wpisy dziennika oznaczone do usunięcia zostaną wyświetlone, ale nie faktycznie usunięte.

Domyślnie ustawionym terminem wygaśnięcia dziennika jest 90 dni. Moment wygaśnięcia można określić przez przekazanie argumentu wiersza poleceń --expire=time do git reflog expire lub ustawienie nazwy konfiguracji git gc.reflogExpire.

Usuń — git reflog delete

Funkcja podpolecenia delete jest dość oczywista — usuwa przekazany wpis dziennika reflog. Podobnie jak w przypadku expire podpolecenie delete może prowadzić do utraty danych i nie jest powszechnie stosowane przez użytkowników końcowych.

Odzyskiwanie utraconych commitów

W rzeczywistości w systemie Git nic nie znika ostatecznie, nawet podczas operacji przepisywania historii takich jak zmiana bazy czy korekta commitów. Na potrzeby kolejnego przykładu załóżmy, że wprowadziliśmy w repozytorium kilka nowych zmian. git log --pretty=oneline wygląda następująco:

 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 

Następnie zatwierdzamy zmiany i wykonujemy polecenie:

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

Po dodaniu nowego commitu dziennik wygląda następująco:

 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 

W tym momencie przeprowadzamy interaktywną zmianę bazy dla głównej gałęzi za pomocą polecenia:

 git rebase -i origin/main 

Podczas zmiany bazy zaznaczamy commity do squashowania za pomocą podpolecenia rebase s. W ramach zmiany bazy squashujemy kilka commitów do ostatniego commitu „some WIP changes”.

Ponieważ zesquashowaliśmy commity, dane wyjściowe git log wyglądają obecnie następująco:

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

Jeśli przyjrzymy się git log w tym momencie, zauważymy, że już nie widać commitów oznaczonych do squashowania. A co zrobić, jeśli zechcemy pracować na jednym z zesquashowanych commitów? Na przykład w celu usunięcia jego zmian z historii? To okazja do skorzystania z dziennika 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 

Widzimy, że istnieją wpisy reflog dla rozpoczęcia i zakończenia procesu rebase, a przed nimi znajduje się commit „some WIP changes”. Możemy przekazać odniesienie dziennika do git reset i cofnąć stan do commitu sprzed zmiany bazy.

 git reset HEAD@{2} 

Wykonanie tego polecenia spowoduje przeniesienie HEAD do commitu, w ramach którego dodano „some WIP changes”, zasadniczo przywracając pozostałe zesquashowane commity.

Podsumowanie

W poradniku omówiliśmy działanie polecenia git reflog. Poruszyliśmy kilka kluczowych kwestii, m.in.:

  • Jak wyświetlić dziennik reflog dla określonych gałęzi
  • Jak cofać efekty git rebase za pomocą polecenia reflog
  • Jak określić i wyświetlić wpisy reflog ze znacznikami czasu

Wspomnieliśmy też, że polecenia git rebase można użyć w połączeniu z innymi narzędziami, takimi jak git checkout, git reset i git merge. Więcej informacji można uzyskać na poświęconych im stronach. Dokładniejsze omówienie odniesień i dziennika reflog znajduje się tutaj.

Chcesz nauczyć się obsługi systemu Git?

Wypróbuj ten interaktywny samouczek.

Zacznij już teraz