Що таке тег git, як створити теги та як замовити віддалені теги git


523

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

git checkout -b local_branch_name origin/remote_tag_name

У мене виникла помилка, як це:

error: pathspec `origin/remote_tag_name` did not match any file(s) known to git.

Я можу знайти remote_tag_name, коли використовую команду git tag.

Відповіді:


1153

Почнемо з пояснення, що таке тег у git

введіть тут опис зображення

Тег використовується для позначення та маркування певного коміксу в історії.
Зазвичай використовується для позначення точок випуску (наприклад, v1.0 і т.д.).

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

введіть тут опис зображення


Ви не зможете перевірити теги, якщо вони локально не знаходяться у вашому сховищі, тож спочатку вам доведеться розмістити fetchтеги у вашому локальному сховищі.

Спочатку переконайтеся, що тег існує локально, виконуючи дії

# --all will fetch all the remotes.
# --tags will fetch all tags as well
$ git fetch --all --tags --prune

Потім перевірте тег, запустивши

$ git checkout tags/<tag_name> -b <branch_name>

Замість originвикористання tags/префікса.


У цьому зразку у вас є 2 теги версії 1.0 та версії 1.1, ви можете перевірити їх за допомогою будь-якого з наступного:

$ git checkout A  ...
$ git checkout version 1.0  ...
$ git checkout tags/version 1.0  ...

Все вищесказане зробить те саме, оскільки тег є лише вказівником на певний коміт.

введіть тут опис зображення
походження: https://backlog.com/git-tutorial/img/post/stepup/capture_stepup4_1_1.png


Як побачити список усіх тегів?

# list all tags
$ git tag

# list all tags with given pattern ex: v-
$ git tag --list 'v-*'

Як створити теги?

Існує 2 способи створення тегу:

# lightweight tag 
$ git tag 

# annotated tag
$ git tag -a

Різниця між двома полягає в тому, що при створенні примітки з примітками ви можете додавати метадані як у git-комітеті:
ім'я, електронна пошта, дата, коментар та підпис

введіть тут опис зображення

Як видалити теги?

# delete any (local) given tag
$ git tag -d <tag name>

# Delete a tag from the server with push tags
$ git push --delete origin <tag name>

Як клонувати певний тег?

Для того, щоб схопити вміст заданого тегу, ви можете скористатися checkoutкомандою. Як пояснено вище, теги є як і будь-які інші зобов'язання, тому ми можемо використовувати, checkoutа замість того, щоб використовувати SHA-1, просто замінивши його на ім'я тега

Варіант 1:

# Update the local git repo with the latest tags from all remotes
$ git fetch --all

# checkout the specific tag
$ git checkout tags/<tag> -b <branch>

Варіант 2:

Використовуючи команду clone

Оскільки git підтримує дрібний клон , додаючи --branchкоманду clone, ми можемо використовувати ім'я тегу замість імені гілки. Git знає, як "перевести" даний SHA-1 у відповідний комітет

# Clone a specific tag name using git clone 
$ git clone <url> --branch=<tag_name>

git clone --branch =

--branch також може взяти теги та від'єднати HEAD під час виконання комісії в отриманому сховищі.


Як натиснути теги?

git push --tags

Щоб натиснути всі теги:

# Push all tags
$ git push --tags 

Використовуючи refs/tagsзамість того, щоб просто вказати <tagname>.

Чому? - Рекомендується використовувати, refs/tagsоскільки іноді теги можуть мати те саме ім’я, що і ваші гілки, а простий git push підштовхне гілку замість тегу

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

git push --follow-tags

Цей прапор --follow-tagsвисуває обидва коміти та лише теги, які є обома:

  • Помічені теги (щоб ви могли пропустити локальні / тимчасові теги побудови)
  • Доступні теги (предка) з поточної гілки (розташовані в історії)

введіть тут опис зображення

З Git 2.4 ви можете встановити його за допомогою конфігурації

$ git config --global push.followTags true

Шпаргалку: введіть тут опис зображення



3
приємно. git checkout A. що таке A? Як ви створили A?
Мед

3
@CodeWizard Хороший графік роботи! Яке програмне забезпечення ви використовували для його створення?
Джованні Ловато

4
@Honey A- це хеш- поступки
Алекс Бакланов

2
@GiovanniLovato Блок-схема є стороною. Посилання на зображення backlog.com/git-tutorial/img/post/stepup / ... , який з цієї сторінки backlog.com/git-tutorial/stepup/stepup4_1.html сайту під назвою Керівництво Git для початківців для чайників (Відставання .com).
Джордж

2
Варто зазначити, що git checkout tags/<tag_name> -b <branch_name>це вимагає -b <branch_name>. git checkout tags/<tag_name>дав мені відірвану голову. Згідно з цією статтею про відокремлену головку , ви уникаєте від'єднаної голови, тимчасово створюючи та видаляючи гілку. Це досить чужий робочий потік. Зрозуміло, що я, як користувач git, повинен звикати до створення та видалення гілок для задоволення та отримання прибутку.
icc97

194

(Ця відповідь потребувала певного часу, а відповідь codeWizard правильна за ціллю та сутністю, але не зовсім повна, тому я все-таки опублікую цю інформацію.)


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

Там є «віддалені гілки», більш правильно називають «дистанційне відстеження гілок», але варто відзначити , що це на самому справі місцеві організації. Однак немає віддалених тегів (якщо ви (пере) їх не вигадали). Є лише локальні теги, тому вам потрібно отримати тег локально, щоб ним користуватися.

Загальна форма для імен для конкретних комісій - на яку Git називає посилання - це будь-який рядок, починаючи з refs/. Рядок, який починається з refs/heads/імені гілки; рядок, що починається з refs/remotes/імені відділення віддаленого відстеження; і рядок, що починається з refs/tags/імен тегу. Назва refs/stash- посилання на скриньку (як використовується git stash; зверніть увагу на відсутність останньої косої риски).

Є деякі незвичайні імена для особливих випадків , які не починаються з refs/: HEAD, ORIG_HEAD, MERGE_HEAD, і , CHERRY_PICK_HEADзокрема , все також імена , які можуть ставитися до конкретних фіксації (хоча HEADзазвичай містить назву філії, тобто містить ). Але загалом посилання починаються з цього .ref: refs/heads/branchrefs/

Одне, що робить Git, щоб зробити це заплутаним, це те, що він дозволяє опускати refs/слово, а часто і слово після refs/. Наприклад, ви можете опустити refs/heads/або refs/tags/при посиланні на локальну гілку або тег, а насправді ви повинні пропустити refs/heads/під час перевірки місцевої гілки! Ви можете це робити, коли результат однозначний, або - як ми недавно відмітили - коли ви повинні це зробити (для ).git checkout branch

Це правда, що посилання існують не тільки у вашому власному сховищі, але і у віддалених сховищах. Однак Git надає вам доступ до посилань на віддалений репозиторій лише у дуже конкретний час: а саме під час fetchта під час pushоперацій. Ви також можете використовувати git ls-remoteабо git remote showпобачити їх, але fetchі pushє більш цікаві точки дотику.

Рефлекси

Під час fetchі pushGit використовує рядки, які викликає refspecs для передачі посилань між локальним та віддаленим сховищем. Таким чином, саме в цей час і за допомогою refspecs два сховища Git можуть синхронізуватися між собою. Коли ваші імена синхронізуються, ви можете використовувати те саме ім’я, яке використовує хтось із віддаленого пристрою. fetchХоча тут є якась особлива магія , і вона впливає як на назви гілок, так і назви тегів.

Вам слід подумати про те git fetch, щоб спрямувати свій Git на виклик (або, можливо, текстове повідомлення) іншого Git - "віддаленого" - і вести розмову з ним. На початку цієї розмови пульт перелічує всі його посилання: усе, що є, refs/heads/і все , що міститься refs/tags/, а також будь-які інші посилання на нього. Ваш Git сканує ці (і базується на звичайній перспективі вибору) перейменує їх гілки.

Давайте подивимось на нормальну характеристику віддаленого імені origin:

$ git config --get-all remote.origin.fetch
+refs/heads/*:refs/remotes/origin/*
$ 

Цей респект вказує вашому Git приймати будь-яке ім'я, яке відповідає ( refs/heads/*наприклад, кожну гілку на пульті), і змінювати його ім'я на refs/remotes/origin/*, тобто зберігати відповідна частина однаковою, змінюючи ім'я гілки ( refs/heads/) на ім'я гілки віддаленого відстеження ( refs/remotes/зокрема , refs/remotes/origin/).

Саме через цю refspec , що originгілки «S стати вашими дистанційного відстеження гілок для віддаленого origin. Назва гілки стає назвою відділення для віддаленого відстеження, при цьому ім'я віддаленого, у цьому випадку origin, включене. Знак "плюс" +в передній частині рефлексу встановлює прапор "сила", тобто ваша гілка дистанційного відстеження буде оновлена ​​відповідно до назви гілки віддаленого відділення, незалежно від того, що потрібно для того, щоб воно відповідало. (Без +оновлення філій обмежуються змінами "швидкого перемотування вперед", а оновлення тегів просто ігноруються, оскільки версія Git 1.8.2 або більше - до цього застосовуються ті самі правила швидкого перемотування.)

Теги

А як щодо тегів? Для них немає жодної перспективи - принаймні, не за замовчуванням. Ви можете встановити його, і в цьому випадку залежність від форми відображення залежить від вас; або ти можеш бігати git fetch --tags. Використання --tagsвпливає на додавання refs/tags/*:refs/tags/*до refspec, тобто воно надсилає всі теги ( але не оновлює ваш тег, якщо у вас уже є тег із цим іменем, незалежно від того, що говорить тег дистанційного керування Edit, січень 2017: станом на Git 2.10 , тестування показує, що --tagsпримусово оновлює ваші теги з тегів віддаленого пристрою, як ніби читається респект +refs/tags/*:refs/tags/*; це може бути різниця в поведінці від попередньої версії Git).

Зверніть увагу, що перейменування тут немає: якщо у віддаленому originє тег xyzzy, а ви цього не зробите, і git fetch origin "refs/tags/*:refs/tags/*"ви потрапляєте refs/tags/xyzzyдо вашого сховища (вказуючи на те саме, що і на віддаленому). Якщо ви використовуєте, +refs/tags/*:refs/tags/*то ваш тег xyzzy, якщо він у вас є, замінюється на тег з origin. Тобто, +прапор сили на refspec означає "замінити значення моєї посилання на те, яке мій Git отримує від їх Git".

Автоматичні теги під час отримання

З історичних причин 3, якщо не використовується ні --tagsопція, ні --no-tagsопція, git fetchвживаються спеціальні дії. Пам'ятайте, що ми говорили вище, що пульт починається з показу вашому локальному Git усіх його посилань, хочете, щоб ваш місцевий Git бачив їх чи ні. 4 Ваш Git приймає до уваги всі теги, які він бачить у цей момент. Потім, коли він починає завантажувати будь-які об'єкти фіксації, йому потрібно обробляти все, що відбувається, якщо одна з цих комісій має той самий ідентифікатор, що і будь-який із цих тегів, git додасть цей тег - або ті теги, якщо кілька тегів мають цей ідентифікатор - ваше сховище.

Редагувати, січень 2017: тестування показує, що поведінка в Git 2.10 зараз є: Якщо їх Git надає тег з назвою T , а у вас немає тегу з іменем T , а ідентифікатор комісії, пов’язаний з T, є родоначальником однієї з їх гілок що ваш git fetchдосліджує, ваш Git додає T у ваші теги з або без --tags. Додавання --tagsзмушує ваш Git отримати всі їх теги, а також змусити оновити.

Нижня лінія

Можливо, вам доведеться використовувати їх, git fetch --tagsщоб отримати їх теги. Якщо їхні імена тегів суперечать вашим існуючим іменам тегів, вам, можливо, доведеться (навіть залежно від версії Git) видалити (або перейменувати) деякі свої теги, а потім запустити git fetch --tags, щоб отримати їх теги. Оскільки теги, на відміну від віддалених гілок, не мають автоматичного перейменування, імена тегів повинні відповідати їхнім іменам тегів, тому у вас можуть виникнути проблеми з конфліктами.

Однак у більшості звичайних випадків простий git fetchвиконає роботу, переносячи їхні коміти та відповідні теги, і оскільки вони - хто б вони не були - позначають свої зобов’язання під час публікації цих комісій, ви будете в курсі їх тегів. Якщо ви не створите власних тегів і не змішаєте їх сховище та інші сховища (за допомогою декількох віддалених пристроїв), у вас також не буде зіткнень імен тегів, тому вам не доведеться метушитися зі видаленням або перейменуванням тегів, щоб отримати їх теги.

Коли вам потрібні кваліфіковані імена

Я вже згадував вище , що ви можете опустити refs/майже завжди, і refs/heads/та refs/tags/і так далі більшу частину часу. Але коли ти не можеш?

Повний (або майже повний в будь-якому випадку) відповідь в в gitrevisionsдокументації . Git вирішить ім'я ідентифікатора комісії за допомогою шестиступеневої послідовності, наведеної у посиланні. Цікаво, що теги переосмислюють гілки: якщо є тег xyzzyі гілка xyzzy, і вони вказують на різні коміти, то:

git rev-parse xyzzy

дасть вам ідентифікатор, на який вказує тег. Однак - і цього не вистачає gitrevisions- git checkoutвіддає перевагу іменам гілок, тому git checkout xyzzyви поставите вас на гілку, нехтуючи тегом.

У разі неоднозначності ви можете майже завжди прописати ім'я посилання, використовуючи його повне ім’я, refs/heads/xyzzyабо refs/tags/xyzzy. (Зверніть увагу , що це робить роботу з git checkout, але в можливо несподіваним чином: git checkout refs/heads/xyzzyвикликає отдельностоящую-ГОЛОВУ перевірку , а не галузева перевірки Ось чому ви просто повинні відзначити , що. git checkoutБуде використовувати коротку назву в якості імені гілки першого: ось як ти перевірити гілку, xyzzyнавіть якщо тег xyzzyіснує. Якщо ви хочете перевірити тег, можете скористатися refs/tags/xyzzy.)

Оскільки (як gitrevisionsзазначає) Git спробує , ви також можете просто написати, щоб визначити фіксований тег . (Якщо комусь вдалося написати дійсну посилання, названу на ім'я , це вирішить як . Але зазвичай повинні міститись лише різні імена .)refs/nametags/xyzzyxyzzyxyzzy$GIT_DIR$GIT_DIR/xyzzy*HEAD$GIT_DIR


1 Добре, добре, "не просто бути педантичним". :-)

2 Дехто сказав би, що "не дуже корисний", і я, як правило, погоджуюся.

3 В основному, git fetchі вся концепція віддалених та рефлексів була трохи пізнім доповненням до Git, що відбувалося за часів Git 1.5. До цього були лише окремі спеціальні випадки, і видобуток тегів був одним із них, тому він отримав грандіозне зібрання за допомогою спеціального коду.

4 Якщо це допомагає, подумайте про віддалений Git як про спалах , в сленговому значенні.


Відмінний запис. Один крихітний ніт: git fetchотримає лише теги дистанційного керування, задані --tagsаргументом.
cweekly

@cweekly: поведінка --tags, --no-tagsі по замовчуванням насправді досить складно. За замовчуванням - вводити теги, яких у вас немає, є в комісіях, які ви вводите. (Див. Редакцію січня 2017 року.) Але тут є і глюки, і сучасний Git має свої --tags / --но-теги для обробки коду ще раз переглянуто, що, ймовірно, призведе до ще більш особливих кутових випадків.
torek

1

Для того щоб перевірити тег git, слід виконати таку команду

git checkout tags/tag-name -b branch-name

наприклад, як зазначено нижче.

 git checkout tags/v1.0 -b v1.0-branch

Для отримання всіх тегів використовуйте команду

git fetch --all --tags

0

Щоб отримати конкретний код тегу, спробуйте створити нову гілку, додайте в неї код тегу. Я зробив це командою:$git checkout -b newBranchName tagName

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