กลยุทธ์ในการใช้การควบคุมเวอร์ชันในระบบโมดูลาร์


15

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

การผสมเข้าด้วยกันอาจจะง่ายต่อการติดตามการเปลี่ยนแปลงที่มีความสัมพันธ์และรักษาสาขาที่สัมพันธ์กัน (เช่นวิวัฒนาการของโปรโตคอล) แต่ในทางกลับกันจะทำให้การพัฒนาแต่ละรายการมีความยุ่งเหยิงมากขึ้น ...


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

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

@ Mark Booth Humm ฉันคิดถึงส่วนของโครงการในแต่ละสาขาเพราะเขาระบุว่าพวกเขาจะแชร์รหัส เพียงติดแท็กแต่ละส่วนเป็นสาขาที่เหมาะสมและคุณก็ทำได้ดี DVCS ของคุณไม่อนุญาตให้มีไฟล์ / การมอบหมายให้มีหลายแท็กหรือไม่?
Spencer Rathbun

คำตอบ:


12

หากคุณกำลังใช้คอมไพล์หรือปรอทแล้วคุณอาจต้องการที่จะดูที่submodulesหรือsubrepositories

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

ด้วยการกระทำกับที่เก็บ super เท่านั้นเมื่อทั้งไคลเอนต์และเซิร์ฟเวอร์มีความเหมาะสมต่อกัน Super-repository จะให้ทางเลือกแก่คุณในการตรวจสอบระบบที่ใช้งานได้เท่านั้นดังนั้นคุณจะไม่พยายามเรียกใช้ไคลเอ็นต์ใหม่กับเก่า เซิร์ฟเวอร์หรือในทางกลับกัน

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

คำตอบนี้ไม่ได้มีวัตถุประสงค์เพื่อสนับสนุนgitหรือhgมากกว่า SCM อื่น ๆ มันก็เกิดขึ้นเพียงว่าฉันรู้SCM เหล่านี้ดีพอที่จะรู้ว่าตัวเลือกนี้มีอยู่ ฉันไม่เข้าใจว่าการsvnทำงานภายนอกเป็นอย่างไร


1
ตอนนี้เป็นคุณสมบัติที่น่าสนใจ ฉันสนใจที่จะเห็นกรณีศึกษาการใช้งานที่เหมาะสมฉันไม่เคยได้ยินมาก่อนเลย!
Ed James

สิ่งที่คล้ายกันในการโค่นล้มเป็นคำจำกัดความภายนอก: svnbook.red-bean.com/en/1.0/ch07s03.html อย่างไรก็ตามมันทำงานในวิธีที่แตกต่างกันเล็กน้อย
liori

1
@ MarkBooth: ใช่คุณทำได้ ในหน้านั้นคุณสามารถดูพารามิเตอร์ที่มีลักษณะเหมือน -r12345 ซึ่งเป็นตัวกำหนดว่าคุณต้องการได้รับการแก้ไขใด และเนื่องจากคุณสมบัติ svn: externals มีเวอร์ชันเหมือนกับไฟล์ข้อความใด ๆ คุณสามารถมีค่าแตกต่างกันสำหรับ -r สำหรับการแก้ไขแต่ละครั้ง นอกจากนี้คุณกำลังเรียกดูเอกสารโบราณ 1.0 คำจำกัดความภายนอกถูกเปลี่ยนแปลงใน 1.5 และเวอร์ชันปัจจุบันคือ 1.7 ดู: svnbook.red-bean.com/en/1.7/svn.advanced.externals.html
liori

6

แยก!

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

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

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

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


1

ในMercurialชุดรูปแบบนี้สามารถใช้->เพื่อแสดงถึงความสัมพันธ์ย่อย:

product -> client -|-> (many components)
                   |->  shared component A

        -> server -|-> (many components)
                   |->  shared component A

ผลิตภัณฑ์มีไคลเอ็นต์ย่อยเซิร์ฟเวอร์ แต่ละรายการมีองค์ประกอบย่อยเป็นอาจย่อยอย่างน้อยหนึ่ง subrepo ร่วมกันระหว่างทั้งสอง

การติดแท็กควรทำในสองระดับแรกไม่ใช่ด้านล่าง

ความมุ่งมั่นจะทำในระดับองค์ประกอบ superrepos ติดตามสาขาที่มีชื่อและรุ่นของผลิตภัณฑ์ได้อย่างมีประสิทธิภาพ สาขา / บุ๊คมาร์คที่มีชื่อมักจะดีกว่าสาขาโคลนสำหรับการใช้งาน (เช่น trainability) และเข้ากันได้กับ subrepos

hg มีแนวโน้มไปสู่การสันนิษฐานว่า superrepos เป็นผลิตภัณฑ์และการกระทำจะกระทำในระดับสูงสุด แต่ไม่ได้ผลดีโดยเฉพาะอย่างยิ่งเมื่อผลิตภัณฑ์หลาย ๆ ชิ้นใช้ส่วนประกอบเดียวกัน :-)

ฉันไม่คิดว่ารูปแบบนี้จะเปลี่ยนไปมากถ้าเปลี่ยนไปใช้คอมไพล์ แต่ฉันยังไม่ได้ลองใช้คอมไพล์


1

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


1

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

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

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

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

มากกว่าหนึ่งครั้งฉันได้สนับสนุน (สำเร็จ) สำหรับทีมของฉันในการรวมที่เก็บข้อมูล git ที่มีอยู่เพราะมันทำให้การพัฒนาและการใช้งานง่ายขึ้น


0

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

  • วางไฟล์ต้นฉบับทั้งหมดสำหรับทั้งไคลเอนต์และเซิร์ฟเวอร์ในไดเรกทอรีเดียวกันหรือไม่

  • สร้างไดเรกทอรีโครงการหลักที่มีไดเรกทอรีย่อยสำหรับลูกค้าและเซิร์ฟเวอร์หรือไม่

  • แยกสองโครงการออกจากกันอย่างสมบูรณ์หรือไม่

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

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

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