log - git diff



Листинг и удаление Git-коммитов, которые не имеют никакой ветки(оборван?) (5)

У меня есть репозиторий Git с множеством коммитов, которые не имеют никакой конкретной ветки, я могу git show их, но когда я пытаюсь перечислить ветви, которые их содержат, он ничего не сообщает.

Я думал, что это проблема оборванных коммитов / деревьев (в результате -D-ветви), поэтому я обрезал репо, но после этого я все еще вижу такое же поведение:

$ git fetch origin

$ git fsck --unreachable
$ git fsck

Нет выхода, ничего не болтается (правда?). Но фиксация существует

$ git show 793db7f272ba4bbdd1e32f14410a52a412667042
commit 793db7f272ba4bbdd1e32f14410a52a412667042
Author: ...

и он недоступен через любую ветку как

$ git branch --contains 793db7f272ba4bbdd1e32f14410a52a412667042

не дает выхода.

Что такое состояние этого обязательства? Как я могу перечислить все коммиты в аналогичном состоянии? Как я могу удалить такие коммиты?


Answer #1

Нет выхода, ничего не болтается (правда?)

Обратите внимание, что фиксации, упомянутые в вашем рефлоге, считаются доступными.

Что такое состояние этого обязательства? Как я могу перечислить все коммиты с аналогичным состоянием

Pass --no-reflogs чтобы убедить git fsck показать их вам.

Как я могу удалить такие коммиты?

Как только ваши записи в журнале будут истекли, эти объекты также будут очищены git gc .

Expiry регулируется параметрами gc.pruneexpire , gc.reflogexpire и gc.reflogexpireunreachable . Ср git help config .

По умолчанию все вполне разумно.


Answer #2

У меня была аналогичная проблема. Я запустил git branch --contains <commit> , и он не возвращал результат, как в вопросе.

Но даже после запуска

git reflog expire --expire-unreachable=now --all
git gc --prune=now

my commit все еще был доступен с помощью git show <commit> . Это было связано с тем, что один из коммитов в его отсоединенной «ветке» был помечен. Я удалил тег, снова выполнил приведенные выше команды, и я был золотым. git show <commit> return fatal: bad object <commit> - именно то, что мне нужно. Надеюсь, это помогает кому-то другому, который так же застрял, как и я.


Answer #3

Чтобы удалить все оборванные коммиты и те, которые доступны из журналов, выполните следующие действия:

git reflog expire --expire-unreachable=now --all
git gc --prune=now

Но будьте уверены, что это то, что вы хотите. Я рекомендую вам прочитать страницы руководства, но вот суть:

git gc удаляет недостижимые объекты (коммиты, деревья, капли (файлы)). Объект недоступен, если он не является частью истории какой-либо ветви. На самом деле это немного сложнее:

git gc делает некоторые другие вещи, но они здесь не актуальны и не опасны.

Недостижимые объекты, которые моложе двух недель, не удаляются, поэтому мы используем --prune=now что означает «удалить недостижимые объекты, которые были созданы до этого».

Объекты также могут быть достигнуты через reflog. В то время как филиалы записывают историю какого-либо проекта, в журналах регистрируются истории этих филиалов. Если вы измените, перезагрузите и т. Д., Коммиты будут удалены из истории филиалов, но git держит их на месте, если вы поймете, что совершили ошибку. Reflogs - это удобный способ узнать, какие деструктивные (и другие) операции выполнялись на ветке (или HEAD), что облегчает отмену деструктивной операции.

Таким образом, нам также необходимо удалить блокировки, чтобы удалить все, что недоступно из ветки. Мы делаем это, истекая - all reflogs. Снова git хранит немного комментариев для защиты пользователей, поэтому мы снова должны сказать, чтобы это не --expire-unreachable=now : --expire-unreachable=now .

Поскольку я в основном использую reflog для восстановления после деструктивных операций, я обычно использую вместо него --expire=now , что полностью блокирует reflogs.


Answer #4

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

Это то, что я сделал, чтобы сделать его по-настоящему недоступным.

git stash clear
git reflog expire --expire-unreachable=now --all
git fsck --unreachable
git gc --prune=now

Answer #5
git branch --contains 793db7f272ba4bbdd1e32f14410a52a412667042

возможно, просто нужно

git branch -a --contains 793db7f272ba4bbdd1e32f14410a52a412667042

также сообщать о филиалах от пультов





git-dangling