ทำความเข้าใจและจดจำพารามิเตอร์ rebase git


12

จนถึงตอนนี้ส่วนที่สับสนมากที่สุดของการคอมไพล์ก็คือการรีเฟรชไปยังสาขาอื่น โดยเฉพาะมันคืออาร์กิวเมนต์บรรทัดคำสั่งที่สร้างความสับสน

ทุกครั้งที่ฉันต้องการ rebase ชิ้นเล็ก ๆ ของกิ่งหนึ่งลงบนปลายอีกอันฉันต้องทบทวนเอกสาร rebit git และใช้เวลาประมาณ 5-10 นาทีเพื่อทำความเข้าใจว่าข้อโต้แย้งหลัก 3 ข้อควรเป็นอย่างไร

git rebase <upstream> <branch> --onto <newbase>

อะไรคือกฎเกณฑ์ที่ดีที่จะช่วยให้ฉันจดจำว่าพารามิเตอร์ทั้งสามเหล่านี้ควรถูกตั้งค่าไว้อย่างไรเมื่อมีการรีบูตใด ๆ ไปยังสาขาอื่น

จำไว้ว่าฉันได้อ่านเอกสาร git-rebase ซ้ำแล้วซ้ำเล่าและอีกครั้งและอีกครั้งและอีกครั้ง (และอีกครั้ง) แต่มันก็ยากที่จะเข้าใจเสมอ (เช่นกระดาษขาววิทยาศาสตร์ที่น่าเบื่อหรือบางอย่าง) ดังนั้น ณ จุดนี้ฉันรู้สึกว่าฉันต้องเกี่ยวข้องกับคนอื่นเพื่อช่วยให้เข้าใจ

เป้าหมายของฉันคือฉันไม่ควรตรวจสอบเอกสารประกอบสำหรับพารามิเตอร์พื้นฐานเหล่านี้ ฉันไม่สามารถจดจำพวกเขาได้จนถึงตอนนี้และฉันได้ทำเงินคืนจำนวนหนึ่งแล้ว ดังนั้นมันเป็นบิตแปลกที่ฉันได้รับสามารถที่จะจดจำทุกคำสั่งอื่น ๆ และพารามิเตอร์เพื่อให้ห่างไกล แต่ไม่ rebase --ontoกับ


คุณสามารถกำหนดนามแฝง git บางอย่างสำหรับกรณีการใช้งานทั่วไปของคุณหรือสร้างสคริปต์ตัวช่วยสร้างขึ้นเพื่อเตือนให้คุณทราบว่าพารามิเตอร์แต่ละตัวมีความหมายอย่างไรก่อนดำเนินการคำสั่ง
Rory Hunter

4
อ่าจิตใจที่งดงามและบริสุทธิ์ของตัวเลือกคำสั่งคอมไพล์ ดังนั้นการใช้อย่างสังหรณ์ใจ เป็นความสุขที่แท้จริงเสมอ
JensG

คำตอบ:


10

ข้าม--ontoไปสักครู่ upstreamและbranchค่อนข้างพื้นฐานและเรียงลำดับจากการเลียนแบบcheckoutและbranch- อาร์กิวเมนต์ที่สองเป็นทางเลือก:

git branch <newbranch>
git branch <newbranch> <base>
git checkout -b <newbranch>
git checkout -b <newbranch> <base>
git rebase <upstream>
git rebase <upstream> <branch>

(นอกเหนือชื่อของการขัดแย้งเหล่านี้ในrebase"ต้นน้ำ" และ "สาขา" ไม่ได้มากพรรณนา IMO ฉันมักจะคิดว่าพวกเขาเช่น peachoftree. <start>และ<end>ซึ่งเป็นวิธีการที่ฉันจะใช้พวกเขา git rebase <start> <end>)

เมื่อละเว้นสาขาที่สองผลลัพธ์จะเหมือนกับการตรวจสอบจากสาขานั้นก่อนแล้วจึงทำราวกับว่าคุณไม่ได้ระบุสาขานั้น ข้อยกเว้นคือbranchสิ่งที่ไม่เปลี่ยนสาขาปัจจุบันของคุณ:

git checkout <base> && git branch <newbranch> && git checkout <previous_branch>
git checkout <base> && git checkout -b <newbranch>
git checkout <end>  && git rebase <start>

สำหรับความเข้าใจว่าrebaseเมื่อไรที่เรียกใช้ฉันแรกเริ่มโดยคิดว่าเป็นการผสานแบบพิเศษ มันไม่ได้จริงๆ แต่มันช่วยเมื่อแรกเริ่มเข้าใจ rebase วิธียืมตัวอย่างของ peachoftree:

A--B--F--G master
    \
     C--D--E feature

git merge masterผลในครั้งนี้:

A--B--F-----G master
    \        \
     C--D--E--H feature

ในgit rebase masterขณะที่featureผลลัพธ์(ในขณะที่สาขา!):

A--B--F--G master
          \
           C'--D'--E' feature

ในทั้งสองกรณีfeatureนี้มีรหัสจากทั้งสองและmaster featureหากคุณไม่ได้อยู่คุณfeatureสามารถใช้อาร์กิวเมนต์ที่สองเพื่อเปลี่ยนเป็นทางลัด: git rebase master featureจะทำสิ่งเดียวกันกับด้านบน


--ontoตอนนี้สำหรับพิเศษ ส่วนที่สำคัญที่ต้องจำในการทำเช่นนี้คือมันจะมีค่าเริ่มต้น<start>หากไม่ได้ระบุไว้ ดังนั้นข้างต้นหากฉันระบุ--ontoโดยเฉพาะสิ่งนี้จะส่งผลเหมือนกัน:

git rebase --onto master master
git rebase --onto master master feature

(ฉันไม่ได้ใช้--ontoโดยไม่ได้ระบุ<end>เพียงเพราะมันง่ายกว่าในการแยกวิเคราะห์ทางจิตใจแม้จะคิดว่าทั้งสองเหมือนกันถ้าเปิดอยู่แล้วfeature)

หากต้องการดูว่าเพราะเหตุใดจึง--ontoมีประโยชน์ต่อไปนี้เป็นตัวอย่างที่แตกต่างกัน สมมติว่าฉันเปิดfeatureและสังเกตเห็นข้อผิดพลาดซึ่งฉันเริ่มแก้ไข - แต่แยกออกจากfeatureแทนmasterโดยไม่ได้ตั้งใจ:

A--B--F--G master
    \
     C--D--E feature
            \
             H--I bugfix

สิ่งที่ผมต้องการคือการ "ย้าย" กระทำเหล่านี้เพื่อให้พวกเขาไม่ได้อยู่บนขึ้นbugfix featureมันคือการจัดเรียงของการผสานหรือ rebase ใด ๆ ดังกล่าวข้างต้นแสดงให้เห็นในคำตอบนี้จะใช้เวลาสามfeatureกระทำพร้อมกับสองbugfixกระทำ

ตัวอย่างเช่นgit rebase master bugfixผิด ช่วงที่<start>จะ<end>เกิดขึ้นเพื่อรวมการกระทำทั้งหมดfeatureที่มีการเล่นซ้ำบนmaster:

A--B--F--G master
    \     \
     \     C'--D'--E'--H'--I' bugfix
      \
       C--D--E feature

สิ่งที่เราต้องการจริงเป็นช่วงของกระทำจากfeatureการที่จะต้องย้อนด้านบนของbugfix masterนั่นคือสิ่งที่--ontoมีไว้เพื่อ - ระบุเป้าหมาย "เล่นซ้ำ" ที่แตกต่างจากสาขา "เริ่มต้น":

git rebase --onto master feature bugfix

A--B--F--G master
    \     \
     \     H'--I' bugfix
      \
       C--D--E feature

1

เพียงการทบทวนการรีบูตเป็นหลักเมื่อคุณต้องการให้ประวัติการกระทำของคุณปรากฏเป็นเส้นตรงถ้าสาขาสองสาขาได้พัฒนาขึ้นโดยแยกจากกัน

วิธีที่ฉันชอบที่จะทำคือ git rebase --onto <target branch> <start branch> <end branch>

โดยที่<target branch>กิ่งที่คุณกำลัง<start branch>จะต่อกิ่งนั้นเป็นกิ่งที่<end branch>แตก<end branch>กิ่งและกิ่งที่เจ้าจะหัก

ถ้าคุณเริ่มต้นด้วย

A--B--F--G master
    \
     C--D--E feature

และทำ

git rebase --onto master master feature

คุณจะได้รับ

A--B--F--G master
          \
           C'--D'--E' feature

อีกสิ่งที่ดีที่ควรทราบคือการ<target branch>เริ่มต้นเพื่อ<start branch>ให้คุณสามารถทำเช่นเดียวกันกับ

git rebase --onto master feature

ถ้าคุณต้องการความช่วยเหลือเพิ่มเติมให้ตรวจสอบRebase โดยไม่ต้องน้ำตาคู่มือ


ผลลัพธ์ของคุณดูผิด rebase ควรปล่อยให้masterสาขาตัวเองไม่เปลี่ยนแปลง คุณเพิ่งได้รับ 'คุณสมบัติ' สาขาออกเช่นG--C'--D'--E'ในขณะที่ยังคงหยุดที่master G
แฟรงค์

@ แฟรงก์ฉันทำอย่างนั้นเพื่อเน้นสิ่งประวัติศาสตร์เชิงเส้นทั้งหมด แต่ตอนนี้ฉันคิดว่าคุณเป็นวิธีที่ดีกว่า แก้ไขแล้ว.
peachoftree

1
คุณสามารถแสดงตัวอย่างที่<target branch>และ<start branch>แตกต่างกันเพื่อช่วยให้ผู้อ่านเข้าใจกรณีทั่วไปมากที่สุด
Rufflewind
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.