リモートの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.
git tag コマンドを使うと remote_tag_name を見つけることができます。
タグは、履歴の中で特定のcommitをラベル付けし、マークするために使用されます。
通常、リリースポイント(v1.0など)を示すために使用されます。
タグはブランチと似ているように見えますが、タグは変更されません。
タグは履歴の中の特定のコミットを直接指し示します。
[![enter image description here][2]][2].
リポジトリにタグが入っていないとチェックアウトできないので、まずタグをローカルリポジトリにfetch
する必要があります。
**まず、タグがローカルに存在することを確認してください。
# --all will fetch all the remotes.
# --tags will fetch all tags as well
git fetch --all --tags --prune
続いて、タグをチェックアウトするために {{38265094}}を実行します。
git checkout tags/<tag_name> -b <branch_name>
originの代わりに
tags/` というプレフィックスを使います。
このサンプルでは、バージョン1.0とバージョン1.1の2つのタグがあるので、以下のいずれかでチェックアウトできます。
git checkout A ...
git checkout version 1.0 ...
git checkout tags/version 1.0 ...
タグは指定されたコミットへのポインタでしかないので、上記のすべての方法で同じことができます。
[![enter image description here][3]][3]. 発信元: 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
この2つの方法の違いは、注釈付きのタグを作成するときには、gitコミットと同じようにメタデータを追加できることです。
名前、メール、日付、コメント、署名
[![Enter image description here][4]][4].
# delete any given tag
git tag -d <tag name>
# Don't forget to remove the deleted tag form the server with push tags
特定のタグの内容を取得するには、checkout
コマンドを使用します。
上で説明したように、タグは他のコミットと同じなので、checkout
を使い、SHA-1 を使う代わりに tag_name に置き換えるだけでいいのです。
**オプション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:
git は clone コマンドに --branch
を追加することで shallow clone をサポートしているので、ブランチ名の代わりにタグ名を使うことができます。Git は、指定された SHA-1 を該当するコミットに "translate" する方法を知っています。
# Clone a specific tag name using git clone
git clone <url> --branch=<tag_name>
git clone --branch=
とします。 * --branch
はタグを取ることもでき、結果としてリポジトリにそのコミットのHEADをデタッチします。
git push --tags
すべてのタグをプッシュするには
git push --tags
注釈付きのタグと現在の履歴のチェーンタグをプッシュするには次のようにします。
git push --follow-tags
。このフラグ --follow-tags
は、コミットとタグの両方をプッシュします。
Git 2.4以降では、コンフィギュレーションで設定することができます。
git config --global push.followTags true
[2]: https://i.stack.imgur.com/Xy20U.png [3]: https://i.stack.imgur.com/X4lvg.png [4]: https://i.stack.imgur.com/EwBtF.jpg
リモートGitタグというものは存在しません。 あるのは、"tag"だけです。 私がこのことを指摘しているのは、衒学的な意味ではなく、カジュアルなGitユーザーがこのことについて非常に混乱しており、Gitのドキュメントが初心者にとってあまり役に立たないからです2。 (混乱の原因がドキュメントの不備にあるのか、ドキュメントの不備が本質的に混乱していることにあるのか、そのあたりはよくわかりません)。
リモートブランチは、正しくはリモートトラッキングブランチと呼ばれていますが、実際にはローカルエンティティであることに注意してください。 しかし、リモートタグはありません(あなたが(再)発明しない限り)。 ローカルなタグしかありませんので、使用するためにはローカルにタグを取得する必要があります。
Git が references と呼ぶ、特定のコミットに対する名前の一般的な形式は、refs/
で始まる任意の文字列です。 refs/heads/で始まる文字列はブランチを表し、
refs/remotes/で始まる文字列はリモートトラッキングブランチを表し、
refs/tags/で始まる文字列はタグを表します。 また、
refs/stashという名前は、stash への参照です (
git stashで使用されます。末尾にスラッシュが付いていないことに注意してください)。 特に、
HEAD,
ORIG_HEAD,
MERGE_HEAD,
CHERRY_PICK_HEADはすべて、特定のコミットを参照する可能性のある名前でもあります (ただし、
HEADは通常、ブランチの名前を含んでいます。つまり、<code>ref: refs/heads/*branch*</code> を含んでいます)。 しかし、一般的には、参照は
refs/で始まります。 Git では、この混乱を避けるために
refs/や
refs/の後の単語を省略することができます。 たとえば、ローカルブランチやタグを参照するときには
refs/heads/や
refs/tags/を省略することができます。実際、ローカルブランチをチェックアウトするときには
refs/heads/を省略しなければなりません。 結果が曖昧でなければいつでもそうすることができますし、先ほど説明したようにどうしてもそうしなければならないときにもそうします (<code>git checkout *branch*</code> の場合)。 確かに、参照は自分のリポジトリだけでなくリモートのリポジトリにも存在します。 しかし、Git がリモートリポジトリの参照にアクセスできるのは、非常に特定のタイミング、つまり
fetchや
pushの操作のときだけです。 git ls-remote
や git remote show
を使って参照することもできますが、より興味深いのは fetch
と push
での接触です。
fetchと
pushの間、Git は *refspecs* と呼ばれる文字列を使って、ローカルとリモートのリポジトリ間で参照を転送します。 したがって、2つのGitリポジトリがお互いに同期するのは、このようなときにrefspecsを介して行われます。 名前が同期すると、リモートの誰かが使っているのと同じ名前を使うことができるようになります。 しかし、
fetchにはいくつかの特別なマジックがあり、それはブランチ名とタグ名の両方に影響します。 git fetch
は、あなたの Git が別の Git ("remote")を呼び出して (あるいはテキストメッセージを送って) 会話をするように指示していると考えるべきでしょう。 この会話の初期段階で、リモートはすべての参照をリストアップします。refs/heads/
にあるもの、refs/tags/
にあるもの、そして自分が持っている他のすべての参照です。 Git はこれらをスキャンして、(通常の fetch refspec に基づいて) ブランチの名前を 変更 します。
ここでは、origin
という名前のリモートに対する通常の refspec を見てみましょう。
$ git config --get-all remote.origin.fetch
+refs/heads/*:refs/remotes/origin/*
$
つまり、マッチした部分はそのままで、ブランチ名 (refs/heads/
) をリモートを追跡するブランチ名 (refs/remotes/
、具体的には refs/remotes/origin/
) に変更するということです。
このrefspec*によって、origin
'のブランチが、リモートのorigin
のためのリモートトラッキングブランチになります。 ブランチ名はリモートトラッキングブランチ名となり、リモートの名前(この場合は origin
)が含まれます。 refspecの前にあるプラス記号 +
は、"force" フラグを設定します。つまり、リモートトラッキングブランチは、リモート'のブランチ名に一致させるために何をしても更新されるということです。 (+
をつけないと、ブランチの更新は "fast forward" の変更に限られ、タグの更新は Git バージョン 1.8.2 以降は単に無視されます。)
しかし、タグはどうでしょうか? 少なくともデフォルトでは、タグに対するrefspecはありません。 設定することもできますが、その場合、refspecの形式はあなた次第です。また、git fetch --tags
を実行することもできます。 --tagsを使うと、
refs/tags/:refs/tags/をrefspecに追加するような効果があります。すべてのタグを引き継ぎます(<s>しかし、すでにその名前のタグを持っている場合は、リモート'sのタグが何を言っているかにかかわらず、*あなたの*タグは更新されません*</s> Edit, Jan 2017: Git 2.10のテストでは、
--tagsは、あたかもrefspecが
+refs/tags/:refs/tags/を読んでいるかのように、強制的に自分のタグをリモート'のタグから更新することがわかりました。これは、Gitの以前のバージョンとの動作の違いかもしれません)。) リモートの
originがタグ
xyzzyを持っていて、あなたが持っていない場合に
git fetch origin "refs/tags/:refs/tags/"とすると、あなたのリポジトリに
refs/tags/xyzzyが追加されます (リモートと同じコミットを指しています)。 もし、
+refs/tags/:refs/tags/を使用すると、タグ
xyzzyがあれば、
originからのタグで *置き換えられます。 つまり、refspecの
+` force flagは、 "replace my reference's value with my Git gets from their Git" という意味になります。
歴史的な理由により、3 --tags
オプションも --no-tags
オプションも使用しない場合、git fetch
は特別な動作をします。 先ほど、リモートはローカルのGitが見たいかどうかにかかわらず、その参照をすべて表示することから始めると言いました。 そして、何かを処理するために必要なコミットオブジェクトのダウンロードを始めるときに、それらのコミットの中にこれらのタグと同じIDを持つものがあれば、gitはそのタグを、あるいは複数のタグがそのIDを持つ場合はそれらのタグをリポジトリに追加します。
Edit, Jan 2017: テストの結果、Git 2.10での動作は現在のものです。相手のGitがTという名前のタグを提供していて、あなたがTという名前のタグを持っておらず、Tに関連するコミットIDがあなたのgit fetch
が調査している相手のブランチの一つの祖先である場合、あなたのGitは、--tags
の有無にかかわらず、Tをあなたのタグに追加します。 --tags` を追加すると、Git は相手のタグをすべて取得し、さらに強制的に更新します。
タグを取得するには、git fetch --tags
を使用する必要があるかもしれません。 タグの名前が既存のタグの名前と衝突する場合は、(Git のバージョンによっては) タグを削除 (またはリネーム) してから git fetch --tags
を実行してタグを取得する必要があるかもしれません。 タグはリモートブランチと違って自動リネームができないので、自分のタグ名と相手のタグ名が一致しなければなりません。これが、コンフリクトの問題を引き起こす理由です。
通常のケースでは、単純に git fetch
を実行するだけで、相手のコミットとそれにマッチするタグを取得できます。 自分でタグを作ったり、相手のリポジトリと他のリポジトリを(複数のリモート経由で)混在させたりしなければ、タグの名前が衝突することもないので、相手のタグを取得するためにタグを削除したり名前を変更したりする必要もありません。
上で、refs/
はほとんどの場合省略でき、refs/heads/
やrefs/tags/
などもほとんどの場合省略できると述べました。 しかし、どのような場合に省略できるのでしょうか。
完全な(あるいはほぼ完全な)答えは、the gitrevisions
documentationにあります。 Git は、リンク先で示されている 6 つのステップを使って名前をコミット ID に解決します。 不思議なことに、タグはブランチを上書きします。タグ xyzzy
とブランチ xyzzy
があり、それらが異なるコミットを指している場合は
git rev-parse xyzzy
gitrevisions
に欠けている点ですが、git checkout
はブランチ名を好むので、git checkout xyzzy
はタグを無視してブランチに移動します。
曖昧な場合には、ほとんどの場合、完全な名前である refs/heads/xyzzy
や refs/tags/xyzzy
を使って ref の名前を綴ることができます。 (これは git checkout
でも動作しますが、おそらく予想外の方法で動作することに注意してください。git checkout refs/heads/xyzzyでは、ブランチチェックアウトではなく detached-HEAD チェックアウトが行われます。 これは、
git checkoutが短い名前を最初にブランチ名として使うことに注意しなければならない理由です: これは、タグ
xyzzyが存在していても、ブランチ
xyzzyをチェックアウトする方法です。 タグをチェックアウトしたければ、
refs/tags/xyzzyを使えばいいのです)。 (
gitrevisionsの注意書きにもあるように) Git は <code>refs/*name*</code> を試みるので、単純に
tags/xyzzyと書いて
xyzzyというタグのついたコミットを特定することもできます。 (ただし、誰かが
xyzzyという名前の有効なリファレンスを
$GIT_DIRに書き込んだ場合には、これは
$GIT_DIR/xyzzyとして解決されます。 しかし、通常は様々な
*HEADの名前だけが
$GIT_DIR` にあるべきなのです)。そのためには、まず、自分が何をしたいのかを明確にする必要があります。)
この点については、「非常に役に立たない」という意見もありますが、私もそう思います。
3基本的には、git fetch
と、remoteとrefspecsの概念全体は、Gitに少し遅れて追加されたもので、Git 1.5の頃に起こりました。 それ以前は、その場限りの特殊なケースがいくつかあり、タグの取得もその一つでしたので、特別なコードで定着させました。
4もし参考になればと思いますが、リモートのGitはスラング的な意味でのflasherと考えてください。