Получить список всех коммитов git, включая «потерянные»

139

Допустим, у меня есть такой график:

A---B---C---D (master)
     \
      \-E---F (HEAD)

Если я это сделаю git log --all --oneline, я получу все шесть моих коммитов.

Но если график

A---B---C---D (master, HEAD)
     \
      \-E---F

Я не увижу E и F. Могу ли я получить мерзавец, чтобы сказать мне все коммиты, в том числе те, что на ветках, которые не названы?

Спасибо

Amadan
источник

Ответы:

63

Не особенно легко - если вы потеряли указатель на верхушку ветки, это все равно что найти иголку в стоге сена. Вы можете найти все коммиты, на которые, похоже, больше не ссылаются, - git fsck --unreachableони сделают это за вас - но это будет включать в себя коммиты, которые вы выбросили после a git commit --amend, старые коммиты на ветках, которые вы перебазировали и т. Д. Скорее всего, слишком много информации, чтобы пролистать.

Так что легкомысленный ответ таков: не забывайте о том, что вас интересует. Если быть более серьезным, то по умолчанию журналы будут содержать ссылки на все коммиты, которые вы использовали за последние 60 дней или около того. Что еще более важно, они будут давать некоторый контекст о том, что эти коммиты являются .

araqnid
источник
7
+1: Нет абсолютно никакой разницы между коммитом, умышленно осиротевшим от commit --amendили, rebaseи коммитом, случайно осиротевшим, например, при работе с отдельным HEAD.
Каскабель
3
на самом деле. Вероятно, самый простой способ выйти из этой ситуации - посмотреть на reflog для самой HEAD.
Аракнид
@Jefromi: Отличное замечание о том, что git commit --amendи т. Д. Выход из тупика, потерянные коммиты. Я сделал некоторую перебазировку и еще много чего и закончил с некоторыми коммитами, недоступными из каких-либо веток, и чувствовал себя немного грязным, оставляя их в репо. Теперь эта мысль уже не так тревожна. :)
Эмиль Лундберг
2
@araqnid Я попал в тот же рассол, что и оригинальный постер, и твое предложение взглянуть на журнал было просто то, что нужно сделать.
Игнацио
7
Я согласен с этим ответом, но в случае, когда кому-то нужно просмотреть все коммиты, в том числе осиротевшие, преднамеренные или случайные, git fsck --unreachableэтого не предусмотрено. Я только что попробовал это. Лучше всего подходит --reflogвариант git log, как ответил Кенорб . Что особенно приятно в этом, так это то, что в сочетании с ним --graphвы легко анализируете визуальный контекст, очень похожий на тот, что показан в исходном вопросе. Например, попробуйте:git log --graph --all --oneline --reflog
Иниго
111

Пытаться:

git log --reflog

который перечисляет все коммиты git, делая вид, что все объекты, упомянутые в reflogs ( git reflog), перечислены в командной строке как <commit>.

kenorb
источник
1
Это то, что я искал - функциональность аргумента --reflog.
Аномалия
3
Кстати, gitk также поддерживает это: gitk --reflog.
ald.li
50

Когда я решаю эту проблему, я использую следующую команду:

git reflog |  awk '{ print $1 }' | xargs gitk

Это позволяет мне визуализировать недавние коммиты, которые стали безголовыми.

Я завернул это в скрипт помощника под названием ~/bin/git-reflog-gitk.

Киран
источник
1
Это просто спасло меня большое время ... СПАСИБО!
Брет Ройстер
это круто! Спасибо! это действительно визуализирует важные части дерева.
Младен Б.
Просто совет: это будет работать только для вашей локальной работы в качестве записей журнала when the tips of branches and other references were updated in the *local repository*. Вы можете использовать, git log --reflogесли вы хотите сделать это для нелокальных изменений ссылок
Кришна Гупта
29

То, что спасло мою жизнь, было следующей командой:

git reflog

Там вы найдете экран с историческими коммитами, сделанными для этого:

введите описание изображения здесь

На данный момент вам нужно только найти то, HEAD@{X}что вам нужно, создать временную ветку и перейти к ней следующим образом:

git checkout -b temp_branch HEAD@{X}

Таким образом, у вас будет временная ветка с вашим потерянным коммитом, не перебирая и не ломая ваш Git-репозиторий

Надеюсь это поможет...

Sonhja
источник
26

Как @Kieran's Answer, но для консоли: git log --oneline --all --graph --decorate $(git reflog | awk '{print $1}')

Флориан Фида
источник
Вам нужно включить последнюю часть: $ (git reflog | awk '{print $ 1}')? Что это делает? После опробования вашего решения кажется, что оно выдает тот же результат даже без этой последней части.
wmock
Если вы переместите указатель ветки и оставите некоторые коммиты без ссылки (как это сделал OP), они больше не будут отображаться в git log --all. Быстрый пример: после того, как git reset --hard @^ваш коммит HEAD @ {0} будет только в reflog, и, поскольку git reflogон не поддерживает, --graphвы должны передать коммиты, git log --graphчтобы получить визуальное представление.
Флориан Фида
5
Вы можете использовать --reflogвместо $(git reflog | awk '{print $1}')
Sild
По сравнению git log --oneline --all --graph --decorate $(git reflog | awk '{print $1}')с ними git log --oneline --all --graph --decorate --reflogони почти идентичны, за исключением того, что --reflog включает такие детали, как записи WIP.
сценарий Вольф
@FlorianFida, а reflogпочему бы не использовать log --reflogвместо этого?
Пейсер
9

Как я решаю эту проблему? Используйте git fsckи войдите!

Сначала создайте файл, содержащий потерянные (недоступные) коммиты и BLOB-объекты. (ПРИМЕЧАНИЕ: если вы сделали что-то подобное git gc, сборщик мусора соберет все их коммиты, а вы их здесь не найдете!)

$git fsck --lost-found > lost_found.commits

Это дает вам такой файл:

оборванный совершить dec2c5e72a81ef06963397a49c4b068540fc0dc3
оборванных блобо f8c2579e6cbfe022f08345fa7553feb08d60a975
оборванных блобо 0eb3e86dc112332ceadf9bc826c49bd371acc194
оборванных блобо 11cbd8eba79e01f4fd7f496b1750953146a09502
оборванных совершить 18733e44097d2c7a800650cea442febc5344f9b3
оборванных блоб 1e53a5cdb3ecdde27081ec6e8b31e4070106ee05

Затем вы можете открыть этот файл в своем любимом текстовом редакторе, чтобы скопировать из него хэши коммитов / блогов. (* кашель * макрос vim отлично подходит для этого * кашля *)

Теперь вы можете выйти из этого коммита с чем-то вроде git log --oneline <commit hash>. Кроме того, должен работать gitk, tig или любой другой git viewer.

В вашем случае, если вы найдете хеш для коммита F, журнал покажет вам что-то вроде этого,

A---B---E---F

Быстро и просто! Теперь вы можете найти контекст за всеми этими висячими коммитами.

PS Да, я знаю, поздний пост, ну да ладно, кто-то может найти это здесь и найти это полезным. (Скорее всего, я через 6 месяцев, когда я снова Google это)

bsimmons
источник
5

Мне повезло восстановить коммит, посмотрев на reflog, который был расположен на .git/logs/HEAD

Затем мне пришлось прокрутить файл до конца , и я нашел потерянный коммит.

GameScripting
источник
Это то, что только что закончилось, когда я что-то напортачил. Попытался взять на себя обязательство, и Сташ отказался, когда я толкнул. Я сбросил --hard, затем понял свою ошибку. Коммит был в reflog, так что я проверил его, сделал из него ветку, а затем выдвинул это. Все получилось в итоге.
Дэвид
5

Мы git logиногда не очень хорошо получаем детали всех коммитов, поэтому чтобы посмотреть это ...

Для Mac: зайдите в свой проект git и введите:

$ nano .git/logs/HEAD

чтобы просмотреть все ваши коммиты в этом, или:

$ gedit .git/logs/HEAD

чтобы увидеть, что вы все делаете в этом,

тогда вы можете редактировать в любом своем любимом браузере.

Винод Джоши
источник
3

@bsimmons

git fsck --lost-found | grep commit

Затем создайте ветку для каждого:

$ git fsck --lost-found | grep commit
Checking object directories: 100% (256/256), done.
dangling commit 2806a32af04d1bbd7803fb899071fcf247a2b9b0
dangling commit 6d0e49efd0c1a4b5bea1235c6286f0b64c4c8de1
dangling commit 91ca9b2482a96b20dc31d2af4818d69606a229d4

$ git branch  branch_2806a3 2806a3
$ git branch  branch_6d0e49 6d0e49
$ git branch  branch_91ca9b 91ca9b

Теперь многие инструменты покажут вам графическую визуализацию этих потерянных коммитов.

yakoda
источник
2

Если вы используете графический интерфейс Git Extensions, он может показать вам графическую визуализацию висячих коммитов, если вы отметите «Просмотр -> Показать ссылки на журналы». Это покажет висячие коммиты в дереве, как и все остальные. Таким образом, будет легче найти то, что вы ищете.

Смотрите это изображение для демонстрации. Коммиты C2, C3, C4 и C5 на изображении висят, но все еще видны.

Zdovc
источник
2
git log --reflog

спас меня! Я потерял свою при слиянии HEAD и не смог найти свои последние коммиты! Не отображается в дереве исходников, но git log --reflogпоказывает все мои локальные коммиты до

Султанмырза Касымбеков
источник