ทำไมคอมไพล์จึงไม่บรรจุชื่อสาขาที่สร้างขึ้น?


20

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

ตัวอย่าง:

สมมติว่ามีฟีเจอร์ branch / make-coffeeฟีเจอร์และการแก้ไขข้อผิดพลาดยังคงดำเนินต่อไปบนมาสเตอร์ขนานกับฟีเจอร์ branch

ประวัติอาจมีลักษณะเช่นนี้:

*     merge feature/make-coffee
|\
| *   small bugfix
| |
* |    fix bug #1234
| |
| *    add milk and sugar
| |
* |    improve comments
| |
* |    fix bug #9434
| |
| *    make coffe (without milk or sugar)
| |
* |    improve comments
|/
*

ปัญหา

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

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

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

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


1
คำถามที่เกี่ยวข้อง: การหาสิ่งที่สาขากระทำมาจาก นี่คือเกี่ยวกับวิธีค้นหาข้อมูลนี้แม้ว่าข้อเท็จจริงที่ว่าคอมไพล์ไม่ได้บันทึกไว้อย่างชัดเจน
sleske

1
หมายเหตุถึงตนเอง: ที่น่าสนใจใน Mercurial การกระทำจะมีชื่อสาขา ดังนั้นดูเหมือนว่า Mercurial devs ได้ตัดสินใจออกแบบที่แตกต่างจาก dev ของ git ดูเช่นfelipec.wordpress.com/2012/05/26/…สำหรับรายละเอียด
sleske

คำตอบ:


14

อาจเป็นเพราะชื่อสาขามีความหมายภายในที่เก็บเดียวเท่านั้น ถ้าฉันอยู่ในmake-coffeeทีมและส่งการเปลี่ยนแปลงทั้งหมดของฉันผ่านทางผู้รักษาประตูmasterสาขาของฉันอาจถูกดึงไปที่make-coffee-guiสาขาของผู้รักษาประตูซึ่งเขาจะรวมกับmake-coffee-backendสาขาของเขาก่อนที่จะรีบูตไปยังmake-coffeeสาขาที่ผสานเข้ากับmasterสาขากลาง

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

ในฐานะที่เป็น CodeGnome พูดพาดพิง, git มีปรัชญาการออกแบบที่แข็งแกร่งของการไม่อบบางสิ่งบางอย่างลงในข้อมูลถ้ามันไม่จำเป็น ผู้ใช้คาดว่าจะใช้ตัวเลือกในgit logและgit diffส่งออกข้อมูลไปยังความชอบของพวกเขาหลังจากความจริง ฉันขอแนะนำให้ลองใช้จนกว่าคุณจะพบรูปแบบที่เหมาะกับคุณมากขึ้น git log --first-parentตัวอย่างเช่นจะไม่แสดงข้อผูกพันจากสาขาที่ถูกรวมเข้าด้วยกัน


2
ควรสังเกตว่าผู้ปกครองคนแรกมักเป็นคนผิด เพราะโดยปกติแล้วคน ๆ หนึ่งจะดึงเจ้านายให้เข้ากับสิ่งที่พวกเขากำลังทำอยู่และผลักดันให้การทำงานของพวกเขากลายเป็นผู้ปกครองคนแรกและเป็นคนที่สอง
Jan Hudec

1
@JanHudec: จริง ๆ แล้วมันขึ้นอยู่กับ :-) ถ้าคนที่ทำผลงานรวมแล้วใช่ หากการผสานเกิดขึ้นในภายหลังอาจเป็นไปได้หลังจากการตรวจสอบก็มีแนวโน้มว่าผู้ตรวจสอบได้ทำการตรวจสอบหลักและผสานสาขาคุณลักษณะเข้ากับต้นแบบแล้วทำการทดสอบและผลักดัน
sleske

5

ติดตามประวัติสาขาด้วย --no-ff

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

Git มุ่งมั่นที่จะไม่นำข้อมูลสาขามาใช้เพราะไม่จำเป็นสำหรับประวัติ Git อย่างไรก็ตามการรวมที่ไม่ใช่การส่งต่ออย่างรวดเร็วสามารถนำข้อมูลเพิ่มเติมเกี่ยวกับสาขาที่ถูกผสานได้ คุณสามารถมั่นใจได้ว่าประวัติของคุณมีข้อมูลนี้โดยส่ง--no-ffค่าสถานะไปยังการรวมของคุณ git-merge (1) พูดว่า:

   --no-ff
       Create a merge commit even when the merge resolves as a
       fast-forward. This is the default behaviour when merging an
       annotated (and possibly signed) tag.

โดยทั่วไปจะสร้างข้อความผสานที่คล้ายกับMerge branch 'foo'ดังนั้นโดยทั่วไปคุณสามารถค้นหาข้อมูลเกี่ยวกับ "สาขาสาขา" ด้วยบรรทัดที่คล้ายกับข้อความต่อไปนี้:

$ git log --regexp-ignore-case --grep 'merge branch'

ขอบคุณ แต่ที่ (ส่วนใหญ่) ไม่ตอบคำถามของฉัน ฉันไม่ได้ถามว่ามีวิธีอื่น ๆ ในการค้นหาสาขาดั้งเดิมได้อย่างไร แต่ทำไมข้อมูลไม่รวมอยู่ในเมทาดาทาทั่วไป - เป็นคำถามออกแบบมากกว่า
sleske

1
@sleske ฉันคิดว่าคำตอบของฉันตอบสนอง: Git ไม่ได้ติดตามเพราะประวัติ Git ไม่ต้องการ ฉันไม่คิดว่ามันจะได้พื้นฐานอะไรมากกว่านี้ คุณต้องดูที่แหล่งข้อมูลเฉพาะ แต่ประวัติจะถูกคำนวณย้อนหลังอย่างมีประสิทธิภาพจากส่วนปลายของสาขาปัจจุบัน คุณสามารถเปรียบเทียบได้กับ DVCS อื่น ๆ ที่ถือว่าสาขาเป็นวัตถุชั้นหนึ่งและดูว่าคุณชอบปรัชญาการออกแบบที่ดีกว่านี้หรือไม่ YMMV
CodeGnome

1
git log --mergesว่าคนสุดท้ายที่ควรจะเป็น
Dan

3

คำตอบที่ง่ายที่สุดคือชื่อของสาขาเป็นแบบชั่วคราว ถ้าคุณจะพูดให้เปลี่ยนชื่อสาขา ( git branch -m <oldname> <newname>) จะเกิดอะไรขึ้นกับสิ่งที่กระทำกับสาขานั้น? หรือเกิดอะไรขึ้นถ้าคนสองคนมีสาขาที่มีชื่อเหมือนกันในที่เก็บในท้องถิ่นต่าง

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

ข้อมูลอยู่ที่นั่นคุณแค่ไม่ขอและไม่ได้อยู่ตรงนั้น

Git .git/refs/headsเก็บการตรวจสอบของหัวของแต่ละสาขาใน ตัวอย่างเช่น:

... /. git / refs / heads ทดสอบ $ ls 
-rw-rw-r-- 1 michealt michealt 41 Sep 30 11:50 ทดสอบ
... /. git / refs / heads $ cat test 
87111111111111111111111111111111111111d4

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

โดยการดูที่นี่และติดตามทุกการกระทำที่มีสิ่งนี้ในฐานะผู้ปกครองหรือผู้ปกครองผู้ปกครองหรือผู้ปกครองผู้ปกครอง ... คุณสามารถค้นหาสิ่งที่สาขากระทำที่กำหนดไว้มามันเป็นกราฟขนาดใหญ่ที่จะทำให้

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

คุณสามารถดูสาขาได้โดยการรันคำสั่ง git log ด้วยการตั้งค่าสถานะที่เหมาะสม

บันทึก git - สาขา - แหล่งที่มา --pretty = oneline - กราฟ
บันทึก git - ทั้งหมด --source --pretty = oneline --graph

มีหลายวิธีในการเลือกสิ่งที่คุณต้องการ - ดูที่เอกสารบันทึก git - -allส่วนและตัวเลือกต่าง ๆ ที่ตามมา

* 871111111111111111111111111111111111111111d4 การทดสอบผสานสาขา 'test1' เข้าสู่การทดสอบ
| \  
| * 42111111111111111111111111111111111111111111e8 การปรับปรุง test1: เพิ่มเนื้อหา
* | dd111111111111111111111111111111111111111159 การทดสอบผสานสาขา 'test3' เข้าสู่การทดสอบ
| \ \  

นั่นคือ 'ทดสอบ', 'test1' และ 'test2' เป็นกิ่งก้านสาขาเหล่านี้

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


3

ทำไมคอมมิท git จึงไม่มีชื่อสาขาที่พวกเขาสร้างขึ้น?

เพียงแค่การตัดสินใจออกแบบ หากคุณต้องการข้อมูลนั้นคุณอาจเพิ่ม hook-commit-msg หรือ commit-msg hook เพื่อบังคับใช้ข้อมูลนั้นในที่เก็บเดียว

หลังจากภัยพิบัติ BitKeeper Linus Torvalds พัฒนาคอมไพล์ให้ตรงกับกระบวนการพัฒนาเคอร์เนล Linux ที่นั่นจนกระทั่งแพทช์ได้รับการยอมรับก็มีการแก้ไข, แก้ไข, ขัดเงาหลายครั้ง (ทั้งหมดผ่านทางจดหมาย), ลงชื่อออก (= แก้ไขการกระทำ), เชอร์รี่เลือก, หลงไปที่สาขาของร้อยโทอาจจะ rebased แก้ไขเพิ่มเติมเชอร์รี่ -picks และต่อไปจนกว่าพวกเขาจะถูกรวมเข้าด้วยกันในที่สุดโดย Linus

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

บางทีการออกแบบนั้นอาจเกิดขึ้นโดยบังเอิญ แต่มันตรงกับกระบวนการพัฒนาเคอร์เนลของลีนุกซ์อย่างแน่นอน


2

เพราะใน Git กระทำเช่น "ทำกาแฟ" ถือเป็นส่วนหนึ่งของทั้งสองสาขาเมื่อมีการรวมสาขาคุณลักษณะ แม้มีคำสั่งให้ตรวจสอบว่า:

% git branch --contains @
  feature/make-coffee
  master

สาขามีราคาถูกท้องถิ่นและไม่มีตัวตน; พวกเขาสามารถเพิ่มลบเปลี่ยนชื่อผลักและลบออกจากเซิร์ฟเวอร์ได้อย่างง่ายดาย

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

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

Mercurial นั้นตรงกันข้าม ไม่ต้องการเปลี่ยนแปลงสิ่งต่าง ๆ กิ่งก้านเป็นแบบถาวรประวัติการเขียนใหม่เป็นขมวดคิ้วคุณไม่สามารถลบสาขาจากเซิร์ฟเวอร์ได้

กล่าวโดยย่อ: Git อนุญาตให้คุณทำทุกอย่าง Mercurial ต้องการทำให้สิ่งต่าง ๆ เป็นเรื่องง่าย (และทำให้ยากที่จะให้คุณทำสิ่งที่คุณต้องการ)

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