Как получить последнее имя тега в текущей ветви в Git?

какой самый простой способ получить самый последний тег в Git?

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

выход:

a
b
c

должен ли я написать сценарий, чтобы получить datetime каждого тега и сравнить их?

19 ответов


вы могли бы взглянуть на git describe, Что делает что-то близкое к тому, о чем вы просите.


чтобы получить самый последний тег:

git describe --tags

чтобы получить самые последние аннотированный tag:

git describe --abbrev=0 --tags

выведет тег последней помеченной фиксации во всех ветвях

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

чтобы получить самый последний тег, вы можете сделать:

$ git for-each-ref refs/tags --sort=-taggerdate --format='%(refname)' --count=1

конечно, вы можете изменить аргумент count или Поле сортировки по желанию. Похоже возможно, вы хотели задать немного другой вопрос, но это ответ на вопрос, как я его интерпретирую.


Как насчет этого?

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

технически, не обязательно получите последний тег, но последний фиксатор, который помечен, который может быть или не быть тем, что вы ищете.


git describe --tags

возвращает последний тег, который может видеть текущая ветвь


"самый последний" может иметь два значения с точки зрения git.

вы можете иметь в виду, "какой тег имеет дату создания последней во времени", и большинство ответов здесь для этого вопроса. Что касается вашего вопроса, Вы хотели бы вернуть tag c.

или вы можете означать "какой тег ближе всего в истории разработки к какой-либо именованной ветви", обычно ветви, на которой вы находитесь,HEAD. В вашем вопросе это вернет tag a.

эти могут быть разные конечно:

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

представьте себе разработчика tag'Ed Z as v0.2 в понедельник, а затем tag'Ed Q as v0.1 во вторник. v0.1 является более поздним, но v0.2 ближе в истории развития к голове, в том смысле, что путь, на котором он находится, начинается в точке ближе к голове.

Я думаю, что вы обычно хотите это второй ответ, ближе в истории развития. Вы можете узнать это, используя git log v0.2..HEAD etc для каждого тега. Это дает вам количество коммитов на HEAD начиная с пути, заканчивающегося на v0.2 сошел с тропы, затем голову.

вот скрипт Python, который делает это, повторяя все теги, выполняющие эту проверку, а затем распечатывая тег с наименьшим количеством коммитов на голове, так как путь тега разошелся:

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

git describe делает что-то немного другое, в том, что он отслеживает от (например) HEAD, чтобы найти первый тег, который находится на пути назад в истории из HEAD. В терминах git,git describe ищет теги, которые "достижимы" из HEAD. Поэтому он не найдет теги, такие как v0.2 которые находятся не на пути назад от головы, но путь, который расходился оттуда.


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

ЕСЛИ ВАМ НУЖНО БОЛЬШЕ, ЧЕМ ОДИН ПОСЛЕДНИЙ ТЕГ

(git describe --tags иногда дает неправильные хэши, я не знаю почему, но для меня-max-count 2 не работает)

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

Если вы хотите больше, чем 2 последние теги - изменение это "sed 2q" в "sed 5q" или все, что вам нужно

затем вы можете легко разобрать каждое имя тега на переменную или около того.


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. Итак, эти теги с первым char 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 о


git describe --abbrev=0 --tags

если вы не видите последний тег, убедитесь, что извлечение origin перед запуском этого:

git remote update


что это неправильно со всеми предложениями (за исключением Мэттью Бретт объяснение, до даты этого поста ответа)?

просто запустите любую команду, предоставленную другим в истории jQuery Git, когда вы в другой момент истории и в результате проверки с визуальное представление истории тегов (I сделал вот почему вы видите этот пост):

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

сегодня многие проекты выполняют выпуски (и так пометка)в отдельной ветке от магистрали.

здесь причина для этого. Просто посмотрите на любые хорошо зарекомендовавшие себя проекты JS/CSS. Для пользовательских соглашений они несут двоичные / минифицированные файлы выпуска в DVCS. Естественно, как сопровождающий проекта вы не хотите мусорить свою магистраль diff история с бесполезными двоичными каплями и выполнение фиксации артефактов сборки из магистрали.

потому что Git использует DAG и не линейная история - это трудно определить метрику расстояния таким образом, мы можем сказать - о, что rev наиболее близок к моему HEAD!

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

что такое ближайший тег в прошлом относительно ветвления в Git?

в настоящее время у меня есть 4 разумных определения расстояния между тегом и ревизией с уменьшением полезность:

  • длина кратчайшего пути С HEAD to объединить базы с тегом
  • дата of объединить базы между HEAD и tag
  • количество оборотов это достижимо из головы, но не достижимо из тега
  • дата тега, независимо от того,объединить базы

Я не знаю как рассчитать длина кратчайшего пути.

скрипт, который сортирует теги в соответствии с дата of объединить базы между HEAD и tag:

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

он может использоваться в большинстве проектов.

скрипт, который сортирует теги в соответствии с количество оборотов это достижимо из головы, но недоступно из тега:

$ 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 С тем, что вы хотите!


следующее работает для меня в случае, если вам нужны последние два тега (например, для создания журнала изменений между текущим тегом и предыдущим тегом). Я тестировал его только в ситуации, когда последним тегом был 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\}\(.*\)_; _"`

это соответствует моим потребностям, но поскольку я не мастер git, я уверен, что его можно улучшить. Я также подозреваю, что он сломается, если история фиксации будет двигаться вперед. Я просто делюсь на случай, если это кому-то поможет.


вы можете выполнить: git describe --tags $(git rev-list --tags --max-count=1) здесь говорили: Как получить последнее имя тега?


моя первая мысль, вы могли бы использовать git rev-list HEAD, в котором перечислены все обороты в обратном хронологическом порядке, в сочетании с git tag --contains. Когда вы найдете ref где git tag --contains создает непустой список, вы нашли самый последний тег(ы).


Если вы хотите найти последний тег, который был применен к определенной ветви, вы можете попробовать следующее:

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

Это старый поток, но, похоже, многим людям не хватает самого простого, простого и правильного ответа на вопрос OP: получить последний тег для текущая филиала, вы используете git describe HEAD. Сделанный.

Edit: вы также можете указать любое допустимое имя refname, даже remotes; т. е. git describe origin/master сообщит вам последний тег, который можно получить из origin/master.


чтобы получить последний тег только на текущем имени ветви / тега, который префиксы с текущей ветви, я должен был выполнить следующее

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

ветки master:

git checkout master

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

master-1448

ветка custom:

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}'

для вопроса, как задано,

как получить последнее имя тега в текущей ветви

вы хотите

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

--first-parent говорит git log не детализировать любые объединенные истории,--pretty=%d говорит, чтобы показать только украшения, т. е. локальные имена для любых коммитов. grep -m1 говорит "матч только один", поэтому вы получаете только самый последний тег.


если теги сортные:

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