git reflog
На этой странице подробно рассматривается команда git reflog
. Git отслеживает изменения в конце веток с помощью механизма журналов ссылок (reflog). Многие команды Git принимают параметр ссылки (ref), которая является указателем на коммит. Ниже представлены распространенные примеры таких команд:
Журналы ссылок позволяют отслеживать время обновления ссылок Git в локальном репозитории. Кроме журналов ссылок для последних коммитов ветки, существует специальный журнал ссылок команды git stash. Журналы ссылок хранятся в подкаталогах внутри каталога .git
локального репозитория. Для размещения каталогов git reflog
используются пути .git/logs/refs/heads/.
и .git/logs/HEAD
, а также .git/logs/refs/stash
(если в репозитории использовалась команда git stash
).
Общий обзор команды git reflog
приводится в документе Страница «Переписывание истории». В этом документе рассматриваются расширенные возможности конфигурации git reflog
, частые примеры и трудности использования git reflog
, отмена изменений с помощью команды git reflog
и многое другое.
Основное назначение
Журнал ссылок используется главным образом для вызова следующих данных:
git reflog
Это ярлык, эквивалентный следующей команде:
git reflog show HEAD
С помощью этой команды вызывается журнал ссылок HEAD
. Вывод команды должен выглядеть примерно так:
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
Другие распространенные примеры использования журнала ссылок см. на странице Переписывание истории.
Ссылки из журнала ссылок
По умолчанию команда git reflog
выводит журнал ссылок для указателя HEAD
. Указатель HEAD
является символической ссылкой на активную в данный момент ветку. Имеются журналы ссылок и для других указателей. Для обращения к ссылке в Git используется синтаксис name@{qualifier}
. Наряду с указателями HEAD
можно использовать ссылки на другие ветки, теги, удаленные объекты и отложенные изменения (stash).
Для вызова полного журнала ссылок выполните следующую команду:
git reflog show --all
Чтобы просмотреть журнал ссылок для конкретной ветки, передайте имя этой ветки команде 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
С помощью этого кода выводится журнал ссылок для ветки otherbranch
. В следующем примере подразумевается, что изменения были отложены ранее с помощью команды git stash
.
git reflog stash 0d44de3 stash@{0}: WIP on git_reflog: c492574 flesh out intro
С помощью этого кода выводится журнал ссылок для git stash. Полученные указатели можно передавать другим командам Git:
git diff stash@{0} otherbranch@{0}
С помощью этого кода выводится результат применения команды git diff, которая выполняет сравнение изменений stash@{0}
относительно указателя otherbranch@{0}
.
Журналы ссылок с заданным сроком действия
К каждой записи журнала ссылок привязана метка времени. Эти метки можно использовать в качестве токена qualifier
в синтаксисе указателя на ссылку Git, чтобы фильтровать журналы ссылок Git по времени. Ниже в качестве примеров приводится несколько префиксов времени:
1.minute.ago
1.hour.ago
1.day.ago
yesterday
1.week.ago
1.month.ago
1.year.ago
2011-05-17.09:00:00
Префиксы времени можно комбинировать (например, 1.day.2.hours.ago
). Кроме того, возможно использование форм множественного числа (например, 5.minutes.ago
).
Указатели префиксов времени можно передавать другим командам Git.
git diff main@{0} main@{1.day.ago}
В этом примере выполняется сравнение актуальной главной ветки с главной веткой по состоянию на 1 день назад. Эту функцию удобно использовать для просмотра изменений за определенный период времени.
Подкоманды и параметры конфигурации
В команде git reflog
можно использовать несколько дополнительных аргументов, которые имеют статус подкоманд.
Просмотр: git reflog show
По умолчанию аргумент show
передается неявным образом. Так, команда
git reflog main@{0}
эквивалентна команде
git reflog show main@{0}
Кроме того, git reflog show
является псевдонимом команды git log -g --abbrev-commit --pretty=oneline
. При выполнении команды git reflog show
отобразится журнал для переданного элемента
Истечение срока действия: git reflog expire
Подкоманда истечения срока действия удаляет устаревшие или недоступные записи из журнала ссылок. Выполнение подкоманды expire
может привести к потере данных. Обычно она не применяется пользователями и является внутренней подкомандой Git. При передаче параметра -n
или --dry-run
команде git reflog expire
выполняется тестовый прогон, который выводит записи журнала ссылок, помеченные для удаления, но на самом деле не удаляет их.
По умолчанию срок действия журнала ссылок составляет 90 дней. Время окончания срока действия можно указать, передав аргумент командной строки --expire=time
команде git reflog expire
или настроив конфигурацию Git с именем gc.reflogExpire
.
Удаление: git reflog delete
Функция подкоманды delete
очевидна. Эта подкоманда удаляет переданную запись журнала ссылок. Как и в случае с подкомандой expire
, использование delete
может привести к потере данных. Обычно она также не вызывается пользователями.
Восстановление потерянных коммитов
Данные в Git не теряются даже при выполнении таких операций переписывания истории, как перебазирование или исправление коммита. Представим, что в репозиторий внесены новые изменения. При этом вывод команды git log --pretty=oneline
имеет следующий вид:
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
Мы отправляем эти изменения и выполняем следующий код:
#make changes to HEAD git commit -am "some WIP changes"
С появлением нового коммита журнал теперь имеет следующий вид:
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
На данном этапе выполним интерактивное перебазирование для главной ветки. При этом используем следующую команду:
git rebase -i origin/main
В ходе перебазирования мы отметим коммиты, подлежащие склеиванию, с помощью подкоманды перебазирования s
. Выполняя перебазирование, мы произведем склеивание нескольких коммитов в последнем коммите под названием «some WIP changes».
После склеивания коммитов вывод команды git log
примет следующий вид:
40dhsoi37656e19d4e4f1a9b419f57850ch87dah987698hs some WIP changes 35aee4a4404c42128bee8468a9517418ed0eb3dc initial commit add git-init and setting-up-a-repo docs
При анализе git log
видно, что на данном этапе больше нет коммитов, отмеченных для склеивания. Но что делать, если необходимо обработать один из склеенных коммитов, например удалить связанные с ним изменения из истории? Для этого можно использовать журнал ссылок.
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
Как можно заметить, в журнале ссылок имеются записи, соответствующие запуску и окончанию команды rebase
, а перед ними находится коммит «some WIP changes». Мы можем передать указатель журнала ссылок команде git reset
и сбросить данные до точки перед перебазированием.
git reset HEAD@{2}
При выполнении команды сброса указатель HEAD
переместится на коммит, в котором были добавлены изменения под названием «some WIP changes». При этом будут восстановлены другие склеенные коммиты.
Резюме
В этом обучающем руководстве была рассмотрена команда git reflog
. При этом были описаны некоторые ключевые моменты:
- Просмотр журнала ссылок для конкретных веток
- Отмена команды git rebase с помощью журнала ссылок
- Определение и просмотр записей журнала ссылок с метками времени
Мы кратко рассмотрели использование git reflog
с другими командами Git, такими как git checkout, git reset и git merge. Дополнительные сведения см. на страницах этих команд. Более подробную информацию о ссылках и журнале ссылок см. здесь.