Как проверить, является ли ветка curent выпуском тегов? - PullRequest
0 голосов
/ 17 апреля 2020

Я пытаюсь для автоматизации в Circleci. Для этого мне нужно проверить, является ли текущая ветка в master версией тега или нет.

git log -1 --pretty=%B | grep "Tag version release [0-9]\+\.[0-9]\+\.[0-9]_[0-9]\+\.[0-9]\+\.[0-9]\+"

Используя приведенную выше команду, я могу прочитать журнал.

Но мне нужен тег: commit sld1kf3ja5ls6kj7gi8rogaeknvaerglreun (HEAD -> master, тег: v1.2.3_0.10.101, origin / master, origin / HEAD)

1 Ответ

2 голосов
/ 17 апреля 2020

TL; DR: рассмотрите возможность использования git tag --points-at, но помните о его ограничениях.

Long

Текущая ветвь никогда не является тегом , по определению.

В Git текущая ветвь - это имя ветки, хранящееся в специальном имени HEAD. Запуск git checkout или, начиная с Git 2.23, git switch, позволяет выбрать ветку по имени и установить эту ветвь в качестве текущей. Чтобы ветвь B текущая ветвь , Git:

  • заменит текущий коммит коммитом tip ветви B при необходимости (или вообще ничего не делать, если текущая фиксация равна кончик коммита ветви B ); 1 затем
  • запишите название ветви в имя HEAD.

Так что теперь, после git checkout master или git checkout develop, текущая ветвь равна master или develop соответственно. Текущий commit является последним коммитом указанной ветви.

Если, однако, вы введете команду git checkout v1.2.3_0.10.101 - или эквивалентную команду git switch - name Вы запросили имя тега , а не имя ветви . Git не будет записывать имя тега в HEAD. Вместо этого Git преобразует имя в коммит ha sh ID. Затем Git отсоединяет HEAD , убедившись, что HEAD больше не содержит никакого имени вообще . Вместо этого Git будет:

  • заменять текущий коммит выбранным коммитом, если необходимо - как и раньше, если текущий коммит является выбранным коммитом здесь ничего не нужно; затем
  • введите raw commit ha sh ID в имя HEAD.

В результате вы больше не находитесь ни на одной ветке в все.

Мне нужно проверить, является ли текущая ветка в master версией тега или нет.

Фраза текущая ветка в master есть просто бессмысленно.

Каждый коммит имеет уникальный идентификатор ha sh (он никогда не sld1kf3j..., так как набор букв и цифр включает только 0-9 и a-f, поэтому он больше похож на badf00d или cafebabe или deadbeef, но дольше). Этот один идентификатор ha sh означает , что коммит, и никаких других коммитов, никогда.

Между тем, каждое имя содержит один идентификатор ha sh. Несколько имен могут содержать один и тот же идентификатор ha sh. Так что, если вы находитесь на ветке, потому что вы проверили один, есть коммит. Если вы извлекли тег, есть фиксация, но вы больше не в ветке.

Вы можете проверить, имеет ли текущий коммит одно или несколько имён . Вот что делает, например, украшение в git log. Но у него может быть много имен:

$ git log -1
commit <hash> (master, develop, feature, tag: v1.0, tag: beta)

Это говорит о том, что текущий коммит - это заданная га sh и что есть два тега и три имени ветви, каждое из которых выбрал бы этот коммит. Отсутствие HEAD -> здесь означает, что, хотя это текущий коммит, мы, вероятно, не выбрали его через имя ветви. (Но git checkout --detach master или git checkout --detach develop может привести к такой же ситуации, поэтому, возможно, мы использовали имя ветви и просто также использовали параметр --detach.)

Единственный действительно надежный способ убедиться, что мы достигли этого конкретного коммита с помощью какой-то конкретной команды git checkout или git switch, - это запомнить команду git checkout или git switch, которую мы выполняли. Если ваша система делает это, используйте это. Если этого не произойдет, то нет надежного способа справиться с этим. 2

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

git tag --points-at HEAD

в приведенном выше примере вытеснит два имени v1.0 и beta. Обратите внимание, что он сделал бы это, даже если бы мы попали сюда, запустив git checkout master.

Если git tag --points-at печатает нет имен, никакие теги не указывают на текущий коммит.

Чтобы узнать, содержит ли HEAD имя ветви прямо сейчас, рассмотрите возможность использования:

git symbolic-ref HEAD

, который печатает полное имя ветви, если HEAD содержит имя ветви:

$ git symbolic-ref HEAD
refs/heads/master

или выдает ошибку, если HEAD отсоединено:

$ git checkout --detach master
[messages]
$ git symbolic-ref HEAD
fatal: ref HEAD is not a symbolic ref

Примечание что --points-at было новым для git tag в Git версии 1.7.10, поэтому, если ваш Git старше этого, вам нужно будет обновить.


1 замена текущего коммита * Шаг 1166 * состоит, по сути, из

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

Выбранный коммит теперь является текущим коммитом, благодаря этому "вырвать все файлы из коммита X и вставьте все файлы из коммита Y вместо «действия». Обратите внимание, что и git checkout, и git switch стараются удалять только те файлы, которые были "аккуратно сохранены" в текущем коммите: проверка или переключение завершатся неудачно с ошибкой, если это приведет к потере данных. Разумеется, вы можете принудительно переключить коммутатор с помощью -f / --force.

2 . Если включены повторные журналы, журнал регистрации содержит большую часть необходимой вам информации. Но метод поинтов, вероятно, лучше.

...