เมื่อใดที่ฉันควรใช้ git pull --rebase


806

ฉันรู้ว่าบางคนที่ใช้เป็นgit pull --rebaseค่าเริ่มต้นและคนอื่น ๆ ที่ยืนยันว่าจะไม่ใช้มัน ฉันเชื่อว่าฉันเข้าใจความแตกต่างระหว่างการควบรวมกิจการและ rebasing git pullแต่ฉันพยายามที่จะวางนี้ในบริบทของ มันเป็นเรื่องเกี่ยวกับที่ไม่ต้องการเห็นข้อความที่รวมเข้ามาจำนวนมากหรือมีปัญหาอื่น ๆ อีกหรือไม่?


1
แหล่งที่มาสำหรับคนที่ให้คำแนะนำกับ git pull --rebase? Rebase หรือ git rebase เป็นกิจกรรมแยกจาก git pull --rebase!
przemo_li

คำตอบ:


584

คุณควรใช้git pull --rebaseเมื่อ

  • การเปลี่ยนแปลงของคุณไม่ควรแยกสาขา

แน่นอน - ทำไมไม่เป็นเช่นนั้น? ชัดเจนยิ่งขึ้นและไม่ได้กำหนดการจัดกลุ่มแบบลอจิคัลในการกระทำของคุณ


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

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

ไม่ว่าจะเป็นอันตรายหรือไม่เป็นคำถามว่าคุณกำลังรักษาสาขาในพื้นที่และห่างไกลเป็นสิ่งที่แยกกันไม่ออก บางครั้งก็สมเหตุสมผล (เมื่อการเปลี่ยนแปลงของคุณมีขนาดเล็กหรือหากคุณอยู่ในช่วงเริ่มต้นของการพัฒนาที่แข็งแกร่งเมื่อมีการเปลี่ยนแปลงเล็ก ๆ น้อย ๆ ที่สำคัญ) บางครั้งมันก็ไม่ได้ (เมื่อคุณสร้างสาขาอื่นตามปกติ แต่คุณขี้เกียจเกินไปที่จะทำ) แต่นั่นเป็นคำถามที่แตกต่าง


17
ฉันคิดว่ามันมีประโยชน์เมื่อคุณทำงานในสาขาเดียวกัน แต่คุณอาจเปลี่ยนเวิร์กสเตชันของคุณ ฉันมักจะยอมรับและผลักดันการเปลี่ยนแปลงของฉันจากเวิร์กสเตชันเครื่องหนึ่งจากนั้นดึง rebase ในอีกอันหนึ่งและทำงานในสาขาเดียวกันต่อไป
Pablo Pazos

11
เป็นวิธีปฏิบัติที่ดีที่สุดที่เป็นประโยชน์ในการตั้งค่า Git ให้รีบูทอัตโนมัติเมื่อดึงด้วยgit config --global pull.rebase preserve (อนุรักษ์กล่าวว่านอกเหนือจากการเปิดใช้งานการรีบูตเพื่อพยายามรักษาการผสานหากคุณได้ทำในพื้นที่)
Colin D Bennett

2
ฉันไม่เห็นด้วยที่คุณควรใช้ pull --rebase เฉพาะเมื่อทำงานในสาขาเดียว คุณควรใช้มันตลอดเวลาเว้นแต่จะเป็นไปไม่ได้เนื่องจากสถานการณ์อื่น ๆ
Tomáš Fejfar

@P Shved ... 'อย่างไรก็ตามบางครั้ง - ไม่ว่าด้วยเหตุผลใด - คุณคิดว่ามันจะดีกว่าถ้าสอง - ทางไกลและในท้องถิ่น - เป็นสาขาเดียว' ... สามารถทำได้หรือไม่? ที่ในสภาพแวดล้อมท้องถิ่นฉันสามารถมีสาขาและกระจกสาขาระยะไกลเป็นแหล่งกำเนิด / ต้นแบบ คุณสามารถให้อินพุตที่นี่ได้ไหม
Mandroid

736

ฉันต้องการให้มุมมองที่แตกต่างกันเกี่ยวกับความหมายของ "git pull --rebase" จริง ๆ เพราะดูเหมือนว่าจะหายไปในบางครั้ง

หากคุณเคยใช้ Subversion (หรือ CVS) คุณอาจคุ้นเคยกับพฤติกรรมของ "svn update" หากคุณมีการเปลี่ยนแปลงที่จะคอมมิทและการคอมมิทล้มเหลวเนื่องจากมีการทำการอัปเดตอัปสตรีมคุณ "svn update" การโค่นล้มได้มาจากการรวมการเปลี่ยนแปลงต้นน้ำกับคุณซึ่งอาจทำให้เกิดความขัดแย้ง

สิ่งที่การโค่นล้มเพียงแค่ทำคือ "pull --rebase" เป็นหลัก การกำหนดรูปแบบการเปลี่ยนแปลงในท้องถิ่นของคุณให้สัมพันธ์กับเวอร์ชันที่ใหม่กว่าคือส่วน "การรีบูต" ของมัน หากคุณทำ "svn diff" ก่อนที่จะพยายามส่งข้อมูลที่ล้มเหลวและเปรียบเทียบผลต่างกับผลลัพธ์ของ "svn diff" หลังจากนั้นความแตกต่างระหว่างทั้งสอง diffs คือการดำเนินการรีบูต

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

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

หากคุณรู้สึกว่าจำเป็นต้องมีบางสิ่งบางอย่างเพื่อเป็นสาขาไม่ว่าด้วยเหตุผลใดก็ตามนั่นเป็นข้อกังวลที่แตกต่างกันในความเห็นของฉัน แต่ถ้าคุณไม่มีความปรารถนาที่เฉพาะเจาะจงและกระตือรือร้นที่จะแสดงการเปลี่ยนแปลงของคุณในรูปแบบของการผสานพฤติกรรมเริ่มต้นควรจะเป็น "git pull --rebase"

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


18
@MarceloCantos เพื่อให้ชัดเจนฉันไม่ได้พูดว่า git (เครื่องมือ) ควรเริ่มต้นเพื่อรีบูต นั่นจะเป็นอันตรายตั้งแต่การลดลงเป็นหลักทำลายประวัติศาสตร์ ฉันกำลังบอกว่าในแง่ของเวิร์กโฟลว์เมื่อคุณไม่ได้ตั้งใจที่จะสาขาและเพิ่งแฮ็คไปที่สาขาที่คนอื่นกำลังทำงานด้วย "git pull --rebase" ควรเป็นพฤติกรรมเริ่มต้นของผู้ใช้
scode

1
คุณกำลังบอกว่าไม่ควรgit config --global branch.autosetupmerge always?
Marcelo Cantos

9
@MarceloCantos ไม่ฉันไม่ใช่;) โดยส่วนตัวแล้วฉันจะปล่อยให้ autosetupmerge เป็นค่าเริ่มต้นที่แท้จริง (ถ้าฉันรวมกลับไปและสี่ระหว่างสาขาอื่นนอกเหนือจาก <-> ระยะไกลท้องถิ่นฉันต้องการให้ชัดเจน) ฉันแค่บอกว่าในฐานะมนุษย์ฉันมักจะใช้ "git pull --rebase" เป็นส่วนหนึ่งของเวิร์กโฟลว์ "grab ล่าสุดในสาขาหลัก" ปกติของฉันเพราะฉันไม่ต้องการสร้างการคอมมิชชันเว้นแต่ฉันจะแยกอย่างชัดเจน
scode

9
+1 @scode หลังจากหลายชั่วโมงที่เจ็บปวดของการต่อสู้กับคำถาม rebase / ผสานในที่สุดนี่คือคำตอบที่ตอกตะปูมัน
AgileYogi

10
คำตอบนี้เป็นเพียงความพยายามในการปรับผู้ใช้ระบบควบคุมเวอร์ชันที่ไม่เผยแพร่ให้กับ Git แทนที่จะให้โอกาสพวกเขาเข้าใจถึงประโยชน์ของการมีสาขาที่เหมาะสม
Alexey Zimarev

211

บางทีวิธีที่ดีที่สุดในการอธิบายคือตัวอย่าง:

  1. อลิซสร้างหัวข้อย่อย A และใช้งานได้
  2. Bob สร้างสาขาหัวข้อที่ไม่เกี่ยวข้อง B และทำงานในหัวข้อนั้น
  3. git checkout master && git pullอลิซไม่ อาจารย์เป็นปัจจุบันแล้ว
  4. git checkout master && git pullบ๊อบไม่ อาจารย์เป็นปัจจุบันแล้ว
  5. อลิซทำ git merge topic-branch-A
  6. บ๊อบทำ git merge topic-branch-B
  7. บ๊อบทำgit push origin masterก่อนอลิซ
  8. อลิซทำgit push origin masterซึ่งถูกปฏิเสธเพราะไม่ใช่การผสานที่รวดเร็ว
  9. อลิซมองไปที่บันทึกการกำเนิด / ปรมาจารย์และเห็นว่าการกระทำนั้นไม่เกี่ยวข้องกับเธอ
  10. อลิซทำ git pull --rebase origin master
  11. การรวมของอลิซนั้นไม่ได้ผูกไว้การกระทำของบ๊อบก็ถูกดึงออกมาและการกระทำของอลิซก็ถูกนำไปใช้หลังจากการกระทำของบ๊อบ
  12. อลิซทำได้git push origin masterและทุกคนมีความสุขที่พวกเขาไม่จำเป็นต้องอ่านการรวมที่ไร้ประโยชน์เมื่อพวกเขาดูบันทึกในอนาคต

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


2
ดี ฉันมักจะมีความชัดเจนและgit co master && git pull; git checkout topic-branch-A; git rebase master; git checkout master; git merge topic-branch-A; git push origin masterทำซ้ำหากผู้อื่นผลักดันให้เกิดต้นแบบก่อนหน้าฉัน แม้ว่าฉันจะเห็นข้อได้เปรียบโดยย่อในสูตรของคุณ
HankCa

คำอธิบายที่ดี @ โพลสำรวจความคิดเห็น
Rajanikanta Pradhan

148

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

เมื่อความรู้ Git ของคุณเพิ่มขึ้นคุณจะพบว่าตัวเองดูประวัติมากขึ้นกว่าระบบควบคุมรุ่นอื่น ๆ ที่ฉันเคยใช้ หากคุณมีการรวมขนาดเล็กจำนวนมากมันง่ายที่จะเสียสมาธิไปกับภาพใหญ่ที่เกิดขึ้นในประวัติศาสตร์ของคุณ

นี่เป็นเพียงครั้งเดียวที่ฉันทำการรีบูต (*) และเวิร์กโฟลว์ที่เหลือของฉันได้รับการผสาน แต่ตราบใดที่ผู้กระทำผิดบ่อยที่สุดของคุณทำเช่นนี้ประวัติดูดีขึ้นมากในที่สุด

(*) ในขณะที่สอนหลักสูตร Git ฉันมีนักเรียนจับกุมฉันเกี่ยวกับเรื่องนี้เนื่องจากฉันยังสนับสนุนสาขาการลดคุณสมบัติในบางกรณี และเขาได้อ่านคำตอบนี้;) การรีบูตเป็นไปได้เช่นกัน แต่มันจะต้องเป็นไปตามระบบที่จัดไว้ล่วงหน้า / ตกลงกันไว้เสมอและไม่ควรใช้ "เสมอ" และในเวลานั้นฉันมักจะไม่ทำpull --rebaseเช่นนั้นซึ่งเป็นคำถามที่เกี่ยวกับ;)


2
แน่นอนว่าคน ๆ หนึ่งสามารถเขียนสคริปต์เพื่อซ่อนการคอมมิชชันได้จากบันทึก
hasen

3
การรวมกันอาจมีความแตกต่างด้วยซึ่งหมายความว่ามันไม่สำคัญเลย
krosenvold

9
@hasen j ใช่ แต่เนื้อหาของการรวมเหล่านั้นอาจมีความสำคัญ
krosenvold

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

1
ความคลุมเครือรอบ ๆ "สาขา" ค่อนข้างมีเจตนาเนื่องจากมีหลายวิธีในการใช้ผู้อ้างอิง "สายงาน" เป็นเพียงทางเลือกเดียว
krosenvold

49

ฉันไม่คิดว่าจะมีเหตุผลอะไรที่จะไม่ใช้pull --rebase- ฉันเพิ่มโค้ดลงใน Git โดยเฉพาะเพื่อให้git pullคำสั่งของฉันรีบูทกับการคอมมิทอัพสตรีมเสมอ

เมื่อมองผ่านประวัติศาสตร์มันไม่น่าสนใจเลยที่จะรู้ว่าเมื่อคน / สาวทำงานบนฟีเจอร์หยุดการซิงโครไนซ์ มันอาจจะมีประโยชน์สำหรับคนที่แต่งตัวประหลาด / สาวในขณะที่เขา / เธอกำลังทำมัน แต่นั่นคือสิ่งที่reflogมีไว้สำหรับ มันเป็นเพียงการเพิ่มเสียงให้กับคนอื่น ๆ


2
"เมื่อมองผ่านประวัติศาสตร์มันไม่น่าสนใจเลยที่จะรู้ว่าเมื่อคนที่ทำงานเกี่ยวกับคุณสมบัติหยุดซิงค์แล้ว" / แต่นั่นไม่ได้หมายความว่าการกระทำระดับกลางเหล่านั้นน่าจะเป็นงานสร้างที่เสียหาย
eglasius

10
ใช่แล้วพวกเขาก็ไม่ได้เป็น "ทั้งรัฐ" นั่นเป็นเหตุผลที่เราไม่ต้องการพวกเขา ฉันอยากรู้ว่าเขาต้องการอะไรไม่ใช่เขาไปที่นั่น
ดัสติน

4
หากpull --rebaseควรใช้อยู่เสมอทำไมไม่pullทำตามค่าเริ่มต้น
straya

2
ฉันเกรงว่าคุณจะต้องแสดงความคิดเห็นของคุณเอง ฉันมีหลายสิ่งหลายอย่างที่.gitconfigจะทำให้ตัวเลือกบางอย่างทำสิ่งที่ถูกต้อง ฉันคิดว่าการรีบูต Git ทำสิ่งที่ผิดโดยค่าเริ่มต้นเช่นเดียวกับแท็ก Git ฯลฯ ... หากคุณไม่เห็นด้วยคุณไม่จำเป็นต้องแสดงความคิดเห็นของคุณ
ดัสติน

8
ดูเหมือนว่าจะเป็นคำแนะนำที่ดีถ้าคุณดึงจาก "ต้นน้ำ" พูดจากmasterและถ้าสาขาที่คุณดึงเข้าไปยังไม่ได้เปิดเผยต่อสาธารณะ ถ้าคุณดึงมือจากสาขาฟีเจอร์ลงไปmasterมันก็เหมือนกับอีกด้าน: มันไม่มีเหตุผลที่จะใช้--rebaseใช่ไหม? นั่นอาจเป็นสาเหตุที่ทำให้มันไม่ได้เป็นค่าเริ่มต้น ฉันพบว่าการคืนค่าเป็นวิธีที่การเปลี่ยนแปลงควรผ่านจากด้านบนของลำดับชั้นลงมาและการรวมกันเป็นวิธีที่พวกเขากลับขึ้นไปด้านบน derekgourlay.com/blog/git-when-to-merge-vs-when-to-rebase
jolvi

38

แค่จำไว้:

  • pull = fetch + merge
  • pull --rebase = fetch + rebase

ดังนั้นเลือกวิธีที่คุณต้องการจัดการสาขาของคุณ

คุณควรทราบถึงความแตกต่างระหว่างการผสานและการลดใหม่ :)


9

ฉันคิดว่ามันทำให้ความชอบส่วนตัวลดลง

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

ฉันเองก็ไม่รังเกียจที่จะเผยแพร่ความผิดพลาดที่โง่ ๆ ของฉันดังนั้นฉันจึงมักจะรวมเข้าด้วยกันแทนที่จะเป็น rebase


8
หมายเหตุสำหรับทุกคนที่ดูคำถามนี้: คำตอบนี้ไม่เกี่ยวข้องกับคำถามทั้งหมด "เมื่อใดฉันจึงควรใช้ git pull --rebase?"
therealklanni

3
@therealklanni ฉันได้แก้ไขคำตอบเพื่อให้ชัดเจนยิ่งขึ้นว่าเกี่ยวข้องกับคำถามนั้นอย่างไร (หวังว่าจะไม่ทำลายเจตนา)
Paŭlo Ebermann

การแชร์บันทึกการทำงานที่สกปรกและไม่มีโครงสร้างนั้นไม่ใช่ความพยายามที่ซื่อสัตย์ แต่เป็นความขี้เกียจ คุณกำลังเสียเวลาของประชาชนโดยทำให้พวกเขาไล่ล่าคุณผ่านหลุมกระต่ายแห่งการพัฒนาและการดีบั๊ก ให้ผลลัพธ์แก่พวกเขาไม่ใช่ผู้ชม
krystah

8

git pull --rebasegit push --forceอาจซ่อนประวัติศาสตร์ที่เขียนจากการทำงานร่วมกัน ฉันแนะนำให้ใช้git pull --rebase เฉพาะเมื่อคุณรู้ว่าคุณลืมที่จะผลักดันการกระทำของคุณก่อนที่คนอื่นทำเช่นเดียวกัน

หากคุณไม่ได้กระทำอะไร แต่พื้นที่ทำงานของคุณไม่ได้ทำความสะอาดเพียงก่อนที่จะgit stash git pullวิธีนี้คุณจะไม่เขียนประวัติของคุณแบบเงียบ ๆ (ซึ่งอาจทำให้งานของคุณเงียบลง)

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