GNU/Linux >> Linux の 問題 >  >> Linux

inotify イベントの欠落 (.git ディレクトリ内)

ほとんどの場合、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 を使用 ファイルアクセスと inotifymmap の変更は報告されません 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 を排除しますが、念のために追加します。


    Linux
    1. ディレクトリサイズの計算の違いは?

    2. Linux – / net Directoryの目的は?

    3. ディレクトリへのシンボリックリンクを削除する

    1. Git でファイルのアクセス許可を保持する

    2. .tar.gz ファイルの作成時にディレクトリを除外する

    3. ディレクトリが存在すると mkdir -p が失敗する

    1. プロジェクトフォルダーなしのgit clone

    2. Docker でディレクトリとしてマウントされた単一のファイル ボリューム

    3. sys/types.h:そのようなファイルまたはディレクトリはありません