สวัสดีครับ หายไปนานเลยจากภาคแรก ซึ่งผมทิ้งท้ายไว้ที่การตั้ง Source Control อย่างงายๆ สำหรับใช้เองในเครื่อง ด้วย SVN รวมไปถึงการใช้งาน SVN อย่างคร่าวๆ ไม่ว่าจะเป็นการสร้าง Repository ใหม่ การนำไฟล์เข้า Source Control, การ Update และ Commit แต่เรื่องที่ผมยังไม่ได้กล่าวถึง คือการทำให้ SVN สามารถใช้งานร่วมกันได้ ภายในทีม และการจัดการกับ Conflict ซึ่งจะเกิดขึ้นได้ เมื่อมีผู้พัฒนาหลายๆ คน ทำการแก้ไขไฟล์พร้อมๆ กัน ในส่วนเดียวกัน
อย่าใช้ Shared Folder!
สำหรับการทำให้ SVN ใช้งานได้พร้อมกันหลายๆ คน บางคนอาจจะนึกได้ว่า ทำไมเราไม่ทำการทำให้โฟลเดอร์ที่เป็น Repository นั้น ให้กลายเป็น Shared Folder แล้วให้ผู้พัฒนาทุกคน ต่อเข้ามาผ่านโปรแกรม Tortoise SVN ล่ะ? คำตอบคือ เป็นสิ่งที่สามารถทำได้ครับ แต่อย่าลืมว่า ในการแก้ไขข้อมูล SVN จะต้องทำการ Lock/Unlock ไฟล์ เหมือนกับการเขียนไฟล์ลงเครื่องทั่วๆ ไป แต่ปัญหาไม่ได้อยู่ที่การที่เราจะ Lock ไฟล์ ไม่ได้ครับ ปัญหามันอยู่ที่ การ Lock ไฟล์ผ่าน Shared Folder ยังเป็นเรื่องที่อันตรายมากๆ ในทางปฏิบัติ จึงเป็นสิ่งที่ไม่สมควรทำเป็นอย่างยิ่ง (ทีนี้รู้หรือยังว่า ไม่ควรเปิดไฟล์ Word/Excel จาก Shared Folder แล้วแก้ไขมันตรงๆ) โดยเฉพาะกับข้อมูลสำคัญอย่าง Source Code ของเรา และเป็นที่มาของส่วนหนึ่งของความไม่ค่อยจะน่าเชื่อถือของ Visual Source Safe นั่นเองครับ
แล้วทีนี้ จะทำยังไงดีละ?
Visual SVN Server
โดยปกติแล้ว เมื่อเราติดตั้ง SVN เราจะได้ SVN Server มาพร้อมกันด้วยครับ ตัวโปรแกรมมันชื่อว่า SVNServe ซึ่งเราสามารถเปิดโปรแกรมนี้ไว้ แล้วให้เครื่องอื่นๆ ใช้ Tortoise SVN ต่อเข้ามาได้เลย แต่ผมจะแนะนำโปรแกรมอีกตัวหนึ่ง ให้ใช้แทน SVNServe ที่ชื่อว่า Visual SVN Server ครับ
Visual SVN Server นี้เป็นผลิตภัณฑ์ของบริษัทแห่งหนึ่ง ซึ่งทำ Plug-in เพื่อให้ Visual Studio สามารถติดต่อกับ SVN ได้ ออกขายครับ แต่ว่าเขาใจดี เปิดให้เราใช้ตัว SVN Server ซึ่งเขาทำการโมมาให้เรียบร้อยแล้วได้ฟรี ถ้าจะใช้จริงๆ จังๆ ก็อย่าลืมอุดหนุนเขาบ้างนะครับ ที่ http://www.visualsvn.com
สาเหตุที่ผมคิดว่า Visual SVN Server นั้นดีกว่า SVN Serve ที่เราได้มาพร้อมกันกับการลง SVN นั่นก็คือ…
- จัดการได้ง่าย เพราะว่า ทีมที่พัฒนา Visual SVN Server นั้น เขาได้ทำ GUI มาเป็น MMC ไว้เลยครับ การสร้าง Repository, จัดการ Permission หรือ จัดการ User ทำได้ง่ายกว่า SVNServe ซึ่งต้องใช้การแก้ Text File ด้วยมือ
- รองรับ Active Directory/Windows Authentication ถ้าเรามีระบบ AD หรือ ที่เครื่อง Server มีการสร้าง User เพื่อจัดการการแชร์ไฟล์ หรืออะไรอื่นๆ อยู่แล้ว เราสามารถให้ Visual SVN ไป Authen กับ AD หรือ Windows Authentication ได้เลยครับ ไม่ต้องสร้าง User หลายๆ ที่ ให้วุ่นวาย
- มี HTTP/HTTPS ให้เลย โดยปกติแล้ว ถ้าเราใช้ SVNServe ตัว Tortoise SVN จะต้องติดต่อผ่านโปรโตคอลของ SVN เอง ซึ่งมันมักจะโดน Firewall บล็อคครับ ทำให้การติดต่อกับ Server SVN ผ่านเน็ต จะต้องมีการคอนฟิก Firewall เพิ่มมาด้วย SVN จึงมีการพัฒนาให้รองรับการใช้ Apache เป็นหน้าด่าน เพื่อทำงานกับ Repository ผ่านโปรโตคอล HTTP ได้ด้วย ติดตรงที่ถ้าเราเอามาทำเอง มันจะวุ่นวายอยู่พอสมควร แต่ Visual SVN นี่ จะเป็น Server SVN แบบ HTTP/HTTPS โดยตัวมันเองอยู่แล้วครับ
- รองรับการทำงานกับระบบอื่นๆ ได้อีก ถ้าหากเราจะเล่น SVN ให้มัน Advance ไปอีก ซึ่งขั้นต่อไป ก็คือทำงานร่วมกับระบบ Project Management อย่างเช่น Trac ที่โปรเจค Open Source ทั้งหลายนิยมใช้กัน Visual SVN เขาก็เปิดช่องไว้ให้เราแล้วด้วยเหมือนกันครับ โดยคุณสามารถตั้งค่าได้จากตัว GUI โดยตรงเลย แต่ผมยังไม่ขอพูดถึงเรื่องนี้นะครับ อาจจะเป็นในภาค 3 ของเรื่องนี้ ถ้าสนใจ ลอง Search หาเรื่อง Commit Hook ดูครับ
การติดตั้งนั้น ง่ายดายมากครับ เปิดตัว Setup ขึ้นมา กด Next ลูกเดียว ก็เสร็จแล้วครับ สำหรับการ Authentication ผมแนะนำให้ใช้ Windows Authentication ครับ เพื่อที่ Username/Password ทั้งหลาย จะได้ไม่ไปกระจายอยู่หลายที่ หลังจากติดตั้ง ตัว Visual SVN Server จะเป็น Windows Service ครับ มันจะทำงานโดนอัตโนมัติเมื่อเปิดเครื่อง
การใช้งานเบื้องต้น
สำหรับการใช้งาน Visual SVN Server นั้น สามารถใช้ GUI จัดการได้เลยครับ โดยหลักๆ แล้ว สิ่งที่เราต้องจัดการ ก็มีแค่สร้าง Repository กับการเปลี่ยน Permission เท่านั้นเองครับ
ปัญหาจากการทำงานร่วมกัน
อย่างที่ผมได้เกริ่นไปแล้ว ว่า SVN นั้น เป็นการทำงานแบบ Copy-Modify-Merge ซึ่งจะทำให้ทุกคนสามารถทำงานพร้อมๆ กันได้ อย่างสะดวก แต่อย่างไรก็ดี ปัญหาที่อาจเกิดขึ้นได้ คือขั้นตอนของการ Merge นี่เองครับ เพราะว่า…
- ผู้พัฒนา อาจจะทำงานในบริเวณเดียวกันของไฟล์ ที่ผมใช้คำว่า บริเวณเดียวกัน นั่นก็เพราะว่า อัลกอริธึมในการ Merge ที่ SVN ใช้นั้น สามารถติดตามได้ว่า Source Code แต่ละบรรทัด ถูกย้ายไปยังตำแหน่งไหนบ้าง มีอะไรที่ต่างกันบ้าง แต่ว่า การเปลี่ยนแปลงที่เกิดขึ้นในบรรทัดเดียวกัน หรือการเปลี่ยนแปลงที่มากจนทำให้อัลกอริธึมสับสน ก็ไม่สามารถ Merge ได้ครับ แต่ข้อดีของ SVN ก็คือ Source Code ที่อยู่ใน Repository จะไม่มีทางอยู่ในสภาพที่เสียหายโดยเด็ดขาด เพราะว่า ก่อนการ Commit Code เข้าไปยัง Repository ตัว SVN จะตรวจว่า มีการเปลี่ยนแปลงที่ไฟล์เดียวกันหรือไม่ ถ้ามี ผู้พัฒนา จะต้องทำการ Update เพื่อดาวน์โหลด Source Code มาทำการ “ทดลอง Merge” ในเครื่องก่อน ถ้าเกิดว่า Merge ไม่ผ่าน ก็จะไม่สามารถ Commit ได้
- การ Merge ไม่สามารถการันตีเรื่อง Semantic/Logic ได้ แต่ทีนี้ ถึงแม้การ Merge จะสำเร็จ เราก็ไม่สามารถการันตีได้ว่า Source Code ที่ Merge สำเร็จแล้ว จะคอมไพล์ผ่าน และทำงานได้ถูกต้อง (ซึ่งก็เป็นปัญหาเดียวกัน กับ Source Control ในทุกรูปแบบ รวมไปถึง แบบที่ไม่มี Source Control ด้วย) ดังนั้น ทีมพัฒนาบางแห่ง จึงจะมี Server อีกตัว เรียกว่า Continuous Integration Server ที่จะคอยดาวน์โหลด Source Code จาก Repository มาเป็นระยะๆ เพื่อคอมไพล์ และรัน Test (บางที อาจจะทั้ง Unit และ Integrated) เพื่อให้มั่นใจว่า Source Code ยังอยู่ในสภาพดีเสมอ และจะได้ชี้นิ้วถูก ว่า ใครคือคนสุดท้าย ที่ Commit Code เข้าไป แล้วทำพัง
สำหรับปัญหาแรก นักพัฒนาจะถูกบังคับให้แก้ไข โดยการ Merge Source Code ด้วยมือ เรียกอย่างเป็นทางการ ก็คือ Conflict Resolution หรือการแก้ Conflict ครับ ส่วนปัญหาที่สอง มีทางเดียวคือต้องใช้ CI ครับ
การแก้ Conflict
ก่อนอื่น ลองมาดูกันว่า Conflict จะเกิดขึ้นได้อย่างไรครับ เริ่มจาก ผมมี Repository ที่มีไฟล์อยู๋ไฟล์หนึ่ง
และผมมีนักพัฒนาอยู่สองคน ชื่อ Nant และ John นะครับ ซึ่งทั้งคู่ ต่างก็ Checkout Repo นี่ไว้ในโฟลเดอร์ของตัวเอง
จากนั้น Nant ก็ทำการแก้ไขไฟล์ โดยการเพิ่มฟังก์ชั่น ไปที่บรรทัดที่ 50
ส่วน John ก็ไปเพิ่มฟังก์ชั่น Test ไว้ที่ด้านล่างของไฟล์
จากนั้น John ก็ทำการ Commit ก่อน
แล้วถ้า Nant จะ Commit บ้าง ก็จะ Commit ไม่ได้ และ SVN ก็จะแนะนำว่า ให้ผมสั่ง Update ก่อน เพราะว่าไฟล์มัน Out-of-Date ไปแล้ว
จากนั้น เมื่อผมสั่ง Update แล้ว ผมก็จะได้ไฟล์ AutoCompleteBox.cs ที่ Merge สำเร็จ แต่มีฟังก์ชั่น Test สองครั้ง ทำให้คอมไพล์ไม่ผ่าน ก็จะเป็นหน้าที่ของผม ที่จะต้องไปสื่อสารกับคุณ John เขาว่า เราจะจัดการยังไง และก็สั่ง Lock ไฟล์นี้ไว้ก่อน เพื่อป้องกันใครมาแก้ไขเพิ่ม ระหว่างเราตกลงกันอยู่ เมื่อเรียบร้อย ผมจึงจะสั่ง Commit ครับ แล้วค่อยปลดล็อค แล้วคุณ John ก็สั่ง Update อีกครั้ง เพื่อให้ไฟล์ของเขา เป็นตัวล่าสุด ที่แก้ไขให้คอมไพล์ได้แล้ว
ทีนี้ ผมก็แก้ไขฟังก์ชั่น Test ต่อไป แล้วสั่ง Commit
แต่คุณ John ก็แก้ไขเหมือนกัน แล้วพอจะ Commit คุณ John ก็จะต้อง Update ก่อน
แต่เนื่องจากเป็นการแก้ไข ที่บริเวณเดียวกัน (บางครั้ง แก้ไขในบรรทัดเดียวกัน ก็ยังสามารถ Merge ได้นะครับ) คือ true กับ false ก็จะเกิดการ Conflict ครับ

สังเกตว่า จะมีไอคอนแสดงเลยว่า ไฟล์นี้ กำลัง Conflict พร้อมกับมีไฟล์ต้นฉบับ เพื่อใช้ในการแก้ Conflict มาให้เห็นด้วย
เนื่องจากว่าในการแก้ไข หรือ Commit แต่ละครั้ง SVN จะไม่ได้จำ Revision เฉพาะไฟล์ใด ไฟล์หนึ่ง แต่จะเป็นการจำการเปลี่ยนแปลงของทั้ง Repository ดังนั้น ถ้าเกิดเรา Commit หลายๆ ไฟล์พร้อมกัน ในการ Update ก็เป็นไปได้ที่จะเกิดการ Conflict หลายๆ ไฟล์พร้อมกัน ซึ่งเราก็ควรจะแก้ให้หมดก่อน แล้วค่อย Commit ครับ
ทีนี้ บางท่านอาจจะบอกว่า ถ้าอย่างนั้น ไล่ Commit ทีละไฟล์จะดีกว่าหรือเปล่า ผมขอแนะนำว่า อย่าครับ เพราะบางครั้ง การเปลี่ยนแปลงที่เราทำ อาจจะกระทบไปหลายๆ ไฟล์ และถ้าเราพบว่า การเปลี่ยนแปลงที่เราทำ มันไปทำให้เกิดปัญหา แล้วต้องการ Revert (ย้อนเวลา) กลับไป Revision ก่อน เราก็จะต้องจำให้ได้ ว่า Commit ไฟล์ไหนไปบ้าง แล้วไล่ Revert ให้ครบ แทนที่จะเป็น Revert การเปลี่ยนแปลงที่เกิดขึ้นทั้งหมด ซึ่งนี่คือจุดดีของ SVN ด้วยครับ
ทีนี้ การแก้ Conflict ก็ทำได้โดยการคลิ๊กขวาที่ไฟล์ แล้วเลือก Edit Conflict
จากนั้น เราก็จะพบหน้าต่างแบบนี้ครับ เรียกว่า TortoiseMerge
สิ่งที่เราต้องทำก็คือ กด Ctrl+ลูกศรขึ้น หรือ ลง เพื่อไล่ดูจุดที่มัน Conflict กันทั้งหมด ซึ่งบางครั้ง อาจจะไม่ได้เป็นแค่บรรทัดเดียว แต่เป็นทั้งบล็อค หลายๆ บรรทัด แล้วจัดการแก้ไขครับ โดยการดูจากหน้าต่างซ้ายมือ (ไฟล์นี้ ใน SVN) กับทางขวามือ (ไฟล์ในเครื่องเรา) แล้วเลือกว่า จะให้ผลลัพธ์การ Merge มาจากด้านไหน โดยการกด Use “Theirs” หรือ Use “Mine” บนทูลบาร์ ตรงนี้ เราก็คงต้องเอาคุณ John มานั่งคุยกับผมครับ ว่าจะ Merge กันอย่างไรดี
แล้วตรงที่ Conflict ในหน้าต่าง Merged ก็จะกลายเป็นสีเขียวครับ
หรือถ้าไม่สามารถเลือกข้างได้ จะพิมพ์ลงไปเลยก็ได้เหมือนกันครับ เมื่อเรียบร้อยแล้ว กด Save แล้วทำการ Flag บอก SVN ว่า ไฟล์นี้แก้ไขเรียบร้อยแล้ว ขั้นตอนนี้ขึ้นอยู่กับดุลยพินิจของเรานะครับ ว่าจะให้มันผ่านหรือเปล่า เพราะยังไง SVN ก็บังคับเราไมได้ จะให้มันผ่านเลย โดยทียังไม่แก้ Conflict ก็ยังได้ครับ
เมื่อถึงจุดนี้แล้ว ก็สามารถ Commit ได้ตามปกติครับ (ยกเว้น มีคน Commit ตัดหน้ามาก่อน ก็ต้อง Update อีกรอบ เพราะส่วนใหญ่ จะแก้ Conflict กันนานเหมือนกัน)
แต่ยังไง…VSTS ก็คือคำตอบ
จะเห็นว่า SVN นั้น ช่วยให้การทำงานเป็นทีมนั้น ราบรื่นขึ้นมากเลยทีเดียว เพราะตอนนี้ ทุกคนก็สามารถพร้อมกันได้ อย่างเป็นสุข โดยไม่ต้องมานั่งรอ Lock ไฟล์ หรือ Copy ไฟล์กันไปมาอีกแล้ว และอย่าลืมว่า โดยส่วนใหญ่ เรามักจะทำงานกันคนละไฟล์อยู่แล้ว ปัญหาด้าน Conflict นี้ จะเกิดขึ้นได้น้อยมาก
แต่ปัญหาที่จะเกิดขึ้นตามมาได้ ก็คือ Human Error ครับ นั่นก็เพราะว่า SVN ไม่ได้ทำงานร่วมกับ IDE อย่างสมบูรณ์ เหมือนกับ Visual Studio Team System เราจึงไม่สามารถควบคุมคุณภาพของ Source Code ใน Repository ได้ และการใช้ CI ก็เป็นการแก้ปัญหาที่ปลายเหตุ เนื่องจากเราจะพบปัญหาได้ ก็ต่อเมื่อ Source Code ใน Repository มันเสียหายไปแล้ว
มาดูกันว่า SVN ยังให้อะไรเราไม่ได้บ้าง
- การควบคุม คุณภาพ Source Code ที่จะเข้าไปยัง Repository อย่างที่เกริ่นไปแล้วว่า SVN นั้น เป็นแค่ Source Control เฉยๆ ด้วยตัว SVN เอง จึงสามารถรับรู้ได้แค่การเปลี่ยนแปลงของ Source Code เท่านั้น แต่ VSTS เราสามารถคุมคุณภาพได้ ตั้งแต่ก่อนที่ผู้พัฒนา จะ Commit โค๊ดเข้าไปใน Repository
ใน VSTS นี่ Project Manager สามารถควบคุมคุณภาพได้จากส่วนกลางเลย โดยการตั้งเงื่อนไขการ Check-in ตั้งแต่เงื่อนไขง่ายที่สุดเช่น จะต้อง Compile ผ่าน ซึ่งผมเองก็พบอยู่หลายครั้งว่า หลายๆ คนก็ Commit โค๊ดไปเลย โดยที่ไม่ได้ทดลอง Compile ดูก่อน ซึ่งจะไปสร้างปัญหากับคนอื่นๆ ในทีม แทบจะในทันที โดยเฉพาะ ทีมใหญ่ๆ ที่ทำงานกันอยู่หลายๆ ออฟฟิศ คนที่เป็น Admin ก็ต้องคอย Monitor ว่า CI มีการรายงานมาหรือไม่ว่า Code คอมไพล์ไม่ผ่าน แล้วก็ต้องคอย Revert กลับให้
หรือถ้าต้องการเงื่อนไขซับซ้อนกว่านั้น ก็มีให้เลือกครับ เช่น จะต้องรัน Unit Test ผ่าน หรือ มี Performance ในระดับที่พอใจ หรือแม้กระทั่ง จะต้องทดสอบผ่าน Static Analysis Tool ก่อน (FxCop)
- การทำงานจากภายใน Visual Studio แม้ว่า Tortoise SVN จะช่วยให้เรา Commit/Update ได้จากใน Explorer แต่ชีวิตประจำวันของผู้พัฒนาจริงๆ ก็ยังอยู่ใน Visual Studio ครับ แม้ว่า SVN จะมี Plugin ของ Visual Studio อยู่ แต่เท่าที่ผมทดลองใช้ดู ก็ยังทำงานได้ไม่สมบูรณ์เท่าที่ควร และผมก็ยังไม่อยากเสี่ยงครับ
- ต้องอาศัยระบบอื่นช่วย เป็นเรื่องธรรมดามากอยู่แล้ว สำหรับโปรเจค Open Source ทั่วไป เพราะเหมือนว่าเขาจะมี Philosophy กันว่า จะไม่ทำอะไรที่มีคนเคยทำมาแล้ว อย่าง SVN ก็จะทำได้แค่ Source Control อย่างเดียว ถ้าอยากได้อะไรเพิ่ม ก็ต้องลงเพิ่มเอง อย่างเช่น Trac เพื่อใช้เป็น Portal, Apache เพื่อให้ติดต่อผ่าน HTTP ได้, NUnit ทำ Test, Cruise Control ทำ Continuous Integration, FxCop ไว้ทำ Static Analysis ซึ่งกว่าจะทำให้มันขึ้นมาได้ และใช้งานได้สมบูรณ์ ก็ซับซ้อนอยู่พอสมควร
สำหรับการใช้งานด้าน Source Control จริงๆ SVN ก็สามารถช่วยเราได้เยอะแล้วครับ แต่หลังจากใช้งานเขาจริงๆ จังๆ เราก็จะพบว่า มันยังไม่สามารถตอบความต้องการเราได้ซะทีเดียว โดยเฉพาะอย่างยิ่ง กับการทำงานเป็นทีม และความสามารถในการใช้งานด้าน Project Management เอาไว้เมื่อผมมีเวลาว่าง ผมจะหาโอกาสเขียนเรื่อง VSTS เพิ่มเติม หรืออาจจะชวนให้คุณมี่ เว็บ greatfriends ให้เขียนลง GreatFriends ก้อได้ครับ เพราะขานั้น เขาเทพ VSTS มาเลยทีเดียว :)
เจอกันคราวหน้าครับ