ローカルの変更を含むスパースチェックアウトのインデックスを再生成するにはどうすればよいですか?

ローカルの変更を含むスパースチェックアウトのインデックスを再生成するにはどうすればよいですか?

私は、非常に大きなモノリシック リポジトリのサブセットを操作するために、スパース チェックアウトを備えた git を使用しています。スパース チェックアウトを使用するとパフォーマンスは良好ですが、スパース チェックアウトを使用しない場合はひどい状態になります。

時々インデックスが破損することがあります (Xcode の git 統合が通常の根本原因ですが、さまざまな方法で対処してきました)。

通常のワークツリーの場合、これは問題ありません。インデックス ファイルを削除するだけです。git resetステージングされた変更がステージングされていない状態に戻る可能性がありますが、通常、重要なものは失われません。

しかし、スパース チェックアウトの場合、git resetクリーンな状態からのスパース マニフェストは考慮されないため、ワークツリーにない完全なリポジトリ内のすべてのファイル (つまり、スパース チェックアウトで除外されたすべてのファイル) が削除されたと結論付けられ、膨大な数の「削除済み」ファイル リストが残ります。

したがって、スパース チェックアウト情報を使用してインデックスをリセットする推奨される方法 (つまり、skip-worktree フラグの設定) は、 を呼び出すことですgit read-tree -mu HEAD。ただし、これにはステージングされていない変更がないことが条件となり、それらのステージングされていない変更を保持する必要があり、インデックスがないため、コミットやステージングなどを行うことはできません (また、すべての「削除された」ファイルを考えると、git がスパース チェックアウトに含まれていないことを認識すると、それらを再度削除できるように、それらをチェックアウトするのに非常に長い時間がかかります)。

ローカルの変更を失っても構わないのであれば、代わりに を呼び出すこともできますgit read-tree -m --reset HEAD。これは機能します。しかし、目標はコミットされていない変更を保持することなので、それだけでは十分ではありません。

答え1

これまでに見つけた最善の解決策は、すべての変更を一時的な場所に移動し、 を実行してgit read-tree -mu HEADから、git が作成したすべてのファイルを削除し、元の変更で置き換えることです。

これは、gitがすべてのスパースチェックアウトファイルを再作成するのを待つことを意味しますが、少なくとも、チェックアウトしたくないリポジトリ内の他のすべてのファイル(多くのより長いです)。

関連情報