Bagaimana saya bisa dengan mudah membatalkan git rebase?
Ide saya saat ini hanya pendekatan manual:
git checkout
pada orang tua komit untuk kedua cabang- Buat cabang temp dari sana
git cherry-pick
semua dilakukan dengan tangan- ganti cabang tempat saya rebased oleh cabang yang dibuat secara manual
Dalam situasi saya saat ini, ini akan berhasil karena saya dapat dengan mudah melihat komit dari kedua cabang (satu adalah barang saya, yang lain adalah barang rekan saya).
Namun pendekatan saya menganggap saya sebagai suboptimal dan rawan kesalahan (misalkan saya baru saja rebased dengan 2 cabang saya sendiri).
Klarifikasi : Saya sedang berbicara tentang rebase di mana sekelompok komit diputar ulang. Bukan hanya satu.
git
rebase
git-rebase
undo
webmat
sumber
sumber
Jawaban:
Cara termudah adalah dengan menemukan komit dari cabang seperti itu segera sebelum rebase dimulai di reflog ...
dan untuk mereset cabang saat ini (dengan peringatan yang biasa tentang menjadi benar-benar yakin sebelum mengatur ulang dengan
--hard
opsi).Misalkan komit lama ada
HEAD@{5}
di ref log:Di Windows, Anda mungkin perlu mengutip referensi:
Anda dapat memeriksa riwayat kandidat kepala lama dengan hanya melakukan
git log HEAD@{5}
( Windowsgit log "HEAD@{5}"
:).Jika Anda tidak menonaktifkan per reflog cabang, Anda seharusnya bisa melakukannya
git reflog branchname@{1}
karena rebase melepaskan kepala cabang sebelum menempel kembali ke kepala akhir. Saya akan mengecek ini, meskipun karena saya belum memverifikasi ini baru-baru ini.Per default, semua reflog diaktifkan untuk repositori non-telanjang:
sumber
git log -g
(tip dari Scott Chacon's progit.org/book ).git rebase --abort
(-i
tidak masuk akal dengan--abort
) adalah untuk meninggalkan rebase yang belum selesai - baik karena ada konflik atau karena itu interaktif atau keduanya; ini bukan tentang membatalkan rebase yang berhasil yang merupakan pertanyaannya. Anda akan menggunakanrebase --abort
ataureset --hard
bergantung pada situasi di mana Anda berada. Anda seharusnya tidak perlu melakukan keduanya.git tag BACKUP
. Anda dapat kembali ke sana jika terjadi kesalahan:git reset --hard BACKUP
commit:
sebagai lawanrebase:
. Kedengarannya jelas tetapi sedikit membingungkan saya.git reset --hard ORIG_HEAD
melakukan trik juga segera setelah rebase yang tidak disengaja?Sebenarnya, rebase menyimpan titik awal Anda
ORIG_HEAD
jadi ini biasanya sesederhana:Namun, the
reset
,rebase
danmerge
semua menyimpanHEAD
pointer asli Anda ke dalamORIG_HEAD
jadi, jika Anda telah melakukan salah satu dari perintah itu sejak rebase Anda mencoba untuk membatalkan maka Anda harus menggunakan reflog.sumber
ORIG_HEAD
tidak lagi berguna, Anda juga dapat menggunakanbranchName@{n}
sintaksis, di manan
posisi ke-n sebelumnya dari penunjuk cabang. Jadi misalnya, jika Anda rebasefeatureA
cabang ke cabang Andamaster
, tetapi Anda tidak menyukai hasil rebase, maka Anda bisa melakukannyagit reset --hard featureA@{1}
untuk mengatur ulang cabang kembali ke tempat itu sebelum Anda melakukan rebase. Anda dapat membaca lebih lanjut tentang sintaks cabang @ {n} di dokumentasi Git resmi untuk revisi .git rebase --abort
.git 2.17.0
.git reset --hard ORIG_HEAD
bisa digunakan berulang-ulang untuk memutar kembali dan lagi. Katakan, Jika A --- rebase ke --- B --- rebase ke --- C, sekarang saya di C, saya bisa kembali ke A dengan menggunakan dua kaligit reset --hard ORIG_HEAD
git rebase --abort
?Jawaban Charles berhasil, tetapi Anda mungkin ingin melakukan ini:
untuk membersihkan setelah
reset
.Kalau tidak, Anda mungkin mendapatkan pesan "
Interactive rebase already started
".sumber
Menyetel ulang cabang ke objek komit yang menjuntai dari tip lamanya tentu saja merupakan solusi terbaik, karena mengembalikan keadaan sebelumnya tanpa mengeluarkan usaha apa pun. Tetapi jika Anda kehilangan komitmen tersebut (mis. Karena Anda mengumpulkan sampah di repositori Anda untuk sementara waktu, atau ini adalah klon baru), Anda selalu dapat rebase cabang lagi. Kunci untuk ini adalah
--onto
saklar.Katakanlah Anda memiliki cabang topik yang secara imajinatif dipanggil
topic
, yang Anda cabutmaster
ketika ujungnyamaster
adalah0deadbeef
komit. Pada titik tertentu saat ditopic
cabang, Anda melakukannyagit rebase master
. Sekarang Anda ingin membatalkan ini. Begini caranya:Ini akan mengambil semua komitmen
topic
yang tidak aktifmaster
dan mengulanginya di atas0deadbeef
.Dengan
--onto
, Anda dapat mengatur ulang sejarah Anda menjadi hampir semua bentuk apa pun .Selamat bersenang-senang. :-)
sumber
--onto
dan-i
Anda dapat mengatur ulang sejarah Anda menjadi hampir semua bentuk apa pun. Gunakan gitk (atau gitx di mac) untuk melihat bentuk yang Anda buat :-).Saya benar-benar meletakkan tag cadangan pada cabang sebelum saya melakukan operasi nontrivial (kebanyakan rebases adalah sepele, tapi saya akan melakukannya jika terlihat rumit di mana saja).
Kemudian, mengembalikannya semudah
git reset --hard BACKUP
.sumber
branchName@{n}
sintaksis, di sinin
adalah posisi ke-n dari penunjuk cabang. Jadi misalnya, jika Anda rebasefeatureA
cabang ke cabang Andamaster
, tetapi Anda tidak menyukai hasil rebase, maka Anda bisa melakukannyagit reset --hard featureA@{1}
untuk mengatur ulang cabang kembali ke tempat itu sebelum Anda melakukan rebase. Anda dapat membaca lebih lanjut tentangbranch@{n}
sintaks di dokumen resmi Git untuk revisi .HEAD
dari cabang disimpan sementaraORIG_HEAD
. Tetapi teknik menggunakan label cabang cadangan juga berfungsi, itu hanya langkah-langkah lebih lanjut.Jika Anda telah mendorong cabang Anda ke repositori jarak jauh (biasanya asalnya) dan kemudian Anda telah melakukan rebase sukses (tanpa penggabungan) (
git rebase --abort
memberikan "Tidak ada rebase sedang berlangsung") Anda dapat dengan mudah mengatur ulang cabang menggunakan perintah:Contoh:
sumber
Menggunakan
reflog
tidak berhasil untuk saya.Apa yang berhasil bagi saya mirip dengan yang dijelaskan di sini . Buka file dalam .git / logs / ref yang diberi nama setelah cabang yang telah direbase dan temukan baris yang berisi "rebase finsihed", sesuatu seperti:
Periksa komit kedua yang terdaftar di telepon.
Setelah dikonfirmasi ini berisi perubahan saya yang hilang, saya bercabang dan menghela napas lega.
sumber
Untuk banyak komit, ingat bahwa komit apa pun merujuk semua riwayat yang mengarah pada komit itu. Jadi dalam jawaban Charles, bacalah "komitmen lama" sebagai "komitmen terbaru". Jika Anda mengatur ulang ke komit itu, maka semua riwayat yang mengarah ke komit itu akan muncul kembali. Ini harus melakukan apa yang Anda inginkan.
sumber
Mengikuti solusi dari @Allan dan @Zearin, saya berharap saya bisa melakukan komentar saja tetapi saya tidak memiliki reputasi yang cukup, jadi saya telah menggunakan perintah berikut:
Alih-alih melakukan
git rebase -i --abort
(perhatikan i ) saya harus hanya melakukangit rebase --abort
( tanpa yang -i ).Menggunakan keduanya
-i
dan--abort
pada saat yang sama menyebabkan Git menunjukkan kepada saya daftar penggunaan / opsi.Jadi status cabang saya sebelumnya dan saat ini dengan solusi ini adalah:
sumber
Jika Anda berhasil rebased terhadap cabang jarak jauh dan tidak bisa
git rebase --abort
Anda masih bisa melakukan beberapa trik untuk menyelamatkan pekerjaan Anda dan tidak memiliki dorongan paksa. Misalkan cabang Anda saat ini yang diubah oleh kesalahan dipanggilyour-branch
dan sedang dilacakorigin/your-branch
git branch -m your-branch-rebased
# ubah nama cabang saat inigit checkout origin/your-branch
# checkout ke status terbaru yang diketahui asalnyagit checkout -b your-branch
git log your-branch-rebased
, bandingkangit log your-branch
dan tentukan komit yang hilang dariyour-branch
git cherry-pick COMMIT_HASH
untuk setiap komit diyour-branch-rebased
remote/your-branch
dan Anda hanya perlu mendorongyour-branch
sumber
Katakanlah saya rebase master ke cabang fitur saya dan saya mendapatkan 30 commit baru yang merusak sesuatu. Saya telah menemukan bahwa sering kali paling mudah menghilangkan komitmen buruk.
Rebase interaktif untuk 31 komit terakhir (tidak ada salahnya jika Anda mengambil terlalu banyak).
Cukup ambil komit yang ingin Anda singkirkan dan tandai dengan "d", bukan "pick". Sekarang komit dihapus secara efektif membatalkan rebase (jika Anda menghapus hanya komit yang baru saja Anda dapatkan saat rebasing).
sumber
Untuk pemula / siapa pun yang terlalu takut melakukan hard reset, Anda dapat checkout komit dari reflog, dan kemudian menyimpannya sebagai cabang baru.
Temukan komit tepat sebelum Anda mulai rebasing. Anda mungkin perlu menggulir lebih jauh ke bawah untuk menemukannya (tekan Enter atau PageDown). Perhatikan nomor KEPALA dan ganti 57:
Tinjau cabang / komit, jika terlihat bagus buat cabang baru menggunakan KEPALA ini:
sumber
Jika Anda menggunakan cabang, Anda dapat menggunakan:
Tidak hanya ada log referensi untuk HEAD (diperoleh oleh
git reflog
), ada juga reflog untuk setiap cabang (diperoleh olehgit reflog <branch>
). Jadi, jika Anda aktifmaster
makagit reflog master
akan mendaftar semua perubahan ke cabang itu. Anda dapat merujuk ke perubahan olehmaster@{1}
,master@{2}
, dllgit rebase
biasanya akan mengubah KEPALA beberapa kali tetapi cabang saat ini akan diperbarui hanya sekali.@{1}
hanyalah jalan pintas untuk cabang saat ini , jadi itu sama denganmaster@{1}
jika Anda aktifmaster
.git reset --hard ORIG_HEAD
tidak akan berfungsi jika Anda digunakangit reset
selama interaktifrebase
.sumber
Apa yang biasanya saya lakukan adalah
git reset #commit_hash
untuk komit terakhir di mana saya pikir rebase tidak berpengaruh.
kemudian
git pull
Sekarang cabang Anda harus sama persis seperti master dan rebased commit seharusnya tidak ada di dalamnya.
Sekarang kita bisa memilih komit di cabang ini.
sumber
Saya mencoba semua saran dengan reset dan reflog tanpa hasil. Mengembalikan sejarah lokal IntelliJ menyelesaikan masalah file yang hilang
sumber
git reset --hard origin / {branchName}
adalah solusi yang tepat untuk mengatur ulang semua perubahan lokal Anda yang dilakukan dengan rebase.
sumber
origin/branch
Anda mungkin kehilangan perubahan antara HEAD dan titik itu. Anda tidak ingin itu secara umum.Jika Anda mengacaukan sesuatu dalam git rebase, misalnya
git rebase --abort
, saat Anda memiliki file yang tidak dikomit, mereka akan hilang dangit reflog
tidak akan membantu. Ini terjadi pada saya dan Anda harus berpikir di luar kotak di sini. Jika Anda beruntung seperti saya dan menggunakan IntelliJ Webstorm maka Anda dapatright-click->local history
dan dapat kembali ke keadaan file / folder sebelumnya, apa pun kesalahan yang Anda lakukan dengan perangkat lunak versi. Itu selalu baik untuk menjalankan kegagalan yang lain.sumber
git rebase --abort
batalkan rebase aktif, itu tidak membatalkan rebase. Juga, menggunakan dua VCS pada saat yang sama adalah ide yang buruk. Ini adalah fitur yang bagus dalam perangkat lunak Jetbrains tetapi Anda sebaiknya tidak menggunakan keduanya. Lebih baik mempelajari Git, terutama saat menjawab pertanyaan tentang Stack Overflow yang membahas tentang Git.