git hapus gabungan komit dari riwayat

99

Riwayat Git saya terlihat seperti itu:

Sejarah Git

Saya ingin menggabungkan komitmen ungu menjadi satu. Saya tidak ingin melihatnya lagi di log komit saya.

Saya sudah mencoba melakukan a git rebase -i 1, tetapi meskipun 1berada di cabang biru (lih. Gambar), saya masih melihat setiap komit di cabang ungu saya.

Bagaimana saya bisa sepenuhnya menghapus cabang ungu (dari log komit)?

Benjamin Toueg
sumber
Apakah repo Anda didorong ke mana pun yang ditarik orang lain?
Schleis
Kedua cabang tersebut murni lokal.
Benjamin Toueg

Jawaban:

101

Lakukan git rebase -i <sha before the branches diverged>ini akan memungkinkan Anda untuk menghapus komit gabungan dan log akan menjadi satu baris seperti yang Anda inginkan. Anda juga dapat menghapus komitmen apa pun yang tidak Anda inginkan lagi. Alasan mengapa rebase Anda tidak berfungsi adalah karena Anda tidak mundur cukup jauh.

PERINGATAN: Anda menulis ulang sejarah dengan melakukan ini. Melakukan ini dengan perubahan yang telah didorong ke repo jarak jauh akan menyebabkan masalah. Saya merekomendasikan hanya melakukan ini dengan komit yang bersifat lokal.

Schleis
sumber
4
Bahkan jika saya memilih sha sebelum cabangnya menyimpang, saya melihat semua komitmen dari cabang ungu -_-
Benjamin Toueg
1
Ya, kemudian Anda menghapusnya di editor yang muncul git rebasedan mereka akan dihapus.
Schleis
4
Menghapus komit mengakibatkan hilangnya semua modifikasi penggabungan. Tetapi saya melakukan soft reset dan saya dapat memiliki sesuatu yang saya inginkan (pesanan tidak sesuai dengan harapan awal).
Benjamin Toueg
2
jawaban ini tidak lengkap secara rinci, dari cabang mana Anda memulai rebase?
grgry
3
Cukup yakin Anda tidak ingin 'menghapus' komit. 'hapus' bukanlah pilihan di rebase, tapi hapus adalah. jika Anda menghapus komit, Anda akan kehilangan perubahan yang diperkenalkan. Anda ingin menghentikan komitmen.
thecoshman
71

Dimulai dengan repo dalam keadaan semula

Sejarah repo asli

Untuk menghapus komit gabungan dan memadatkan cabang menjadi satu komit di jalur utama

Komit terjepit, tidak ada komit penggabungan

Gunakan perintah ini (mengganti 5 dan 1 dengan SHA dari komit yang sesuai):

git checkout 5
git reset --soft 1
git commit --amend -m '1 2 3 4 5'
git rebase HEAD master

Untuk mempertahankan komit gabungan tapi squash cabang komit menjadi satu:

Komit tergencet, komit gabungan yang dipertahankan

Gunakan perintah ini (mengganti 5, 1 dan C dengan SHA dari komit yang sesuai):

git checkout -b tempbranch 5
git reset --soft 1
git commit --amend -m '1 2 3 4 5'
git checkout C
git merge --no-ff tempbranch
git rebase HEAD master

Untuk menghapus komit gabungan dan menggantinya dengan komit individu dari cabang

Cabang dipindahkan ke jalur utama, tidak ada komit penggabungan

Lakukan saja (mengganti 5 dengan SHA dari komit yang sesuai):

git rebase 5 master

Dan akhirnya, untuk menghapus seluruh cabang

Cabang dicabut seluruhnya

Gunakan perintah ini (mengganti C dan D dengan SHA dari komit yang sesuai):

git rebase --onto C D~ master
Allen Luce
sumber
di git rebase 5 masterkasus, mengapa tidak "ABC 1 2 3 4 5 D ..." order?
Roy
1
Perintah itu mengambil komit yang mastertidak memiliki kesamaan dengan 5dan menjatuhkannya di atasnya 5. Komit di Cbukanlah bagian dari garis keturunan 5, itu yang pertama dipindahkan ke atas 5.
Allen Luce
2
Jika Anda ingin berakhir dengan "ABC 1 2 3 4 5 D ..." Anda dapat melakukan:git rebase C 5; git rebase 5 master
Allen Luce
19

Untuk Hanya Menghapus Komitmen Gabungan

Jika semua yang ingin Anda lakukan adalah menghapus komit gabungan (2) sehingga tidak pernah terjadi, perintahnya adalah sebagai berikut

git rebase --onto <sha of 1> <sha of 2> <blue branch>

Dan sekarang cabang ungu tidak ada di log komit biru sama sekali dan Anda memiliki dua cabang terpisah lagi. Anda kemudian dapat menekan ungu secara mandiri dan melakukan manipulasi lain apa pun yang Anda inginkan tanpa melakukan penggabungan.

Warren
sumber
1
Dari semua jawaban, menurut saya ini yang paling mudah dan paling mudah dilakukan. Terima kasih.
Roshambo
16

Ada dua cara untuk mengatasinya berdasarkan apa yang Anda inginkan:

Solusi 1 : Hapus komit ungu, pertahankan riwayat (jika Anda ingin memutar kembali)

git revert -m 1 <SHA of merge>

-m 1 menentukan baris induk mana yang akan dipilih

Komit ungu akan tetap ada dalam riwayat tetapi karena Anda telah mengembalikan, Anda tidak akan melihat kode dari komit tersebut.


Solusi 2 : Hapus komit ungu sepenuhnya (perubahan yang mengganggu jika repo dibagikan)

git rebase -i <SHA before branching out>

dan hapus (hapus garis) sesuai dengan komitmen ungu.

Ini akan lebih mudah jika komit tidak dibuat setelah penggabungan. Komit tambahan meningkatkan kemungkinan konflik selama revert/rebase.

prem
sumber
Kedengarannya tidak benar. Mengesampingkan fakta bahwa sulit untuk mengatakan apa yang poster asli ingin lakukan dengan komitmen ungu di tempat pertama, jika Anda mengembalikan penggabungan, tidak apa-apa, itu akan melakukan patch terbalik dari perubahan dari komit itu dan menambahkannya sebagai komit lain, membatalkan komitmen ungu. Ini seperti 1 - 1 = 0. Tetapi jika Anda kemudian menghapus kembali komitmen ungu, Anda meninggalkan tambalan yang dikembalikan, kecuali jika Anda mengubah kembali itu juga. Jika tidak, ini seperti menerapkan -1ke riwayat Anda, tidak 0, jadi Anda akan meninggalkan perubahan yang tidak Anda inginkan.
@Cupcake, disediakan dua jawaban terpisah. Saya telah merevisi jawaban agar tidak terlalu membingungkan: P
prem
AFAIK bukan ini yang diminta OP. Dia ingin menyimpan perubahan, tetapi menghilangkan kebisingan dari lognya. Untuk itu, dia perlu menghentikan komit, menghapus akan menghapus perubahan.
thecoshman
Benar, sepertinya pertanyaan asli telah diubah kata-katanya. Jawaban ini bukan untuk masalah OP.
Prem