ほとんどの場合、Git は atomic を使用していると推測できます 次のように行われるファイルの更新:
<オール>mktemp
-スタイル) 名前rename(2)
です d -d 元のものの上。この操作により、その名前を使用してファイルを開こうとするすべてのオブザーバーが、古い内容または新しい内容のいずれかを取得することが保証されます。
そのような更新は inotify(7)
によって見られます moved_to
として イベント—ファイルがディレクトリに「再表示」されるため。
git
の質問に個別に回答するには Linux 4.19.95 上の 2.24.1:
- これらのイベントがこれらのファイルにないのはなぜですか?
IN_MODIFY
が表示されない /IN_CLOSE_WRITE
git clone
のためのイベント .git/objects
の下のファイルには常にハードリンクを使用しようとします ディレクトリ。ネットワークまたはファイル システムの境界を越えてクローンを作成すると、これらのイベントが再び表示されます。
- それについて何ができるでしょうか?具体的には、これらのファイルへの書き込みの完了にどのように応答できますか?注:理想的には、「未完成」の書き込みを不必要に/(誤って) アップロードすることを避けるために、書き込みが「終了」したときに応答したいと考えています。
ハードリンクの変更をキャッチするには、inotify CREATE
のハンドラを設定する必要があります これらのリンクをたどって追跡するイベント。単純な CREATE
であることに注意してください 空でないファイルが作成されたことを意味する場合もあります。次に、IN_MODIFY
で /IN_CLOSE_WRITE
すべてのリンクされたファイルでも同じアクションをトリガーする必要があるファイルのいずれかに。明らかに、DELETE
でその関係も削除する必要があります。 イベント。
よりシンプルで堅牢なアプローチは、すべてのファイルを定期的にハッシュし、ファイルの内容が変更されたかどうかを確認することです。
訂正
git
を確認した後 ソースコードを綿密に実行し、git
を実行しています strace
で 、 git
であることがわかりました メモリマップファイルを使用しますが、主にコンテンツの読み取りに使用します。 xmmap
の使い方を見る これは常に PROT_READ
で呼び出されます のみ..したがって、以下の私の以前の答えは NOT です 正解。それにもかかわらず、情報提供の目的で、ここに残しておきたいと思います:
-
IN_MODIFY
が表示されないpackfile.c
によるイベントmmap
を使用 ファイルアクセスとinotify
用mmap
の変更は報告されません ed ファイル。inotify マンページから:
<ブロック引用>inotify API は、mmap(2)、msync(2)、および munmap(2) が原因で発生する可能性のあるファイル アクセスと変更を報告しません。
この受け入れられた回答に基づいて、使用されているプロトコル (つまり、ssh または https) に基づいて、イベントにいくつかの違いがある可能性があると思います。
--no-hardlinks
を使用してローカル ファイル システムからのクローン作成を監視しているときに、同じ動作を観察しますか? オプション?
$ git clone [email protected]:user/repo.git
# set up watcher for new dir
$ git clone --no-hardlinks repo new-repo
Linux と Mac ホストの両方で実験を実行する際に観察された動作は、おそらくこの未解決の問題が原因である https://github.com/docker/for-mac/issues/896 を排除しますが、念のために追加します。