TDE&W (2) :: Git Basix command


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

Clone/New
       สิ่งนี้เป็นสิ่งแรกที่ต้องทำเมื่อเราจะใช้งาน Git กับ Project ใดๆ ก็ตามไม่ว่าจะทำเองหรือทำกับทีม สิ่งสำคัญ 2 สิ่งสำหรับการ Clone ก็คือ Source Path กับ Destination Path โดย Source Path จะเป็น link ของ Remote repository ไว้สำหรับเก็บ Source code นอกเครื่องเรา (ที่เราเรียกว่า Local repository) โดยส่วนใหญ่มักจะอยู่ในรูป http url หรือ ssh url เช่น https://github.com/user/project.git พอเราได้ลิงค์มาแล้วแปะไว้โปรแกรมจะสร้าง Destination Path ซึ่งเป็นโฟลเดอร์ที่เราจะใช้ในการเก็บไฟล์ที่เรา Clone มานี้และเป็นโฟลเดอร์หลักที่เราจะใช้ในการทำงานในโปรเจ็คนี้นะครับ โดยถ้าไม่พอใจก็เปลี่ยนได้ซึ่งส่วนใหญ่ก็จะเปลี่ยนอยู่แล้วเพราะคงไม่มีใครไปนั่งพัฒนาเว็บอยู่ใน My Document หรอกจริงมั้ยครับ
       ส่วนในกรณีมี Project อยู่ในเครื่องหรือกำลังจะเริ่มสร้าง Project ในเครื่องเราก็จะมายุ่งในแท็บที่ 2 และ 3 แทนโดยในแท็บที่ 2 จะเป็นกรณีที่เรามีไฟล์ Project อยู่ในเครื่องอยู่แล้ว แล้วต้องการเอา Git ไปใช้งานเราก็เพียงแค่เพิ่ม Working copy path เข้าไปซึ่งก็คือ Destination Path ของกรณีที่แล้วนั่นเองครับ กรณีเราจะเริ่มสร้าง Project จากศูนย์เลยเราก็จะมายุ่งในแท็บที่ 3 ซึ่งก็คือการเพิ่ม Destination Path เข้าไปให้โปรแกรมมันจับแค่นั้นเองครับ

Fetch/Pull
       ในการทำงานประจำวันของผมกับ Git คำสั่ง 2 คำสั่งนี้จะเป็นสิ่งแรกที่ผมทำในทุกวันหลังจากเปิดโปรแกรมครับ โดยคำสั่งแรกก็คือ Fetch จุดประสงค์ของมันก็เพื่อเช็คว่ามีการกระทำอะไรใดๆ ใน remote repository ที่เราใช้อยู่รึเปล่า ซึ่งถ้ามีตัวโปรแกรมก็จะแจ้งเตือนเป็นตัวเลขจำนวน Commit พร้อมกับลูกศรลงอยู่ข้างหลัง Branch นั้นๆ หรือถ้าเราอยู่ใน Branch นั้นแล้วมันจะแสดงเป็นตัวเลขแดงๆ อยู่ตรงปุ่ม Pull กลายๆ ว่าเมิงกดกูซักทีเหอะนะ ซึ่งถ้าเรากดปุ่ม Pull ก็จะเป็นการดาวน์โหลดการเปลี่ยนแปลงใดๆ ที่เกิดใน Branch นั้นที่อยู่บน Remote repo ลงมายัง Branch เดียวกันที่อยู่เครื่องเราเป็นการทำให้แน่ใจว่าเครื่องเรามี Source code ล่าสุดพร้อมสำหรับการพัฒนาต่อเสมอ

Commit
       คำสั่งนี้เป็นคำสั่งพื้นฐานที่สุดและใช้บ่อยที่สุดสำหรับ Git โดยการ Commit คือการเก็บบันทึกการเปลี่ยนแปลงใดๆ ที่เราทำใน  Working Folder หรือโฟลเดอร์ Project ของเราเองไว้ ซึ่งก็จะแบ่งเป็น 2 Mode หลักๆ คือ Stage changes และ Working copy change โดย Stage change คือการเปลี่ยนแปลงที่เรากระทำกับไฟล์ในโฟลเดอร์นั้นๆ เช่น การสร้างไฟล์, การลบไฟล์ รวมถึงการ Merge Branch หลายๆ ครั้งเราก็จะใช้ Mode นี้ด้วย ส่วน Mode Working copy change คือการเปลี่ยนแปลงใดๆ ที่เรากระทำกับไฟล์ใดๆ ที่มีอยู่แล้วในโฟลเดอร์นั้น (ซึ่งอันนี้ใช้บ่อยที่สุดละ) ข้อควรระวังก็คือ ถ้าเราต้องการเปลี่ยนไป Branch อื่นๆ เช่นจาก Feature หนึ่งไปอีก Feature หนึ่งถ้ามีการเปลี่ยนแปลงใดๆ ที่ทำไปแล้วก็ควรจะ Commit ก่อนเปลี่ยน Branch (ซึ่งโดยปกติแล้วโปรแกรมจะเตือนไม่ให้เปลี่ยน แต่ก็จะมีตัวเลือก discard all change ไว้ในกรณีขี้เกียจด้วย)

Push
       หลังจากเรากด commit ไปแล้วการเปลี่ยนแปลงนั้นก็เพียงแค่บันทึกไว้ใน Local repository ซึ่งถ้าเครื่องเรา HDD พัง OS เจ๊งก็ยังมีโอกาสที่เราจะสูญเสีย Source code ที่เราอุตส่าห์พร่ำเขียนมา ซึ่งการที่เรามี Remote repository ก็เพื่อป้องกันเหตุร้ายดังกล่าว (แต่ก็ใช้ว่ามันจะไม่มีโอกาสเสียเลย) รวมถึงเป็นการ Synchronous ตัวงานหรือโมดูลที่เราทำเข้ากับส่วนกลางเพื่อให้คนอื่นในทีมได้ใช้งานร่วมกันรวมถึงรวมเข้าด้วยกันในภายหลังโดยการ Push เราสามารถเลือกได้ว่าจะ Push ทุก Branch ที่มีอยู่ในเครื่องหรือเพียงแค่ Branch ที่เราได้ทำการเปลี่ยนแปลงไปในข้างต้น ข้อควรระวังคือโปรแกรมจะไม่ให้เรากด Push ถ้ามีการค้าง Pull ไว้ใน Branch ที่เราเลือก วิธีแก้ก็คือ Pull มันลงมาซะแล้วค่อยกด Push ใหม่อีกรอบหนึ่ง

Branch/Merge/Checkout
       อย่างที่ผมได้กล่าวไปแล้วในตอนที่ 1 เรื่องแนวทางการแตก Branch จากประสบการณ์ผมเคยแตก Branch เองจริงๆ น้อยมากครับ ส่วนใหญ่จะใช้ฟีเจอร์ Git Flow ให้เป็นประโยชน์โดยหลังจากที่เราสร้าง Project มาแล้วการกด Git Flow ครั้งแรกจะเป็นการ Initial ตัว Local repository เราว่า เราจะทำงานแบบ Git Flow นะโดยตัวโปรแกรมก็จะแยก Branch ใหม่ให้เองเป็น Master กับ Develop ก่อนโดยเราจะถูกสลับ (Checkout) มาไว้ที่ Branch นี้โดยอัตโนมัติ หลังจากนั้นแล้วเมื่อเราต้องการพัฒนาฟีเจอร์ใหม่ใดๆ ก็กดตรง Git Flow แล้วเลือก Start New Feature ซึ่งส่วนใหญ่แตกแล้วแตกยาว เพราะหลายงานที่ทำอยู่ปัจจุบันก็ยังทำไม่เสร็จจน Finish Feature ซึ่งตัวโปรแกรมจะทำการรวม (Merge) ตัว Branch Feature นั้นๆ เข้า Develop ให้โดยอัตโนมัติ วิธีแก้ปัญหาในปัจจุบันส่วนใหญ่ผมยังใช้การ Merge เองด้วยมือในตอนวันท้ายๆ ของสัปดาห์ซึ่งเป็นการ Release ตัว Project ออกมาเป็นเวอร์ชั่นย่อยๆ รวมถึงเป็นการรวม Source Code จากคนอื่นๆ ในทีมมาอัพเดทไว้ที่ Branch Develop ด้วย ซึ่งถ้าคนในทีมเริ่มแก้ไฟล์เดียวกันเมื่อไร สิ่งที่ตามมาอยู่ในย่อหน้าถัดไปครับ
       Merge Conflict เป็นปัญหาที่เกิดขึ้นจากการแก้ไขไฟล์เดียวกันในบรรทัดเดียวกันจากต่าง Branch กันซึ่งพอเราจะกด Merge ตัวโปรแกรมก็จะงงว่าตกลงเราจะเอาอันไหน ซึ่งมีตัวเลือกในการแก้ (resolve conflict) อยู่ 2 ทางคือใช้ไฟล์ของเรา หรือใช้ไฟล์จากอีก Branch หนึ่งที่กำลังจะรวมเข้าไป ซึ่งอันนี้ก็ขึ้นอยู่กับสถานการณ์ว่าจะใช้แบบไหนในการแก้

สิ่งที่เกิดขึ้นหลังจากแตก Branch อย่างเมามันส์... นรกของการ Merge Code
Tag
       ตอนผมเริ่มใช้ Git ใหม่ๆ ผมยอมรับเลยว่าผมไม่เคยเห็นความสำคัญของ Tag เลย จนกระทั่งผมกับทีมเริ่มแตก Branch มากกว่า 5 สายผมถึงเริ่มเข้าใจทันที่ว่าเรามี Tag ไว้เพื่ออะไร การติด Tag ก็เหมือนการติดป้ายบอกว่าเราทำอะไรอยู่ในตรงนั้นนอกจาก Commit message โดยส่วนใหญ่จะติดตอน Finish Feature หรือ Release เป็นการอ้างอิงถึงที่หาง่ายกว่า Commit Message มากโดยตัว Git Flow จะมีตัวเลือกให้เราใส่ Tag โดยอัตโนมัติเมื่อเข้าสู่เงื่อนไขดังกล่าวข้างต้น

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

ปล.ถ้าผมอธิบายงง ก็แสดงว่าผมสอนไม่รู้เรื่องจริงๆ ถ้าผู้อ่านท่านใดยังงงกับที่ผมอธิบายอยู่สามารถทิ้งความคิดเห็นไว้ได้ซึ่งทางผมจะได้นำไปปรับปรุงรวมถึงแก้ไขความเข้าใจต่อไปครับ

Comments

Anonymous said…
อ่านแล้วได้ความรู้ดีมากค่ะ เขียนเข้าใจง่ายดี