Як отримати останню назву тегу в поточній гілці в Git?


462

Який найпростіший спосіб отримати найсвіжіший тег у Git?

git tag a HEAD
git tag b HEAD^^
git tag c HEAD^
git tag

вихід:

a
b
c

Чи слід писати сценарій, щоб отримати дату часу кожного тегу та порівняти їх?


1
останній створений тег або останній тег, упорядкований за датою здійснення? У вашій прийнятій відповіді відображається останній створений тег. Це може бути проблемою, якщо хтось вирішить змінити теги existig ...
Paebbels

Відповіді:


412

Ви можете поглянути git describe, що робить щось наближене до того, що ви просите.


194
З --abbrev=0він повинен повернути найближчий анотований тег
Якуб Narębski

13
Повертає останню тег у поточній гілці.
бритохаллоран

42
Щоб отримати останній анотований тег, який націлений лише на поточну комісію в поточній гілці , використовуйте git describe --exact-match --abbrev=0.
Нафтулі Кей

5
Ця відповідь, із коментарями, не дала мені правильної мітки. @kilianic забезпечило правильне рішення.
Герман Дж. Радтке III

19
git describe --tagsі порівняйте останній тег com на сторінці випуску github
Adriano Resende

627

Щоб отримати найновіший тег:

git describe --tags

Щоб отримати останній помічений тег:

git describe --abbrev=0

2
Так, як git describeговорить сторінка для чоловіка : --abbrev=<n> [...] An <n> of 0 will suppress long format, only showing the closest tag.
Giorgos Kylafas

22
Або простоgit describe --tags
james_womack

5
Ця відповідь (і, можливо, інші) стикається з проблемою, якщо у вас є два теги, які вказують на одну і ту ж фіксацію. Якщо теги не є анотованими тегами, я думаю, що немає можливості git відрізнити, хто з цих двох був створений раніше.
Пол Лінч

10
Це має бути прийнятою відповіддю. Дякуємо за надсилання
crmpicco

6
якщо ви хочете безпосередньо оформити останній тег:git checkout $(git describe --abbrev=0 --tags)
JohnRDOrazio,

320

Виведе тег останнього тегу комітів у всіх гілках

git describe --tags $(git rev-list --tags --max-count=1)

8
або TAG=$(git describe --tags $(git rev-list --tags --max-count=1))@ william-pursell
kilianc

20
Це найкраща відповідь. Він фактично отримує теги в усіх галузях, а не тільки в поточній гілці, як це робить нинішня "правильна" відповідь.
brittohalloran

61
За винятком питання, яке конкретно задається поточній галузі.
michaeltwofish

3
@michaeltwofish, коли я цього не знав, я зрозумів це пізніше і відповідно виправив свою відповідь. Вибач за те.
kilianc

3
Примітки: Ця команда повертає "найновіший" тег, навіть якщо цей тег знаходиться на іншій гілці.
Алан Чжилянг Фен

47

Щоб отримати найновіший тег, ви можете:

$ git для кожного ref refs / tags --sort = -taggerdate --format = '% (перейменування)' - рахунок = 1

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


2
Це майже саме те, що я шукав (останній тег у всіх галузях), але принаймні з моєю версією git (1.7.7.6) теги створюються в одному порядку для обох --sort=-authordateі для --sort=authordate.
larsks

3
Ага, тому що ти насправді хочеш --sort=-taggerdate. Для тегів, authordateі committerdateпорожні (так марні в якості ключів сортування).
larsks

8
git for-each-ref refs/tags --sort=-taggerdate --format='%(refname:short)' --count=1ще краще :)
Крістоф Еблє

5
Дійсно, забороняючи ідеально правильну відповідь, якій майже 5 років без коментарів? Це просто грубо.
Вільям Перселл

1
І --points-at=$SHAдасть вам тег для хеш-файлів.
Райан

34

Як щодо цього?

TAG=$(git describe $(git rev-list --tags --max-count=1))

Технічно не обов'язково ви отримаєте останню тег, але останню комісію, яка позначена тегами, яка може бути, а може і не бути предметом, який ви шукаєте.


Цей не отримує останню тег у поточній гілці, але для будь-яких гілок. Що чудово, адже це саме те, що мені було потрібно. Дякую, Вінсенте.
jasongregori

2
Якщо вам потрібно отримати шаблон відповідності тегів, який ви можете використовувати --tags=<pattern>в rev-list. Наприклад, отримати тег останньої версіїgit describe --tags $(git rev-list --tags='v[0-9].[0-9]*' --max-count=1)
Wirone

1
$ (git описуй - містить $ (git rev-parse HEAD))
Вайдас Зіліоніс

Дякую, це спрацювало, але, мені довелося додати --таги git describe --tags $(git rev-list --tags --max-count=1)
Gianluca Casati

25

Ви можете виконати: git describe --tags $(git rev-list --tags --max-count=1)говорили тут: Як отримати останню назву тегу?


Я почав з верхньої / прийнятої відповіді і працював своїм шляхом вниз. Це перша відповідь, яка насправді дає мені останню тег (не впевнений, чому, але звичайний старий git describe ...повертає попередній тег ?!)
Джеремі Девіс

Це єдине, що працює для мене. Спробував деякі --abbrev=0відповіді, і вони відрізали частину тегу, який я хочу.
Люк Девіс

22

"Найновіший" може мати два значення з точки зору git.

Ви можете сказати, "який тег має дату створення найсвіжіший у часі", і більшість відповідей тут на це питання. З точки зору вашого питання, ви хочете повернути тег c.

Або ви могли б означати «який тег є найближчою в історії розвитку в який - то по імені філії», як правило , в галузі ви знаходитеся, HEAD. У вашому питанні це поверне тег a.

Звичайно, вони можуть бути різними:

A->B->C->D->E->F (HEAD)
       \     \
        \     X->Y->Z (v0.2)
         P->Q (v0.1)

Уявіть, що розробник позначає тег Zяк v0.2у понеділок, а потім тег, Qяк v0.1у вівторок. v0.1є більш новітньою, але v0.2ближчою в історії розвитку до HEAD, в тому сенсі, що шлях, по якому він йде, починається в точці, ближчій до HEAD.

Я думаю, що ти зазвичай хочеш цієї другої відповіді, ближче до історії розвитку. Ви можете дізнатися це, використовуючи git log v0.2..HEADetc для кожного тегу. Це дає вам кількість комісій на HEAD з моменту закінчення шляхуv0.2 відхиленому від шляху, за яким йде HEAD.

Ось сценарій Python, який робить це шляхом повторення всіх тегів, на яких виконується ця перевірка, а потім роздруковування тегу з найменшими комісіями на HEAD, оскільки шлях тегу розходився:

https://github.com/MacPython/terryfy/blob/master/git-closest-tag

git describeробить щось трохи інше, тим, що він відслідковує назад від (наприклад) HEAD, щоб знайти перший тег, який знаходиться на шляху назад в історії від HEAD. У git термінах git describeшукає теги, які можна "дістати" від HEAD. Тому вони не знайдуть таких тегів, v0.2які знаходяться не на шляху назад від HEAD, а в шляху, який розходився звідти.



15
git log --tags --no-walk --pretty="format:%d" | sed 2q | sed 's/[()]//g' | sed s/,[^,]*$// | sed  's ......  '

ЯКЩО ВИ ПОТРІБНЕ БІЛЬШЕ, ЩО ОСТАНО ТАГ

(git описую - теги іноді дає неправильні хеші, я не знаю чому, але для мене - max-count 2 не працює)

ось як ви можете отримати список із останніми 2 іменами тегів у зворотному хронологічному порядку, відмінно працює на git 1.8.4. Для більш ранніх версій git (на зразок 1.7. *) У виводі немає рядка "tag:" - просто видаліть останній дзвінок sed

Якщо ви хочете більше двох останніх тегів - замініть цей "sed 2q" на "sed 5q" або все, що вам потрібно

Тоді ви можете легко проаналізувати кожне ім’я тегу до змінної чи так.


це дуже корисно, багато розробників намагаються автоматизувати процес випуску, відкочуючись до попереднього тегу, якщо розгортання перерветься. Дивовижні речі !!!
AkD

1
Для того, щоб продовжити: git log --tags --no-walk --pretty="format:%D" | sed -nr '5q;s;^.*(tag: )([^,]*).*;\2;p' де %Dвиключає навколишні ()символи, а seds, починаючи з 5q, залишає 4 рядки до 5, після чого виводить усі символи між 'тегом: `і першим', '. Отже ... припускаючи, що всередині тегу не використовуються коми, це працює чудово.
Cometsong

14

Що не так у всіх пропозиціях (окрім пояснення Метью Бретта , оновленого цього відповіді)?

Просто запустіть будь-яку команду, надану іншими в історії jQuery Git, коли ви знаходитесь в іншому пункті історії, і перевірте результат за допомогою візуального представлення історії тегівце зробив , тому ви бачите цю публікацію):

$ git log --graph --all --decorate --oneline --simplify-by-decoration

Сьогодні багато проектів виконують релізи (і так маркують їх) в окремій галузі від основної лінії .

Для цього є вагомі причини . Подивіться на будь-які налагоджені проекти JS / CSS. Для конвенцій користувачів вони містять файли двійкових / мінімізованих релізів у DVCS. Звичайно, як керівник проекту, ви не хочете сміття своєї історії основного розряду непотрібними бінарними краплями і виконувати фіксацію складання артефактів поза межі лінії .

Оскільки Git використовує DAG, а не лінійну історію - важко визначити метрику відстані, тому можна сказати - о, що обороти найбільш близькі до мого HEAD!

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

Що є найближчим тегом у минулому щодо розгалуження в Git?

В даний час у мене є 4 розумні визначення відстані між тегом та версією зі зменшенням корисності:

  • довжина найкоротшого шляху від HEADдо злиття бази з тегом
  • дата від злиття бази між HEADі тегів
  • кількість обертів, які доступні від HEAD, але не доступні від тегу
  • дата тегу незалежно від бази злиття

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

Сценарій , що сортувати тег в відповідно до датою від злиття бази між HEADі ключові слова:

$ git tag \
     | while read t; do \
         b=`git merge-base HEAD $t`; \
         echo `git log -n 1 $b --format=%ai` $t; \
       done | sort

Він корисний для більшості проектів.

Сценарій, який сортує теги відповідно до кількості оборотів, які доступні від HEAD, але не доступні для тегу:

$ git tag \
    | while read t; do echo `git rev-list --count $t..HEAD` $t; done \
    | sort -n

Якщо у вашій історії проекту є дивні дати на комісії (через перезаписи чи інше переписування історії або якийсь дебіл забудьте замінити батарею BIOS або інші магії, які ви робите в історії), використовуйте вище написаний скрипт.

Для останнього параметра ( дата тегу незалежно від бази злиття ), щоб отримати список тегів, відсортованих за використанням дати:

$ git log --tags --simplify-by-decoration --pretty="format:%ci %d" | sort -r

Щоб отримати відому поточну дату перегляду, використовуйте:

$ git log --max-count=1

Зауважте, що git describe --tagsце використання у власних випадках, але не для пошуку очікуваного людиною найближчого тегу в історії проекту .

ПРИМІТКА Ви можете використовувати вищезазначені рецепти на будь-якій редакції, просто замініть HEADтим, що хочете!


12

git describe --abbrev=0 --tags

Якщо ви не бачите останнього тегу, переконайтеся, що ви отримаєте походження, перш ніж запустити його:

git remote update


12
git tag -l ac* | tail -n1

Отримайте останній тег із префіксом "ac" . Наприклад, тег з ім'ям ac1.0.0, або ac1.0.5. Інші теги, названі 1.0.0, 1.1.0будуть ігноровані.

git tag -l [0-9].* | tail -n1

Отримайте останній тег, першим символом якого є 0-9. Отже, ці теги з першим символом a-zбудуть ігноровані.

Більше інформації

git tag --help # Help for `git tag`

git tag -l <pattern>

Перерахуйте теги з іменами, які відповідають заданому шаблону (або всі, якщо шаблон не вказаний). Запуск "git tag" без аргументів також містить список усіх тегів. Візерунок являє собою підстановку оболонки (тобто, зіставлену за допомогою fnmatch (3)). Можна надати кілька моделей; якщо будь-який з них відповідає, тег відображається.


tail -n <number> # display the last part of a file
tail -n1 # Display the last item 

Оновлення

З git tag --help, про sortаргумент. Він використовуватиметься lexicorgraphic orderза замовчуванням, якщо tag.sortвластивості не існує.

Сортуйте параметри за замовчуванням до значення, налаштованого для змінної tag.sort, якщо вона існує, або лексикографічного порядку в іншому випадку. Див. Git-config (1).

Після google хтось сказав, що git 2.8.0 підтримує наступний синтаксис.

git tag --sort=committerdate

це не wok для мене, останній тег 2.11.174, але це друк 2.11.99, тому що сортувати не як версію
Ali.MD

8
git tag --sort=committerdate | tail -1

Поясніть, будь ласка, як цей фрагмент коду вирішить проблему замість публікації відповіді, що стосується лише коду.
Арун Вінот

5

Наступні роботи для мене працюють у випадку, якщо вам потрібні два останні теги (наприклад, для створення журналу змін між поточним тегом і попереднім тегом). Я перевіряв його лише в ситуації, коли останній тег був HEAD.

PreviousAndCurrentGitTag=`git describe --tags \`git rev-list --tags --abbrev=0 --max-count=2\` --abbrev=0`
PreviousGitTag=`echo $PreviousAndCurrentGitTag | cut -f 2 -d ' '`
CurrentGitTag=`echo $PreviousAndCurrentGitTag | cut -f 1 -d ' '`

GitLog=`git log ${PreviousGitTag}..${CurrentGitTag} --pretty=oneline | sed "s_.\{41\}\(.*\)_; \1_"`

Це відповідає моїм потребам, але оскільки я не є майстром з git, я впевнений, що це може бути вдосконалено. Я також підозрюю, що він порушиться у випадку, якщо історія фіксації рухається вперед. Я просто ділюсь на випадок, якщо це комусь допоможе.


4

Моя перша думка - це ти можеш використовувати git rev-list HEAD, де перераховуються всі обороти у зворотному хронологічному порядку в поєднанні з git tag --contains. Коли ви знайдете реферат, де git tag --containsстворюється непорожній список, ви знайшли останні теги.


4

Якщо ви хочете знайти останній тег, який застосовано до певної гілки, ви можете спробувати наступне:

git describe --tag $(git rev-parse --verify refs/remotes/origin/"branch_name")

3

Якщо вам потрібен один вкладиш, який отримує останню назву тегу (за датою тегу) на поточній гілці :

git for-each-ref refs/tags --sort=-taggerdate --format=%(refname:short) --count=1 --points-at=HEAD

Ми використовуємо це для встановлення номера версії в налаштуваннях.

Приклад виводу:

v1.0.0

Працює і в Windows.


1
У Linux (Debian Stretch) я потрапляю-bash: syntax error near unexpected token '('
Джеремі Девіс

1
Якщо я загортаю цю частину в лапки (тобто --format="%(refname:short)") і пропускаю її, --points-at=HEADвона працює. З цим останнім комутатором він нічого не повертає, я думаю, тому що мій HEADне позначений
Джеремі Девіс

@JeremyDavis, так, я думаю, що це тому, що ваш HEADне позначений.
Маркус

2

Це стара нитка, але, здається, багато людей пропускають найпростішу, найпростішу та найправильнішу відповідь на питання ОП: щоб отримати останню тег для поточної гілки , ви використовуєте git describe HEAD. Зроблено.

Редагувати: ви також можете надати будь-яке дійсне ім'я, навіть віддалене; тобто git describe origin/masterрозповість вам останній тег, до якого можна дістатись від origin / master.


Ніщо не гарантує, що "найсвіжішим тегом" керує будь-яка гілка. Дві робочі рішення є for-each-refкоманда ( stackoverflow.com/a/5261470/515973 ) і поєднання , rev-listі describe( stackoverflow.com/a/7979255/515973 )
Жюльєн Carsique

1
Це не отримує останнього тегу для мене.
Карл Моррісон

git describe branchname --tagsпрацює для мене, щоб отримати останню тег у відділенні (git версія 2.12.2)
Rob_M

0

Щоб отримати останній тег лише на поточній імені гілки / тегу, що префіксує поточну гілку, мені довелося виконати наступне

BRANCH=`git rev-parse --abbrev-ref HEAD` && git describe --tags --abbrev=0 $BRANCH^ | grep $BRANCH

Майстер відділення:

git checkout master

BRANCH=`git rev-parse --abbrev-ref HEAD` && git describe --tags 
--abbrev=0 $BRANCH^ | grep $BRANCH

master-1448

Спеціальна галузь:

git checkout 9.4

BRANCH=`git rev-parse --abbrev-ref HEAD` && git describe --tags 
--abbrev=0 $BRANCH^ | grep $BRANCH

9.4-6

І моя остаточна потреба збільшити та отримати тег +1 для наступного тегування.

BRANCH=`git rev-parse --abbrev-ref HEAD` && git describe --tags  --abbrev=0 $BRANCH^ | grep $BRANCH | awk -F- '{print $NF}'

0

Що стосується питання,

Як отримати останню назву тегу в поточній гілці

ти хочеш

git log --first-parent --pretty=%d | grep -m1 tag:

--first-parentговорить git logне деталізувати об'єднані історії, --pretty=%dкаже показувати лише прикраси, тобто місцеві назви для будь-яких комітетів. grep -m1каже "відповідь лише одному", тож ви отримуєте лише найновіший тег.


0

якщо ваші теги можна сортувати:

git tag --merged $YOUR_BRANCH_NAME | grep "prefix/" | sort | tail -n 1

0

Тут не так вже й багато згадок про не помічені теги проти анотованих. "Опис" працює над поміченими тегами та ігнорує ненаголошені.

Це некрасиво, але запитується завдання, і воно не знайде тегів на інших гілках (а не на тій, що вказана в команді: master у прикладі нижче)

Проблема фільтрації повинна бути оптимізована (консолідована), але знову ж таки, це здається завданням.

git log  --decorate --tags master |grep '^commit'|grep 'tag:.*)$'|awk '{print $NF}'|sed 's/)$//'|head -n 1

Критика вітається, тому що я зараз збираюся використовувати це для використання :)


-2

Ще один простий спосіб отримати останню назву тегу - це за допомогою

git tag | tail -1

або

TAG=$(git tag | tail -1)

щоб зберегти його у змінній.

git tagперераховує всі доступні теги та поверне останній рядок, якщо результат.tail-1


4
Без сортування це поганий хід.
mjd2
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.