注: Git 2.12 (2017 年第 1 四半期) では、大文字と小文字を区別しないオプションでブランチをリストできるため、これを見つけやすくなります。
Nguyễn Thái Ngọc Duy ( )によるコミット 3bb16a8 (2016 年 12 月 4 日)を参照してください。( 2016 年 12 月 19 日、コミット 73e494fでJunio C Hamanoによってマージされました)pclouds
gitster
tag
、branch
、 :並べ替えとフィルタリングのためにfor-each-ref
追加します。このオプションは、ソートで大文字と小文字を区別しないようにします。これは、 という名前のブランチがあり
、それらをグループ化したい場合に便利です。
git-branch と git-tag から色付けと列のレイアウトが失われるため、外部での並べ替えはオプションではない場合があります。--ignore-case
bug-12-do-something
Bug-12-do-some-more
BUG-12-do-what
フィルタリングについても同じことが言え[bB][uU][gG]-*
ますが、必死の場合はいつでも醜いパターンを使用できるため、おそらくそれほど重要ではありません。
ただし、これでは、大文字と小文字を区別するフィルタリングと大文字と小文字を区別しない並べ替え (またはその逆) を行うことはできません。branch
とについてtag
は、問題ありません。for-each-ref
、配管として、より細かい制御が必要になる場合があります。ただし、必要な場合は
いつでも追加できます。--{filter,sort}-ignore-case
git branch --ignore-case --list
注: --ignore-case
" " (およびその仲間) の " " オプションがgit for-each-ref
正しく機能しませんでした。これは Git 2.19 (2018 年第 3 四半期) で修正されています。
コミット 639ab5e (2018 年 7 月 2 日) によるAleksandr Makarov ( deviance
)を参照してください。commit e674eb2、commit ee0f3e2 (2018 年 7 月 2 日) by Jeff King ( )
を参照してください。( 2018 年 7 月 24 日、コミット 4301330でJunio C Hamanoによってマージされました)peff
gitster
ref-filter
: バックエンド フィルタリングを避ける--ignore-case
for-each-ref
を とともに使用すると、大文字と小文字を区別しない一致が--ignore-case
期待されます。
しかし、そこにたどり着く前に、追加のフィルタリング層があります。commit cfe004a ( : limit traversal to prefix, 2017-05-22, Git v2.14.0) 以来、ref 反復を最適化できるように、ref バックエンドにプレフィックスをフィードします。match_name_as_path()
ref-filter
大文字と小文字を区別せずに一致していることをバックエンドに伝えるメカニズムはありません。また、パックされたバックエンドは、ソートされた参照のリストのバイナリ検索に依存しているため、すぐにそうなる可能性はありません。
このケースに当てはめてみましょう。追加のフィルタリングは、私たちが実行できない最適化です。のフィルタリングを介して正しい答えを提供しますmatch_name_as_path(
)。
Git 2.23 (Q3 2019) ではgit for-each-ref
、複数のパターンを持つ " " が最適化されていることに注意してください。
Taylor Blau ( )によるコミット b31e268 (2019 年 6 月 26 日)を参照してください。( 2019 年 7 月 19 日にコミット b4b8c35でJunio C Hamanoによってマージされました)ttaylorr
gitster
ref-filter.c
: 互いに素なパターン接頭辞を検索
cfe004a ( : トラバーサルをプレフィックスに制限、 2017-05-22ref-filter
、Git v2.14.0-rc0) 以降、ref-filter
コードはトラバーサルを特定のパターンのプレフィックスに制限しようとしました。
そのコードは、「for_each_ref_in」を複数回呼び出すことを意味するため、複数のパターンを処理することができませんでした。
どのパターンが重複するか注意しないと、同じ参照を複数回出力してしまいます。
たとえば、一連のパターン「refs/heads/a/*」、「refs/heads/a/b/c」、および「refs/tags/v1.0.0」を考えてみましょう。単純に実行した場合:
for_each_ref_in("refs/heads/a/*", ...);
for_each_ref_in("refs/heads/a/b/c", ...);
for_each_ref_in("refs/tags/v1.0.0", ...);
' refs/heads/a/b/c
' (およびその下のすべて) が 2 回表示されます。
代わりに、パターンを互いに素なセットに分割したいと考えています。ここでは、異なるセットのどの 2 つのパターンとも一致する参照がないことがわかっています。
上記では、これらは次のとおりです。
{'refs/heads/a/*', 'refs/heads/a/b/c'}
、 と
{'refs/tags/v1.0.0'}
これらの素集合の 1 つが与えられた場合、' for_each_ref_in
' に渡すのに適したパターンはどれですか?
1 つのアプローチは、そのばらばらなセット内のすべての要素で最も長い共通のプレフィックスを計算し、呼び出し元が不要な参照を除外できるようにすることです。
最長のプレフィックスを計算するということは、ほとんどの場合、呼び出し元が無視したいものにあまり多く一致しないことを意味します。
上記の最も長い一般的なプレフィックスは次のとおりです。
{'refs/heads/a/*', 'refs/heads/a/b/c'} -> refs/heads/a/*
{'refs/tags/v1.0.0'} -> refs/tags/v1.0.0
代わりに以下を呼び出します。
for_each_ref_in("refs/heads/a/*", ...);
for_each_ref_in("refs/tags/v1.0.0", ...);
これにより、最小限の余分なクラフトで探していた参照が提供されますが、要求した参照の複製は決してありません.
ここで実装されているのは、上記を実現するアルゴリズムで、次のように機能します。
指定されたパターンのリストを辞書順にソートします。
'prefix' を空の文字列に初期化します。ここでの目標は、上記の最長共通プレフィックスのセットの各要素を構築することです。
指定されたセット内の各パターンを考慮し、パターンの最後に到達するか、ワイルドカード文字に触れた場合に「プレフィックス」を発行します。文字列の末尾は、ワイルドカードの前にあるかのように扱われます。(たとえば、'a?b' と 'abc' が素であることを検出するための将来の作業の余地があることに注意してください)。
(3)
それ以外の場合は、現在のプレフィックス (つまり、リテラル文字列プレフィックスとしてプレフィックスを持つパターンのサブセット) に対応するリストのスライスを使用してステップを再帰します。
このアルゴリズムは ' O(kn + n log(n))
' で、' k
' はmax(len(pattern))
リスト内の各パターン、' n
' はlen(patterns)
です。
この一連の興味深いパターンを発見することで、マルチパターン ' git for-each-ref
' (およびその他の参照トラバーサル)
の実行時間を からO(N)
に短縮しますO(n log(N))
。ここで、' N
' はパックされた参照の総数です。
'refs/tags/huge-N' に 10,000,000 の参照があるリポジトリで 'git for-each-ref refs/tags/a refs/tags/b' を実行すると、私のベスト 5 回は以下からドロップします:
real 0m5.805s
user 0m5.188s
sys 0m0.468s
に:
real 0m0.001s
user 0m0.000s
sys 0m0.000s
linux.git
では、最新のタグのうち 2 つを掘り出す時間が0.002-rc
秒から 0.001 秒に短縮されるため、タグの少ないリポジトリでの変化はあまり目立ちません。
" git branch
" およびその他の " for-each-ref
" バリアントは--sort=<key>
、優先順位の高い順に複数のオプションを受け入れましたが、" --ignore-case
" ハンドリングと参照名とのタイブレークに関していくつかの破損があり、Git 2.27 (2020 年第 2 四半期) で修正されました。
commit 7c5045f、commit 76f9e56 (2020 年 5 月 3 日) by Jeff King ( peff
)を参照してください。
( 2020 年 5 月 8 日、コミット 6de1630でJunio C Hamanoによってマージされました)gitster
ref-filter
:すべてのソート キー--ignore-case
に適用
署名者: Jeff King
すべてのref-filter
ユーザー ( for-each-ref
、branch
、およびtag
) は、--ignore-case
フィルタリングと並べ替えで大文字と小文字を区別しないオプションを使用します。
ref_sorting
ただし、このオプションはlistの最初の要素にのみ適用されました。
そう:
git for-each-ref --ignore-case --sort=refname
あなたが期待することをしますが、:
git for-each-ref --ignore-case --sort=refname --sort=taggername
主キー (taggername) は大文字と小文字を区別せずに並べ替えますが、refname は大文字と小文字を区別して並べ替えます。ここには 2 つのオプションがあります。
ここでは最初のものを使用しました。後でユーザーがキーごとにフラグを設定できるようにしたい場合に柔軟性が増すためです (おそらく、キーを定義するときに何らかの特別な構文を使用します。今のところ、すべてかゼロか--ignore-case
です)。
新しいテストでは、タグ付け者と件名の両方で大文字と小文字を区別せずに並べ替えることでこれをカバーします。これにより、" a
" と " " は同じように比較されますが、" " と " " のA
前に並べ替えられます。
安定した出力を得るために refname でソートすることで同点を解消します (これは実際には自動的に行われるはずですが、次のコミットで修正される別のバグがあります)。b
B