5

私はリモートブランチをフェッチしていて、ある種のループに陥っています。

私は一度フェッチして取得します:

$ git fetch
* [new branch]      minorRelease/something-> origin/minorRelease/something

そして、もう一度フェッチして取得します:

$ git fetch
* [new branch]      minorRelease/Something-> origin/minorRelease/Something

同じ支店ですが、首都がありSます。

次のフォルダからファイルを削除しようとし.git/refs/remotes/origin/minorReleaseましたが、再度フェッチすると、両方を取得して上記のループに戻ります。

$ git fetch
* [new branch]      minorRelease/Something-> origin/minorRelease/Something
* [new branch]      minorRelease/something-> origin/minorRelease/something
4

2 に答える 2

8

@torekLinuxとの違いが原因だというのは正しいですWindowsLinux大文字と小文字が区別されますが、そうでWindowsはありません。ls-remoteサーバー内のブランチを表示するために使用できます。

git ls-remote --heads origin

そして、あなたの場合、出力には大文字と小文字のみがS異なる2つのブランチが含まれている必要があると思います。

ref/heads/minorRelease/Something
ref/heads/minorRelease/something

それらのいずれかが実際に複製されていることがわかった場合は、リモート ブランチを削除できます。そして、fetchもう一度やり直してください。今は大丈夫なはずです。

git push origin :minorRelease/Something
git fetch
于 2014-09-29T05:56:13.403 に答える
2

注: Git 2.12 (2017 年第 1 四半期) では、大文字と小文字を区別しないオプションでブランチをリストできるため、これを見つけやすくなります。

Nguyễn Thái Ngọc Duy ( )によるコミット 3bb16a8 (2016 年 12 月 4 日)を参照してください。( 2016 年 12 月 19 日コミット 73e494fJunio C Hamanoによってマージされました)pclouds
gitster

tagbranch、 :並べ替えとフィルタリングのためにfor-each-ref追加します。このオプションは、ソートで大文字と小文字を区別しないようにします。これは、 という名前のブランチがあり それらをグループ化したい場合に便利です。 git-branch と git-tag から色付けと列のレイアウトが失われるため、外部での並べ替えはオプションではない場合があります。--ignore-case
bug-12-do-somethingBug-12-do-some-moreBUG-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 e674eb2commit ee0f3e2 (2018 年 7 月 2 日) by Jeff King ( )
を参照してください。( 2018 年 7 月 24 日コミット 4301330Junio 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 日コミット b4b8c35Junio 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", ...);

これにより、最小限の余分なクラフトで探していた参照が提供されますが、要求した参照の複製は決してありません.

ここで実装されているのは、上記を実現するアルゴリズムで、次のように機能します。

  1. 指定されたパターンのリストを辞書順にソートします。

  2. 'prefix' を空の文字列に初期化します。ここでの目標は、上記の最長共通プレフィックスのセットの各要素を構築することです。

  3. 指定されたセット内の各パターンを考慮し、パターンの最後に到達するか、ワイルドカード文字に触れた場合に「プレフィックス」を発行します。文字列の末尾は、ワイルドカードの前にあるかのように扱われます。(たとえば、'a?b' と 'abc' が素であることを検出するための将来の作業の余地があることに注意してください)。

  4. (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 7c5045fcommit 76f9e56 (2020 年 5 月 3 日) by Jeff King ( peff)を参照してください。
( 2020 年 5 月 8 日、コミット 6de1630Junio C Hamanoによってマージされました)gitster

ref-filter:すべてのソート キー--ignore-caseに適用

署名者: Jeff King

すべてのref-filterユーザー ( for-each-refbranch、および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 を設定するよう呼び出し元に教える

  • ref_sorting リストを、並べ替えキーのリストとすべてのキーに適用されるオプションの両方を含む構造体に置き換えます

ここでは最初のものを使用しました。後でユーザーがキーごとにフラグを設定できるようにしたい場合に柔軟性が増すためです (おそらく、キーを定義するときに何らかの特別な構文を使用します。今のところ、すべてかゼロか--ignore-caseです)。

新しいテストでは、タグ付け者と件名の両方で大文字と小文字を区別せずに並べ替えることでこれをカバーします。これにより、" a" と " " は同じように比較されますが、" " と " " のA前に並べ替えられます。 安定した出力を得るために refname でソートすることで同点を解消します (これは実際には自動的に行われるはずですが、次のコミットで修正される別のバグがあります)。bB

于 2016-12-23T20:30:43.757 に答える