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

158

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

Noich
источник

Ответы:

221

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

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

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

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

ben_h
источник
26
Предостережение: иногда вы МОЖЕТЕ потерять данные, потому что записи журналов не сохраняются вечно - они удаляются при определенных условиях. Посмотрите этот ответ и документы для git-reflog и git-gc . Как правило, если разрушительная операция была не более 2 недель назад, вы, скорее всего, в безопасности.
mcmlxxxvi
@mcmlxxxvi У меня есть две локальные папки для одного репозитория, могу ли я объединить reflogs для двух папок?
Tmx
@ TMX, я не совсем понимаю ваш случай - что вы подразумеваете под двумя локальными папками для одного репо ? Если у вас есть два клона одного и того же репо, которые актуальны, и вы хотите «объединить» их историю редактирования, .git/logs/refs/<branch>записи будут иметь формат <old_rev> <new_rev> [...] <timestamp> [...]. Вы можете попробовать объединить и отсортировать по отметке времени. Однако некоторые строки new_revмогут не совпадать со следующими old_rev, и в этом случае я подозреваю, что reflog будет недействительным. Затем вы можете попробовать вставить фальшивые записи, чтобы «исправить» последовательность, но это кажется мне слишком сложным.
mcmlxxxvi
62
  • git log показывает журнал коммитов, доступный из ссылок (заголовки, теги, пульты)
  • git reflogявляется записью всех коммитов, на которые есть ссылки в вашем репо в любое время.

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

gc.reflogexpire
gc.<pattern>.reflogexpire

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

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

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

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

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

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

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

VonC
источник
14

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

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

Вы можете увидеть ваш reflog, используя 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Команда также может быть использована для удаления записей или истекает записи из reflog, которые слишком стары. Из официальной документации Linux Kernel Git дляreflog :

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

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

Сообщество
источник
Но разве они не git logпредоставляют вам ту же информацию? Извините, если это кажется очевидным, я очень плохо знаком с GIT и хотел бы получить некоторые основы прямо перед моим первым OMG.
Noich
2
Журнал Git - это запись ваших коммитов . Рефлог, как говорится в книге Pro Git, - это запись ваших ссылок (в основном, ваших указателей веток и вашего HEADуказателя), и на какие коммиты они указывали. Имеет ли это смысл? В logдополнение к этому , может также показать вам информацию reflog, но вы должны передать флаг специальной опции в качестве аргумента --walk-reflogs.
3
Кроме того, поскольку вы новичок в Git, я настоятельно рекомендую вам прочитать книгу о Pro Git, именно так я узнал большую часть того, что узнал о Git. Я рекомендую главы 1-3 и 6-6.5. Я также настоятельно рекомендую вам научиться перебазировать как интерактивно, так и неинтерактивно.
8

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

  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

Митч
источник
1

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

Частное против публичного

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

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

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

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

Посмотрите на это изображение, чтобы подчеркнуть суть. После инициализации хранилища произошел ряд исправлений и сбросов. Reflog показывает все это. Тем не менее, команда log создает впечатление, будто против репо был только один коммит:

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

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

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

Кэмерон Маккензи
источник
-6

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

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

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

user10028634
источник
9
В git log, -gэто краткая форма для --walk-reflogs. Итак, это ничего не объясняет.
Адриан У,