10

最近、gitサーバーのセットアップ方法について読んでいて、特定のデーモンがまったく必要ないことがわかったとき(背後にファイルシステムがあるSSHサーバーだけ)、gitがファイルを管理する方法についてもっと調べ始めましたフード。

各コミットが .objects フォルダー内でどのように表現されるか、およびすべてがどのように組み合わされるかという戦略は非常に巧妙ですが、このアプローチにより実際に git が非常に単純な方法で並行性を達成できるようになることは明示的に言及されていないようです。シグナリング サーバー。

それにもかかわらず、並行性が保証されない状況があります。これは、基本的に履歴が書き換えられる場合 (強制プッシュ) です。この場合、並行性の問題を回避するためにツリーで使用されるロック戦略はありますか? このトピックに関するドキュメントは他にありますか?

(この SO answerでこのトピックについて何かが述べられていますが、非常に簡単です。)

4

2 に答える 2

12

git データ構造は、参照 (つまり、ブランチ/タグ/など) を除いて不変であり、「履歴の書き換え」はあまり正確な用語ではなく、より適切な「別の履歴の作成」です。リポジトリには、新しいオブジェクトと古いオブジェクトのすべてのオブジェクトが含まれます。さらに、オブジェクトの「プッシュ」中にローカルリポジトリで作成されたすべての変更は転送されます。次にプッシュすると、最初にすべてのオブジェクトが送信されます (オブジェクトはそのコンテンツによって定義されるため、オブジェクトは一意であり、同時実行の問題はありません)。すべてのオブジェクトが送信された後、参照が変更されます。これは小さな単一のファイルです (refs/heads/<branchName>) 40 バイトの sha1 キーでオーバーライドします。私が知っているように、ファイルのアトミックな比較と設定の変更を行います。古い ref 値を読み取り、ロック ファイルを作成し、古い値が変更されていないかどうかを確認し、新しい sha1 に置き換えて、ロックを削除します。失敗した場合、プッシュは失敗し、再試行する必要があります (楽観的ロック)。ソースコード、 update_ref 関数から詳細を把握できます。

強制プッシュの後、いくつかの「ルーズ オブジェクト」(つまり、既存の参照から参照されていないオブジェクト) が表示される可能性があるため、これらのオブジェクトは後でガベージ コレクションされます。

とても賢く、きちんとしています。

于 2013-11-13T21:09:59.933 に答える
4

ロックとして機能するために、必要に応じてさまざまなファイルが作成されます。Git は.git/index.lock、インデックスをロックするために呼び出されるファイルを作成します。競合状態を防ぐためgit index-packにファイルを作成できます。.keepもっと多くの例があるかもしれません。

于 2013-11-13T19:38:48.017 に答える