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 topic
cabang yang dibuat dengan git checkout -b topic origin/master
, riwayat cabang pelacak jarak jauh origin/master
mungkin 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/master
digunakan untuk titik di komit B3
, B2
, B1
dan sekarang menunjuk B
, dan Anda topic
cabang dimulai di atas itu kembali ketika origin/master
berada di B3
.
Mode ini menggunakan reflog dari origin/master
to find B3
sebagai titik percabangan, sehingga topic
dapat 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-base
perintah 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 base
cabang " " (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
base
cabang " " ada di B
, tetapi pengambilan sebelumnya mengamati bahwa ujungnya dulu B3
dan kemudian B2
dan kemudian B1
sebelum sampai ke komit saat ini, dan
- cabang yang di-rebased di atas "base" terbaru didasarkan pada commit
B3
,
mencoba untuk menemukan B3
dengan 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 Derived
dan 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 B
yang tidak identik dengan patch B
;
C*
dan D*
yang patch-identik dengan C
dan D
masing-masing dan konflik tekstual jika diterapkan dalam urutan yang salah;
E
tergantung secara tekstual D
.
Hasil yang benar dari git rebase master dev
yaitu yang B
diidentifikasi sebagai garpu-titik dev
dan master
, sehingga C
, D
, E
adalah commit yang perlu diputar ke master
; tetapi C
dan D
identik 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 B
ke cabang yang berisi B'
hasil dalam konflik dan jika komit yang identik dengan tambalan tidak diidentifikasi dengan benar, maka memilih C
ke 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-point
perbaikan 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.