Bagaimana mengubah komit terakhir untuk membatalkan penambahan file?

108

Saya telah memodifikasi dua file a, bpada komit terakhir. Tetapi file btidak boleh dilakukan, apa alur kerja untuk mengubah ini?

Xiè Jìléi
sumber

Jawaban:

109

Perbarui (beberapa tahun kemudian)

Jan Hudec

Itu sepele untuk menghapusnya dari indeks saja.

Benar: Anda dapat mengatur ulang file ke konten indeksnya dengan cukup mudah, seperti yang disarankan oleh jawaban yang lebih baru (ditulis oleh Matt Connolly ):

git reset HEAD^ path/to/file/to/revert

HEAD^memungkinkan file untuk mengakses kontennya di komit sebelumnya sebelum yang terakhir.

Maka Anda bisa git commit --amend, seperti yang saya tulis di bawah ini.


Dengan Git 2.23 (Agustus 2019), Anda mungkin menggunakan perintah barugit restore

 git restore --source=HEAD^ --staged  -- path/to/file/to/revert

singkat:

 git restore -s@^ -S -- path/to/file/to/revert

Sekali lagi, Anda bisa git commit --amend, seperti yang saya tulis di bawah ini.


Jawaban asli (Januari 2011)

Jika ini adalah komit terakhir Anda (dan Anda belum mendorongnya ke mana pun), Anda dapat mengubahnya :
(simpanan pertama atau simpan b)

 git commit --amend

Kemudian hapus b, komit kembali. Kembalikan b dan Anda selesai.

--amend

Digunakan untuk mengubah ujung cabang saat ini.
Persiapkan objek pohon yang ingin Anda ganti komit terbaru seperti biasa (ini termasuk jalur -i / -o dan eksplisit yang biasa), dan editor log komit diunggulkan dengan pesan komit dari ujung cabang saat ini.
Komit yang Anda buat menggantikan tip saat ini - jika itu gabungan, itu akan membuat orang tua dari tip saat ini sebagai orang tua - sehingga komit teratas saat ini dibuang.

VONC
sumber
... Then stash/delete b, re-commit.., di sini bukankah seharusnya kata Thenitu after? - --amendsetelah stach / delete b, ...
Xiè Jìléi
@ 谢 继 雷: dengan kata lain, simpan b pertama, kemudian komit - ubah, lalu pulihkan? Benar. Saya telah memperbarui jawabannya.
VonC
Dengan kekuatan indeks git, menyuruh siapa pun untuk menyimpan / menyimpan file itu benar-benar konyol (-1). Itu sepele untuk menghapusnya dari indeks saja.
Jan Hudec
1
@ JanHudec Benar, saya telah mengedit jawaban yang sesuai. Saya tidak mengikuti jawaban lama itu sedekat yang saya lakukan di Stack Overflow. 99% pertanyaan git pada SU tetap harus dimigrasikan pada SO.
VonC
66
  1. git diff --name-only HEAD^ - (opsional) gunakan untuk membuat daftar file yang diubah dalam komit terakhir.
  2. git reset HEAD^ path/to/file/to/revert- untuk mereset indeks ke versi terakhir, membiarkan copy pekerjaan tidak tersentuh.
  3. git commit --amend- untuk mengubah komitmen terakhir untuk memasukkan perubahan indeks
Matt Connolly
sumber
9
Imho itu jawaban yang jauh lebih baik daripada yang diterima.
mik01aj
1
Perhatikan bahwa Anda tidak boleh menggunakan git commit -a --amend(yaitu jangan menambahkan file) untuk langkah 3, atau Anda akan melakukan perubahan copy pekerjaan Anda yang merupakan pengeditan yang Anda coba hapus. Langkah opsional 2.5 bisa juga git checkout path/to/file/to/revertuntuk membersihkan copy pekerjaan Anda juga.
dmnd
1
Cara lain git rm --cached path/to/file/to/revertuntuk membatalkan penambahan file tanpa menghapusnya dari struktur pohon.
Jan Hudec
13

Atau jika Anda menggunakan git gui, Anda cukup memilih opsi "Amend last commit", file yang ditambahkan muncul di daftar "Staged", klik ikon itu untuk memindahkannya ke daftar "Unstaged" dan komit.

Jan Hudec
sumber
1
@VonC: Mengedit dan memisahkan patch adalah operasi yang cukup umum untuk pengguna git berat, jadi gui dirancang untuk membuatnya mudah dan merupakan alat terbaik IMO untuk itu.
Jan Hudec
Yang itu berhasil! Saya tidak berhasil dengan opsi lain untuk tugas tertentu itu. Terima kasih atas tipnya!
Serguzest
10

Jika Anda ingin menghapus b dari komit terakhir Anda

git rm --cached b (will preserve the file in the working tree but remove it from the index)
git commit --amend

Jika Anda ingin menghapus semua perubahan ke b di komit terakhir Anda

(backup b)
(modify b to state before incorrect commit)
git commit --amend
(restore b)
pingo
sumber
git rm --cacheddan lakukan backup / restore dance (-1).
Jan Hudec
Terima kasih telah menunjukkannya. Saya ingin berbagi bagaimana saya melakukan ini karena ini adalah pendekatan yang saya rasa paling nyaman bahkan setelah membaca seluruh utas.
pingo
4

Alternatif yang tidak memerlukan peretasan indeks, namun tetap mempertahankan pesan komit lama:

$ git reset HEAD^
$ git add <all the files you want, excluding the one you don't want>
$ git commit -C HEAD@{1}

Saya suka ini karena (a) ia menggunakan perintah yang saya gunakan secara teratur, dan (b) saya bisa lakukan git add -puntuk mengetahui dengan tepat apa yang ingin saya komit.

Justin L.
sumber