เริ่มต้นด้วย git 1.9 / 2.0 Q1 2014 คุณจะไม่ต้องทำเครื่องหมายที่มาของสาขาก่อนหน้าก่อนที่จะทำการรีฐานข้อมูลบนสาขาต้นน้ำที่เขียนใหม่ตามที่อธิบายไว้ในคำตอบของAristotle Pagaltzis :
ดูที่กระทำ 07d406bและกระทำ d96855f :
หลังจากทำงานกับtopic
สาขาที่สร้างขึ้นgit checkout -b topic origin/master
ประวัติของสาขาการติดตามระยะไกลorigin/master
อาจได้รับการกรอกลับและสร้างขึ้นใหม่ซึ่งนำไปสู่ประวัติของรูปร่างนี้:
o---B1
/
---o---o---B2--o---o---o---B (origin/master)
\
B3
\
Derived (topic)
ที่origin/master
ใช้ในการกระทำที่จุดB3
, B2
, B1
และตอนนี้ก็ชี้ที่B
และคุณtopic
สาขาเริ่มต้นด้านบนของมันกลับมาเมื่ออยู่ที่ origin/master
B3
โหมดนี้ใช้ reflog ของorigin/master
เพื่อค้นหาB3
เป็นจุดแยกเพื่อให้topic
สามารถ rebased ที่ด้านบนของการปรับปรุงorigin/master
โดย:
$ fork_point=$(git merge-base --fork-point origin/master topic)
$ git rebase --onto origin/master $fork_point topic
นั่นคือเหตุผลที่git merge-base
คำสั่งมีตัวเลือกใหม่:
--fork-point::
ค้นหาจุดที่สาขา (หรือมีประวัติใด ๆ ที่นำไปสู่การ<commit>
) คดเคี้ยวจากสาขาอื่น (หรือการอ้างอิงใด ๆ<ref>
)
สิ่งนี้ไม่เพียงแค่มองหาบรรพบุรุษร่วมของทั้งสองคนเท่านั้น แต่ยังคำนึงถึง reflog <ref>
เพื่อดูว่าประวัติศาสตร์ที่นำไปสู่การ<commit>
แยกจากชาติก่อนของสาขา<ref>
หรือไม่
ว่า " git pull --rebase
คำสั่ง" คำนวณจุดแยกของสาขาที่ถูก rebased ใช้รายการ reflog ของ " base
สาขา" (โดยปกติจะเป็นสาขาที่ห่างไกลการติดตาม) การทำงานของสาขาอยู่บนพื้นฐานในการสั่งซื้อที่จะรับมือกับกรณีที่ "ฐาน" สาขาได้รับการกรอใหม่และสร้างใหม่
ตัวอย่างเช่นหากประวัติดูเหมือนที่ไหน:
- เคล็ดลับในปัจจุบันของ "
base
สาขา" ที่B
แต่ก่อนหน้านี้ดึงข้อมูลข้อสังเกตว่าปลายที่เคยเป็นB3
แล้วB2
และจากนั้นB1
ก่อนที่จะเดินทางไปยังปัจจุบันกระทำและ
- สาขาที่ถูก rebased ด้านบนของ "ฐาน" ล่าสุดอยู่บนพื้นฐานการกระทำ
B3
,
ก็พยายามที่จะหาB3
โดยจะผ่านการส่งออกของ " git rev-list --reflog base
" (คือB
, B1
, B2
, B3
) จนกว่าจะพบการกระทำที่เป็นบรรพบุรุษของปลายปัจจุบัน " Derived (topic)
"
ภายในเรามีget_merge_bases_many()
ที่สามารถคำนวณสิ่งนี้ได้ในครั้งเดียว
เราต้องการการผสานฐานระหว่างDerived
และการผสานรวมที่สมมติขึ้นซึ่งจะเกิดจากการรวมเคล็ดลับทางประวัติศาสตร์ทั้งหมดของ " base (origin/master)
"
เมื่อมีการคอมมิตดังกล่าวเราควรได้ผลลัพธ์เดียวซึ่งตรงกับหนึ่งในรายการ reflog ของ " base
"
Git 2.1 (Q3 2014) จะเพิ่มทำให้คุณลักษณะนี้มีประสิทธิภาพมากขึ้น: ดูการกระทำ 1e0dacdโดยJohn Keeping ( johnkeeping
)
จัดการกับสถานการณ์ที่เรามีโทโพโลยีต่อไปนี้อย่างถูกต้อง:
C --- D --- E <- dev
/
B <- master@{1}
/
o --- B' --- C* --- D* <- master
ที่ไหน:
B'
เป็นรุ่นที่ได้รับการแก้ไขแล้วของB
ที่ไม่ได้แพทช์เหมือนกันกับB
;
C*
และD*
เป็นแพทช์เหมือนกันC
และD
ตามลำดับและขัดแย้งกันทางข้อความหากนำไปใช้ในลำดับที่ไม่ถูกต้อง
E
ขึ้นอยู่ textually D
บน
ผลที่ถูกต้องของการgit rebase master dev
เป็นสิ่งที่B
ถูกระบุว่าเป็นส้อมจุดdev
และmaster
เพื่อให้C
, D
, E
เป็นกระทำที่จะต้องมีการย้อนสู่master
; แต่C
และD
มีแพทช์เหมือนกันกับC*
และD*
และเพื่อให้สามารถปรับตัวลดลงเพื่อให้ผลลัพธ์ที่ได้คือ:
o --- B' --- C* --- D* --- E <- dev
หากไม่ได้ระบุจุดส้อมการเลือกB
ไปยังสาขาที่มีB'
ผลลัพธ์ในความขัดแย้งและหากระบุการกระทำที่เหมือนกันของแพทช์ไม่ถูกต้องการเลือกC
ไปยังสาขาที่มีD
(หรือเทียบเท่าD*
) จะทำให้เกิดความขัดแย้ง
ว่า " --fork-point
โหมด" ของ " git rebase
" ถดถอยเมื่อคำสั่งที่ถูกเขียนใหม่ใน C ย้อนกลับไปในยุค 2.20 ซึ่งได้รับการแก้ไขด้วย Git 2.27 (Q2 2020)
ดูกระทำ f08132f (9 ธันวาคม 2019) โดยJunio C Hamano (gitster
)
(ผสานโดยJunio C Hamano - gitster
-ในการกระทำ fb4175b , 27 มี.ค. 2020)
rebase
: --fork-point
การแก้ไขการถดถอย
ลงนามโดย: Alex Torok
[jc: ปรับปรุงการแก้ไขและใช้การทดสอบของ Alex]
ลงนามโดย: Junio C Hamano
" git rebase --fork-point master
" เคยใช้งานได้ตามที่เรียกภายใน " git merge-base --fork-point
" ซึ่งรู้วิธีจัดการ refname สั้น ๆ และย่อให้เป็น refname แบบเต็มก่อนที่จะเรียกget_fork_point()
ฟังก์ชันพื้นฐาน
สิ่งนี้ไม่เป็นความจริงอีกต่อไปหลังจากที่เขียนคำสั่งใหม่ในภาษา C เนื่องจากการเรียกภายในที่โทรโดยตรงไปยังget_fork_point()
ไม่ได้ลดการอ้างอิงสั้น ๆ
ย้ายอาร์กิวเมนต์ "dwim the refname ไปยัง refname แบบเต็ม" ที่ใช้ใน "git merge-base" ไปยังget_fork_point()
ฟังก์ชันพื้นฐานเพื่อให้ผู้เรียกใช้ฟังก์ชันอื่นในการใช้ "git rebase" ทำงานในลักษณะเดียวกันในการแก้ไข การถดถอยนี้