(チェックアウトされていない) リモートリポジトリから最後のタグを取得する方法は?
私が使用するローカルコピーでdescribe
git describe --abbrev=0 --tags
しかしdescribe
、リモートストレージでは使用できません
(チェックアウトされていない) リモートリポジトリから最後のタグを取得する方法は?
私が使用するローカルコピーでdescribe
git describe --abbrev=0 --tags
しかしdescribe
、リモートストレージでは使用できません
を使用git ls-remote
すると、リモート リポジトリから参照のリストを取得できます。
最新バージョンが何であるかを確認するには、次の出力の最後の行を見てください。
git -c 'versionsort.suffix=-' ls-remote --tags --sort='v:refname' <repository>
セマンティック バージョニングを使用するリポジトリの最新のタグ (シェル スクリプトなど)のみを出力するには、次のようにします。
git -c 'versionsort.suffix=-' \
ls-remote --exit-code --refs --sort='version:refname' --tags <repository> '*.*.*' \
| tail --lines=1 \
| cut --delimiter='/' --fields=3
フラグを持たない古いバージョンの Git --sort
(v2.18 より前)、またはサポートしていないバージョン (v2.4 より前) では、versionsort.suffix
次を使用します。
git ls-remote --refs --tags <repository> \
| cut --delimiter='/' --fields=3 \
| tr '-' '~' \
| sort --version-sort \
| tail --lines=1
フラグがsort
ない古いバージョンは、この質問の範囲外です...--version-sort
を使用--tags
すると、リストにタグ参照のみが含まれていることが確認されます。
これには、参照されたタグと参照されていないタグの両方が含まれます。つまり、一部のタグは^{}
refname の末尾にあります。(詳細については、 StackOverflow の他の場所でこの質問を参照してください。)
^{}
人間が消費する場合、これはあまり重要ではありませんが、それらの addを見たくない場合は--refs
.
を使用して参照のリストを並べ替えることができます--sort
。
sort オプションは、 と同じソート キーを使用しますgit for-each-ref
。すべての情報がローカルにあるわけではないため、すべてのオプションを使用できるわけではありません (日付関連のソート キーなど)。
参照名に基づいて、バージョンの並べ替えを使用したいと考えています。そのために、キーを使用します。と略すこともできます。version:refname
v:refname
これにより、バージョンが昇順で並べ替えられます。つまり、最新バージョンがlastになります。
リストを逆にするには、ソートキーの先頭に : を追加し-
ます--sort='-v:refname'
。
この時点で、version-sortはリリース候補 (たとえばv2.28.0-rc2
)を安定バージョンの後に配置します。
v2.12 以降、Git に特定の文字サフィックスが付いた refname を、その文字サフィックスのない参照の後にソートするように指示する構成フラグを使用できます。git -c 'versionsort.suffix=-'
常にversionsort.suffix
このように使用するには、グローバルに設定できます。
git config --global 'versionsort.suffix' '-'
v2.4 と v2.12 の間では、フラグは と呼ばれversionsort.prereleaseSuffix
ます。
古いバージョンの Git では、トリックを使用できます。ダッシュ文字-
はスペースの前に
並べ替えられますが、チルダはスペースの後~
に並べ替えられます。
したがって、ダッシュ-
を tilde~
に置き換えると、正しい順序で並べ替えられます。これは、tr '-' '~'
最後の行以外のすべての出力を実際に気にするわけではないので、末尾のみを表示します: tail --lines=1
。もちろん、リストが降順で取得される場合 ( を使用--sort='-v:refname'
)、これは次のようになりますhead --lines=1
。
ls-remote コマンドからの出力には、参照ハッシュも出力されます。
ada126bd28d66c8c8ff5966a52d63ce2c9e4d031 refs/tags/v2.28.0-rc0
実際のタグ (つまり参照名) だけを表示するには、行の最初の部分を切り取ることができます。cut --delimiter='/' --fields=3
最後に注意すべきことは、ls-remote にフィルターを指定して、フィルター パターンに一致する参照のみを表示できることです。たとえば、セマンティック バージョニングの場合、以下を使用できます'*.*.*'
。そのパターンに一致しないものは表示されません。
リポジトリが常にバージョン タグの前に を付けている場合は、v
さらに'v*.*.*'
.
もう 1 つの例は、特定のメイン バージョンの最新のタグのみを取得することです。たとえば、リポジトリのバージョン 2 のタグのみを表示するには、'v2.*'
.
必ずフィルターを引用符で囲んでください。そうしないと、その星で*
問題が発生します。
フィルタを使用する場合は、--exit-code
フラグを使用することをお勧めします。
これは、Git が0
リモート リポジトリとの通信に成功したことを示すステータス コードで常に終了するためです。
参照が見つかった場合に画面に表示されるように、人間が消費する場合はこれで問題ありません。
ただし、このコードをシェル スクリプトで使用すると、問題が発生する可能性があります。
2
リモート リポジトリに一致する参照が見つからない場合、Git にステータス コードを使用するように指示できます。これは、--exit-code
フラグを使用して行われます。
そうすれば、スクリプトは何か問題が発生したときにそれを知ることができます!
明らかに、フィルターを使用しない場合、使用--exit-code
しても意味がありません。
Git の最新のタグが何であるかを知りたいとしましょう。
次のようにします。
git ls-remote --sort='version:refname' --tags https://github.com/git/git.git
以下に示すように、すべてのタグを順番に並べた長いリストが返されます (健全性のために切り捨てられています)。
...
4c8bcdda4d6e4757caf876ddc401b5392e874e21 refs/tags/v2.28.0
ada126bd28d66c8c8ff5966a52d63ce2c9e4d031 refs/tags/v2.28.0-rc0
bd42bbe1a46c0fe486fc33e82969275e27e4dc19 refs/tags/v2.28.0-rc0^{}
49bfe36405d1631a303992cac5cc408980a0454e refs/tags/v2.28.0-rc1
3ddac3d691c3633cd4d9a74c07e3b2301f546f77 refs/tags/v2.28.0-rc1^{}
84a0d5cc2107b83a791aa4034cc54874e1d50668 refs/tags/v2.28.0-rc2
b066807397fd55553f4910ede74839e319b661fd refs/tags/v2.28.0-rc2^{}
47ae905ffb98cc4d4fd90083da6bc8dab55d9ecc refs/tags/v2.28.0^{}
これは、最新のタグが であることを示していv2.28.0
ます。
もう 1 つの例は、versionsort.suffix
グローバルに設定してから最後のタグだけを取得することです。
git config --global 'versionsort.suffix' '-'
git ls-remote --refs --sort=':refname' --tags https://github.com/git/git.git \
| tail --lines=1 | cut --delimiter='/' --fields=3
では、Git のバージョン 3 が既に存在するかどうかを見てみましょう。
$ git ls-remote --exit-code --refs --tags https://github.com/git/git.git 'v3.*'
$ echo $?
2 # nope, not yet
残念ながら、git ls-remote --tags
実際にはタグをアルファベット順にリストしています (少なくとも 1.7.2.5 では)。したがって、1.7.10、1.7.11、または 1.7.12 が最新のタグだった時点では、1.7.9 がリストの最後でした。
git ls-remote --tags git://github.com/git/git.git |grep "1\.7\."
[...]
bf68fe0313c833fa62755176f6e24988ef7cf80f refs/tags/v1.7.9.6
cb2ed324fc917db0b79d7b1f3756575ffa5f70d5 refs/tags/v1.7.9.6^{}
3996bb24c84013ec9ce9fa0980ce61f9ef97be4d refs/tags/v1.7.9.7
d0f1ea6003d97e63110fa7d50bb07f546a909b6e refs/tags/v1.7.9.7^{}
ただし、これらの結果を 'sort' にパイプして、探している結果に近づけることができます。
git ls-remote --tags git://github.com/git/git.git |grep "1\.7\."| sort -g -k3 -t.
[...]
eab05abaeb51531e11835aaa4c26564a1babebac refs/tags/v1.7.9-rc2
eac2d83247ea0a265d923518c26873bb12c33778 refs/tags/v1.7.9-rc0^{}
f59f511e26b4924b22c6966e79fe4f754bc81dc6 refs/tags/v1.7.9.2
0e2d57fd50f61e668be3180bc8f25991ea88aa8c refs/tags/v1.7.10-rc1^{}
121f71f0da1bc9a4e1e96be2c3e683191a82a354 refs/tags/v1.7.10.4^{}
26e5c5d09334d157bd04f794f16f6e338d50c752 refs/tags/v1.7.10.3^{}
[...]
cffb45719f60d6fc2cc98ead6af88a895c63c9ac refs/tags/v1.7.12.4
d8cf053dacb4f78920c112d10c7be21e4f5a5817 refs/tags/v1.7.12.2^{}
dcd07fb6262fd8bb9f531890df3986a8b719a0b5 refs/tags/v1.7.12-rc0
e15c16de396a1e1f42001b03cb885ce64eb4098e refs/tags/v1.7.12-rc2^{}
まだ正しくありませんが、より近いです。-rc と ^{} を除外し、最後のサブバージョン番号に追加の並べ替えを追加すると、おそらくほとんどのニーズに十分に近づけることができます。
git ls-remote --tags git://github.com/git/git.git |grep "1\.7\."|grep -v -|grep -v {| sort -n -t. -k3 -k4
23ed9debf17263ed6bed478a4d6d86e71342c18a refs/tags/v1.7.11.6
527b331100ddba839cc54bb31c1bcd66acc08321 refs/tags/v1.7.11.7
14d20a75e3d57a872a8c81ae90dcc4c61ddba011 refs/tags/v1.7.12
51993a414a76120fda20d56ba767fa513d9ff440 refs/tags/v1.7.12.1
04043f4d1ae42bddee67d354a2e6fd2464592a1e refs/tags/v1.7.12.2
b38da673be332933b8f3a873ce46ffea08d2ee2c refs/tags/v1.7.12.3
cffb45719f60d6fc2cc98ead6af88a895c63c9ac refs/tags/v1.7.12.4
git ls-remote --tags "#{github_repo}" | awk '{print $2}' | grep -v '{}' | awk -F"/" '{print $3}' | sort -n -t. -k1,1 -k2,2 -k3,3 | tail -n 1.chomp