คุณจะทำโครงร่างการกำหนดตัวเลขด้วย Git ได้อย่างไร


131

องค์กรของฉันกำลังพิจารณาย้ายจาก SVN เป็น Git การโต้แย้งหนึ่งเรื่องการเคลื่อนย้ายมีดังนี้:

เราจะทำเวอร์ชันอย่างไร

เรามีการเผยแพร่ SDK ตามแพลตฟอร์ม NetBeans เนื่องจากการแก้ไข SVN เป็นตัวเลขอย่างง่ายเราจึงสามารถใช้พวกเขาเพื่อขยายหมายเลขรุ่นของปลั๊กอินและการสร้าง SDK ของเรา เราจะจัดการกับสิ่งนี้ได้อย่างไรเมื่อเราย้ายไปที่ Git

การแก้ปัญหาที่เป็นไปได้:

  • การใช้หมายเลขบิลด์จากฮัดสัน (ปัญหา: คุณต้องตรวจสอบฮัดสันเพื่อเชื่อมโยงกับเวอร์ชัน Git จริง)
  • upping เวอร์ชันด้วยตนเองสำหรับทุกคืนและมีเสถียรภาพ (ปัญหา: เส้นโค้งการเรียนรู้ข้อผิดพลาดของมนุษย์)

หากคนอื่นพบปัญหาที่คล้ายกันและแก้ไขมันเรายินดีที่จะได้ยินว่า


3
คุณช่วยให้เซิร์ฟเวอร์ฮัดสัน (ไม่ใช่เจนกินส์ ?) ของคุณเพิ่มgitแท็กโดยอัตโนมัติหลังจากแต่ละบิลด์ที่สำเร็จหรือไม่ สิ่งนี้จะมีข้อได้เปรียบเพิ่มเติมที่ทำให้ชัดเจนว่าการคอมมิชชันgitมีปัญหาในการสร้างหรือทดสอบความล้มเหลวเนื่องจากจะไม่มีการติดแท็ก
Mark Booth


ตามบันทึกข้างคุณสามารถเพิ่มการสร้างนับแท็กโดยการติดตามการสร้างครั้ง
Shahbaz

ไม่แน่ใจว่าเป็นโซลูชันที่ทำงานได้ แต่จะส่งออกจาก git ไปยัง svn repo ก่อนการสร้างทุกครั้งหรือไม่ จากนั้นก็สร้างจาก svn repo - ถ้ารวมศูนย์เป็นสิ่งที่เราต้องการเพียงแค่ใช้มันแทน
Jonny

คำตอบ:


152

ใช้แท็กเพื่อทำเครื่องหมายคอมมิชชันด้วยหมายเลขเวอร์ชัน:

git tag -a v2.5 -m 'Version 2.5'

กดแท็กอัปสตรีมซึ่งไม่ได้ทำตามค่าเริ่มต้น:

git push --tags

จากนั้นใช้คำสั่งอธิบาย :

git describe --tags --long

สิ่งนี้จะทำให้คุณมีรูปแบบสตริง:

v2.5-0-gdeadbee
^    ^ ^^
|    | ||
|    | |'-- SHA of HEAD (first seven chars)
|    | '-- "g" is for git
|    '---- number of commits since last tag
|
'--------- last tag

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

20
การปรับปรุงgit describe --long --tags --dirty --alwaysเล็กน้อย: . 'สกปรก' จะบอกคุณว่ามีการเปลี่ยนแปลงในท้องถิ่นเมื่อทำ 'อธิบาย' (หมายความว่ามันไม่สามารถอธิบายสถานะของ repo ได้อย่างเต็มที่) 'เสมอ' หมายความว่าคุณจะไม่ได้รับข้อผิดพลาดเมื่อไม่มีแท็ก มันจะย้อนกลับไปยังแฮชคอมมิท ดังนั้นคุณสามารถรับ76001f2-dirtyเป็นตัวอย่าง เห็นได้ชัดว่าการเห็น 'สกปรก' หมายถึงบางคนเกิดความผิดพลาด
Mike Weller

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

@ void.pointer: แน่นอนหมายเลขเวอร์ชันนี้ตอบคำถาม“ การปล่อยรุ่นนี้อิงจากอะไร?” ไม่ใช่“ เวอร์ชั่นนี้จะส่งมอบการกระทำใดบ้าง” อย่างไรก็ตามคุณมีอิสระในการตีความแท็กแตกต่างกัน ตัวอย่างเช่นถ้าคุณติดแท็กHEADเป็นv2.5คุณก็สามารถตีความได้เป็นอย่างดีว่าเป็นจุดเริ่มต้นของวงจร 2.5 เปิดตัวแล้วแท็กv2.5-releaseหรือสิ่งที่คุณต้องการ
Jon Purdy

8
การปรับปรุงเล็ก ๆ อีกประการหนึ่ง หากคุณต้องการมีแท็กอื่นเช่นกัน แต่ใช้แท็กที่มีรูปแบบเฉพาะสำหรับการสร้างรุ่นคุณอาจใช้--matchตัวเลือกเช่นนี้:git describe --long --tags --dirty --always --match 'v[0-9]\.[0-9]'
Alexander Amelkin

42

สิ่งนี้ได้เกิดขึ้นในสองสามโครงการสำหรับฉัน ทางออกที่ดีที่สุดที่ฉันเคยมีคือการสร้างหมายเลขรุ่นดังนี้:

xy <จำนวนคอมมิต> .r <git-hash>

โดยปกติจะสร้างขึ้นโดยการสร้างระบบของเราใช้การรวมกันของไฟล์แบบคงที่บางส่วนหรือแท็กที่จะได้รับการแก้ไขตัวเลขที่สำคัญgit rev-list HEAD | wc -l(ซึ่งเร็วกว่าการใช้git log) git rev-parse HEADและ เหตุผลมีดังนี้:

  1. เราต้องการความสามารถในการสร้างเวอร์ชันระดับสูงอย่างชัดเจน (iexy)
  2. เมื่อการพัฒนาแบบขนานเกิดขึ้นเราจำเป็นต้องไม่สร้างหมายเลขรุ่นเดียวกัน
  3. เราต้องการติดตามว่าเวอร์ชั่นมาจากไหน
  4. เมื่อเส้นขนานถูกรวมเข้าด้วยกันเราต้องการเวอร์ชั่นใหม่เพื่อแก้ไขปัญหาที่สูงกว่าสาขาใดสาขาหนึ่ง

หมายเลข 2 จะมองไม่เห็นคนส่วนใหญ่ แต่จริงๆที่สำคัญและมันยากลำบากกับการควบคุมแหล่งกระจาย SVN ให้ความช่วยเหลือในเรื่องนี้โดยให้หมายเลขการแก้ไขเดียวแก่คุณ ปรากฎว่าการนับการกระทำนั้นใกล้เคียงที่สุดเท่าที่คุณจะทำได้ในขณะที่การแก้ข้อที่ 4 อย่างน่าอัศจรรย์ ในการปรากฏตัวของสาขานี้ยังคงไม่ซ้ำกันซึ่งในกรณีนี้เราเพิ่มแฮชซึ่งแก้ไข # 3 ได้อย่างเรียบร้อย

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

ในกรณีที่คุณสงสัยเราเลือกที่จะใส่ r ไว้ข้างหน้าของแฮชเนื่องจากความแปลกประหลาดกับวิธีที่บรรจุภัณฑ์ของงูใหญ่จัดการตัวอักษรในหมายเลขรุ่น (เช่น ae น้อยกว่า 0 ซึ่งจะทำให้ "1.3.10.a1234" < "1.3.10" <"1.3.10.1234")


1
btw คุณจัดการกับปัญหาไก่ไข่ในการพิจารณา git-hash ก่อนที่จะตรวจสอบได้อย่างไร คุณใช้. gignignore หรือเคล็ดลับอื่น ๆ บ้างหรือไม่?
kfmfe04

3
ฉันไม่ได้ ฉันไม่ใช้แฮชจนกระทั่งเวลาสร้างแพ็คเกจซึ่งนานหลังจากเช็คอิน ภาษาที่ต่างกันมีวิธีที่แตกต่างกันในการฉีดสิ่งนี้ สำหรับ Python ฉันใช้ './setup.py egg_info -b ". $ {BUILD_VERSION}" sdist' สำหรับ C และ C ++ ฉันจะนิยามมาโครในเวลารวบรวมด้วย 'CFLAGS = -D "$ {BUILD_VERSION}" " สำหรับ Go ฉันจะกำหนดสัญลักษณ์ ณ เวลาลิงก์ด้วย 'go install -ldflags appmodule.BuildVersion "-X. $ {BUILD_VERSION}"'
Jayson

1
นี่ควรเป็นคำตอบที่ดีที่สุด
alvinabad

คำตอบที่ดีมาก
haelix

9

นี่อาจจะเกินเลยไปหน่อย แต่ฉันจะบอกให้คุณรู้ว่าเราจะทำอย่างไร

เราใช้โครงสร้างที่แตกแขนงคล้ายกันมากกับเรื่องนี้

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

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

ตัวอย่าง: 2.1.0 build 1337

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


8

รุ่นต่างๆจะถูกแฮช SHA1 hash ของไฟล์ทั้งหมดในแผนผังไดเรกทอรีที่จัดเก็บในเวลาที่ทำการเช็คอิน แฮชนี้จะถูกเก็บไว้พร้อมกับแฮชของการเช็คอินของผู้ปกครองเพื่อให้สามารถอ่านประวัติทั้งหมดได้

ดูกระบวนการใช้ 'git-อธิบาย' ผ่าน GIT-VERSION-GEN และวิธีที่คุณสามารถเพิ่มสิ่งนี้ผ่านกระบวนการสร้างของคุณเมื่อคุณแท็กการเปิดตัวของคุณ

นี่เป็นบล็อกที่ดีที่ให้ตัวอย่างของวิธีการได้รับสิ่งที่คุณต้องการ:

http://cd34.com/blog/programming/using-git-to-generate-an-automatic-version-number/


0

Jon Purdy มีความคิดที่ถูกต้อง ทำให้การบริหารจัดการที่เกิดขึ้นจริงในสาขาเหล่านี้ได้ง่ายเช่นกันและการจัดการสาขาการโต้แย้งสำหรับการย้ายไปgit flowgit

ขอเริ่มต้นด้วยบทสรุปพื้นฐานของgitตั้งแต่คุณมาจากsvn-to- gitมุมมอง พิจารณาในgitสิ่งต่อไปนี้:

master--...............-.....-..............-
        \             /     /              /
         ---develop---------............../
                            \            /
                             --feature---

ด้านบนคุณแยกmasterไปที่develop(แสดงโดย\) และแยกdevelopไปที่featureสาขา เรารวมสาขาเหล่านั้นกลับมา (แสดงโดย/) ด้วยคอมมิชชัน ( -) ตามสาขา (ถ้าไม่มีการคอมมิชชัน แต่การผสานเป็นวิธีที่ถูกต้องมี.ตัวบ่งชี้ที่แสดงว่าการถัดไป-เป็นการคอมมิทถัดไป)

ง่ายพอสมควร เกิดอะไรขึ้นถ้าเรามีโปรแกรมแก้ไขด่วนในรุ่นหลักของเรา

master--...............-.....-................-...........-.........-
        \             /     /                / \         /|        /
         \           /     /                /   -hotfix-- V       /
          ---develop---------............../..............-...----
                             \            / \             V   /
                              --feature---   --feature2...----

ข้างต้นแยกจากdevelop masterข้อผิดพลาดที่พบในการmasterได้รับการแก้ไขโดยการแตกแขนงจากการแก้ไขมันและกลับเข้ามาในการควบรวมกิจการmaster masterจากนั้นเราก็รวมmasterเข้ากับdevelopและจากนั้นdevelopเข้าสู่feature2ซึ่งรีดรหัสใหม่จากhotfixในสาขาเหล่านี้

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

ดังนั้นนี่เป็นอีกวิธีในการทำเช่นนั้น

master--..........-........-
        \        /\       /
         ---1.0--  --1.1-- 

1.0 รีลีสของคุณจะถูกแท็1.0.11.0.21.0.3,, และอื่น ๆ

ต่อไปนี้เป็นเคล็ดลับ: คุณพบข้อบกพร่องใน 1.0 และมีผลกับ 1.1, 1.2 และ 1.3 คุณทำอะไร?

คุณแยกสาขาออกเป็นรุ่นล่าสุดหรือรุ่นที่เก่าที่สุดและทำการแก้ไข จากนั้นคุณผสานใหม่hotfixสาขาเข้า1.3และอื่นเข้า1.2, และ1.1 1.0อย่าแยกสาขาจากเวอร์ชันการบำรุงรักษาแต่ละสาขา อย่ารวม1.0เข้าmasterหรือผสานmasterเข้า1.0ด้วยกัน นำhotfixสาขาเดียวและรวมเข้าไปในสาขาเวอร์ชันทั้งหมดของคุณ หากมีความขัดแย้งก็จะบอกคุณ ตรวจสอบรหัสของคุณเพื่อให้แน่ใจว่าการเปลี่ยนแปลงนั้นถูกต้อง ( git diffคือเพื่อนของคุณ)

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

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

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


-6

Pro Git ในส่วน 7.2 "แอตทริบิวต์ Git"ในส่วน "การขยาย" คำหลัก "มีตัวอย่างที่ดีของการใช้ตัวกรองรอยเปื้อน & ทำความสะอาดสำหรับการสร้างคำหลักสไตล์ RCS คุณสามารถใช้เทคนิคเดียวกันสำหรับการฝังบางรุ่นสตริงเป็นรหัสในรูปแบบและคำนวณตามกฎของคุณ คุณยังสามารถใช้git describeเป็นจุดเริ่มต้นได้ แต่คุณมีความเป็นไปได้ที่จะแปลงเป็นรูปแบบที่เหมาะสมมากขึ้นและได้รับจาก v2.5-14-feebdaed ตัวอย่างเช่นทำความสะอาด 2.5.14


9
-1 สำหรับการทำลายคำตอบที่ดีโดยไม่มีข้อยกเว้นสำหรับการโจมตีโฆษณา
Jörg W Mittag

9
ใครจะบอกว่าเป็นเด็กคอมไพล์โหวตให้คุณลง มันสามารถจะเป็นคนที่ชอบน้อยสุภาพ
Mark Booth

FYI ฉันเพิ่งแก้ไขคำตอบ
Keith Thompson

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