Отказ от ответственности: этот вопрос носит чисто информационный характер и не представляет собой реальную проблему, с которой я столкнулся. Я просто пытаюсь разобраться во всем ради этого (потому что я люблю разбираться во всем, и я знаю, что вы тоже).
Итак, я играл с 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.
Что не имеет смысла в моём случае. По крайней мере, я этого не понимаю, поскольку очевидно, что это что-то меняет.