Bagaimana saya bisa membatalkan stage file saya lagi setelah membuat komit lokal?

268

Saya telah menjalankan perintah berikut

git add <foo.java>
git commit -m "add the foo.java file"

Bagaimana saya bisa menghapus komit lokal saya sekarang dan unstage foo.java?

Jika saya mengetik git reset --hard, saya menemukan bahwa itu mengembalikan yang saya modifikasi foo.javake yang asli.

Kit Ho
sumber

Jawaban:

452

git reset --soft HEAD~1harus melakukan apa yang Anda inginkan. Setelah ini, Anda akan memiliki perubahan pertama dalam indeks (terlihat dengan git diff --cached), dan perubahan terbaru Anda tidak dilakukan. git statusakan terlihat seperti ini:

# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       modified:   foo.java
#
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   foo.java
#

Anda kemudian dapat melakukan git add foo.javadan melakukan kedua perubahan sekaligus.

Antti
sumber
Saya mengedit jawaban: "Perubahan yang akan dikomit" memiliki perubahan pertama, dan "perubahan yang tidak dilakukan untuk komit" memiliki perubahan kedua.
Antti
4
Apa yang dijelaskan dalam jawaban ini sebenarnya adalah apa yang git commit --amenddilakukan; tetapi dengan alur kerja yang jauh lebih rumit. Ini tidak menjawab pertanyaan yang diajukan OP, meskipun memberikan arahan yang baik ( git reset).
7heo.tk
2
Harus mengganti '^' dengan '~' untuk membuatnya bekerja, jadi sepertinya:git reset --soft HEAD~
Shahar
3
lakukan git reset --soft HEAD ~ 1 lalu git reset HEAD
Joko Wandiro
jawaban sempurna untuk apa yang saya inginkan!
DeepInJava
78

Menggunakan:

git reset HEAD^

Itu melakukan reset "campuran" secara default, yang akan melakukan apa yang Anda minta; masukkan foo.java di dalam stage, hapus komit terbaru.

Ryan Stewart
sumber
2
Maukah Anda menjelaskan kepada saya apa yang reset "campuran", reset "soft" dan "hard"?
Kit Ho
1
@Kit Ho - git manual reset memiliki deskripsi yang sangat baik tentang ini.
manojlds
4
@Kit, @manojlds: Begitu juga stackoverflow.com/questions/2530060/… ( pluging tak tahu malu)
Cascabel
5
Itu sebenarnya satu-satunya jawaban yang benar . Dua jawaban lainnya akan menggelar kembali file setelah melakukan komit.
7heo.tk
git reset --softtidak bekerja, tetapi git reset HEAD^melakukan
wordsforthewise
43

Bagi saya, berikut ini cara yang lebih mudah dibaca (jadi lebih disukai) untuk melakukannya:

git reset HEAD~1

Alih-alih 1, mungkin ada sejumlah komit yang ingin Anda hapuskan panggung.

Andrey Deineko
sumber
39

git reset --softhanya untuk itu: itu seperti git reset --hard, tetapi tidak menyentuh file.

wRAR
sumber
4
Itu adalah penjelasan yang paling mudah dimengerti yang pernah saya dengar (hanya dalam 11 kata)! Terima kasih!
phreakhead
3
Jawaban itu salah. git reset"seperti git reset --hardtetapi tidak menyentuh file." Tidak git reset --soft. git reset --softakan mengatur perubahan, jadi Anda tidak perlu menambahkannya ke pementasan jika Anda ingin mengkomitnya, tetapi Anda harus melakukannya git reset(ya, untuk kedua kalinya, dan tanpa --soft) jika Anda tidak melakukannya. Jadi jawaban itu pendek, tetapi salah.
7heo.tk
12

Untuk menghapus semua file dalam komit terakhir Anda -

git reset HEAD~

Lavika
sumber
8

"Reset" adalah cara untuk membatalkan perubahan secara lokal. Ketika melakukan, Anda pertama-tama memilih perubahan untuk disertakan dengan " git add " --yang disebut "staging." Dan begitu perubahan dilakukan, maka Anda " git melakukan " mereka.

Untuk mundur dari pementasan atau komit, Anda "mengatur ulang" KEPALA. Di cabang, HEAD adalah variabel git yang menunjuk ke komit terbaru. Jadi jika Anda telah melakukan tetapi belum melakukan komitmen, Anda " set ulang HEAD ." Itu mendukung KEPALA saat ini dengan mengambil perubahan dari panggung. Ini adalah singkatan untuk " git reset - KEPALA dicampur ~ 0. "

Jika Anda sudah berkomitmen, maka HEAD sudah maju, jadi Anda harus mencadangkan ke komitmen sebelumnya. Di sini Anda " reset HEAD ~ 1 " atau " reset HEAD ^ 1 " atau " reset HEAD ~ " atau " reset HEAD ^ " - semua referensi HEAD minus satu.

Mana simbol yang lebih baik, ~ atau ^? Pikirkan ~ tilde sebagai aliran tunggal - ketika setiap komit memiliki orangtua tunggal dan itu hanya serangkaian perubahan secara berurutan, maka Anda dapat merujuk cadangan sungai menggunakan tilde, seperti HEAD ~ 1, HEAD ~ 2, HEAD ~ 3, untuk orang tua, kakek nenek, kakek buyut, dll. (Secara teknis ia menemukan orang tua pertama di generasi sebelumnya).

Ketika ada penggabungan, maka komit memiliki lebih dari satu orangtua. Saat itulah ^ caret ikut bermain - Anda bisa ingat karena itu menunjukkan cabang-cabang berkumpul. Menggunakan tanda sisipan, HEAD ^ 1 akan menjadi orang tua pertama dan HEAD ^ 2 akan menjadi orang tua kedua dari satu komit - ibu dan ayah, misalnya.

Jadi jika Anda hanya akan mengembalikan satu hop pada komit orang tua tunggal, maka HEAD ~ dan HEAD ^ adalah sama - Anda dapat menggunakan salah satunya.

Selain itu, reset dapat berupa --soft , --mixed , atau --hard . Reset lunak hanya memundurkan komit - me-reset HEAD, tetapi tidak memeriksa file dari komit sebelumnya, sehingga semua perubahan dalam direktori kerja dipertahankan. Dan --soft reset bahkan tidak menghapus panggung (juga dikenal sebagai indeks ), jadi semua file yang dipentaskan akan tetap di atas panggung.

Sebuah --Dicampur ulang (default) juga tidak memeriksa file dari sebelumnya komit, sehingga semua perubahan yang diawetkan, tapi panggung dibersihkan. Itu sebabnya " git reset HEAD " yang sederhana akan membersihkan panggung.

Sebuah --hard ulang ulang HEAD, dan membersihkan panggung, tetapi juga memeriksa semua file dari sebelumnya komit dan sehingga menimpa perubahan.

Jika Anda telah mendorong komit ke repositori jarak jauh, maka reset tidak berfungsi dengan baik. Anda dapat mereset secara lokal, tetapi ketika Anda mencoba untuk mendorong ke remote, git akan melihat bahwa HEAD lokal Anda berada di belakang HEAD di cabang jauh dan akan menolak untuk mendorong. Anda mungkin bisa memaksakan dorongan, tetapi git benar-benar tidak suka melakukan itu.

Sebagai alternatif, Anda dapat menyimpan perubahan Anda jika Anda ingin menyimpannya, memeriksa komit sebelumnya, menghapus simpanan perubahan, tahapan mereka, membuat komit baru, dan kemudian mendorong itu.

HieroB
sumber
+1 untuk penjelasan detail operasi. IMO ini harus menjadi jawaban yang diterima!
ISAE
2

Katakanlah Anda ingin membatalkan perubahan hingga komitmen dilakukan,

Dimana hash komit adalah sebagai berikut:

  • h1
  • h2 ...
  • hn
  • hn + 1

Kemudian jalankan perintah berikut:
git reset hn

Sekarang KEPALA akan di hn +1. Perubahan dari h1 ke hn akan tidak bertahap.

Vasantha Ganesh K
sumber