Git Cherry-pick และ Merge Workflow


302

สมมติว่าฉันเป็นผู้ดูแลธุรกรรมซื้อคืนและฉันต้องการดึงการเปลี่ยนแปลงจากผู้สนับสนุนมีเวิร์กโฟลว์ที่เป็นไปได้สองสามประการ:

  1. ฉันcherry-pickแต่ละคนกระทำจากระยะไกล (ตามลำดับ) ในกรณีนี้คอมไพล์บันทึกการกระทำที่ไม่เกี่ยวข้องกับสาขาระยะไกล
  2. ฉันmergeเป็นสาขาดึงการเปลี่ยนแปลงทั้งหมดและเพิ่ม "ข้อขัดแย้ง" ใหม่ที่กระทำ (ถ้าจำเป็น)
  3. ฉันmergeแต่ละคนกระทำจากสาขาระยะไกลเป็นรายบุคคล (ตามลำดับอีกครั้ง) อนุญาตให้บันทึกข้อขัดแย้งสำหรับแต่ละการกระทำแทนที่จะจัดกลุ่มทั้งหมดเข้าด้วยกันเป็นหนึ่งเดียว
  4. เพื่อความสมบูรณ์คุณสามารถทำrebase(เหมือนcherry-pickตัวเลือก) แต่ความเข้าใจของฉันคือสิ่งนี้อาจทำให้เกิดความสับสนสำหรับผู้มีส่วนร่วม บางทีนั่นอาจกำจัดตัวเลือกที่ 1

ในทั้งสองกรณี 2 และ 3 คอมไพล์บันทึกประวัติสาขาของคอมมิทซึ่งต่างจาก 1

สิ่งที่เป็นของข้อดีและข้อเสียของระหว่างการใช้อย่างใดอย่างหนึ่งcherry-pickหรือmergeวิธีการอธิบาย? ความเข้าใจของฉันคือวิธีที่ 2 เป็นบรรทัดฐาน แต่ฉันรู้สึกว่าการแก้ไขความมุ่งมั่นขนาดใหญ่ด้วยการผสาน "ความขัดแย้ง" เดียวไม่ใช่วิธีที่สะอาดที่สุด

คำตอบ:


296

ทั้งrebase(และcherry-pick) และmergeมีข้อดีและข้อเสีย ฉันโต้แย้งmergeที่นี่ แต่มันก็คุ้มค่าที่จะเข้าใจทั้งคู่ (ดูที่นี่เพื่อหาคำตอบกรณีอื่นที่rebaseเป็นที่ถกเถียงกันดีระบุกรณีที่ต้องการ)

mergeเป็นที่ต้องการมากกว่าcherry-pickและrebaseด้วยเหตุผลสองประการ

  1. ความแข็งแรง ตัวระบุ SHA1 ของการกระทำเป็นการระบุว่าไม่เพียง แต่ในตัวของมันเอง แต่ยังเกี่ยวข้องกับการกระทำอื่น ๆ ทั้งหมดที่นำหน้ามัน นี่เป็นการรับประกันว่าสถานะของที่เก็บของ SHA1 ที่ระบุนั้นเหมือนกันในทุก ๆ โคลน ในทางทฤษฎีแล้วไม่มีโอกาสที่ใครบางคนทำในสิ่งที่ดูเหมือนว่าจะเป็นการเปลี่ยนแปลงแบบเดียวกัน แต่จริงๆแล้วเป็นการทำลายหรือการจี้พื้นที่เก็บข้อมูลของคุณ คุณสามารถเลือกรับเชอร์รี่ในการเปลี่ยนแปลงรายบุคคลและพวกเขามีแนวโน้มที่เหมือนกัน แต่คุณไม่รับประกัน (ในฐานะรองลงมารองลงมาคือเชอร์รี่ที่หยิบมาใหม่จะใช้พื้นที่เพิ่มขึ้นหากมีคนอื่นที่เลือกเชอร์รี่ในความมุ่งมั่นเดียวกันอีกครั้งเพราะทั้งคู่จะปรากฏตัวในประวัติศาสตร์แม้ว่าสำเนางานของคุณจะเหมือนกัน)
  2. สะดวกในการใช้ ผู้คนมักจะเข้าใจmergeกระบวนการทำงานค่อนข้างง่าย rebaseมีแนวโน้มที่จะพิจารณาขั้นสูงขึ้น เป็นการดีที่สุดที่จะเข้าใจทั้งคู่ แต่คนที่ไม่ต้องการเป็นผู้เชี่ยวชาญในการควบคุมเวอร์ชัน (ซึ่งจากประสบการณ์ของฉันได้รวมเพื่อนร่วมงานหลายคนที่ด่าดีในสิ่งที่พวกเขาทำ แต่ไม่ต้องการใช้เวลาเพิ่มเติม) ง่ายขึ้น เวลาเพียงแค่ผสาน

แม้ว่าจะมีเวิร์กโฟลว์ที่ผสานกันอย่างหนักrebaseและcherry-pickยังคงมีประโยชน์สำหรับบางกรณี:

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

สำหรับการรวมการเปลี่ยนแปลงหลาย ๆ อย่างเข้าด้วยกัน: มันง่ายกว่ามาก มันอาจเป็นเรื่องที่น่าเบื่อมากที่จะรวมการเปลี่ยนแปลงแต่ละเซ็ตเมื่อคุณเริ่มมีจำนวนมาก การรวมความละเอียดในคอมไพล์ (และใน Mercurial และในบาซาร์) ดีมาก คุณจะไม่เจอกับปัญหาสำคัญ ๆ ที่รวมสาขากิ่งใหญ่ไว้เป็นส่วนใหญ่ ฉันมักจะรวมทุกอย่างทั้งหมดในครั้งเดียวและเฉพาะในกรณีที่ฉันได้รับความขัดแย้งจำนวนมากฉันจะสำรองและเรียกใช้งานชิ้นส่วนผสานอีกครั้ง ถึงอย่างนั้นฉันก็ทำมันเป็นก้อนใหญ่ ตัวอย่างจริง ๆ ฉันมีเพื่อนร่วมงานที่มีการเปลี่ยนแปลง 3 เดือนเพื่อรวมและมีความขัดแย้ง 9000 ในฐานรหัสบรรทัด 250000 สิ่งที่เราทำในการแก้ไขคือทำการผสานมูลค่าของเดือนละครั้ง: ความขัดแย้งไม่ได้สร้างขึ้นเป็นเส้นตรงและการทำเป็นชิ้น ๆ จะส่งผลในระยะไกลความขัดแย้งน้อยกว่า 9000 มันยังคงทำงานมาก แต่ก็ไม่มากเท่าที่พยายามทำในแต่ละครั้ง


1
ตามความเป็นจริงแล้วในทางทฤษฎีมีโอกาสที่มัลลอรี่จะทำลายที่เก็บข้อมูลของคุณด้วยการสร้างคอมมิชชันด้วย SHA1 เดียวกัน แต่เนื้อหาที่แตกต่างมันอาจจะไม่เกิดขึ้นจริงในทางปฏิบัติ :)
Bombe

1
ฮา :) ฉันหมายถึง "ในทางทฤษฎีแล้วอัตราต่อรองต่ำมากจนคุณสามารถเชื่อได้ว่าจะไม่เกิดขึ้น" แต่คุณพูดถูกต้องว่ามันอ่านเรื่องยุ่งเหยิง
quark

คุณคิดอย่างไรเกี่ยวกับ "ผสาน - สควอช"
cmcginty

@Bombe หากมัลลอรี่ต้องการประสบความสำเร็จเธอจะต้องสร้างการคอมมิชชันดั้งเดิมและการคอมมิชชันที่สองด้วย SHA1 เดียวกันโดยเฉพาะ ดังนั้นคำถามอื่นอาจเป็น: อัตราเดิมพันของสอง (ค่อนข้าง) เป็นการหลอกลวงที่ปรากฏและคุณไม่สังเกตเห็น? ;)
João Portela

64
ความขัดแย้ง 9000 ฉันจะลาออกจากงานและเป็นผู้รักษาผึ้ง
Sebastian Patten

95

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

โปรดจำไว้ว่าการกระทำที่หยิบเชอร์รี่หรือการปฏิเสธนั้นแตกต่างจากมุมมองของ Git (มีตัวระบุ SHA-1 ที่แตกต่าง) กว่าต้นฉบับดังนั้นจึงแตกต่างจากการเก็บในรีโมตระยะไกล (การรีบูตมักจะสามารถจัดการกับสิ่งนี้ได้เพราะมันจะตรวจสอบรหัสแพทช์เช่นการเปลี่ยนแปลงไม่ใช่รหัสการกระทำ)

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

HTH


19
+1 สำหรับจุดที่การรีบูต / การเก็บเชอร์รี่จริง ๆ แล้ว "คัดลอก" การกระทำและดังนั้นจึงสูญเสียการเชื่อมโยงกับการส่งต้นฉบับ
studgeek

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

3
@foxxtrot: อีกวิธีหนึ่งคือการสร้างสาขาแยกต่างหากสำหรับ bugfix โดยอิงจากคอมมิชชันเก่าที่สุดที่แสดงข้อผิดพลาดนี้และรวมมันเข้ากับ 'maint' และ 'master' ... แม้ว่าในกรณีนี้คุณต้องรู้ว่า bugfix กล่าว นำไปใช้กับทั้งสองสาขา
Jakub Narębski

4
@Jakub คำสั่งสองคำสั่งที่จำเป็นสำหรับการสร้างและรวมสาขาgit blameบั๊กแก้ไข: เพื่อค้นหาคอมมิชชันที่แนะนำบั๊กและgit branch --containsเพื่อพิจารณาว่าจะรวมสาขาเข้าไว้ที่ไหน อธิบายรายละเอียดเพิ่มเติมในโพสต์นี้
gcbenison

-10

Rebase และ Cherry-pick เป็นวิธีเดียวที่คุณสามารถเก็บประวัติการกระทำที่สะอาดได้ หลีกเลี่ยงการใช้การผสานและหลีกเลี่ยงการสร้างความขัดแย้งในการผสาน หากคุณใช้ gerrit ให้ตั้งค่าหนึ่งโครงการเป็นผสานหากจำเป็นและอีกหนึ่งโครงการเป็นโหมดรับเชอร์รี่แล้วลองด้วยตัวเอง


ไม่ชัดเจนเลยว่าวิธีนี้ตอบคำถามได้อย่างไรบางทีตัวอย่างบางส่วนอาจทำให้เกิดแสงสว่าง
Adrian Nasui

1
ความจริงที่ว่าประวัติของคุณจะดูตรงไม่ได้หมายความว่ามันจะง่ายต่อการเข้าใจ
nicolimo86

การผสานเป็นวิธีปกติในการมีประวัติที่สะอาด Cherry-pick และ rebase ส่วนใหญ่จะใช้สำหรับสถานการณ์ที่คุณต้องแก้ไขประวัติ หมายความว่าการผสานควรเป็นตัวเลือกแรกเสมอ สาเหตุ rebase เปลี่ยน comit sha`s สิ่งที่อันตรายมากเมื่อคุณทำงานกับรีโมทและหลายคน
Radon8472

เจ้าชายนี่สมควรได้รับเหรียญ เขารู้ว่าเขาจะยังคงลงคะแนนต่อไป แต่มันเป็นคำตอบที่ถูกต้อง ความรุ่งโรจน์
PW Kad

ขออภัยฉันไม่เห็นความคิดเห็นเหล่านี้จนกระทั่งตอนนี้โปรดลองในสภาพแวดล้อมการทดสอบของคุณก่อนที่จะสรุปและทำสิ่งที่เหมาะกับคุณ! ฉันมีนักพัฒนาประมาณ 600 คนที่สนับสนุนสาขาผลิตภัณฑ์หลายแห่งฉันไม่สนใจว่านักพัฒนาจะทำอะไรในพื้นที่ทำงานในพื้นที่นั้นเมื่อมีการส่งการเปลี่ยนแปลงเพื่อการรวมควรจะเลือกสาขาเชอร์รี่เพื่อการพัฒนา FYI ... ฉันใช้ Gerrit
Nagaraj Magadum
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.