Hapus git commit lama

89

Saya sangat baru mengenal git, dan bertanya-tanya apakah hal seperti ini mungkin?

>git log --pretty=oneline --abbrev-commit
2f05aba Added new feature
3371cec Fixed screw up    <-- I want to remove this
daed25c Screw up          <-- and remove this.
e2b2a84 First.                So it's like they never happend.

Apakah ini mungkin?

Josh
sumber

Jawaban:

63

Ini dimungkinkan dengan git rebase. Coba berikut ini

git rebase -i HEAD~4

dan kemudian, ikuti petunjuk interaktif di editor Anda. Pada langkah pertama, Anda "menekan" komitmen. Seharusnya terlihat seperti ini:

pick 2f05aba ... will be preserved
squash 3371cec ... will be squashed with daed25c
squash daed25c ... will be squashed with e2b2a84
pick e2b2a84 .. will contain this and 3371cec and daed25c

Pada langkah kedua Anda dapat mengedit pesan komit.

Deve
sumber
27
Bukankah pertanyaannya tentang menghapus komit daripada menghancurkannya?
Richard
4
@Stony: Ya, Anda mungkin juga bisa menghapusnya. Tapi dari komentar komit di OP ("Screw up" dan "Fixed screw up") saya berasumsi bahwa yang satu membatalkan yang lain dan Anda juga bisa menekan keduanya.
Deve
85

Jika Anda benar-benar ingin menghapusnya (menghapusnya dari riwayat, tidak akan pernah terlihat lagi), Anda bisa

jalankan rebase:

git rebase -i HEAD~4

dan kemudian, hapus saja (atau komentari) baris yang sesuai dengan komit yang ingin Anda hapus, seperti:

pick 2f05aba ... #will be preserved
#pick 3371cec ... #will be deleted
#pick daed25c ... #will be deleted
pick e2b2a84 ... #will be preserved
Shathur
sumber
2
Saya baru mengenal github, Bagaimana Anda mendorong perubahan setelah itu (ketika saya mengklik Sinkronkan, itu hanya mengembalikan apa yang saya lakukan). Saya rasa saya mengerti: git push origin HEAD --force
Nicolas Thery
@NicolasThery Anda tidak. Itulah mengapa git push menolak untuk bekerja tanpa --force, karena Anda menulis ulang sejarah dan Anda akan merusak repositori orang lain. Jika Anda sudah mendorong maka satu-satunya pilihan Anda adalah melakukan a git revert. Yang mana, ketika Anda memikirkannya masuk akal karena jika Anda menarik kode orang lain, Anda tidak ingin mereka dapat menghapus komitmen lama Anda tanpa semacam riwayat, bukan?
Angry Dan
Saya berasumsi ini hanya berfungsi di repo Git saat ini dan tidak mengubah apa pun di upstream / node Git lainnya?
Alexander Mills
2
@AlexanderMills Itu tidak mengubah apa pun di upstream selama Anda tidak mendorongnya (dan jika Anda melakukannya, Anda harus menambahkan flag --force seperti yang dikatakan Angry Dan).
Shathur
datau dropadalah perintah untuk menghapus komit dari riwayat.
Keranjang Terbengkalai
5

Untuk sepenuhnya menghapus komit, ada opsi baru dropuntuk rebases interaktif git sekarang. Lari pertama:

git rebase -i HEAD~4

Kemudian ganti pickdengan dropuntuk komit yang akan dijatuhkan:

pick 2f05aba ... #will be preserved
drop 3371cec ... #will be dropped
drop daed25c ... #will be dropped
pick e2b2a84 ... #will be preserved

Ini berfungsi di Fedora untuk saya dengan versi berikut:

$ git version
git version 2.21.0
russoue
sumber
2

Squash berguna ketika Anda ingin membuat daftar komit gabungan di bawah satu hash, tetapi jika Anda ingin mengambil tiga komit terpisah dan memiliki hasil akhir yang terlihat seperti komit tunggal, saya sarankan fixup

git rebase -i HEAD~4

pick 2f05aba ... will be preserved
fixup 3371cec ... will be merged with daed25c
fixup daed25c ... will be merged with e2b2a84
pick e2b2a84 .. will include 3371cec and daed25c, but only the commit message of e2b2a84

Anda dapat menemukan informasi selengkapnya di daftar perintah UI rebase interaktif.

Keranjang Terbengkalai
sumber