Hapus direktori dari repositori jarak jauh setelah menambahkannya ke .gitignore


599

Saya berkomitmen dan mendorong beberapa direktori ke github. Setelah itu, saya mengubah .gitignorefile menambahkan direktori yang harus diabaikan. Semuanya berfungsi dengan baik, tetapi direktori (sekarang diabaikan) tetap di github.

Bagaimana cara menghapus direktori itu dari github dan riwayat repositori?


Jawaban:


1067

Aturan dalam .gitignorefile Anda hanya berlaku untuk file yang tidak dilacak. Karena file-file di bawah direktori itu sudah dikomit di repositori Anda, Anda harus menghapusnya, membuat komit, dan mendorongnya ke GitHub:

git rm -r --cached some-directory
git commit -m 'Remove the now ignored directory "some-directory"'
git push origin master

Anda tidak dapat menghapus file dari riwayat Anda tanpa menulis ulang sejarah repositori Anda - Anda tidak boleh melakukan ini jika orang lain bekerja dengan repositori Anda, atau Anda menggunakannya dari banyak komputer. Jika Anda masih ingin melakukan itu, Anda dapat menggunakannya git filter-branchuntuk menulis ulang sejarah - ada panduan yang bermanfaat di sini .

Selain itu, perhatikan keluaran dari git rm -r --cached some-directoryakan menjadi sesuatu seperti:

rm 'some-directory/product/cache/1/small_image/130x130/small_image.jpg'
rm 'some-directory/product/cache/1/small_image/135x/small_image.jpg'
rm 'some-directory/.htaccess'
rm 'some-directory/logo.jpg'

The rmadalah umpan balik dari git tentang repositori; file-file tersebut masih dalam direktori kerja.


3
Jika orang lain menarik, apakah file yang sekarang diabaikan akan dihapus atau tidak tersentuh?
Martin Konicek

3
@ Martin Konicek: jika pengguna yang menarik perubahan itu tidak memiliki modifikasi pada file-file itu, maka mereka akan dihapus.
Mark Longair

@MarkLongair Apa yang dilakukan -rdan --cached. Terima kasih.
Labanino

13
@ Labanino: -rberarti rekursif, perlu jika Anda melakukan seluruh direktori. --cachedmengesampingkan perilaku normal git untuk menghapusnya dari direktori kerja dan mengatur penghapusan untuk komit, dan membuat git hanya beroperasi pada area staging yang siap untuk melakukan. Begitulah cara Anda memberi tahu git bahwa Anda ingin menyimpan salinan file lokal Anda.
entheh

2
Ini bekerja dengan baik, tetapi saya harus terlebih dahulu melakukannya: git reset name_of_fileuntuk apa yang dijelaskan di atas berfungsi
Edvard Haugland

248

Saya melakukan ini:

git rm --cached `git ls-files -i --exclude-from=.gitignore` 
git commit -m 'Removed all files that are in the .gitignore' 
git push origin master

Yang akan menghapus semua file / folder yang ada di git Anda abaikan, menghemat Anda harus memilih masing-masing secara manual


Ini tampaknya telah berhenti bekerja untuk saya, sekarang saya lakukan:

 git rm -r --cached . 
 git add .
 git commit -m 'Removed all files that are in the .gitignore' 
 git push origin master

4
Terima kasih, ini banyak membantu saya! Jika Anda menggunakan Windows PowerShell, Anda dapat melakukannyaforeach ($i in iex 'git ls-files -i --exclude-from=.gitignore') { git rm --cached $i }
Matius

10
Mencoba pendekatan kedua Anda, itu menghapus semua file dari git lokal saya!
artnikpro

2
Saya pikir Anda harus menavigasi ke subdirektori dan melakukannya. Koreksi saya jika saya salah.

Jadi apa yang telah kita pelajari hari ini, anak-anak? "Jangan jalankan kode acak yang kamu temukan di Stack Overflow!"
Jonathan Landrum

49

Sesuai Jawaban saya di sini: Bagaimana cara menghapus direktori dari repositori git?

Untuk menghapus folder / direktori hanya dari repositori git dan bukan dari lokal coba 3 langkah sederhana.


Langkah-langkah untuk menghapus direktori

git rm -r --cached FolderName
git commit -m "Removed folder from repository"
git push origin master

Langkah-langkah untuk mengabaikan folder itu di commit berikutnya

Untuk mengabaikan folder itu dari commit selanjutnya, buat satu file di root bernama .gitignore dan masukkan nama folder itu ke dalamnya. Anda dapat menempatkan sebanyak yang Anda inginkan

File .gitignore akan terlihat seperti ini

/FolderName

hapus direktori


1
Inilah yang saya cari. Terima kasih :)
Rohit Singh

Saya senang itu membantu @Rohit Singh
eirenaios

9

Jawaban pertama Blundell tidak berhasil untuk saya. Namun itu menunjukkan saya jalan yang benar. Saya telah melakukan hal yang sama seperti ini:

> for i in `git ls-files -i --exclude-from=.gitignore`; do git rm --cached $i; done
> git commit -m 'Removed all files that are in the .gitignore'
> git push origin master

Saya menyarankan Anda untuk memeriksa file yang akan dihapus terlebih dahulu dengan menjalankan pernyataan di bawah ini:

git ls-files -i --exclude-from=.gitignore

Saya menggunakan file .gitignore default untuk studio visual dan saya perhatikan bahwa itu menghapus semua folder log dan bin dalam proyek yang bukan tindakan yang saya maksudkan.


5

Catatan: Solusi ini hanya bekerja dengan Github Desktop GUI .

Dengan menggunakan Github Desktop GUI itu sangat sederhana.

  1. Pindahkan folder ke lokasi lain (untuk keluar dari folder proyek) sementara.

  2. Edit .gitignorefile Anda dan hapus entri folder yang akan menghapus repositori master pada halaman github.

  3. Komit dan Sinkronkan folder proyek.

  4. Pindahkan kembali folder ke folder proyek

  5. Sunting ulang .gitignorefile.

Itu saja.


5

Jawaban dari Blundell seharusnya berhasil, tetapi untuk beberapa alasan aneh itu tidak ada hubungannya dengan saya. Saya harus mem-pipe terlebih dahulu nama-nama file yang dihasilkan oleh perintah pertama ke dalam sebuah file kemudian loop melalui file itu dan menghapus file itu satu per satu.

git ls-files -i --exclude-from=.gitignore > to_remove.txt
while read line; do `git rm -r --cached "$line"`; done < to_remove.txt
rm to_remove.txt
git commit -m 'Removed all files that are in the .gitignore' 
git push origin master

4

Metode ini menerapkan perilaku .gitignore standar, dan tidak memerlukan secara manual menentukan file yang perlu diabaikan .

Tidak bisa digunakan --exclude-from=.gitignore lagi: / - Inilah metode yang diperbarui:

Saran umum: mulai dengan repo bersih - semua yang dilakukan, tidak ada yang tertunda di direktori atau indeks kerja, dan buat cadangan !

#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

#optionally add anything to the index that was previously ignored but now shouldn't be:
git add *

#commit again
#optionally use the --amend flag to merge this commit with the previous one instead of creating 2 commits.

git commit -m "re-applied modified .gitignore"

#other devs who pull after this commit is pushed will see the  newly-.gitignored files DELETED

Jika Anda juga perlu membersihkan file yang baru saja diabaikan dari riwayat commit cabang atau jika Anda tidak ingin file yang baru saja diabaikan dihapus dari penarikan di masa mendatang , lihat jawaban ini .


0

Jika Anda bekerja dari PowerShell, coba yang berikut ini sebagai satu perintah.

PS MyRepo> git filter-branch --force --index-filter
>> "git rm --cached --ignore-unmatch -r .\\\path\\\to\\\directory"
>> --prune-empty --tag-name-filter cat -- --all

Kemudian, git push --force --all ,.

Dokumentasi: https://git-scm.com/docs/git-filter-branch


Bagaimana menggunakan git filter-branchberbeda dari menggunakan git rm? Saya awalnya berpikir saya harus menggunakan versi git filter-branchtetapi kebanyakan komentar di sini merekomendasikan menggunakan git rm. Dari apa yang saya mengerti git rmhanya menghapusnya dari direktori dan indeks kerja saat ini. Tetapi jika beberapa komit ditambahkan sebelumnya, itu masih dalam repositori.
alpha_989

Baik. git rmakan menghapus file dari komit terbaru ke masa depan. git filter-branchmemungkinkan kami menghapusnya dari seluruh riwayat. Lihat juga: help.github.com/articles/…
Shaun Luttin
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.