私はこれがうまくいくと思っていました:
git checkout remote/tag_name
しかし、そうではありません。これは:
git checkout tags/tag_name
しかし、私は多くのリモコンがあるところで奇妙なことをしていて、2つのリモコンが同じタグを持っているとどうなるか心配です。タグをチェックアウトするときにリモートを指定する方法はありますか?
これを行うには、リモートごとに1つずつ、一連のrefspecを使用します。これ以降は、これらが何であるか、どのように機能するかなどについてです。
あなたの質問は「リモートタグ」のチェックアウトについて尋ねますが、Gitはリモートタグをhaveしません。
しかし、私はたくさんのリモコンがあるところで奇妙なことをしていて、2つのリモコンが同じタグを持っているとどうなるか心配です。タグをチェックアウトするときにリモートを指定する方法はありますか?
あなたの混乱の原因を明らかにします。
ちょっと戻って、Gitが一般的な意味で持っているもの、つまり「参照」について話しましょう。アイデアを固めるために、特定のformsにはローカルブランチ名(master
、devel
、feature
など)、Origin/master
やstuff_from_bobs_computer/master
などの「リモートブランチ名」、およびタグ名が含まれます。 Gitの「スタッシュ」のようなものも参照を使用します。HEAD
さえも参照ですが、非常に特別なものであり、通常は「シンボリック」参照です。ここでのポイントは、Gitには多くの参照形式があり、最終的にはすべて同じように機能するということです。参照名は、最終的に、これらの大きなSHA-1値、676699a0e0cdfd97521f3524c763222f1c30a094
などのいずれかに解決されます。
ほとんどの参照(例外はHEAD
、ORIG_HEAD
、MERGE_HEAD
、およびこれらの行に沿った他のいくつか)は、実際にはrefs/
で始まる名前で綴られています。これらは、一種のディレクトリまたはフォルダのような構造に保持され、1 サブディレクトリあり:refs/tags/
にはタグが含まれ、2 refs/heads/
にはすべてのブランチが含まれ、refs/remotes/
にはすべてのリモートブランチが含まれます。
リモートブランチは、リモートの名前によってさらに細分化されます。refs/remotes/Origin/
には、すべてのOrigin
リモートブランチが含まれますが、refs/remotes/stuff_from_bobs_computer/
には、すべてのstuff_from_bobs_computer
リモートブランチが含まれます。多数のリモートがある場合、refs/remotes/
内に多数のサブディレクトリがあります。
あなたのタグはすべてrefs/tags/
にあると言ったばかりです。リモートのタグについてはどうですか、すべてのさまざまなリモートのすべてのタグはどうですか?繰り返しますが、gitには「リモートタグ」はありません。 Gitには「リモートブランチ」がありますが、実際にはそれらはすべてローカルにあります。これらはrefs/remotes/
見出しの下のyourリポジトリに保存されます。
Gitが「リモート」にアクセスすると、通常はgit fetch remote
を介しますが、Push
(および最初のclone
ステップも)を通じて、yourGitはリモートGitに問い合わせます3 質問:「ローカルブランチは何ですか?SHA-1の値は何ですか?」これは、実際、fetch
の仕組みです。簡単な説明として、フェッチのプロセスは、リモートGitに「ねえ、whaddayaを手に入れましたか?」また、一連の名前とSHA-1を提供します。 Gitは、同じSHA-1を持っているかどうかを確認します。もしそうなら、会話は完了です。そうでない場合、Gitは「OK、これらのSHA-1のコミットに何でも必要です」と言います。これは実際にはSHA-1の別の束であることがわかり、GitとそのGitと彼らが話し合います必要なファイルなどもすべてSHA-1で識別されます。 Gitはこれらのオブジェクトを持ち込み、新しいSHA-1をリモートの名前で、次にローカルのブランチ名でrefs/remotes/
に詰め込みます。
fetch
を使用してタグを要求すると、Gitはもう少し処理を行います。4 ブランチについてGitに質問するだけでなく、Gitはタグについても彼らに尋ねます。繰り返しますが、彼らのGitは名前とSHA-1のリストを提供するだけです。次に、Gitが必要な基礎となるオブジェクトをもたらします。次に、これが問題全体の鍵となります。それは、タグ名をrefs/tags/
.に書き込みます
したがって、リモートのOrigin
に移動してタグを要求すると、「refs/tags/pinky
とrefs/tags/brain
があります」と表示されると、参照用にrefs/tags/pinky
とrefs/tags/brain
という名前のローカルタグpinky
とbrain
が作成されます名前空間。
次に、ボブのコンピューター(上記のstuff_from_bobs_computer
という名前のリモート)に移動して、タグを要求します。彼はワーナーブラザーズアンドシスターではなく神経学に興味があり、彼のタグはrefs/tags/spinal_cord
とrefs/tags/brain
であり、2番目のタグはおそらくOrigin
のタグとは関係ありません。ええとああ!
ここで何が起こるかは少し複雑になりますが、5 しかし、要するに、これはただの悪い状況であり、可能であればおそらく避けるべきです。それを避けるための2つの簡単な(まあ...)方法があります。 1つは明らかな欠点ですが、タグを取得しないでください。そうすれば、タグの競合は発生しません。もう1つは、すべてのタグを互いに分離した状態に保つことです(おそらく、あなたのタグからも分離します)。 2番目のものはそれほど難しくないことがわかります。リモートタグを「発明」するだけです。
Gitが実際に「リモートブランチ」を実装する方法と、fetch --tags
がどのように機能するかを簡単に見てみましょう。どちらもgitが「refspecs」と呼ぶ同じ基本メカニズムを使用します。
最も単純な形式では、refspecはコロンで区切られた2つのref名のように見えます。たとえば、refs/heads/master:refs/heads/master
です。実際、refs/heads/
を省略することもできます。Gitはそれを自動的に配置します。6 場合によっては、コロンと同じ名前を省略することもできます。これは、git Push
で使用する種類です。git Push Origin branch
は、refs/heads/branch
を使用してOrigin
にプッシュし、 "their" Gitに到着したときにrefs/heads/branch
を呼び出すことを意味します。
ただし、fetch
の場合、リモートブランチを実行すると、次のようなrefspecが取得されます。
+refs/heads/*:refs/remotes/Origin/*
先頭の+
は「力」を意味し、*
sは明白なことを行います。あなたのGitは彼らと話をし、refのリストを取得します。 refs/heads/*
に一致するものは、(必要に応じてリポジトリオブジェクトとともに)持ち込みますが、その後、refs/remotes/Origin/
で始まる名前の下にyourリポジトリにそれらを貼り付け、すべての「リモートOrigin
から分岐します。7
git fetch --tags
を実行すると、gitは使用するrefspecに+refs/tags/*:refs/tags/*
を追加します。8 これにより、タグが表示され、ローカルタグに配置されます。したがって、あなたがしなければならないのは、fetch
に次のようなrefspecを与えることです:
+refs/tags/*:refs/rtags/Origin/*
突然、refs/rtags/
の下に「リモートタグ」のまったく新しい名前空間ができます(この場合はOrigin
のみ)。タグのコピーを更新しているだけなので、ここで+
force-flagを使用しても安全です。タグを強制的に移動(または削除して再作成)した場合は、コピーを強制的に移動します。また、コマンドラインで--no-tags
を指定することで取得できる--no-tags
の動作が必要な場合や必要になる場合もあります。次の段落を参照してください。
知っておくべき唯一の便利な項目は、git fetch
がGit構成ファイルから特定のリモートのデフォルトのrefspecsを取得することです。9 Git構成ファイルを調べると、fetch =
文字列を使用して、各リモートの下に+refs/heads/*:refs/remotes/remote-name/*
行が表示されます。リモートごとに好きなだけfetch =
行を追加できるため、タグを追加するために1行を追加できますが、新しく(再)発明された「リモートタグ」名前空間にそれらを配置できます。この同じセクションで--no-tags
を設定して、このリモートのtagOpt = --no-tags
をデフォルトにすることもできます。 ser200783によるこのコメント を参照してください。
名前を未加工のSHA-1に解決するすべてのGitコマンドと同様に、完全な参照名でgit checkout
を実行して、対応するSHA-1で「デタッチされたHEAD」モードにすることができます。
git checkout refs/rtag/stuff_from_bobs_computer/spinal_cord
Gitには「リモートタグ」という概念が組み込まれていないため、長い形式を詳しく説明する必要があります(詳細については gitrevisions を参照してください)。
1実際、.git/refs
内の実際のディレクトリです。ただし、参照用の「パック」フォームもあり、それは.git/packed-refs
になります。パックされたフォームは、頻繁に変更されない(またはタグで一般的な)refで時間と労力を節約するためのものです。また、参照用に「バックエンド」ストレージシステムを書き直す努力も継続されているため、ある時点でこの多くが変更される可能性があります。この変更は、WindowsおよびMacシステムに必要です。 Gitでは、ブランチ名とタグ名では大文字と小文字が区別されると考えています。シューシャイン素材にはpolish
を、ソーセージにはPolish
を使用できます。パックバージョンは大文字と小文字が区別されるため、したがって、これは機能します。しかし、ファイルに保存されたバージョンは時々しないので、そうではありません!
2ここでは、軽量タグと注釈付きタグの違いについて説明します。注釈付きタグはリポジトリ内の実際のオブジェクトですが、軽量タグはrefs/tags/
スペース内のラベルです。ただし、一般的に、各注釈付きタグには対応する軽量タグが1つあるため、この特定の使用法では同じように機能します。
3ほとんどの場合、別のGitレポジトリですが、GitからMercurial、svnなどへのアダプタがあります。 Gitリポジトリのふりをするための独自のトリックがあります。また、この説明は決定的なものではありません。操作の実際のシーケンスは、人間に理解させるためではなく、転送効率のためにコーディングされています。
4ここでは、プレーンなfetch
とclone
について、つまり--tags
を使用しないバージョンについて、少し特別な奇妙さを説明しました。バージョンwith--tags
は説明が簡単です。ここで説明したrefspecを使用してすべてのタグを提供します。少なくともGit 2.10および2.11では、--tags
も強制更新を行います。 +
forceフラグが設定されているかのように。ただし、--no-tags
を明示的に呼び出さない限り、プレーンフェッチ(およびクローン)はsomeタグをもたらします。それが行う卑劣なことは、フェッチによって入ってくるオブジェクトに対応するタグを探し、それらを(更新を強制せずに)(グローバル)タグの名前空間に追加することです。 --tags
がなければ、Gitは既存のタグを上書きしません。 --tags
を使用すると、Gitwillは、2017年初頭に実行された実際の実験ごとに、少なくともGit 2.10では既存のタグを上書きします。
5Gitの以前のバージョンは、Pushの間にタグに「ブランチ」ルールを適用しました(ただし、必ずしもフェッチする必要はありません)。 git Push
の新しいバージョンでは、forceタグのみが必要です。 --tags
からのfetchrefspecには、強制フラグが設定されていませんが、機能するように動作します。 --tags
を使用したプッシュの実験は行っていません。 git fetch
対--tags
対明示的なrefspecには、--no-tags
の動作に関係する特別な--Prune
の奇妙な点がもう1つあります。ドキュメントでは、--Prune
は明示的なコマンドラインrefs/tags/
refspecに適用されますが、暗黙的な--tags
refspecには適用されません。これを検証するための実験も行っていません。
6Gitがrefs/heads/
またはrefs/tags/
を入力するためには、Gitが意図したものをfigure outできる必要があります。ある場合とそうでない場合があります。 Gitがそれを理解できなかった場合、エラーメッセージが表示され、それを埋めて再試行できますが、スクリプトでは、より予測可能な動作を得るために、常に明示的に入力する必要があります。 git Push
を実行して既存のブランチをプッシュする場合は、ほとんどいつでもGitにそれを理解させることができます。
7コロンと2番目の名前を省くと、git fetch
でうまく機能しません。Gitに、独自の参照をまったく更新しないように指示します。これは無意味に思えますが、git fetch
alwaysが特殊ファイルFETCH_HEAD
を書き込むため、実際にはcanが役立ちます。 GitオブジェクトID(SHA-1)を特殊ファイルから取り出して、何が取得されたかを確認できます。これは、リモートトラッキングブランチが発明される前の、Gitの非常に初期のバージョンからのホールドオーバーです。
8git fetch --tags
およびgit Push --tags
が使用するrefspecは、Gitバージョン2.10で内部的にプリコンパイルされ、特別なケースコードによって処理されます。プリコンパイルされたフォームには+
フラグが設定されていません。しかし、実験により、フェッチされたタグはGit 2.10/2.11で強制的に更新されることが示されています。何年も前にGit 1.xで実験し、これらの--tags
- fetchedタグがnot強制更新されたことを思い出したので、これは変更されたと思いますが、それは単なる欠陥のあるメモリかもしれません。いずれにせよ、リモートタグを(再)発明している場合は、おそらく明示的に--tags
を使用したいnotを行うでしょう。
9実際、これがミラーの仕組みです。たとえば、fetch = +*:*
を使用すると、純粋なフェッチミラーが取得されます。フェッチプロセスでは、すべての参照を確認できます。 git ls-remote
を使用して自分で確認できます。また、--single-branch
の動作方法も同じです。クローン中に--single-branch
を使用すると、Gitの構成ファイルにはフェッチ行に1つのブランチのみがリストされます。単一ブランチから全ブランチに変換するには、通常のglob-patternエントリを含むように行を編集するだけです。
1-リモートでタグを取得します:
git fetch Origin --tags
または、別のリモート使用からタグをチェックアウトするには:
git fetch your_remote --tags
2実行してタグをチェックアウトします
git checkout tags/<tag_name>
詳細: Gitで特定のタグをダウンロード
私の場合、新しいリポジトリがリモートリポジトリに追加されたとき[私はStashを使用しています]、新しいタグはgit tag -l
の結果で利用できませんでした。
しかし、git ls-remote --tags
を使用して、新しく追加されたタグを表示できました。
次のコマンドを実行して、すべての最新のタグをローカルリポジトリに取得する必要がありました。git pull --tags
実行中git tag -l
は、新しく追加されたタグも表示するようになりました。
タグをチェックアウトするには、次を使用します。git checkout <tag_name>
注:git statusを実行し、次のようなメッセージを見つけるのは正常なことです。HEAD detached at tag_name
私の心にはいくつかの質問があります:
事は次のとおりです。
git checkout tags/fancytag
を使用してタグをチェックアウトすると、(マシン上の)現在のリポジトリで適切なタグが検索されます。
特定のリモートからタグをチェックアウトする場合は、最初にfetch
それ(特定のリモートのツリー)をチェックアウトする必要があります。