Bagaimana cara menghapus file yang terdaftar di .gitignore tetapi masih di repositori?

327

Saya memiliki beberapa file di repositori saya yang harus diabaikan, saya menambahkannya ke .gitignore tetapi, tentu saja, mereka tidak dihapus dari repositori saya.

Jadi pertanyaan saya adalah, apakah ada perintah atau skrip ajaib menggunakan cabang-filter yang dapat menulis ulang riwayat saya dan menghapus semua file ini dengan mudah? Atau hanya sebuah perintah yang akan membuat komit yang akan menghapusnya?

Intrepidd
sumber
PERINGATAN: Meskipun ini tidak akan menghapus file fisik dari lokal Anda, itu akan menghapus file dari mesin pengembang lain di git pull berikutnya. Bagaimana membuat Git "lupa" tentang file yang dilacak tetapi sekarang ada di .gitignore?
Kris Roofe
@Stevoisiak ini bukan duplikat dari pertanyaan itu karena yang ini menanyakan tentang SEMUA file yang diabaikan dan juga memiliki jawaban yang lebih baik daripada pertanyaan serupa lainnya.
Omn

Jawaban:

438

Anda dapat menghapusnya dari repositori secara manual:

git rm --cached file1 file2 dir/file3

Atau, jika Anda memiliki banyak file:

git rm --cached `git ls-files -i --exclude-from=.gitignore`

Tapi ini sepertinya tidak berfungsi di Git Bash di Windows. Ini menghasilkan pesan kesalahan. Berikut ini berfungsi lebih baik:

git ls-files -i --exclude-from=.gitignore | xargs git rm --cached  

Mengenai menulis ulang seluruh sejarah tanpa file-file ini, saya sangat ragu ada cara otomatis untuk melakukannya.
Dan kita semua tahu bahwa menulis ulang sejarah itu buruk, bukan? :)

Samy Dindane
sumber
2
Sayangnya perintah Git Bash pada Windows tidak berfungsi dengan jalur yang berisi spasi
Nate Bundy
19
@Cupcake terima kasih. git ls-files -i -z --exclude-from=.gitignore | xargs -0 git rm --cachedtampaknya melakukan trik
Nate Bundy
3
Saya terjebak dengan masalah yang sama pada windows. Saya menggunakan PowerShell, dan dalam kasus saya, saya mendapatkan perintah ketiga dengan @ samy-dindane dan mengubahnya menjadi foreach. Menjadi inigit ls-files -i --exclude-from=.gitignore | %{git rm --cached $_}
digaomati
1
"git ls-files -i --exclude-from = .gitignore" sangat membantu, ini memberitahu saya file apa yang dikecualikan oleh .ignore.
Owen Cao
1
Saya senang menemukan perintah ini, TETAPI itu tidak benar-benar menghapus file dari repositori. Ketika saya menghapus 2300 kB gambar, ukuran repositori turun hanya 10 kB. Jadi itu tidak dapat digunakan, misalnya, untuk membuat repositori lebih kecil dan lebih cepat untuk ditransfer.
Jan Potužník
343

Cara yang lebih mudah yang berfungsi pada OS apa pun adalah dengan melakukannya

git rm -r --cached .
git add .
git commit -m "Removing all files in .gitignore"

Anda pada dasarnya membaca semua file, kecuali yang ada di .gitignore

gtatr
sumber
1
Bagaimana hal ini memengaruhi pengguna lain pada repo yang melakukan tarikan - saat saya membacanya, folder yang tidak ingin kami lacak dihapus? Bagaimana kita bisa mencegah ini - kita hanya ingin
melepaskannya
Ini akan menandai semua file yang diubah dengan pesan komit palsu!
Haidar Zeineddine
3
apa yang Anda maksud dengan pesan komit palsu? Ini adalah pesan komit yang nyata: P Anda dapat mengubah pesan tentu saja, tergantung pada kebutuhan Anda ...
gtatr
1
Hanya demi kelengkapan, Anda perlu perintah git push di akhir.
Mariusz Bialobrzeski
1
Jangan lakukan ini, itu akan menghapus histori pada semua file
agrath
145

Karena file-file di .gitignore tidak dilacak, Anda dapat menggunakan perintah git clean untuk menghapus file secara rekursif yang tidak di bawah kontrol versi.

Gunakan git clean -xdnuntuk melakukan lari kering dan melihat apa yang akan dihapus.
Kemudian gunakan git clean -xdfuntuk menjalankannya.

Pada dasarnya, git clean -hatau man git-clean(dalam unix) akan memberi Anda bantuan.

Ketahuilah bahwa perintah ini juga akan menghapus file baru yang tidak ada dalam area pementasan.

Semoga ini bisa membantu.

weiz
sumber
6
Ini harus menjadi jawaban yang diterima. Ini benar-benar berfungsi (jawaban yang diterima tidak bekerja untuk saya, di macOS), dan itu jauh lebih bersih.
Roger Oba
25
Jawaban ini tidak berlaku - OP mengatakan file dalam .gitignore yang sedang dilacak.
Ken Williams
20
AWAS! Ini secara permanen menghapus semua file yang tidak terlacak, daripada hanya menghapus dari cabang
Emmanuel
1
yang git clean -xdnadalah lari kering yang tidak akan menghapus. yang berikutnya akan.
JohnZaj
17
-1: Ini adalah jawaban yang sangat menyesatkan - poster asli ingin dihapus dari repositori, tidak menghapus file sepenuhnya. Saya sudah hampir menghapus file dinamis yang diperlukan oleh IDE saya tetapi tidak harus di repo.
Auspice
4

Saya melakukan solusi yang sangat mudah dengan memanipulasi output dari pernyataan .gitignore dengan sed:

cat .gitignore | sed '/^#.*/ d' | sed '/^\s*$/ d' | sed 's/^/git rm -r /' | bash

Penjelasan:

  1. cetak file .gitignore
  2. hapus semua komentar dari cetakan
  3. hapus semua baris kosong
  4. tambahkan 'git rm -r' ke awal baris
  5. jalankan setiap baris.
Scott Crossen
sumber
10
sedmudah?
IgorGanapolsky
0

Di linux Anda dapat menggunakan perintah ini:

sebagai contoh saya ingin menghapus "* .py ~" jadi perintah saya harus ==>

find . -name "*.py~" -exec rm -f {} \;

Saloua SAHNOUNE
sumber
-3

Git akan mengabaikan file yang cocok dengan pola .gitignore setelah Anda menambahkannya ke .gitignore.

Tetapi file-file yang sudah ada di repositori akan tetap masuk

gunakan git rm files_ignored; git commit -m 'rm no use files'untuk menghapus file yang diabaikan.

pensz
sumber
4
Ada banyak dari mereka, apakah ada cara untuk menghapusnya tanpa harus menyebutkan nama mereka?
Intrepidd