git reflog

На этой странице подробно рассматривается команда git reflog. Git отслеживает изменения в конце веток с помощью механизма журналов ссылок (reflog). Многие команды Git принимают параметр ссылки (ref), которая является указателем на коммит. Ниже представлены распространенные примеры таких команд:

  • git checkout
  • git reset
  • git merge

Журналы ссылок позволяют отслеживать время обновления ссылок 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 master to git_reflog
9a4491f HEAD@{3}: checkout: moving from Git_Config to master
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 master@{0} master@{1.day.ago} 

В этом примере выполняется сравнение актуальной главной ветки с главной веткой по состоянию на 1 день назад. Эту функцию удобно использовать для просмотра изменений за определенный период времени.

Подкоманды и параметры конфигурации

В команде git reflog можно использовать несколько дополнительных аргументов, которые имеют статус подкоманд.

Просмотр: git reflog show

По умолчанию аргумент show передается неявным образом. Так, команда

 git reflog master@{0} 

эквивалентна команде

 git reflog show master@{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/master 

В ходе перебазирования мы отметим коммиты, подлежащие склеиванию, с помощью подкоманды перебазирования 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/master 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?

Ознакомьтесь с этим интерактивным обучающим руководством.

Начните прямо сейчас