Теги git
Все в курсе, что у git раковый UX, но даже он не перестает удивлять. Вот есть в репозитории теги:
$ git tag
v1
v2
Уже на этом этапе я обычно хочу написать tags
, ну да ладно. Вот я хочу посмотреть список коммитов, на которые эти теги указывают. Берем первый ответ из гугла:
$ git show-ref --tags
1baddd8efa7f0afac329e16876d94fa54febef4f refs/tags/v1
24105f5ffeb2c93c8dd6f8f10ce0d1701e67a1cd refs/tags/v2
Вроде все логично, однако если сравнить этот вывод с историей:
$ git log --pretty=format:"%H %s"
0c4bd3ad8d403463fbdd6dda50bfe7834ecd2634 second commit
1baddd8efa7f0afac329e16876d94fa54febef4f first commit
То видна проблема — хэши не совпадают. Тут я должен вспомнить, что в git есть два вида тегов: обычные и аннотированные, в которых есть сообщение, автор и т.п.:
$ git for-each-ref refs/tags --format="%(refname:short) %(objecttype)"
v1 commit
v2 tag
Ладно, но как получить то, что я хотел? Для одного тега проще всего запомнить git show $tag
, а вот для всего списка нужно всего лишь
$ git for-each-ref --format='%(if)%(*objectname)%(then)%(*objectname)%(else)%(objectname)%(end) %(refname:short)' refs/tags
1baddd8efa7f0afac329e16876d94fa54febef4f v1
0c4bd3ad8d403463fbdd6dda50bfe7834ecd2634 v2
24105f5ffeb2c93c8dd6f8f10ce0d1701e67a1cd v2.1 # oops!
Но даже этот метод (от мейнтейнера git, между прочим!) — неправильный, потому что аннотированные теги могут быть вложенными. Поэтому надо сделать
git tag | while read tag; do echo "$(git rev-parse $tag^{}) $tag"; done