Какой самый простой способ получить самый последний тег в Git?
git tag a HEAD
git tag b HEAD^^
git tag c HEAD^
git tag
вывод:
a
b
c
Должен ли я написать скрипт, чтобы получить дату и время каждого тега и сравнить их?
Какой самый простой способ получить самый последний тег в Git?
git tag a HEAD
git tag b HEAD^^
git tag c HEAD^
git tag
вывод:
a
b
c
Должен ли я написать скрипт, чтобы получить дату и время каждого тега и сравнить их?
Ответы:
Вы могли бы взглянуть git describe
, что делает что-то близкое к тому, что вы просите.
--abbrev=0
этом должен возвращаться ближайший аннотированный тег
git describe --exact-match --abbrev=0
.
git describe --tags
и сравните последний тег на странице релиза github
Чтобы получить самый последний тег:
git describe --tags
Чтобы получить самый последний аннотированный тег:
git describe --abbrev=0
git describe
говорится на странице руководства : --abbrev=<n> [...] An <n> of 0 will suppress long format, only showing the closest tag.
git describe --tags
git checkout $(git describe --abbrev=0 --tags)
Выведет тэг последнего тегированного коммита во все ветви
git describe --tags $(git rev-list --tags --max-count=1)
TAG=$(git describe --tags $(git rev-list --tags --max-count=1))
@ william-pursell
Чтобы получить самый последний тег, вы можете сделать:
$ git for-each-ref refs / tags --sort = -taggerdate --format = '% (refname)' --count = 1
Конечно, вы можете изменить аргумент count или поле сортировки по своему усмотрению. Похоже, что вы, возможно, хотели задать немного другой вопрос, но это действительно отвечает на вопрос, как я его понимаю.
--sort=-authordate
и --sort=authordate
.
--sort=-taggerdate
. Для тегов authordate
и committerdate
пусто (так бесполезно, как ключи сортировки).
git for-each-ref refs/tags --sort=-taggerdate --format='%(refname:short)' --count=1
еще лучше :)
--points-at=$SHA
даст вам тег для хэша коммита.
Как насчет этого?
TAG=$(git describe $(git rev-list --tags --max-count=1))
Технически, это не обязательно даст вам последний тег, но последний коммит, который будет помечен, что может быть, а может и не быть тем, что вы ищете.
--tags=<pattern>
в rev-list
. Например, получить тег последней версииgit describe --tags $(git rev-list --tags='v[0-9].[0-9]*' --max-count=1)
git describe --tags $(git rev-list --tags --max-count=1)
Вы можете выполнить: git describe --tags $(git rev-list --tags --max-count=1)
говорили здесь: Как получить последнее имя тега?
git describe ...
возвращает более ранний тег ?!)
--abbrev=0
ответы, и они отрезали часть тега, который я хочу.
«Самый последний» может иметь два значения с точки зрения мерзавца.
Вы могли бы иметь в виду, «какой тег имеет самую последнюю дату создания», и большинство ответов здесь на этот вопрос. С точки зрения вашего вопроса, вы хотели бы вернуть тег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..HEAD
etc для каждого тега. Это дает вам количество коммитов на 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, а на пути, который расходится оттуда.
git describe --tags
возвращает последний тег, видимый текущей веткой
git log --tags --no-walk --pretty="format:%d" | sed 2q | sed 's/[()]//g' | sed s/,[^,]*$// | sed 's ...... '
ЕСЛИ ВАМ НУЖНО БОЛЬШЕ, ЧЕМ ОДИН ПОСЛЕДНИЙ ТЕГ
(git description --tags иногда выдает неправильные хэши, я не знаю почему, но для меня --max-count 2 не работает)
это то, как вы можете получить список с двумя последними именами тегов в обратном хронологическом порядке, отлично работает на git 1.8.4. Для более ранних версий git (например, 1.7. *) В выводе нет строки «tag:» - просто удалите последний вызов sed
Если вы хотите более 2 последних тегов - измените «sed 2q» на «sed 5q» или что вам нужно
Затем вы можете легко разобрать каждое имя тега в переменную или около того.
git log --tags --no-walk --pretty="format:%D" | sed -nr '5q;s;^.*(tag: )([^,]*).*;\2;p'
если in %D
исключает окружающие ()
символы, а sed
s, начинающийся с 5q, оставляет 4 строки перед 5, затем выводит все символы между тегом: `и первым ','. Итак ... при условии, что внутри тега не используются запятые, это работает отлично.
Что не так со всеми предложениями (кроме Мэтью Бретта объяснения , до даты публикации этого ответа)?
Просто запустите любую команду, предоставленную другим, в истории jQuery Git, когда вы находитесь в другой точке истории, и проверьте результат с помощью визуального представления истории тегов (я сделал это, поэтому вы видите этот пост):
$ git log --graph --all --decorate --oneline --simplify-by-decoration
Сегодня многие проекты выполняют релизы (и т. Д. С тегами) в отдельной ветке от основной линии. .
Есть веские причины для этого. Просто посмотрите на любые хорошо известные JS / CSS проекты. Для пользовательских соглашений они несут двоичные / минимизированные файлы выпуска в DVCS. Естественно, как сопровождающий проекта, вы не хотите очищать свою историю различий в магистрали бесполезными двоичными двоичными объектами и выполнять фиксацию артефактов сборки из магистрали. .
Поскольку Git использует DAG, а не линейную историю - трудно определить метрику расстояния, поэтому мы можем сказать - о, эта скорость самая близкая к моей HEAD
!
Я начинаю свое собственное путешествие (загляните внутрь, я не копировал причудливые доказательства в этот длинный пост):
Что является ближайшим тегом в прошлом относительно ветвления в Git?
В настоящее время у меня есть 4 разумных определения расстояния между тегом и ревизией с уменьшением полезности:
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
на то, что вы хотите!
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).
После гугла кто-то сказал, что git 2.8.0 поддерживает следующий синтаксис.
git tag --sort=committerdate
git tag --sort=committerdate | tail -1
Следующее работает для меня, если вам нужны последние два тега (например, для создания журнала изменений между текущим тегом и предыдущим тегом). Я проверял это только в ситуации, когда последний тег был 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 rev-list HEAD
, который перечисляет все обороты в обратном хронологическом порядке, в сочетании с git tag --contains
. Когда вы найдете ссылку, где git tag --contains
создается непустой список, вы нашли самые последние теги.
Если вам нужен один вкладыш, который получает последнее имя тега (по дате тега) в текущей ветви :
git for-each-ref refs/tags --sort=-taggerdate --format=%(refname:short) --count=1 --points-at=HEAD
Мы используем это, чтобы установить номер версии в настройке.
Пример вывода:
v1.0.0
Работает и на Windows тоже.
-bash: syntax error near unexpected token '('
--format="%(refname:short)"
) и пропущу --points-at=HEAD
это работает. С этим последним переключателем он ничего не возвращает, я думаю, потому что мой HEAD
не помечен?
HEAD
не помечен.
Это старая ветка, но, похоже, многим не хватает самого простого, простого и правильного ответа на вопрос OP: чтобы получить последний тег для текущей ветки , вы используете 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 )
git describe branchname --tags
у меня работает, чтобы получить последний тег на ветке (git версия 2.12.2)
Чтобы получить последний тег только для текущей ветви / имени тега, в котором используется префикс текущей ветви, мне пришлось выполнить следующее
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}'
На вопрос, как задано,
Как получить последнее имя тега в текущей ветке
ты хочешь
git log --first-parent --pretty=%d | grep -m1 tag:
--first-parent
говорит git log
не детализировать какие-либо объединенные истории, --pretty=%d
говорит показывать только декорации, т.е. локальные имена для любых коммитов. grep -m1
говорит "соответствует только один", так что вы получите только самый последний тег.
Не так много упоминаний о аннотированных тегах и аннотированных здесь. «description» работает с аннотированными тегами и игнорирует аннотированные.
Это некрасиво, но делает запрошенную работу и не найдет никаких тегов в других ветвях (а не в теге, указанном в команде: master в приведенном ниже примере)
Фильтрация должна быть оптимизирована (консолидирована), но, опять же, это похоже на работу.
git log --decorate --tags master |grep '^commit'|grep 'tag:.*)$'|awk '{print $NF}'|sed 's/)$//'|head -n 1
Критика приветствуется, так как я собираюсь сейчас использовать это :)