Hapus tahapan file yang dihapus di git

504

Biasanya, untuk membuang perubahan pada file yang akan Anda lakukan:

git checkout -- <file>

Bagaimana jika perubahan yang ingin saya buang adalah menghapus file? Baris di atas akan memberikan kesalahan:

error: pathspec '<file>' did not match any file(s) known to git.

Perintah apa yang akan mengembalikan file tunggal itu tanpa membatalkan perubahan lain?

poin bonus: Juga, bagaimana jika perubahan yang ingin saya buang adalah menambahkan file? Saya ingin tahu bagaimana cara unstage perubahan itu juga.

lurscher
sumber
1
Membuang perubahan dan menghapus stage adalah dua hal yang berbeda, yang ingin Anda lakukan?
Andrew Marshall
1
Ini adalah dua pertanyaan dan masalah yang berbeda dalam satu posting. Hal ini membuat jawabannya terlalu membingungkan dan tidak perlu.
David Sopko

Jawaban:

779

Dengan asumsi Anda ingin membatalkan efek git rm <file>atau rm <file>diikuti oleh git add -Aatau sesuatu yang serupa:

# this restores the file status in the index
git reset -- <file>
# then check out a copy from the index
git checkout -- <file>

Untuk membatalkan git add <file>, baris pertama di atas sudah cukup, dengan anggapan Anda belum berkomitmen.

Twalberg
sumber
70
The --adalah kuncinya. git reset <file>tidak bekerja, itulah yang membawaku ke sini.
2
Mengapa hanya end-of-options-markerdiperlukan dalam case file yang dihapus?
haridsv
5
@ handv Ini tidak sepenuhnya diperlukan (Anda dapat melakukannya secara bergantian git reset HEAD <file>, yang setara), tetapi git resetmemperlakukan argumen pertamanya sebelum end-of-options-markersebagai nama ref, bukan nama file. Mungkinkah itu ditulis sedikit lebih fleksibel? Mungkin. Kenapa tidak? Mungkin hanya pengembang yang tahu pasti.
twalberg
2
@twalberg git reset filenameberfungsi dengan baik untuk file yang tidak dihapus.
Brian Gordon
1
@ Harunahan - tolong jelaskan perbedaan antara git reset <file>dan git reset -- <file>. Saya mengalami kesulitan menemukan jawaban untuk itu di google.
Neeraj B.
56

Kedua pertanyaan dijawab dalam git status.

Untuk menghapus tahapan menambahkan penggunaan file baru git rm --cached filename.ext

# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#   new file:   test

Untuk menghapus tahapan menghapus penggunaan file git reset HEAD filename.ext

# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   deleted:    test

Di sisi lain, git checkout --jangan pernah turun panggung, itu hanya membuang perubahan yang tidak dipentaskan.

seppo0010
sumber
5
Saya tidak melihat petunjuk untuk file yang dihapus di git 1.7.2.5 di Debian.
tripleee
Senang melihat git statusdikutip; menunjukkan kepada pengguna cara untuk membantu sendiri sekarang dan nanti, dan jika informasi ditambahkan atau diperbarui di versi git yang akan datang.
Will Cain
Ini salah. "Perubahan menjadi komitmen" adalah apa yang Anda lihat sebelum ini git reset. Setelah itu git reset, Anda melihat "Berubah tetapi tidak diperbarui" yang berarti "Perubahan tidak dipentaskan" dalam bahasa asli penulis git, tampaknya. Lebih penting lagi, seluruh dogma tentang "status git memberi tahu Anda semua yang Anda tahu" adalah bohong. (Manajer yang mengatakan bahwa itu membuang-buang waktu orang dan harus dipecat.)
personal_cloud
11

Jawaban untuk dua pertanyaan Anda terkait. Saya akan mulai dengan yang kedua:

Setelah Anda mementaskan file (sering kali dengan git add, meskipun beberapa perintah lain secara implisit juga melakukan tahapan perubahan, git rmAnda) dapat mundur dari perubahan itu dengan git reset -- <file>.

Dalam kasus Anda, Anda harus menggunakan git rmuntuk menghapus file, yang setara dengan hanya menghapusnya dengan rmdan kemudian menentukan perubahan itu. Jika Anda pertama kali membatalkan stage dengan git reset -- <file>Anda, maka Anda dapat memulihkannya dengan git checkout -- <file>.

Ben Jackson
sumber
7

Jika telah dipentaskan dan dikomit, maka yang berikut ini akan mengatur ulang file:

git reset COMMIT_HASH file_path
git checkout COMMIT_HASH file_path
git add file_path

Ini akan berfungsi untuk penghapusan yang terjadi beberapa komit sebelumnya.

michaeldever
sumber
1
Ini lebih efisien untukgit revert COMMIT_HASH
Flair
2

Pada git v2.23 , Anda memiliki opsi lain:

git restore --staged -- <file>

Kreempuff
sumber