注: Git 2.1git replace
では、git リポジトリの破損したエントリを変更するときに役立つ2 つのオプションが追加されます。
オブジェクトのコンテンツをインタラクティブに編集します。の既存のコンテンツ<object>
が一時ファイルにプリティプリントされ、そのファイルに対してエディタが起動され、結果が解析されて と同じタイプの新しいオブジェクトが作成されます<object>
。次に、新しく作成されたオブジェクト
に置き換えるために、置換参照が作成されます。エディタの選択方法の詳細については、 を参照してください。<object>
git-var
そして、Jeff King ( )による2deda62 をコミットします。peff
replace
--raw
:モードを追加--edit
" " の目的の 1 つはgit replace --edit
、ユーザーが不正な形式または破損したオブジェクトを修復できるようにすることです。通常、生のバイナリ データよりもはるかに扱いやすい
" " でツリーを整形します。ls-tree
ただし、一部の形式の破損はツリー ウォーカーを壊します。その場合、きれいな印刷は失敗--edit
し、ユーザーにとって役に立たないものになります。
このパッチ--raw
では、これらのインスタンスでバイナリ データを編集できる " " オプションが導入されています。
Jeff が Git のデバッグにどのように使用されているか (この場合のように) を知っているので、このオプションが表示されてもそれほど驚くことはありません。
Git 2.27 (2020 年第 2 四半期) より前のバージョンでは、" git fsck
" はツリー オブジェクトに記録されたパスが重複せずに並べ替えられていることを保証していましたが、BLOB の後に同じ名前のツリーの前に並べ替えられたエントリが続く場合に気付きませんでした。
これは修正されました。
René Scharfe ( )によるcommit 9068cfb (2020 年 5 月 10 日)を参照してください。( 2020 年 5 月 14 日、コミット 0498840でJunio C Hamanoによってマージされました)rscharfe
gitster
fsck
: ツリー内の連続していない重複名を報告します
提案者: Brandon Williams
元のテスト者: Brandon Williams
署名者: René Scharfe
レビュー者: Luke Diamand
ツリー エントリはパス順に並べ替えられます。つまり、ディレクトリ名には暗黙的にスラッシュ ('/') が追加されます。
Git fsck は、ツリーに連続した重複が含まれているかどうかをチェックしますが、その順序により、そのうちの 1 つがディレクトリであり、もう 1 つがそうでない場合、連続していない重複も存在する可能性があります。
このようなツリーは完全にチェックアウトできません。
候補ファイル名をスタックに記録してこれらの重複を見つけ、そのスタックに対して候補ディレクトリ名をチェックして一致を見つけます。
Git 2.30 (2021 年第 1 四半期) では、同じパックファイルを作成することになった再パック操作を処理するロジックが簡素化されました。
コミット 2fcb03b (2020 年 11 月 17 日)、およびTaylor Blau ( )によるコミット 704c4a5 (2020 年 11 月 16 日)を参照してください。Jeff King ( )によるcommit 63f4d5c (2020 年 11 月 16 日)
を参照してください。( 2020 年 12 月 3 日、コミット 39d38a5でJunio C Hamanoによってマージされました)ttaylorr
peff
gitster
支援者: Jeff King
署名者: Taylor Blau
' git repack
' ( man )が既存のパックと同じ名前のパックを作成すると、既存のパックを ' old-pack-xxx.{pack,idx,...}
' に移動し、新しいパックの名前を変更します。
最終的には、' git repack
' ( man )が重要なタイミングで (新しいパックが書き込まれた後/移動された後、古いパックが削除される前に) マルチパック インデックスを書き込めるようになるとよいでしょう。このオプションが ' --write-midx
' と呼ばれる可能性があると推測すると、次の状況 (新しいオブジェクトなしでリパックが連続して発行される) が不可能になります:
$ git repack -adb
$ git repack -adb --write-midx
2 番目のリパックでは、既存のパックは同じ名前から古いものへの順序で逐語的に上書きされます。その時点で、現在の MIDX は、現在欠落しているパックを参照しているため、無効になります。そのため、MIDX が書き直された後にコードを実行する必要があります。ただし、(このパッチの前に) 新しい MIDX は、新しいパックが所定の位置に移動されるまで書き込むことができません。したがって、循環依存関係があります。
' ( man ) 'の間に MIDX を安全に書き込むためのコードが現在存在しないため、これはすべて仮説です(' ' は安全ではありません)。仮説はさておき、なぜ既存のパックの名前を変更して「old-」という接頭辞を付ける必要があるのでしょうか?git repack
GIT_TEST_MULTI_PACK_INDEX
この動作は2ad47d6までさかのぼります(「git-repack
: 既存のパックと同じパックを更新する場合は注意してください。」、2006-06-25、Git v1.4.1 --マージ)。2ad47d6は主に、新しく作成されたパックがそのインデックスとは異なる構造を持つ場合について懸念しています。これは、パック名が一連のオブジェクトのハッシュである場合に可能でした。この命名方式では、同じオブジェクト セットを格納する 2 つのパックが、デルタ選択、オブジェクトの配置、またはその両方で異なる可能性があります。これが発生した場合、そのようなパックは、新しいパックと新しいインデックスをコピーする間、瞬時に読み取ることができなくなります (つまり、コピーされた順序に応じて、インデックスまたはパックのいずれかが古くなります)。
しかし、1190a1a (" pack-objects
: name pack files after Trailer hash", 2013-12-05, Git v1.9-rc0 -- merge ) 以降、これは不可能になりました。オブジェクトのセット)、しかしそれらの内容の実際のチェックサムによって。
したがって、このold-
動作は安全に実行でき、上記の循環依存を回避できます。
循環依存を回避することに加えて、このパッチは ' git repack
' ( man )をよりシンプルにします。これは、既存のパックの名前を ' ' で始まるように名前変更する際に発生した失敗に対処する必要がないためold-
です。
このパッチは主に、「古い」プレフィックスを処理するコード パスの削除に限定されてい.idx
ます.bitmap
。例外は、pack-objects が書いたものを信頼し続けたいということです。つまり、pack-objects が既に存在するファイルと同一のファイルを作成しなかったかのように装うのではなく、pack-objects が作成したものを信頼できる情報源として尊重します。それは2つの方法をカットします:
- pack-objects が、ビットマップで既に存在するものと同一のパックを生成したが、ビットマップを生成しなかった場合、既に存在するビットマップを削除します。(この動作は t7700.14 で体系化されています)。
- pack-objects が既に存在するものと同一のパックを生成した場合、対応する
.idx
、.promisor
、およびその他のファイルの作成されたばかりのバージョンを、既存のものよりも信頼します。これにより、このファイルの最新バージョンを使用することが保証されます。これは、たとえば.idx
ファイルの形式が変更されても安全です (ファイル名には反映されません.idx
)。
既存のファイルを再利用してマルチパック インデックス ファイルを再構築するとき、既存のファイルを盲目的に信頼し、破損したデータを更新されたファイルに持ち込むことになりました。これは Git 2.33 (2021 年第 3 四半期) で修正されました。
コミット f89ecf7、コミット ec1e28e、コミット 15316a4、コミット f9221e2 (2021 年 6 月 23 日) by Taylor Blau ( ttaylorr
)を参照してください。
( 2021 年 7 月 16 日、コミット 3b57e72でJunio C Hamanoによってマージされました)gitster
midx
: 「検証」中にチェックサムの不一致を報告します
提案者: Derrick Stolee
署名者: Taylor Blau
' git multi-pack-index verify
' ( man )は、記録されたオブジェクトのオフセットが正しいことを確認するなどして、既存の MIDX 内のデータの正確性を検査します。
ただし、ファイルの末尾のチェックサムが記録するデータと一致するかどうかはチェックしません。
したがって、最後の数バイトでディスク上の破損が発生した場合 (および他のすべてのデータが正しく記録された場合) は、次のようになります。
git multi-pack-index verify
' 'からクリーンな結果を取得しますが、
- 新しい MIDX を作成するときに既存の MIDX を再利用できない (MIDX を再利用する前にチェックサムの不一致をチェックするようになったため)
verify
' ' サブコマンドを呼び出して、チェックサムの破損を認識するように教えmidx_checksum_valid()
ます。
Git 2.34 (2021 年第 4 四半期) では、" git repack
" ( man )はマルチパックの到達可能性ビットマップを生成するように教えられました。
Jeff King ( )によるコミット e861b09 (2021 年 10 月 6 日)を参照してください。commit 324efc9
( 2021 年 10 月 1 日) およびcommit 6d08b9d、commit 1d89d88、commit 5f18e31、commit a169166、commit 90f838b、commit 08944d1、commit 6fb22ca、commit 56d863e (2021 年 9 月 28 日) by Taylor Blau ( )を参照してください。( 2021 年 10 月 18 日、コミット 0b69bb0でJunio C Hamanoによってマージされました)peff
ttaylorr
gitster
署名者: Taylor Blau
再パック中にマルチパック インデックスをリポジトリに保持したい呼び出し元に新しいオプションを教えます( man ) 。git repack
--write-midx
この新しいフラグには 2 つの既存の代替手段がありますが、それらは特定のユース ケースをカバーしていません。
これらの代替手段は次のとおりです。
前者は機能しますが、再パックと新しい MIDX の書き込みの間にビットマップ カバレッジにギャップが生じます (再パックにより、既存の MIDX に含まれるパックが削除され、完全に無効になる可能性があるため)。
git repack
重要なポイントで MIDX を生成するように教えることで、この競合を排除する新しいオプションを導入します。つまり、新しいパックが作成され、所定の場所に移動された後、冗長なパックが削除される前です。
git repack
このオプションは、 '--bitmap'オプションと互換性があります (解釈が次のように変更されます:「MIDX が生成された後に、対応するビットマップを書き込む」)。
MIDX コードはこれを処理しないため、最初からゼロ パックをカバーする MIDX を生成しようとすることは避けてください。
git repack
manページに含まれるようになりました:
このオプションは、複数のパックファイルが作成された場合、MIDX を作成しない限り効果がありません (この場合、マルチパック ビットマップが作成されます)。
そして今でもmanページgit repack
に含まれています:
-m
--write-midx
git multi-pack-index
非冗長パックを含むマルチパック インデックス ( を参照) を書き込みます。