Jawaban yang diterima tidak "membuat Git " lupa " tentang file ..." (secara historis). Itu hanya membuat git diabaikan file di masa sekarang / masa depan.
Metode ini membuat git benar-benar lupa file yang diabaikan ( dulu / sekarang / masa depan), tetapi tidak menghapus apa pun dari direktori kerja (bahkan ketika ditarik kembali dari jarak jauh).
Metode ini membutuhkan penggunaan /.git/info/exclude
(lebih disukai) ATAU yang sudah ada .gitignore
di semua komit yang memiliki file untuk diabaikan / dilupakan. 1
Semua metode penegakan git mengabaikan perilaku setelah-fakta-secara efektif menulis ulang sejarah dan dengan demikian memiliki konsekuensi yang signifikan untuk setiap repositori publik / bersama / kolaboratif yang mungkin ditarik setelah proses ini. 2
Saran umum: mulai dengan repo bersih - semua yang dilakukan, tidak ada yang tertunda di direktori atau indeks kerja, dan buat cadangan !
Juga, komentar / riwayat revisi dari jawaban ini ( dan riwayat revisi dari pertanyaan ini ) mungkin berguna / mencerahkan.
#commit up-to-date .gitignore (if not already existing)
#this command must be run on each branch
git add .gitignore
git commit -m "Create .gitignore"
#apply standard git ignore behavior only to current index, not working directory (--cached)
#if this command returns nothing, ensure /.git/info/exclude AND/OR .gitignore exist
#this command must be run on each branch
git ls-files -z --ignored --exclude-standard | xargs -0 git rm --cached
#Commit to prevent working directory data loss!
#this commit will be automatically deleted by the --prune-empty flag in the following command
#this command must be run on each branch
git commit -m "ignored index"
#Apply standard git ignore behavior RETROACTIVELY to all commits from all branches (--all)
#This step WILL delete ignored files from working directory UNLESS they have been dereferenced from the index by the commit above
#This step will also delete any "empty" commits. If deliberate "empty" commits should be kept, remove --prune-empty and instead run git reset HEAD^ immediately after this command
git filter-branch --tree-filter 'git ls-files -z --ignored --exclude-standard | xargs -0 git rm -f --ignore-unmatch' --prune-empty --tag-name-filter cat -- --all
#List all still-existing files that are now ignored properly
#if this command returns nothing, it's time to restore from backup and start over
#this command must be run on each branch
git ls-files --other --ignored --exclude-standard
Terakhir, ikuti panduan GitHub lainnya ini (mulai dari langkah 6) yang mencakup peringatan / informasi penting tentang perintah di bawah ini .
git push origin --force --all
git push origin --force --tags
git for-each-ref --format="delete %(refname)" refs/original | git update-ref --stdin
git reflog expire --expire=now --all
git gc --prune=now
Pengembang lain yang menarik dari repo jarak jauh yang dimodifikasi sekarang harus membuat cadangan lalu:
#fetch modified remote
git fetch --all
#"Pull" changes WITHOUT deleting newly-ignored files from working directory
#This will overwrite local tracked files with remote - ensure any local modifications are backed-up/stashed
git reset FETCH_HEAD
Catatan kaki
1 Karena /.git/info/exclude
dapat diterapkan pada semua commit historis menggunakan instruksi di atas, mungkin detail tentang memasukkan .gitignore
file ke dalam commit historis yang memerlukannya berada di luar cakupan jawaban ini. Saya ingin yang tepat .gitignore
berada di root commit, seolah-olah itu adalah hal pertama yang saya lakukan. Orang lain mungkin tidak peduli karena /.git/info/exclude
dapat mencapai hal yang sama di mana pun .gitignore
ada dalam sejarah commit, dan jelas menulis ulang sejarah adalah subjek yang sangat sensitif, bahkan ketika menyadari konsekuensi .
FWIW, metode potensial dapat mencakup git rebase
atau git filter-branch
yang menyalin eksternal .gitignore
ke setiap komit, seperti jawaban untuk pertanyaan ini
2 Menegakkan perilaku git abaikan setelah fakta dengan melakukan hasil dari git rm --cached
perintah mandiri dapat mengakibatkan penghapusan file yang baru-baru ini diabaikan di tarikan di masa depan dari remote yang didorong paksa. The --prune-empty
bendera di berikut git filter-branch
perintah menghindari masalah ini dengan secara otomatis menghapus sebelumnya "menghapus semua file diabaikan" Indeks hanya komit. Menulis ulang sejarah git juga mengubah hash, yang akan mendatangkan malapetaka di masa depan dari repositori publik / bersama / kolaboratif. Harap pahami konsekuensi sepenuhnya sebelum melakukan ini pada repo tersebut. Panduan GitHub ini menetapkan yang berikut:
Beri tahu kolaborator Anda untuk rebase , bukan menggabungkan, cabang apa pun yang mereka buat dari riwayat repositori Anda yang lama (ternoda). Satu komit gabungan dapat memperkenalkan kembali sebagian atau seluruh sejarah yang tercemar yang baru saja Anda susahkan untuk dibersihkan.
Solusi alternatif yang tidak memengaruhi repo jarak jauh adalah git update-index --assume-unchanged </path/file>
atau git update-index --skip-worktree <file>
, contohnya dapat ditemukan di sini .
git clean -X
terdengar mirip, tetapi tidak berlaku dalam situasi ini (ketika file masih dilacak oleh Git). Saya menulis ini untuk siapa saja yang mencari solusi agar tidak mengikuti rute yang salah.