อัปเดตสาขา Git จากต้นแบบ


675

ฉันใหม่กับ Git และตอนนี้ฉันอยู่ในสถานการณ์นี้:

  • ฉันมีสี่สาขา (ปรมาจารย์ b1, b2 และ b3)
  • หลังจากที่ฉันทำงานใน b1-b3 ฉันก็รู้ว่าฉันมีอะไรที่จะเปลี่ยนอาจารย์สาขาที่ควรจะอยู่ในสาขาอื่นทั้งหมด
  • ฉันเปลี่ยนสิ่งที่ฉันต้องการในmasterและ ... นี่คือปัญหาของฉัน:

ฉันจะอัปเดตสาขาอื่น ๆ ด้วยmasterรหัสสาขาได้อย่างไร



58
อีกงานง่าย ๆ ที่ Git ทำได้ยาก Git devs ควรใช้ Stack Overflow เป็นผลป้อนกลับใน SDLC loop ประชาชน 300,000 คนควรระบุว่ามีบางอย่างผิดปกติกับเวิร์กโฟลว์ของ Git พวกเขาต้องจ้างผู้เชี่ยวชาญ UX เพราะพวกเขาไม่สามารถคอมไพล์มันเองได้อย่างชัดเจน
jww

คำตอบ:


620

คุณมีสองทางเลือก:

อันแรกคือการผสาน แต่สิ่งนี้จะสร้างความมุ่งมั่นเพิ่มเติมสำหรับการผสาน

ชำระเงินแต่ละสาขา:

git checkout b1

จากนั้นรวม:

git merge origin/master

จากนั้นกด:

git push origin b1

หรือคุณสามารถทำการ rebase:

git fetch
git rebase origin/master

15
ฉันมีความกังวลเกี่ยวกับวิธีการนี้ เมื่อฉันเรียกใช้ git log --graph กราฟที่แสดงว่ามาสเตอร์นั้นจะถูกรวมเข้ากับสาขาหัวข้อ สิ่งนี้จะทำให้เกิดปัญหาใด ๆ ในระยะยาวหรือไม่? ฉันคิดว่าวิธีปฏิบัติที่ดีที่สุดคือการรวมสาขาหัวข้อกลับมาเป็นหลักเสมอ โปรดแสดงความคิดเห็น.
Patrick

2
ระวังปัญหานี้หากคุณกำลังทำตามขั้นตอนการผสาน: randyfay.com/node/89
Hampus Ahlgren

22
คุณกำลังรวมต้นแบบเป็น b1 ทำไมคุณgot push origin master... ไม่สมเหตุสมผล คุณไม่ได้เปลี่ยนสาขาหลัก ฉันคิดว่ามันเป็นความผิดพลาดกับ 119 upvote: /
Yves Lange

22
อย่าใช้วิธีการผสานโดยใช้git rebase masterเป็นคำตอบที่ถูกต้อง
Weston Ganger

6
สำหรับพวกเราที่อ่านในภายหลัง - ความกังวลของ @Kursion เกี่ยวกับการพิมพ์ผิดได้รับการแก้ไขโดยผู้เขียน นอกจากนี้คำตอบ upvote ที่สูงที่สุดลำดับที่สองด้านล่างยังบอกโดยทั่วไปเหมือนกับคำตอบนี้ แต่มีไดอะแกรมของโครงสร้างสาขาและคำเตือนว่าทำไมคุณไม่ต้องการรีบูต
Beyondtheteal

496

คุณมีสองตัวเลือกโดยทั่วไป:

  1. คุณรวม ที่จริงแล้วค่อนข้างง่ายและการดำเนินงานในท้องถิ่นอย่างสมบูรณ์แบบ:

    git checkout b1
    git merge master
    # repeat for b2 and b3
    

    สิ่งนี้ทำให้ประวัติตรงตามที่เกิดขึ้น: คุณแยกจากต้นแบบคุณทำการเปลี่ยนแปลงทุกสาขาและในที่สุดคุณก็รวมการเปลี่ยนแปลงจากต้นแบบเข้ากับสาขาทั้งสาม

    gitสามารถจัดการกับสถานการณ์นี้ได้ดีจริงๆมันถูกออกแบบมาสำหรับการรวมที่เกิดขึ้นในทุกทิศทางในเวลาเดียวกัน คุณสามารถเชื่อถือได้ว่าสามารถรวมเธรดทั้งหมดได้อย่างถูกต้อง มันก็ไม่สนใจว่าสาขาb1ผสานmasterหรือmasterผสานb1ผสานกระทำลักษณะเหมือนกันทั้งหมดจะคอมไพล์ ความแตกต่างเพียงอย่างเดียวคือสาขาใดจบลงที่ชี้ไปที่การรวมการกระทำนี้

  2. คุณ rebase ผู้ที่มี SVN หรือพื้นหลังที่คล้ายกันพบว่าใช้งานง่าย คำสั่งนั้นคล้ายกับกรณีการผสาน:

    git checkout b1
    git rebase master
    # repeat for b2 and b3
    

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

    A --- B --- C --- D <-- master
     \
      \-- E --- F --- G <-- b1
    

    ผลการผสานในประวัติศาสตร์ที่แท้จริง:

    A --- B --- C --- D <-- master
     \                 \
      \-- E --- F --- G +-- H <-- b1
    

    อย่างไรก็ตามการ rebase ทำให้คุณมีประวัตินี้:

    A --- B --- C --- D <-- master
                       \
                        \-- E' --- F' --- G' <-- b1
    

    ประเด็นก็คือว่ากระทำE', F'และG'ไม่เคยมีอยู่อย่างแท้จริงและมีแนวโน้มที่ไม่เคยได้รับการทดสอบ พวกเขาอาจไม่ได้รวบรวม มันเป็นจริงค่อนข้างง่ายต่อการสร้างกระทำไร้สาระผ่าน rebase โดยเฉพาะอย่างยิ่งเมื่อมีการเปลี่ยนแปลงในมีความสำคัญต่อการพัฒนาในmasterb1

    ผลที่ตามมาของเรื่องนี้อาจจะเป็นว่าคุณไม่สามารถแยกแยะความแตกต่างที่ของทั้งสามกระทำE, Fและแนะนำจริงถดถอยลดน้อยลงค่าของGgit bisect

    git rebaseผมไม่ได้บอกว่าคุณไม่ควรใช้ มันมีประโยชน์ แต่เมื่อใดก็ตามที่คุณใช้มันคุณจะต้องตระหนักถึงความจริงที่ว่าคุณโกหกเกี่ยวกับประวัติศาสตร์ และอย่างน้อยคุณควรทดสอบคอมมิทใหม่


ผมได้รับการผสานสาขาอีกหนึ่งแหล่ง (ไม่ใช่ต้นแบบ) และขั้นตอนเพิ่มเติมเพื่อเพิ่มคำตอบที่ดีนี้คือการอัปเดตใน repo ท้องถิ่นของฉันก่อนจะรวม git checkout <source branch> git pull(จะมีรหัสล่าสุดในประเทศ): จากนั้นต่อเนื่องกับด้านบน: git checkout b1...
ร็อด

3
ในฐานะผู้ใช้ SVN เป็นเวลานานฉันชอบตัวเลือกการรวมกับการรีบูท: การใช้การควบคุมเวอร์ชันใด ๆ มันสำคัญมากที่จะต้องเก็บบันทึกการเปลี่ยนแปลงที่คุณทำและเหตุผล ฉันเห็นการอุทธรณ์ของ rebase เพื่อทำให้ประวัติชัดเจนง่ายขึ้น แต่คุณควรย้อนกลับไปและเพิ่มความคิดเห็นคอมมิทของ E ', F', G '- และควรเพิ่ม rebase ให้กับความคิดเห็นเหล่านั้นโดยอัตโนมัติ มิฉะนั้นหากกระบวนการสร้าง / ทดสอบ / ทดสอบการปรับใช้แตกใน G 'คุณต้องคิดออกว่าเหตุใดการเปลี่ยนแปลงจึงเกิดขึ้นโดยไม่มีข้อมูลครบถ้วน
WillC

13
ประวัติเป็นเรื่องโกหก
piratemurray

ขอบคุณฉันใช้ "git ผสาน any-branch-name" เพื่อรวมรหัสสาขาหนึ่งไปยังสาขาอื่น ในพื้นที่ฉันสามารถทดสอบรหัสสาขา 1 ในขณะที่ฉันอยู่ในสาขา 2
Priti

1
@blamb ผสานความขัดแย้งเกิดขึ้นกับทั้งสองและgit merge git rebaseไม่มีการหลีกเลี่ยงสิ่งเหล่านั้น git rebaseมีข้อได้เปรียบในการอนุญาตให้คุณซ่อนหลาย ๆ ขั้นตอนของการรีบูท (เช่นการรีบูทสาขาเดียวกันไปยังคอมมิชชันต่าง ๆ ตามลำดับเพื่อลดจำนวนความขัดแย้งในแต่ละสเตจ) อย่างไรก็ตามข้อเท็จจริงที่ว่า rebase กำลังโกหกเกี่ยวกับประวัติทำให้ง่ายขึ้นมากที่จะมีเพศสัมพันธ์ที่ดีใน rebaseage แบบหลายขั้นตอน ... นั่นเป็นเหตุผลที่ฉันมักจะชอบผสานแม้ว่ามันหมายความว่าฉันต้องยุ่งเหยิงประวัติศาสตร์ที่มีหลายคอมมิชชัน .
cmaster - คืนสถานะโมนิ

238

git rebase masterเป็นวิธีที่เหมาะสมในการทำเช่นนี้ การผสานจะหมายถึงการคอมมิชชันที่สร้างขึ้นสำหรับการผสานในขณะที่การรีบูตจะไม่เกิดขึ้น


52
เมื่อคุณผลักไปที่จุดเริ่มต้นแล้วถ้าคุณรีบูตคุณจะต้องเขียนประวัติการกระทำและสิ่งนี้จะขัดแย้งกับสาขาระยะไกลของคุณ ฉันคิดว่าการลดระดับเสียงควรใช้กับการดึงหรือเมื่อคุณไม่ได้ผลักไปยังสาขาระยะไกล
Matt Smith

6
หากคุณเป็นเพียงคนเดียวที่ทำงานในสาขาระยะไกลคุณสามารถใช้คุณสมบัติการพุชแบบพุช - บังคับต้นทางเพื่ออัปเดตสาขาระยะไกลของคุณด้วยสาขาท้องถิ่นที่ถูกรีบูต stackoverflow.com/questions/8939977/…
stormwild

7
rebase และผสานทั้งสองงานการ rebase นั้นดีที่สุดสำหรับสาขาส่วนตัวเพราะจะให้กราฟประวัติที่สะอาดยิ่งขึ้น คำตอบนี้ดีที่สุด
Junchen Liu

5
จำเป็นต้องมีความชัดเจนเกี่ยวกับการแลกเปลี่ยนระหว่างความชัดเจน (เหมาะสำหรับผู้ใช้คนเดียวหรือทีมเล็ก ๆ ) หรือความจริงที่ยุ่งเหยิง (สำหรับสาขารหัสผู้สนับสนุนหลายคน - จำเป็นสำหรับการบำรุงรักษา (ในประสบการณ์ของฉัน - YMMV))
WillC

1
"จะเกิดอะไรขึ้นถ้าคุณผลักไปแล้ว" -> กฎทองของ rebase คอมไพล์คือการไม่ใช้มันในสาขาที่สาธารณะ
เทรเวอร์บอยด์สมิ ธ

53

หากคุณกำลังทำงานในสาขาเปิดและปิดหรือเกิดขึ้นมากมายในสาขาอื่นในขณะที่คุณกำลังทำงานกับบางสิ่งบางอย่างที่ดีที่สุดคือการลดสาขาของคุณลงบนต้นแบบ สิ่งนี้ทำให้ประวัติศาสตร์เป็นระเบียบเรียบร้อยและทำให้ง่ายต่อการติดตาม

git checkout master
git pull
git checkout local_branch_name
git rebase master
git push --force # force required if you've already pushed

หมายเหตุ:

  • อย่ารีบูตสาขาที่คุณร่วมมือกับคนอื่น ๆ ใน
  • คุณควรทำการ rebase ในสาขาที่คุณจะทำการผสานซึ่งอาจไม่ใช่มาสเตอร์

มีบทเกี่ยวกับการรีบูตที่http://git-scm.com/book/ch3-6.htmlและโหลดแหล่งข้อมูลอื่น ๆ มากมายบนเว็บ


ขอบคุณสำหรับวิธีแก้ปัญหาที่ง่าย
ชาย

18

@cmaster ได้ทำคำตอบที่ดีที่สุดแล้ว โดยย่อ:

git checkout master #
git pull # update local master from remote master
git checkout <your_branch>
git merge master # solve merge conflicts if you have`

คุณไม่ควรเขียนประวัติสาขาแทนเก็บไว้ในสถานะที่แท้จริงสำหรับการอ้างอิงในอนาคต ในขณะที่ผสานเข้ากับมาสเตอร์มันจะสร้างการคอมมิทพิเศษหนึ่งอย่าง ความมุ่งมั่นไม่มีค่าใช้จ่าย


13

หากต้องการอัปเดตสาขาอื่นเช่น (สำรอง) ด้วยสำเนาสาขาหลักของคุณ คุณสามารถทำตามวิธีใดวิธีหนึ่ง (รีบูตหรือรวม) ...

  1. ทำการ rebase (จะไม่มีการกระทำใด ๆ เพิ่มเติมกับสาขาสำรอง)
  2. รวมสาขา (จะมีการส่งพิเศษไปยังสาขาสำรองโดยอัตโนมัติ)

    หมายเหตุ: Rebase ไม่มีอะไรนอกจากสร้างฐานใหม่ (สำเนาใหม่)

git checkout backup
git merge master
git push

(ทำซ้ำสำหรับสาขาอื่น ๆ หากมีการสำรองข้อมูล 2 และอื่น ๆ .. )

git checkout backup
git rebase master
git push

(ทำซ้ำสำหรับสาขาอื่น ๆ หากมีการสำรองข้อมูล 2 และอื่น ๆ .. )


9

คุณสามารถผสานหรือคุณสามารถใช้การกระทำของแต่ละบุคคลข้ามสาขาโดยใช้คอมไพล์เชอร์รี่เลือก


1

มีสองตัวเลือกสำหรับปัญหานี้

1) rebit คอมไพล์

2) คอมไพล์ผสาน

เฉพาะความแตกต่างด้านบนทั้งสองกรณีรวมจะมีความมุ่งมั่นพิเศษในประวัติศาสตร์

1) สาขาการชำระเงิน git (b1, b2, b3)

2) git rebase origin / master (ในกรณีที่มีข้อขัดแย้งแก้ไขภายในเครื่องโดยทำการ rebit git - ยุติ)

3) git push

หรือมิฉะนั้นตัวเลือกการรวมคอมไพล์ก็เหมือนกัน

1) ชำระเงิน git "your_branch" (b1, b2, b3)

2) git merge master

3) git push


1

เพื่ออัปเดตสาขาของคุณจากต้นแบบ:

  git checkout master
  git pull
  git checkout your_branch
  git merge master
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.