Bagaimana menghapus banyak file yang terhapus di repositori Git

237

Saya telah menghapus beberapa file dan menunjukkan status git seperti di bawah ini.

Saya telah berkomitmen dan mendorong.

GitHub masih menampilkan file yang dihapus di repositori. Bagaimana saya bisa menghapus file di repositori GitHub?

# On branch master
# Changes not staged for commit:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   deleted:    modules/welcome/language/english/kaimonokago_lang.php
#   deleted:    modules/welcome/language/french/kaimonokago_lang.php
#   deleted:    modules/welcome/language/german/kaimonokago_lang.php
#   deleted:    modules/welcome/language/norwegian/kaimonokago_lang.php

Jika saya menggunakan git rm, itu memberi yang berikut.

usage: git rm [options] [--] <file>...

-n, --dry-run         dry run
-q, --quiet           do not list removed files
--cached              only remove from the index
-f, --force           override the up-to-date check
-r                    allow recursive removal
--ignore-unmatch      exit with a zero status even if nothing matched
shin
sumber

Jawaban:

638
git add -u 

memperbarui semua perubahan Anda

mshameers
sumber
31
Bekerja dengan pesona. Ketika Anda melihat sesuatu seperti "git status | sed -n '/ ^ # * dihapus: / s /// p' | xargs git rm" sebagai solusi yang diusulkan untuk persyaratan sesederhana dan sesering itu, maka Anda tahu solusi yang lebih baik adalah, atau akan segera, di tikungan.
arcseldon
sederhana lebih baik, ini benar-benar berguna maka cara "bash"
castiel
1
Penulis bertanya bagaimana cara menghapus file, mengapa menambahkan file adalah jawaban yang benar?
kelin
3
@kelin: from git docs ( git-scm.com/docs/git-add ): "-u --update Perbarui indeks di tempat yang sudah memiliki entri yang cocok dengan <pathspec>. Ini menghapus serta memodifikasi entri indeks untuk cocok dengan pohon kerja, tetapi tidak menambahkan file baru. Jika tidak ada <pathspec> diberikan ketika opsi -u digunakan, semua file yang dilacak di seluruh pohon kerja diperbarui (versi Git lama digunakan untuk membatasi pembaruan ke direktori saat ini dan subdirektori). "
HEDMON
92

Berhati-hatilah git rm .; mungkin menghapus lebih dari yang Anda inginkan. Tentu saja, Anda dapat pulih, tetapi lebih mudah tidak harus melakukannya.

Yang paling sederhana adalah:

git rm modules/welcome/language/english/kaimonokago_lang.php \
       modules/welcome/language/french/kaimonokago_lang.php \
       modules/welcome/language/german/kaimonokago_lang.php \
       modules/welcome/language/norwegian/kaimonokago_lang.php

Anda tidak dapat menggunakan shell wildcard karena file tidak ada, tetapi Anda dapat menggunakan (setidaknya di Bash):

git rm modules/welcome/language/{english,french,german,norwegian}/kaimonokago_lang.php

Atau pertimbangkan:

git status | sed -n '/^# *deleted:/s///p' | xargs git rm

Ini mengambil output dari git status, tidak mencetak apa pun secara default ( sed -n), tetapi pada baris yang dimulai # deleted:, ia menghilangkan #dan deleted:dan mencetak apa yang tersisa; xargsmengumpulkan argumen dan menyediakannya untuk suatu git rmperintah. Ini berfungsi untuk sejumlah file terlepas dari kesamaan (atau perbedaan) dalam nama.

Jonathan Leffler
sumber
6
Anda dapat menggunakan wildcard (meskipun Anda mungkin perlu menghindarinya), dan git akan cocok dengan path dalam indeks, bukan hanya yang ada di pohon kerja, jadi tidak masalah bahwa mereka tidak ada di sistem file.
Ben James
109
git diff --diff-filter=D --name-only -z | xargs -0 git rmadalah pendekatan yang lebih andal daripada mencoba mem-parsing git statusyang berorientasi pengguna dan tidak dijamin stabil di versi mendatang.
CB Bailey
@ Charles: itu tentu saja lebih baik, tetapi membutuhkan cukup banyak pengetahuan tentang pilihan apa yang tersedia dengan git diff(yang saya tidak miliki, tidak memiliki kebutuhan sebelumnya). Terima kasih!
Jonathan Leffler
8
Perhatikan bahwa ada juga "git ls-files --deleted"
Petr Gladkikh
1
jadi, git ls-files --deleted | xargs git rmlakukan trik untuk saya.
fiacobelli
50

Versi lain untuk jawaban ByScripts adalah

git rm $(git ls-files --deleted)

Ini HANYA akan menghapus file yang dihapus dari git.

Bisa juga digunakan untuk menambahkan file yang HANYA dimodifikasi juga.

git add $(git ls-files --modified)

Perintah-perintah ini juga berfungsi di gitbash untuk windows.

Vijay C
sumber
2
Tak ternilai, git ls-filesdengan status yang dihapus atau diubah sangat membantu.
Mario Peshev
1
Perilaku 'git add --update (or -u)'tanpa argumen jalur dari subdirektori pohon akan berubah di Git 2.0 dan tidak boleh digunakan lagi. Untuk menambahkan konten untuk seluruh pohon, jalankan: git add --update :/ (atau git add -u: /) Untuk membatasi perintah ke direktori saat ini, jalankan: git add --update . (atau git add -u.) Dengan versi Git saat ini, perintah dibatasi untuk direktori saat ini
Ans
1
Adakah yang tahu cara menangani jalur dengan spasi di dalamnya? Contoh: src/my spaced directory/myfile. Ini bisa ditangani secara individual tetapi bagaimana bisa ditangani menggunakan perintah dalam jawaban ini?
Muhammad Gelbana
35

Perbarui semua perubahan yang Anda buat:

git add -u

File yang dihapus harus berubah dari yang tidak dipentaskan (biasanya warna merah) menjadi bertahap (hijau). Kemudian komit untuk menghapus file yang dihapus:

git commit -m "note"
Aziz Alto
sumber
1
Pantas lencana populis.
John
1
Sejauh ini, ini adalah solusi terbaik. Tidak ada scripting hack, tidak ada proses yang panjang, hanya sebuah flag untuk memberitahu git untuk memperbarui indeksnya secara menyeluruh.
Ron Dahlgren
Cemerlang! Menyelamatkan saya dari keharusan mengetik 20+ jalur file. Terima kasih!
allardbrain
12

Solusi terbaik jika Anda tidak peduli tentang pementasan file yang dimodifikasi adalah dengan menggunakan git add -useperti yang dikatakan oleh mshameers dan / atau pb2q .

Jika Anda hanya ingin menghapus file yang dihapus, tetapi tidak membuat stage yang dimodifikasi, saya pikir Anda harus menggunakan ls-filesargumen dengan --deletedopsi (tidak perlu menggunakan regex atau argumen / opsi kompleks lainnya):

git ls-files --deleted | xargs git rm
ByScripts
sumber
1
git add -AAtasi masalah ini ... untuk berjaga-jaga jika ada yang ingin tahu di masa depan. periksa jawaban di bawah ini
Ja8zyjits
8

Ya, git rm <filename>akan menampilkan status file yang dihapus, di mana <filename>bisa menjadi pola glob:

$ git rm modules/welcome/language/*/kaimonokago_lang.php
rm modules/welcome/language/english/kaimonokago_lang.php
rm modules/welcome/language/french/kaimonokago_lang.php
rm modules/welcome/language/german/kaimonokago_lang.php
rm modules/welcome/language/norwegian/kaimonokago_lang.php

$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       deleted:    modules/welcome/language/english/kaimonokago_lang.php
#       ...

Lalu, Anda bisa berkomitmen.

git commit -a akan melakukan ini dalam sekali jalan, jika Anda mau.

Anda juga dapat menggunakan git add -uuntuk mengatur semua perubahan, termasuk semua file yang dihapus, kemudian komit.

Ben James
sumber
jadi rm. (berhenti penuh) menghapusnya sekaligus?
Shin
jadi hanya git rm akan menghapus sekaligus?
Shin
1
Anda dapat menggunakan pola gaya bola untuk menghapus banyak file; Saya memperbarui jawaban saya untuk menunjukkan contoh.
Ben James
5
Tampaknya git add -upersis seperti apa yang kami cari - jika Anda membuat banyak penghapusan, maka ingin melakukan semua penghapusan, yang tampaknya merupakan cara termudah dan paling 'standar' (artinya, tanpa gumpalan khusus kasus atau shell kompleks menguraikan ke dalam xargs). Apakah ada alasan mengapa kami tidak ingin menggunakan ini, selain karena itu menambahkan semua perubahan sekaligus?
trisweb
7

Ketika saya memiliki banyak file yang saya hapus yang tidak dipentaskan untuk komit, Anda dapat git rmsemuanya dalam satu acara dengan:

for i in `git status | grep deleted | awk '{print $3}'`; do git rm $i; done

Seperti yang disebutkan oleh penjawab pertanyaan, berhati-hatilah dengan git rm.

Justin Mandzik
sumber
5

Coba ini:

 git rm `git ls-files -d`
Eludom
sumber
Ini memecahkan masalah saya dalam pementasan hanya skrip yang dihapus (menggunakan bash)
Mariano Argañaraz
3

Kamu bisa memakai

git commit -m "remove files" -a
git push

Setelah Anda menghapus file secara manual.

onalbi
sumber
1
Atau identik tetapi lebih ringkas: git commit -am "hapus file"
BradChesney79
3

Anda dapat membuat skrip shell yang akan menghapus semua file Anda saat dijalankan:

git status | grep deleted | awk '{print "git rm " $3;}' > ../remove.sh

Script yang dibuat adalah remove.shdan berisi daftar git rmperintah lengkap.

La-comadreja
sumber
2
git status | sed 's/^#\s*deleted:\s*//' | sed 's/^#.*//' | xargs git rm -rf
Boush
sumber
2
git add -u .

git add --update .
eucas
sumber
2

Jika Anda ingin menghapus semuanya dengan menggunakan "git rm". Inilah yang saya lakukan:

git ls-files --deleted -z | xargs -0 git rm

Kueri ini mencantumkan semua file yang telah dihapus dan menghapusnya dari repositori git Anda. Semoga ini bisa membantu.

DevWL
sumber
1

Fungsi bersih bawaan juga dapat membantu ...

git clean -fd
Randall Borck
sumber
1
Ini hanya berlaku untuk file yang tidak dilacak.
Elijah Lynn
1

Saya memiliki masalah ini file hantu muncul di repo saya setelah saya menghapusnya dan menemukan perintah yang rapi ini!

git add -A

Ini pada dasarnya sama dengan git add -adan git add -udigabungkan, tetapi case-sensitive. Saya mendapatkannya dari tautan luar biasa ini ( tautan ini menunjuk ke versi di archive.org sekarang, karena yang asli telah dikonversi ke halaman spam / phishing pada Juni 2016)

NetOperator Wibby
sumber
0

Berikut adalah cara mendeteksi file yang dihapus dan menghapus tahapannya sebagai bagian dari komit berikutnya. Semua solusi pada utas ini memiliki kelebihan yang berbeda. Solusi ini di bawah ini secara khusus berkaitan dengan masalah nama file dengan spasi di dalamnya.

git status --porcelain | awk '/^.D .*$/ {print $0}' | sed 's/.D \(.*\)/\1/' | tr -d '"' | xargs -I {} git rm '{}'

pastikan Anda mengujinya dengan opsi --dry-run git sebelum menjalankannya dengan yang berikut:

git status --porcelain | awk '/^.D .*$/ {print $0}' | sed 's/.D \(.*\)/\1/' | tr -d '"' | xargs -I {} git rm --dry-run '{}'

penjelasan:

git status --porcelain

Ini mencetak sesuatu seperti D "/ path ke folder / path ke file" yang terjadi hanya ketika ada spasi di nama path

awk '/^.D .*$/ {print $0}'

hanya cocokkan garis yang dimulai dengan "D"

sed 's/ D \(.*\)/\1/'

hapus "D" dari bagian depan setiap string

tr -d '"'

hapus tanda kutip, jika ada

xargs -I {} git rm '{}'

mendefinisikan variabel nama file sebagai {} jalankan nama file di bawah git rm yang dilampirkan dalam tanda kutip tunggal untuk memastikan bahwa ia mendukung nama file dengan spasi.

ND
sumber