Jika Git melaporkan bahwa suatu berkas menjadi dapat dieksekusi—atau berhenti menjadi dapat dieksekusi—di Mac Anda, pertama-tama cari tahu lapisan mana yang berubah: berkas kerja, indeks staging, atau commit. Bandingkan status-status tersebut sebelum mengubah izin atau konfigurasi Git. Git mencatat berkas reguler sebagai mode 100644 (tidak dapat dieksekusi) atau 100755 (dapat dieksekusi); perubahan terisolasi di antara keduanya biasanya mengarah pada bit eksekusi, bukan perubahan isi berkas. Dokumentasi diff Git
1. Periksa apakah perubahannya sudah di-stage
Di Terminal, buka repositori dan periksa statusnya beserta kedua diff:
git status --short
git diff --summary
git diff --cached --summary
git diff membandingkan working tree dengan indeks; git diff --cached membandingkan indeks dengan HEAD. Git status membedakan lapisan-lapisan yang sama ini, sehingga perubahan yang sudah di-stage muncul terpisah dari yang belum di-stage. Dokumentasi git status
Perhatikan keluaran seperti mode change 100644 => 100755 path/to/file. Jika hanya muncul di git diff --summary, berkas kerja berbeda dengan indeks. Jika muncul di git diff --cached --summary, perubahan mode telah di-stage dan dapat di-commit. Jika keduanya kosong tetapi rekan tim melaporkan adanya perubahan yang sudah di-commit, periksalah riwayatnya berikutnya.
2. Bandingkan indeks dengan berkas di Mac
Untuk jalur yang dilacak, periksa mode yang tercatat di indeks dan izin berkas saat ini:
git ls-files --stage -- "scripts/build.sh"
ls -l "scripts/build.sh"
Ganti scripts/build.sh dengan jalur relatif repositori yang tepat; beri tanda kutip agar spasi dan karakter shell diperlakukan secara harfiah. Pada keluaran git ls-files --stage, bidang pertama adalah mode yang disimpan dalam indeks: 100644 berarti Git tidak mencatat berkas sebagai dapat dieksekusi, sedangkan 100755 berarti iya. Keluaran ls -l menampilkan bit izin lokal; huruf x dalam triplet izin menunjukkan izin eksekusi untuk kelas pengguna tersebut. Dokumentasi git ls-files dan panduan izin Apple menjelaskan kedua sudut pandang tersebut.
Perbandingan ini mempersempit penyebabnya. Jika indeks menunjukkan 100644, tetapi ls -l menampilkan izin eksekusi, perbedaannya ada pada berkas kerja (atau Git dikonfigurasi untuk mengabaikan perbedaan mode berkas). Jika indeks menunjukkan 100755, Git sudah men-stage atau meng-checkout mode eksekusi, terlepas dari apa yang Anda inginkan untuk berkas tersebut.
3. Temukan commit yang memperkenalkan mode tersebut
Jika perubahan sudah ada dalam riwayat, periksa ringkasan commit berkas terkait:
git log --summary -- "scripts/build.sh"
Format patch Git mencetak header old mode dan new mode secara terpisah ketika mode berkas berubah. Tinjau commit di mana nilai-nilai tersebut beralih, lalu bandingkan induknya dan alur kerja di sekitarnya: apakah berkas sengaja dibuat agar dapat dijalankan, apakah ada editor atau skrip yang mengubah izin, atau apakah repositori digunakan pada sistem berkas atau sistem operasi lain? Commit tersebut mengidentifikasi kapan Git mencatat perubahan; itu tidak membuktikan aplikasi atau orang mana yang menyebabkannya. Dokumentasi format diff Git
Perubahan mode di beberapa berkas yang tidak saling terkait dapat mengindikasikan operasi pengaturan izin secara luas atau transisi sistem berkas/lingkungan. Git mendokumentasikan bahwa beberapa sistem berkas gagal mempertahankan bit eksekusi, dan bahwa repositori yang dipindahkan antarlingkungan dapat mengalami perilaku mode berkas yang berbeda. Perlakukan hal ini sebagai petunjuk untuk diselidiki, bukan bukti penyebab pasti. Dokumentasi konfigurasi Git
4. Periksa pengaturan file-mode di Git
Periksa pengaturan dan dari mana asalnya:
git config --show-origin --get core.filemode
core.filemode mengontrol apakah Git mematuhi perbedaan bit eksekusi di working tree. Git menetapkannya ke true secara default jika tidak ditentukan dan mungkin menguji perilaku sistem berkas saat repositori diinisialisasi atau di-clone. Jika perintah mencetak false, Git mungkin mengabaikan perubahan bit eksekusi lokal; pengaturan tersebut tidak menjelaskan mode yang sudah tercatat dalam commit. Jika tidak mencetak apa pun, pengaturan mungkin belum disetel, dan dalam hal ini default yang didokumentasikan Git akan berlaku. Dokumentasi konfigurasi Git
Hindari menyetel opsi ini ke false hanya untuk menyembunyikan satu diff yang mengejutkan. Pertama-tama, pastikan apakah repositori berada pada sistem berkas atau penyiapan bersama yang tidak mempertahankan bit eksekusi dengan andal, dan apakah kolaborator mengandalkan pelacakan mode. Mengubah pengaturan akan mengubah cara Git menangani perbedaan mode; ini tidak memperbaiki mode yang salah tercatat dalam indeks atau commit.
5. Perbaiki hanya setelah mengidentifikasi mode yang dimaksud
Jika berkas seharusnya tidak dapat dieksekusi dan perubahannya belum di-stage, pulihkan izin lokal dengan chmod:
chmod a-x "scripts/build.sh"
git diff --summary
Jika mode yang dimaksud adalah dapat dieksekusi, gunakan chmod a+x "scripts/build.sh". Di macOS, chmod mengubah izin item yang ditentukan; pilih mode yang dimaksud berdasarkan peran berkas dan konvensi repositori, bukan hanya agar diff menghilang. Panduan izin Apple
Jika mode yang salah telah di-stage, atur izin lokal yang dimaksud, lalu stage kembali jalur tersebut dan tinjau ringkasan yang di-stage:
chmod a-x "scripts/build.sh"
git add -- "scripts/build.sh"
git diff --cached --summary
Gunakan a+x sebagai pengganti a-x jika berkas seharusnya dapat dieksekusi. Jika mode salah dalam commit yang sudah ada, commit perbaikan baru umumnya lebih jelas daripada menulis ulang riwayat bersama; lakukan koordinasi sebelum menulis ulang commit yang mungkin sudah digunakan orang lain. Dalam setiap kasus, periksa git diff dan git diff --cached setelahnya agar Anda tidak melewatkan pengeditan konten yang menyertai perubahan izin.
Sumber
Izin dan Kepemilikan BSD — Apple Developer