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 ref используется синтаксис name@{qualifier}. Наряду с указателями HEAD можно использовать ссылки на другие ветки, теги, удаленные объекты и git 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 ref, чтобы фильтровать журналы ссылок 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 отобразится журнал для переданного элемента <refid>.

Истечение срока действия — 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. Выполняя перебазирование, мы произведем склеивание нескольких коммитов в последнем коммите под названием «Рабочий вариант изменений».

После склеивания коммитов выходные данные 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, а перед ними расположен коммит «Рабочий вариант изменений». Мы можем передать указатель журнала ссылок команде git reset и сбросить данные до точки перед перебазированием.

git reset HEAD@{2}

При выполнении команды сброса HEAD переместится в коммит, в который был добавлен элемент «Рабочий вариант изменений». При этом будут восстановлены другие склеенные коммиты.

Резюме

В этом обучающем руководстве была рассмотрена команда git reflog. При этом были описаны некоторые ключевые моменты:

  • Просмотр журнала ссылок для конкретных веток
  • Отмена git rebase с помощью журнала ссылок
  • Определение и просмотр записей журнала ссылок, основанных на метках времени

Мы кратко рассмотрели использование git reflog с другими командами Git, такими как git checkout, git reset и git merge. Дополнительные сведения см. на страницах этих команд. Более подробную информацию о ссылках и журнале ссылок см. здесь.
 

Готовы изучить Git?

Попробуйте это интерактивное учебное руководство.

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