git reflog expire и git fsck --unreachable

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

Итак, я играл с git'ом, пытаясь просрочить изменённый коммит. Мой рефлог выглядит так:

4eea1cd HEAD@{0}: commit (amend): amend commit
ff576c1 HEAD@{1}: commit: test: bar
5a1e68a HEAD@{2}: commit: test: foo
da8534a HEAD@{3}: commit (initial): initial commit

Что означает, что я сделал два коммита (da8534a и 5a1e68a), затем третий коммит ff576c1, который я изменил на 4eea1cd.

Как и ожидалось, мой git log выглядит примерно так:

* 4eea1cd (HEAD, master) amend commit
* 5a1e68a test: foo
* da8534a initial commit

Из того, что я (хотя я) знаю об истечении срока действия коммитов, когда-нибудь (скорее всего, через 30 дней по умолчанию) git gc должен собрать ff576c1. Теперь я не хочу ждать 30 дней, чтобы увидеть, как это произойдёт, поэтому я начинаю выполнять несколько команд, сначала:

git fsck --unreachable --no-reflogs

Которая, как и ожидалось, снова даёт мне:

unreachable blob 5716ca5987cbf97d6bb54920bea6adde242d87e6
unreachable tree 1e60e555e3500075d00085e4c1720030e077b6c8
unreachable commit ff576c1b4b6df57ba1c20afabd718c93dacf2fc6

Будучи уверенным в том, что я собираюсь исключить этот бедный одинокий ff576c1 коммит, я затем запускаю git reflog expire:

git reflog expire --dry-run --expire-unreachable=now --all

Что в этот раз даёт мне:

would prune commit: test: bar
would prune commit (amend): amend commit

Сначала я подумал, что мой HEAD не ссылается на master, но, как вы можете видеть в git log, который я приводил ранее, это действительно так. Кроме того, cat .git/HEAD подтверждает это (выделение ref: refs/heads/master). В любом случае, даже это было глупо, поскольку 4eea1cd - это голова моей ветки master.

И вот я здесь, сбитый с толку тем, что эти две команды не дают мне одинаковых коммитов, и задающийся вопросом, как, чёрт возьми, 4eea1cd может быть недоступным, поскольку это фактическая вершина моей ветки master.

Есть идеи, что происходит?

EDIT: Я только что заметил, что если я добавлю опцию --rewrite к git reflog expire, вот так:

git reflog expire --dry-run --expire-unreachable=now --all --rewrite

Тогда я получу только изменённый коммит:

would prune commit: test: bar

Я всё ещё не понимаю, потому что согласно git help reflog:

   --rewrite
       While expiring or deleting, adjust each reflog entry to ensure that
       the old sha1 field points to the new sha1 field of the previous
       entry.

Что не имеет смысла в моём случае. По крайней мере, я этого не понимаю, поскольку очевидно, что это что-то меняет.

18
задан Geoffrey Bachelet 7 February 2012 в 21:43
поделиться