Saya mungkin berspekulasi bahwa Git sering menggunakan atomic pembaruan file yang dilakukan seperti ini:
- Konten file dibaca ke dalam memori (dan dimodifikasi).
- Konten yang dimodifikasi ditulis ke dalam file terpisah (biasanya terletak di direktori yang sama dengan yang asli, dan memiliki file acak (
mktemp
-style) nama. - Berkas yang baru adalah
rename(2)
d -d di atas yang asli; operasi ini menjamin bahwa setiap pengamat yang mencoba membuka file menggunakan namanya akan mendapatkan konten lama atau baru.
Pembaruan tersebut terlihat oleh inotify(7)
sebagai moved_to
acara—karena file "muncul kembali" di direktori.
Untuk menjawab pertanyaan Anda secara terpisah untuk git
2.24.1 di Linux 4.19.95:
- Mengapa peristiwa ini hilang pada file ini?
Anda tidak melihat IN_MODIFY
/IN_CLOSE_WRITE
acara karena git clone
akan selalu mencoba menggunakan tautan keras untuk file di bawah .git/objects
direktori. Saat melakukan kloning melalui jaringan atau melintasi batas sistem file, peristiwa ini akan muncul lagi.
- Apa yang bisa dilakukan? Secara khusus, bagaimana saya bisa menanggapi penyelesaian penulisan ke file-file ini? Catatan:idealnya saya ingin menanggapi ketika tulisan "selesai" untuk menghindari tidak perlu/(salah) mengunggah tulisan "belum selesai".
Untuk menangkap modifikasi tautan keras, Anda harus menyiapkan penangan untuk inotify CREATE
acara yang mengikuti dan melacak tautan tersebut. Harap perhatikan bahwa CREATE
sederhana juga dapat berarti bahwa file kosong telah dibuat. Kemudian, pada IN_MODIFY
/IN_CLOSE_WRITE
ke salah satu file Anda juga harus memicu tindakan yang sama pada semua file yang ditautkan. Jelas Anda juga harus menghapus hubungan itu di DELETE
acara.
Pendekatan yang lebih sederhana dan lebih kuat mungkin adalah dengan mencirikan semua file secara berkala dan memeriksa apakah konten file telah berubah.
Koreksi
Setelah memeriksa git
kode sumber dengan cermat dan menjalankan git
dengan strace
, saya menemukan bahwa git
memang menggunakan file yang dipetakan memori, tetapi kebanyakan untuk membaca konten. Lihat penggunaan xmmap
yang selalu disebut dengan PROT_READ
hanya.. Oleh karena itu jawaban saya sebelumnya di bawah adalah TIDAK jawaban yang benar. Namun demikian untuk tujuan informasi saya masih ingin menyimpannya di sini:
-
Anda tidak melihat
IN_MODIFY
acara karenapackfile.c
menggunakanmmap
untuk akses file daninotify
tidak melaporkan modifikasi untukmmap
file ed.Dari halaman manual inotify:
API inotify tidak melaporkan akses file dan modifikasi yang mungkin terjadi karena mmap(2), msync(2), dan munmap(2).
Berdasarkan jawaban yang diterima ini, saya berasumsi mungkin ada beberapa perbedaan dalam kejadian berdasarkan protokol yang digunakan (yaitu ssh atau https).
Apakah Anda mengamati perilaku yang sama saat memantau kloning dari sistem file lokal dengan --no-hardlinks
opsi?
$ git clone [email protected]:user/repo.git
# set up watcher for new dir
$ git clone --no-hardlinks repo new-repo
Perilaku Anda yang diamati dalam menjalankan eksperimen pada host linux dan Mac mungkin menghilangkan masalah terbuka ini sebagai penyebabnya https://github.com/docker/for-mac/issues/896 tetapi menambahkan hanya untuk berjaga-jaga.