นโยบายการใช้งาน Version Control System แบบต่าง ๆ

ผมเคยเล่าให้ฟังเรื่องของ VCS หรือ Version Control System ไปเมื่อสักพักใหญ่ ๆ ที่ผ่านมา วันนี้จะพูดถึงนโยบายการนำ VCS ไปใช้กับการบริหารโปรเจคเท่าที่เคยเห็นมานะครับ

ทั้งสามแบบมีข้อดีข้อเสียแตกต่างกันไปครับ ก็ต้องดูกันที่สถานการณ์ไหนจะเหมาะกับวิธีไหนมากกว่า

รับเฉพาะโค๊ดที่ทำเสร็จแล้วเท่านั้น

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

วิธีนี้ถ้ามองในมุมมองของ SCM นั้นจะเป็นวิธีที่ง่ายที่สุด เพราะปัญหาของเขาจะน้อยมาก เขาจะทำแค่แบ่ง Branch เท่าที่จำเป็น แยก Tag เมื่อถึงเวลาตัดโค๊ด สองอย่าง …

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

แยก Branch เอาไว้สำหรับโปรเจค

เรายังอยู่ที่ VCS แบบรวมศูนย์นะครับ วิธีนี้เป็นวิธีที่ออกมารองรับนักพัฒนามากกว่า กล่าวคือ เวลาเริ่มโปรเจคเราจะสร้าง Branch ขึ้นมาใหม่ นักพัฒนาในโปรเจคนี้ทุกคนจะมีสิทธิเข้าถึง branch นี้ (ส่วนคนอื่นอาจจะดูได้อย่างเดียว) ทุกคนเวลาแก้โค๊ดไปก็จะ commit เข้ามาใน branch นี้ แล้วพอทดสอบจนเป็นที่น่าพอใจแล้วจึง merge กลับเข้าไปใน trunk อีกทีหนึ่ง
วิธีนี้เป็นวิธีที่ได้รับการแนะนำในอดีต (วิธีบนนี่ไม่ต่างกับเอาโค๊ดไปเก็บไว้ใน file server เลยล่ะครับ) เพราะว่า … คนที่แนะนำก็เป็นคนเขียนโค๊ดนั่นล่ะครับ SCM อาจจะหงุดหงิดนิดหน่อยที่ต้องมานั่งแตกนั่งแยก Branch ให้แต่ละโปรเจค 
วิธีนี้ช่วยนักพัฒนาตรงที่เราสามารถใช้ VCS เป็นเครื่องมือในการแชร์โค๊ดกันระหว่างโปรเจค (โดยยังไม่เอาเข้าไปในฐานโค๊ดหลัก)  ไม่ต้องมาแชร์ไฟล์ผ่านอีเมล์กันแล้ว และที่สำคัญคือทุกการกระทำของโปรเจคจะถูกติดตามโดยเวอร์ชั่นของโค๊ดที่เรา commit เข้าไป
วิธีนี้ยังสนับสนุนกฎการใช้ VCS ที่ว่า commit เร็ว ๆ commit บ่อย ๆ (commit early, commit often) อีกด้วย (เป็นส่วนหนึ่งของการทำ CI)
สำหรับปัญหาของวิธีนี้คือ การ merge code ในช่วงปิดโปรเจคนั้นอาจจะมีปริมาณมาก (ก็ขึ้นอยู่กับจำนวนไฟล์ที่เปลี่ยน) ทำให้ต้องทำการทดสอบหน่วยย่อยของโปรแกรมเยอะหน่อย แต่ถ้าเราใช้ Unit Test Framework ช่วยแล้วล่ะก็เราแทบไม่ต้องทำอะไรเพิ่มเลยครับ รัน Unit Test เสร็จปุ๊บก็รู้ผลเลยว่ามันใช้งานได้ไหม อะไรทำนองนี้

ใช้ VCS แบบกระจาย

คำแนะนำในยุคปัจจุบันนี้ก็คือ จงใช้ VCS แบบกระจาย ซึ่งเหมาะมากกับทีมงานขนาดใหญ่ อย่าง git ที่เป็น DVCS ยอดนิยมตัวหนึ่งนั้น ถูกสร้างมาเพื่อรองรับนักพัฒนาของ Linux Kernel ซึ่งในเวอร์ชั่น 3.5 (เก่าแล้ว) มีจำนวนนักพัฒนาถึง ~1200 คนเชียวนะครับ แถมมาจากคนละบริษัทกันด้วย
คำว่าระบบจัดการเวอร์ชั่นแบบกระจาย หรือ DVCS — Distrbuted Version Control System นั้น โดยหลักการก็คือ ไม่มี client-server ผู้ใช้ทุกคนจะมีระบบจัดการเวอร์ชั่นเป็นของตัวเอง รันอยู่ในเครื่องตัวเอง ดังนั้นเมื่อเรา commit งานแล้วเนี่ยไอ้ไฟล์ที่เปลี่ยนแปลงมันไม่ไปไหนครับ มันก็อยู่ในเครื่องเรานั่นล่ะ แต่เราสามารถที่จะผลัก (push) งานที่เราทำเสร็จแล้วไปให้คนอื่นได้ และเราก็สามารถดึง (pull) งานจากเครื่องคนอื่นมายังเครื่องเราได้
พอมันเป็นแบบนี้ปุ๊บ เราก็ไม่ต้องไปง้อ SCM ให้ทำอะไรอีกต่อไป (ที่จริงก็แค่ง้อน้อยลงมากเท่านั้นล่ะครับ) กล่าวคือ ถ้าสมมติเรามีโปรเจคใหม่ตัวหนึ่ง เราก็สามารถที่จะตั้งเครื่องขึ้นมาตัวนึงเป็นศูนย์กลางโปรเจค แล้วก็สร้าง repository ในเครื่องเราให้ sync เข้ากับเจ้าเครื่องนี้ หลังจากที่ทำงานเสร็จเรียบร้อยเราก็ merge กับตัว repository หลักของบริษัท แล้วก็ push เข้าไป … จบ!
หรือเราจะทำแบบกระจายเต็มที่เลยก็ยังได้ ไม่ต้องมีละเครื่องกลางของโปรเจค พอใครทำโค๊ดเสร็จเรียบร้อยถึงระดับที่ว่าเสถียรพอก็สามารถ push ไฟล์ของเราไป repository ของคนอื่นได้! หรือถ้าเราต้องการจะไปเอา change ของคนอื่นก็ไป pull มา ทั้งทีมทำงานของตัวเองให้เสร็จ แล้ว push change เข้าไปเครื่องหัวหน้าให้เขารีวิว แล้วเขาก็ทำการ push ต่อเข้าไปใน repository กลางของบริษัท
SCM เองก็ไม่ต้องมาเจ๊าะแจ๊ะกับผู้ใช้ พอเขาจะตัด build ใหม่ เขาก็ไป pull มาจาก repository กลาง จบ ง่าย
ปัญหาคือ DVCS เป็นคอนเซ็ปท์ค่อนข้างใหม่ ผู้ใช้หลายคนงง .. ไม่เข้าใจ อย่างเมื่อวันที่ผมไปบาร์แคมป์บางเขน 4 ที่ผ่านมา มีผู้เข้าร่วมใน session หนึ่งบอกว่าเขามีการ push บ่อยมาก แทบจะทุก commit ทำให้เกิดการ merge ขึ้นบ่อยมากเกินไป ที่จริงถ้าเรา push ทุก commit เลยก็จะไม่ต่างอะไรกับการใช้ Centralized VCS เลยนะครับ การ push ควรจะทำแค่หลังจากที่ change ที่เราทำนั้นสเถียรพอและผ่านการทดสอบแล้วเท่านั้น 
แต่ถ้าลองใช้ไปสักพัก และทำความเข้าใจกับมัน ไม่มีอะไรยากครับ มองให้กว้าง มองให้ง่ายเข้าไว้ แล้วจะเข้าใจเองว่าจริง ๆ มันไม่มีอะไรหรอก
ส่วนข้อเสียเรื่องการ merge นั้นก็อาจจะมีมากเช่นกันในช่วงที่จะ push กลับเข้าไปยัง repository หลัก แต่ก็อย่างที่ผมบอกไปเมื่อตอนต้นว่า ถ้าเราเอา unit test framework มาประยุกต์สร้างเป็น automated unit test ได้ตรงนี้จะไม่เสียเวลามากครับ

ใส่ความเห็น

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.