Branch คืออะไร
เข้าใจว่า branch เป็นเพียง label ชี้ไปที่ commit ไม่ใช่การ copy ทำให้แยกสายทำงานได้โดยไม่กระทบกัน
ใน lesson ที่แล้วคุณเห็น commit เป็นก้อนๆ ต่อกันเป็นสายยาว แต่ถ้าวันดีคืนดีคุณอยากลองเขียน feature ใหม่ใหญ่ๆ โดยไม่อยากไปยุ่งกับของเดิมที่ทำงานได้อยู่แล้ว คุณจะทำยังไง
คำตอบคือ branch
Branch คือ label ไม่ใช่ก๊อปปี้
ความเข้าใจผิดยอดฮิตของคนเพิ่งเริ่มใช้ Git คือคิดว่า branch เป็น “ก๊อปปี้ของโปรเจกต์” ซึ่งไม่ใช่เลย branch คือแค่ label ที่ชี้ไปที่ commit ก้อนใดก้อนหนึ่ง
ลองกดปุ่ม “ทำ commit ใหม่” ข้างล่าง สังเกตว่า label “main” จะค่อยๆ เลื่อนตาม commit ล่าสุด ไม่ได้อยู่กับที่
5f2a8c9สังเกตว่า main ค่อยๆ เลื่อนตาม commit ล่าสุดเสมอ main ไม่ได้เก็บ commit ไว้ใน branch มันแค่ชี้ไปที่ commit ก้อนเดียว
เห็นไหมว่า main ไม่ได้ “เก็บ commit ไว้ใน branch ของมันเอง” commit ต่างหากที่อยู่ในประวัติของ repo main เป็นเพียง ป้ายบอกว่า commit ล่าสุดของ branch นี้คือก้อนไหน
สร้าง branch ใหม่ = แค่เพิ่ม label
เมื่อคุณรัน git branch feature ตอนที่ HEAD อยู่ที่ commit C ก็เท่ากับสร้าง label ใหม่ชื่อ “feature” ที่ชี้ไปที่ C พร้อมกับ main ตอนนั้นทั้งสอง label ชี้ commit เดียวกัน ไม่มี commit ใหม่เกิดขึ้น ไม่มี copy อะไรทั้งสิ้น
ของเด็ดคือ สอง label นี้ ขยับแยกกันได้ ถ้าคุณ commit ตอน HEAD อยู่ที่ feature feature ก็เลื่อนไปชี้ commit ใหม่ main อยู่ที่เดิม
ลองเล่นดู
ด้านล่างคือ graph เริ่มต้นที่มี 3 commit อยู่บน main กดปุ่ม “สร้าง branch feature”เพื่อเพิ่ม label feature ที่ commit ล่าสุด แล้วลองเลือก active branch ให้กด commit ต่อบน branch ไหนก็ได้ สังเกตกราฟแยกเป็น 2 สายแต่ต้นไม้มีรากเดียวกัน
ใช้ branch ตอนไหนดี
- เวลาทำ feature ใหม่ที่ยังไม่พร้อมลง production
- เวลาแก้ bug เร่งด่วนโดยไม่กระทบ feature ที่ทำค้างอยู่
- เวลาทดลองไอเดียที่อาจจะทิ้งได้ ไม่เสียหายถ้าไม่รอด
- เวลาทำงานหลายคน แต่ละคนทำ branch ของตัวเอง ไม่ชนกัน
สรุป
- Branch คือ label ที่ชี้ไปที่ commit 1 ก้อน ไม่ใช่ก๊อปปี้ของไฟล์
- สร้าง branch ใหม่ = เพิ่ม label ที่ commit ปัจจุบัน ไม่ copy อะไร
- Commit บน branch ไหน label ของ branch นั้นเลื่อนไปที่ commit ใหม่
- HEAD = ตัวบอกว่าตอนนี้คุณอยู่ที่ branch ไหน commit ไหน
lesson ถัดไปจะเป็นเรื่อง merge ทำยังไงเมื่อเราอยากเอา commit ของ feature กลับมารวมเข้ากับ main ให้กลายเป็นเส้นเดียวอีกครั้ง