Saya ingin rebase ke komit tertentu, bukan ke KEPALA cabang lainnya:
A --- B --- C master
\
\-- D topic
untuk
A --- B --- C master
\
\-- D topic
dari pada
A --- B --- C master
\
\-- D topic
Bagaimana saya bisa mencapainya?
git
version-control
rebase
git-rebase
Ondra Žižka
sumber
sumber
git checkout B
sebelum menjalankangit rebase
?rebase
perintah yang penting.Jawaban:
Anda dapat menghindari menggunakan parameter --onto dengan membuat cabang temp pada komit yang Anda sukai dan kemudian menggunakan rebase dalam bentuknya yang sederhana:
sumber
git rebase temp
(ketika di grup ) menyerah dengan "Grup cabang saat ini adalah yang terbaru.".git rebase --onto <target> <from> <to>
sehingga Anda dapat menentukan komit <dari>.Anda bahkan dapat mengambil pendekatan langsung:
sumber
topic
dancommitB
.It works by going to the common ancestor of the two branches (the one you’re on and the one you’re rebasing onto), getting the diff introduced by each commit of the branch you’re on, saving those diffs to temporary files, resetting the current branch to the same commit as the branch you are rebasing onto, and finally applying each change in turn.
saya mencobanya lagi sekarang dan sepertinya berfungsi dengan baik.m > n
.Gunakan opsi "ke":
sumber
D
danD^
apakah hash dari commit terakhir dan selanjutnya dari "topik"?git rebase --onto <new-parent> <old-parent>
. Lihat Mengatur pointer git parent ke induk yang berbeda . Dalam kasus Anda, <new-parent> adalah B, dan <old-parent> adalah A.git rebase --onto <commit-ID> master
git rebase --onto master <commit-ID-of-old-parent>
dan untuk OPgit rebase --onto B A
.Komentar oleh jsz di atas menyelamatkan saya dari banyak rasa sakit, jadi inilah penerima langkah-demi-langkah berdasarkan itu yang telah saya gunakan untuk rebase / memindahkan komit di atas komit lainnya:
git rebase --onto <new parent> <old parent>
Dalam contoh di atas itu sesederhana:
sumber
git rebase --onto B master
, lihat jawaban saya untuk penjelasan yang lebih menyeluruh.Solusi Topik
Perintah yang benar untuk menjawab pertanyaan yang diposting dapat berupa salah satu dari yang berikut (dengan asumsi cabang
topic
sudah diperiksa):Jika
topic
tidak dicentang, Anda cukup menambahkantopic
perintah (kecuali yang terakhir) seperti:Atau, periksa cabang pertama dengan:
Rebase Setiap String Komit ke Komit Target
Bentuk dasar dari perintah yang kita butuhkan, yang dikutip dari dokumentasi, adalah:
<Branch>
bersifat opsional dan yang dilakukannya hanyalah memeriksa cabang yang ditentukan sebelum menjalankan sisa perintah. Jika Anda sudah memeriksa cabang yang ingin Anda rebase, maka Anda tidak perlu ini. Perhatikan bahwa Anda harus menentukan<Upstream>
untuk menentukan<Branch>
atau git akan berpikir Anda menentukan<Upstream>
.<Target>
adalah komitmen yang akan kami lampirkan pada komitmen kami. Saat memberikan nama cabang, Anda cukup menentukan komit kepala cabang itu.<Target>
bisa berupa komit apa pun yang tidak akan dimuat dalam string komit yang dipindahkan. Sebagai contoh:Untuk memindahkan seluruh cabang fitur, Anda tidak dapat memilih
X
,Y
,Z
, ataufeature
sebagai<Target>
karena mereka semua komit dalam kelompok dipindahkan.<Upstream>
istimewa karena dapat berarti dua hal yang berbeda. Jika itu adalah komit yang merupakan leluhur dari cabang yang diperiksa, maka itu berfungsi sebagai titik potong. Dalam contoh saya disediakan, ini akan menjadi sesuatu yang tidakC
,D
ataumaster
. Semua komit setelah<Upstream>
sampai kepala cabang yang diperiksa adalah yang akan dipindahkan.Namun, jika
<Upstream>
bukan leluhur, maka git mencadangkan rantai dari komit yang ditentukan sampai jika menemukan leluhur yang sama dengan cabang yang dicentang (dan batal jika tidak dapat menemukannya). Dalam kasus kami, seorang<Upstream>
dariB
,C
,D
, ataumaster
semua akan mengakibatkan berkomitmenB
melayani sebagai titik potong.<Upstream>
itu sendiri merupakan perintah opsional dan jika tidak ditentukan, maka git melihat induk dari cabang yang diperiksa yang setara dengan memasukkanmaster
.Sekarang git telah memilih commit yang akan dipotong dan dipindahkan, ia menerapkannya untuk
<Target>
, melompati semua yang sudah diterapkan pada target.Contoh dan Hasil yang Menarik
Menggunakan titik awal ini:
git rebase --onto D A feature
Akan berlaku komit
B
,C
,X
,Y
,Z
untuk melakukanD
dan berakhir melompat-lompatB
danC
karena mereka sudah telah diterapkan.git rebase --onto C X feature
Akan menerapkan komit
Y
danZ
berkomitmenC
, menghapus komit secara efektifX
sumber
Solusi yang lebih sederhana adalah
git rebase <SHA1 of B> topic
. Ini berfungsi terlepas dari di mana AndaHEAD
berada.Kami dapat mengkonfirmasi perilaku ini dari git rebase doc
Anda mungkin berpikir apa yang akan terjadi jika saya menyebutkan SHA1
topic
juga dalam perintah di atas?git rebase <SHA1 of B> <SHA1 of topic>
Ini juga akan berfungsi tetapi rebase tidak akan
Topic
menunjukkan cabang baru yang dibuat danHEAD
akan berada dalam kondisi terpisah. Jadi dari sini Anda harus menghapus secara manualTopic
dan membuat referensi cabang baru pada cabang baru yang dibuat oleh rebase.sumber
Saya telah menggunakan campuran solusi yang dijelaskan di atas:
Saya merasa lebih mudah untuk membaca dan memahami. Solusi yang diterima membawa saya ke konflik gabungan (terlalu malas untuk diperbaiki dengan tangan):
sumber
Karena rebasing sangat mendasar, inilah perluasan jawaban Nestor Milyaev . Menggabungkan komentar jsz dan Simon South dari jawaban Adam Dymitruk menghasilkan perintah ini yang bekerja di
topic
cabang terlepas dari apakah itu cabang darimaster
komit cabangA
atauC
:Perhatikan bahwa argumen terakhir diperlukan (jika tidak, akan memutar kembali cabang Anda untuk melakukan
B
).Contoh:
Jadi perintah terakhir adalah yang biasanya saya gunakan.
sumber
Ada cara lain untuk melakukannya atau jika Anda ingin kembali ke lebih dari satu komitmen.
Berikut adalah contoh untuk kembali ke
n
sejumlah komitmen:Demi pertanyaan ini, ini juga dapat dilakukan:
Perintah ini bekerja dengan sempurna
git version 2.7.4
. Belum mengujinya pada versi lain.sumber