เหตุใด git จึงทำการผสานการกรอไปข้างหน้าอย่างรวดเร็ว


641

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

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

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

ด้วยเหตุผลนี้ฉันไม่ต้องการรวมการกรอไปข้างหน้าอย่างรวดเร็วและมองไม่เห็นสาเหตุที่เป็นค่าเริ่มต้น มีอะไรดีเกี่ยวกับมัน


38
หมายเหตุ: โปรดดูที่sandofsky.com/blog/git-workflow.htmlและหลีกเลี่ยงการใช้ ' no-ff' ด้วย "จุดตรวจของการกระทำ" ที่ทำให้เกิดความผิดเพี้ยนหรือตำหนิ
VonC

15
คุณเสียใจด้วยการใช้คอมไพล์ในโปรเจคเดียวหรือไม่?
HaveAGuess

27
ไม่ได้อย่างแน่นอน! ในโฟลเดอร์งานของฉันฉันมี 7 โปรเจ็กต์เดียวที่ฉันใช้คอมไพล์ ให้ฉันใช้ถ้อยคำใหม่ที่: ฉันเริ่มต้นหลายโครงการตั้งแต่ฉันถามคำถามนี้และทั้งหมดของพวกเขาเป็นรุ่นผ่านทางคอมไพล์ เท่าที่ฉันรู้มีเพียง git และ mercurial ที่สนับสนุนเวอร์ชันท้องถิ่นซึ่งจำเป็นสำหรับฉันตั้งแต่ฉันคุ้นเคย ง่ายในการติดตั้งและคุณจะมีประวัติทั้งหมดกับคุณเสมอ ในกลุ่มโปรเจ็กต์จะดียิ่งขึ้นเนื่องจากคุณสามารถส่งมอบได้โดยไม่ต้องรบกวนใครก็ตามด้วยโค้ดที่กำลังดำเนินการอยู่ นอกจากนี้ฉันใช้ github เพื่อแบ่งปันบางโครงการของฉัน (เช่น micro-optparse) โดยที่ git นั้นเป็นข้อกำหนด
Florian Pilz

7
@Cawas จริง-no-ffไม่ค่อยเป็นความคิดที่ดี แต่ยังสามารถช่วยเก็บประวัติภายในสถานที่ในขณะที่บันทึกเพียงหนึ่งกระทำในสาขาหลัก ที่เหมาะสมสำหรับประวัติคุณสมบัติที่ยาวนานเมื่อคุณรวมเป็นครั้งคราวความคืบหน้าในสาขาหลัก
VonC

12
สำหรับคำถามของคุณที่ว่า "ไม่ว่า [ประวัติสาขาเชิงเส้น] ดูไม่เป็นมืออาชีพหรือไม่" ไม่มีอะไรที่ไม่เป็นมืออาชีพเกี่ยวกับการใช้ระบบซอร์สโค้ดด้วยค่าเริ่มต้น นี่ไม่เกี่ยวกับความเป็นมืออาชีพ นี่เป็นเรื่องเกี่ยวกับการพิจารณาว่าสาขาใดที่คุณสมัครเป็นสมาชิก ตัวอย่างเช่น @VonC เชื่อมโยงกับบทความของ sandofsky ซึ่งเขาใช้การกรอไปข้างหน้าอย่างรวดเร็วเป็นวิธีการที่เหนือกว่า ไม่ถูกหรือผิดเพียงแค่ปรัชญาที่แตกต่างกันสำหรับบริบทที่แตกต่างกัน
Marplesoft

คำตอบ:


718

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

คำเตือน : การไม่ส่งต่ออย่างรวดเร็วมีผลข้างเคียงเช่นกัน โปรดตรวจสอบhttps://sandofsky.com/blog/git-workflow.htmlหลีกเลี่ยง 'no-ff' ด้วย "checkpoint commits" ที่แบ่งความผิดหรือความผิดและพิจารณาอย่างรอบคอบว่าควรเป็นแนวทางเริ่มต้นของคุณmasterหรือไม่

ข้อความแสดงแทน
(จากnvie.com , Vincent Driessen , โพสต์ " รูปแบบการแตกสาขา Git ที่ประสบความสำเร็จ ")

การรวมคุณสมบัติที่เสร็จสมบูรณ์ในการพัฒนา

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

$ git checkout develop
Switched to branch 'develop'
$ git merge --no-ff myfeature
Updating ea1b82a..05e9557
(Summary of changes)
$ git branch -d myfeature
Deleted branch myfeature (was 05e9557).
$ git push origin develop

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

Jakub Narębskiยังกล่าวถึงการตั้งค่าmerge.ff :

โดยค่าเริ่มต้น Git จะไม่สร้างการรวมพิเศษส่งมอบเมื่อรวมการกระทำที่เป็นผู้สืบทอดของการกระทำปัจจุบัน แต่เคล็ดลับของสาขาปัจจุบันจะถูกส่งต่ออย่างรวดเร็ว
เมื่อตั้งค่าเป็นfalseตัวแปรนี้จะบอกให้ Git สร้างการรวมพิเศษในกรณีดังกล่าว (เทียบเท่ากับการให้--no-ffตัวเลือกจากบรรทัดคำสั่ง)
เมื่อตั้งค่าเป็น ' only' จะอนุญาตการรวมอย่างรวดเร็วไปข้างหน้าเท่านั้น (เทียบเท่ากับการให้--ff-onlyตัวเลือกจากบรรทัดคำสั่ง)


กรอไปข้างหน้าเป็นค่าเริ่มต้นเนื่องจาก:

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

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

ในกรณีนี้คุณสามารถสิ้นสุดการตั้งค่าไฟล์ประเภทนี้ :

[branch "master"]
# This is the list of cmdline options that should be added to git-merge 
# when I merge commits into the master branch.

# The option --no-commit instructs git not to commit the merge
# by default. This allows me to do some final adjustment to the commit log
# message before it gets commited. I often use this to add extra info to
# the merge message or rewrite my local branch names in the commit message
# to branch names that are more understandable to the casual reader of the git log.

# Option --no-ff instructs git to always record a merge commit, even if
# the branch being merged into can be fast-forwarded. This is often the
# case when you create a short-lived topic branch which tracks master, do
# some changes on the topic branch and then merge the changes into the
# master which remained unchanged while you were doing your work on the
# topic branch. In this case the master branch can be fast-forwarded (that
# is the tip of the master branch can be updated to point to the tip of
# the topic branch) and this is what git does by default. With --no-ff
# option set, git creates a real merge commit which records the fact that
# another branch was merged. I find this easier to understand and read in
# the log.

mergeoptions = --no-commit --no-ff

OP เพิ่มในความคิดเห็น:

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

คำตอบ Jefromi:

ฉันคิดว่าอายุการใช้งานของสาขาแตกต่างกันอย่างมากจากผู้ใช้กับผู้ใช้ อย่างไรก็ตามในหมู่ผู้ใช้ที่มีประสบการณ์อาจมีแนวโน้มที่จะมีสาขาที่มีอายุสั้นกว่ามาก

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

โดยทั่วไปแล้วฉันเพิ่ม:

ขึ้นอยู่กับขั้นตอนการพัฒนาของคุณ:

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

โปรดดู " คุณควรจะสาขาเมื่อไหร่ "

อันที่จริงเมื่อคุณพิจารณารูปแบบกิ่งมันเป็นที่หลักของหนึ่งในสาขาต่อพื้นที่เก็บข้อมูล (แม้ว่าคุณสามารถสร้างหัวที่ไม่ระบุชื่อบุ๊คมาร์คและแม้แต่ชื่อสาขา )
ดู"Git และ Mercurial - เปรียบเทียบและความคมชัด"

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


ว้าวนั่นเร็วมาก ;) ฉันรู้เกี่ยวกับตัวเลือก - no-ff แต่จะค้นหาเฉพาะเกี่ยวกับการกรอไปข้างหน้าหลังจากที่ฉันทำให้ฟีเจอร์ของฉันเสียไป ฉันเห็นความรู้สึกบางอย่างในการก้าวไปข้างหน้าอย่างรวดเร็วสำหรับกิ่งก้านที่มีชีวิตสั้น แต่การทำให้มันเป็นการกระทำเริ่มต้นหมายความว่าคอมไพล์จะถือว่าคุณส่วนใหญ่มีกิ่งก้านสั้น ๆ มีเหตุผล?
Florian Pilz

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

ขอบคุณไฟล์กำหนดค่าควรช่วยหลีกเลี่ยง gotchas ดังกล่าว :) ใช้การกำหนดค่านี้เฉพาะที่ด้วย "git config branch.master.mergeoptions '--no-ff'"
Florian Pilz

2
@BehrangSaeedzadeh: การรีบูทเป็นหัวข้ออื่น (ที่ไม่ได้กล่าวถึงในหน้านี้): ตราบใดที่คุณไม่ได้ผลักfeatureสาขาของคุณไปสู่ ​​repo สาธารณะคุณสามารถรีบูตมันได้masterหลายครั้งตามที่คุณต้องการ ดูstackoverflow.com/questions/5250817/…
VonC

4
@BehrangSaeedzadeh: การคืนเงินด้วยตัวเองจะไม่ทำให้เกิดประวัติเชิงเส้น มันเป็นวิธีที่คุณรวมการเปลี่ยนแปลงของfeatureสาขาของคุณกลับเข้าไปในmasterที่ทำให้ประวัติศาสตร์กล่าวว่าเป็นเส้นตรงหรือไม่ การผสานที่รวดเร็วอย่างง่ายจะทำให้มันเป็นเส้นตรง ซึ่งสมเหตุสมผลถ้าคุณล้างประวัติของfeatureสาขานั้นก่อนที่จะผสานการกรอไปข้างหน้าโดยทิ้งเฉพาะการกระทำที่สำคัญดังที่กล่าวไว้ในstackoverflow.com/questions/7425541/ stackoverflow.com/questions/7425541/...
VonC

42

ฉันขอขยายคำตอบที่ครอบคลุมมากของVonC :


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

โปรดทราบว่าการใช้ประโยชน์ของฟีเจอร์บรานช์และการมีหลายสาขาในที่เก็บเดียวมาในภายหลังด้วยการใช้ VCS ที่กว้างขวางขึ้นพร้อมการสนับสนุนการผสานที่ดีและการลองเวิร์กโฟลว์ที่ใช้การผสานที่หลากหลาย นั่นคือเหตุผลที่ตัวอย่างเช่น Mercurial ได้รับการสนับสนุนเพียงสาขาเดียวต่อที่เก็บ (รวมถึงเคล็ดลับที่ไม่ระบุชื่อสำหรับการติดตามสาขาระยะไกล) ดังที่เห็นในรุ่นเก่าของ "Mercurial: The Definitive Guide"


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

HTH


เกี่ยวกับสาขาฟีเจอร์จากรีลีสที่เสถียร: จะเป็นอย่างไรถ้าฟีเจอร์ที่ฉันกำลังพัฒนาสำหรับรีลีสถัดไปนั้นขึ้นอยู่กับการเปลี่ยนแปลงของฟีเจอร์อื่นที่ฉันได้พัฒนาและรวมเข้ากับมาสเตอร์แล้ว? นั่นหมายความว่าฉันต้องสร้างสาขาฟีเจอร์ที่สองนี้จากต้นแบบหรือไม่
dOxxx

1
@dOxxx: ใช่มีข้อยกเว้นเช่นเช่นที่สาขาหนึ่งสร้างบนอื่น ๆ (ไม่ว่าโดยตรงหรือหลังจากการรวมก่อนหน้านี้เป็นหลัก)
Jakub Narębski
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.