Dimulai dengan git 1,9 / 2,0 Q1 2014, Anda tidak perlu menandai asal cabang Anda sebelumnya sebelum rebasing pada cabang hulu ditulis ulang, seperti yang dijelaskan dalam Aristoteles Pagaltzis 's jawabannya :
Lihat komit 07d406b dan berkomitmen d96855f :
Setelah mengerjakan topiccabang yang dibuat dengan git checkout -b topic origin/master, riwayat cabang pelacak jarak jauh origin/mastermungkin telah diputar ulang dan dibangun kembali, yang mengarah ke riwayat bentuk ini:
o---B1
/
---o---o---B2--o---o---o---B (origin/master)
\
B3
\
Derived (topic)
di mana origin/masterdigunakan untuk titik di komit B3, B2, B1dan sekarang menunjuk B, dan Anda topiccabang dimulai di atas itu kembali ketika origin/masterberada di B3.
Mode ini menggunakan reflog dari origin/masterto find B3sebagai titik percabangan, sehingga topicdapat di-rebased di atas yang diperbaruiorigin/master oleh:
$ fork_point=$(git merge-base --fork-point origin/master topic)
$ git rebase --onto origin/master $fork_point topic
Itulah mengapa git merge-baseperintah tersebut memiliki opsi baru:
--fork-point::
Temukan titik di mana cabang (atau sejarah yang mengarah ke <commit>) bercabang dari cabang lain (atau referensi apa pun) <ref>.
Ini tidak hanya mencari nenek moyang yang sama dari dua commit, tetapi juga memperhitungkan reflog <ref>untuk melihat apakah sejarah yang mengarah ke <commit>bercabang dari inkarnasi cabang sebelumnya<ref> .
Perintah " git pull --rebase" menghitung titik percabangan dari cabang yang di-rebased menggunakan entri reflog dari basecabang " " (biasanya cabang pelacak jarak jauh) yang menjadi dasar pekerjaan cabang, untuk mengatasi kasus di mana "basis" cabang telah diputar ulang dan dibangun kembali.
Misalnya, jika sejarah tampak seperti di mana:
- ujung saat ini dari
basecabang " " ada di B, tetapi pengambilan sebelumnya mengamati bahwa ujungnya dulu B3dan kemudian B2dan kemudian B1
sebelum sampai ke komit saat ini, dan
- cabang yang di-rebased di atas "base" terbaru didasarkan pada commit
B3,
mencoba untuk menemukan B3dengan pergi melalui output dari " git rev-list --reflog base" (yaitu B, B1, B2, B3) sampai menemukan komit yang merupakan nenek moyang dari ujung saat ini " Derived (topic)".
Secara internal, kami memiliki get_merge_bases_many()yang dapat menghitung ini dengan sekali jalan.
Kami menginginkan basis penggabungan antara Deriveddan komitmen penggabungan fiktif yang akan dihasilkan dengan menggabungkan semua kiat historis dari " base (origin/master)".
Jika komit seperti itu ada, kita harus mendapatkan satu hasil, yang sama persis dengan salah satu entri reflog " base".
Git 2.1 (Q3 2014) akan menambahkan untuk membuat fitur ini lebih kuat untuk ini: lihat komit 1e0dacd oleh John Keeping ( johnkeeping)
menangani dengan benar skenario di mana kita memiliki topologi berikut ini:
C --- D --- E <- dev
/
B <- master@{1}
/
o --- B' --- C* --- D* <- master
dimana:
B'adalah versi tetap Byang tidak identik dengan patch B;
C*dan D*yang patch-identik dengan Cdan Dmasing-masing dan konflik tekstual jika diterapkan dalam urutan yang salah;
Etergantung secara tekstual D.
Hasil yang benar dari git rebase master devyaitu yang Bdiidentifikasi sebagai garpu-titik devdan master, sehingga C, D, Eadalah commit yang perlu diputar ke master; tetapi Cdan Didentik dengan patch C*dan D*dan dan karenanya dapat dihilangkan, sehingga hasil akhirnya adalah:
o --- B' --- C* --- D* --- E <- dev
Jika titik percabangan tidak teridentifikasi, maka memilih Bke cabang yang berisi B'hasil dalam konflik dan jika komit yang identik dengan tambalan tidak diidentifikasi dengan benar, maka memilih Cke cabang yang berisi D(atau setara D*) menghasilkan konflik.
" --fork-point" Mode " git rebase" mengalami kemunduran saat perintah ditulis ulang di C kembali di era 2.20, yang telah diperbaiki dengan Git 2.27 (Q2 2020).
Lihat commit f08132f (09 Des 2019) oleh Junio C Hamano ( gitster) .
(Digabung oleh Junio C Hamano - gitster- di commit fb4175b , 27 Mar 2020)
rebase: --fork-pointperbaikan regresi
Ditandatangani oleh: Alex Torok
[jc: mengubah perbaikan dan menggunakan tes Alex]
Ditandatangani oleh: Junio C Hamano
" git rebase --fork-point master" dulu bekerja dengan baik, karena secara internal disebut " git merge-base --fork-point" yang tahu bagaimana menangani refname singkat dan mengubahnya menjadi nama ref lengkap sebelum memanggil get_fork_point()fungsi yang mendasarinya .
Hal ini tidak berlaku lagi setelah perintah ditulis ulang dalam C, karena panggilan internal yang dibuat langsung ke get_fork_point()tidak hanya berupa ref singkat.
Pindahkan logika "dwim the refname to the full refname" yang digunakan dalam "git merge-base" ke get_fork_point()fungsi yang mendasarinya , sehingga pemanggil lain dari fungsi tersebut dalam implementasi "git rebase" berperilaku sama untuk memperbaikinya regresi ini.