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:
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.