В чем разница между git reflog и log?

Страница man говорит, что log показывает журналы фиксации, а reflog управляет информацией reflog. Что такое информация reflog и что она имеет, чего нет в журнале? Журнал кажется гораздо более подробным.

5 ответов

Решение

git log показывает текущую ГОЛОВКУ и ее происхождение. То есть он печатает коммит, на который указывает HEAD, затем его родитель, родитель и т. Д. Он проходит через родословную репо, рекурсивно просматривая родителя каждого коммита.

(На практике некоторые коммиты имеют более одного родителя. Чтобы увидеть более репрезентативный журнал, используйте команду вроде git log --oneline --graph --decorate .)

git reflog не пересекает родословную HEAD вообще. Reflog - это упорядоченный список коммитов, на которые указал HEAD: это история отмены вашего репо. Рефлог не является частью самого репо (он хранится отдельно от самих коммитов) и не включается в толчки, выборки или клоны; это чисто местное.

Кроме того: понимание рефлога означает, что вы не сможете действительно потерять данные из своего репо после его фиксации. Если вы случайно сбросили прежний коммит, или сделали неправильный перебаз, или любую другую операцию, которая визуально "удаляет" коммиты, вы можете использовать reflog, чтобы увидеть, где вы были раньше, и git reset --hard вернуться к этой ссылке, чтобы восстановить ваше предыдущее состояние. Помните, что ссылки подразумевают не только коммит, но и всю его историю.

  • git log показывает журнал коммитов, доступный из ссылок (руководители, теги, удаленные)
  • git reflog это запись всех коммитов, на которые есть ссылки в вашем репо в любое время.

Поэтому git reflog (локальная запись, которая по умолчанию удаляется через 90 дней) используется, когда вы выполняете "деструктивную" операцию (например, удаление ветки), чтобы вернуть SHA1, на который ссылалась эта ветка.
Увидеть git config:

gc.reflogexpire
gc.<pattern>.reflogexpire

git reflog expire удаляет записи reflog старше этого времени; по умолчанию до 90 дней.
С " <pattern> "(например" refs/stash ") в центре настройки применяются только к ссылкам, которые соответствуют <pattern>,

защитная сетка

git reflog часто упоминается как " ваша сеть безопасности "

В случае проблем общий совет, когда git log не показывает то, что вы ищете:

" Сохраняйте спокойствие и используйте git reflog "

сохраняй спокойствие

Опять же, reflog - это локальная запись вашего SHA1.
В отличие от git log: если вы подтолкнете свое репо к обратному репозиторию, вы увидите то же самое git log, но не обязательно то же самое git reflog,

Вот объяснение reflog из книги Pro Git:

Одна из вещей, которые Git делает в фоновом режиме, пока вы работаете, - это вести журнал изменений - журнал того, где ваши ссылки на HEAD и ветви были за последние несколько месяцев.

Вы можете увидеть свой рефлог, используя git reflog:

$ git reflog
734713b... HEAD@{0}: commit: fixed refs handling, added gc auto, updated
d921970... HEAD@{1}: merge phedders/rdocs: Merge made by recursive.
1c002dd... HEAD@{2}: commit: added some blame and merge stuff
1c36188... HEAD@{3}: rebase -i (squash): updating HEAD
95df984... HEAD@{4}: commit: # This is a combination of two commits.
1c36188... HEAD@{5}: rebase -i (squash): updating HEAD
7e05da5... HEAD@{6}: rebase -i (pick): updating HEAD

Каждый раз, когда ваш совет по какой-либо причине обновляется, Git сохраняет эту информацию для вас во временной истории. И вы можете указать более старые коммиты с этими данными.

reflog Команда также может быть использована для удаления записей или истечения срока действия записей из журнала слишком старых. Из официальной документации Linux Kernel Git для reflog:

Подкоманда expire используется для удаления старых записей reflog.

Чтобы удалить отдельные записи из reflog, используйте подкоманду delete и укажите точную запись (например, git reflog delete master@{2}).

Мне было любопытно и это, и я просто хочу уточнить и подвести итог:

  1. git log показывает историю всех ваших коммитов для ветки, в которой вы находитесь. Оформите другую ветку, и вы увидите другую историю коммитов. Если вы хотите увидеть историю ваших изменений для всех веток, введите git log --all,

  2. git reflog показывает запись ваших ссылок, как сказал Кекс. Существует запись каждый раз, когда совершается фиксация или проверка. Попробуйте переключаться между двумя ветвями несколько раз, используя git checkout и беги git reflog после каждой проверки. Вы увидите, что верхняя запись обновляется каждый раз как запись "оформить заказ". Вы не видите эти типы записей в git log,

Ссылки: http://www.lornajane.net/posts/2014/git-log-all-branches

Мне нравится думать о разнице между git log и reflog как о разнице между частной записью и общедоступной.

Частный vs публичный

С помощью git reflog он отслеживает все, что вы сделали локально. Вы совершили? Reflog отслеживает это. Вы сделали полный сброс? Reflog отслеживает это. Вы внесли поправки в коммит? Reflog отслеживает это. Все, что вы делали локально, есть в журнале ссылок.

Это не относится к журналу. Если вы измените фиксацию, в журнале будет отображаться только новая фиксация. Если вы выполните сброс и пропустите несколько коммитов в своей истории, те коммиты, которые вы пропустили, не будут отображаться в журнале. Когда вы отправляете свои изменения другому разработчику или GitHub или что-то в этом роде, отображается только контент, отслеживаемый в журнале. Для другого разработчика это будет выглядеть так, как будто ни сброса, ни исправления не произошло.

Бревно шлифованное. Рефлог лапидарный.

Так что да, мне нравится аналогия "частное против публичного". Или, может быть, лучшая аналогия журнала и рефлога - "шлифовка против гранильного". В рефлоге показаны все ваши попытки и ошибки. Журнал просто показывает чистую и отточенную версию вашей истории работы.

Взгляните на это изображение, чтобы подчеркнуть суть. С момента инициализации репозитория произошел ряд исправлений и сбросов. В рефлоге все это показано. Тем не менее, команда log выглядит так, как будто когда-либо была только одна фиксация против репо:

Вернуться к идее "сети безопасности"

Кроме того, поскольку журнал ссылок отслеживает все, что вы изменили, и фиксирует ваш сброс, он позволяет вам вернуться и найти эти фиксации, потому что он предоставит вам идентификаторы фиксации. Предполагая, что ваш репозиторий не был очищен от старых коммитов, это позволяет вам восстанавливать элементы, которые больше не отображаются в журнале. Вот как иногда рефлог спасает чью-то шкуру, когда им нужно вернуть то, что, по их мнению, они случайно потеряли.

git logбудет начинаться с текущей HEAD, то есть указывать на некоторую ветку (например, master) или непосредственно для фиксации объекта (код sha), и фактически будет сканировать объектные файлы внутри .git/ objects directory commit после фиксации с использованием родительского поля, которое существует внутри каждого зафиксировать объект.

Эксперимент: направьте HEAD прямо на какой-нибудь коммит: git checkout a721d (создайте новое репо и заполните его коммитами и ветвями. замените a721d с частью вашего кода фиксации) и удалите ветки rm .git/refs/heads/* Сейчас git log --onelineпокажет только HEAD и его предков-коммитов.

git reflog, с другой стороны, использует прямой журнал, который создается внутри .git/ logs

Эксперимент: rm -rf .git/logs а также git reflog пусто.

В любом случае, даже если вы потеряете все теги, все ветки и все журналы внутри папки журналов, объекты коммитов находятся внутри каталога .git/ objects, поэтому вы можете восстановить дерево, если найдете все висячие коммиты:git fsck

На самом деле, reflog это псевдоним для

 git log -g --abbrev-commit --pretty=oneline

поэтому ответ должен быть: это особый случай.

Другие вопросы по тегам