Я случайно удалил локально аннотированный тег, который не собирался удалять. Я еще не отправил удаление тега на пульт. Я хотел бы исправить эту ошибку.
$ git tag -n999
v1.0.0 Initial release
$ git tag -d v1.0.0
Deleted tag 'v1.0.0' (was 1a2b3c4)
Я искал в Интернете и здесь, в Stack Overflow, пытаясь найти решение. Несмотря на кажущуюся простоту этого действия, мне не повезло найти решение.
Как я могу отменить удаление локального тега, вернув тег в состояние, которое было до его удаления?
К вашему сведению, я никогда не делал этого раньше, прежде чем ответить на этот вопрос.
Но погуглив ваш вопрос, я нашел эту статью:
https://dzone.com/articles/git-tip-restore-deleted-tag
Я проверил его совет, и он сработал для меня.
В итоге:
Используйте это, чтобы получить список аннотированных объектов тегов, которые были удалены:
git fsck --unreachable | grep tag
# if don't have grep because you're on windows, you can use this:
git fsck --unreachable | sls tag
Используйте это, чтобы изучить результаты предыдущей команды:
git show KEY
Используйте это, чтобы восстановить тег:
git update-ref refs/tags/NAME KEY
$ git tag -d v1.0.0 Deleted tag 'v1.0.0' (was 1a2b3c4) $
Это удалило местную ссылку refs/tags/v1.0.0
. Чтобы положить его обратно,
git tag v1.0.0 1a2b3c4
Вот почему при удалении упоминается идентификатор объекта в базе данных. Git не будет очищать объекты из БД, пока они не будут недоступны через любую ссылку в течение двух или более недель (скажем, git help config
и выполните поиск gc.*expire), в частности, чтобы он не выхватывал вещи из-под в полете операций и обычных ошибок и раздумий. Реф можно повесить на любой объект.
Аннотированный тег является объектом. Если у вас нет для него ссылочного имени, то у вас нет для него ссылочного имени. Если вы делаете, то вы делаете. git tag -d
удаляет имя ссылки. git tag
кладет обратно. Только repack и prune (и вспомогательные команды, которые их вызывают, например gc) удаляют объекты из объекта db, удаление refname абсолютно ничего не делает с объектом db.
Похоже, я исправляюсь. Если я правильно понимаю, хэш, возвращаемый при удалении, является ссылкой на объект тега. Вызов git tag
(без -a
) создает легковесный тег (то есть просто указатель), указывающий на объект тега. Поскольку это указатель на объект тега, конечный результат такой же, как при создании аннотированного тега: именованный указатель на объект тега, и, таким образом, это полноценный аннотированный тег. Это правильный анализ?
Вот и все. Вы извлекаете или создаете объекты тегов, git автоматически создает (обычные) refs/tags
ссылки для них. Вот и весь особый подход к ним.
Похоже, это хороший способ восстановить неаннотированный тег, если у вас все еще есть удаленный хэш. Однако он не восстановит аннотированный тег с сообщением и т. д.