Cherry-pick — คือคําสั่ง Git ที่ใช้“นํา”การเปลี่ยนแปลงจากหนึ่งคอมมิตหรือหลายคอมมิตที่มีอยู่ไปยังสาขาปัจจุบัน ต่างจาก Merge (ย้ายทั้งสาขา) และ Rebase (ย้ายลําดับของคอมมิต) cherry-pick จะเลือกเฉพาะคอมมิตที่ระบุเท่านั้น ตามข้อมูลจาก git-scm.com, 2025 cherry-pick ถูกใช้มากที่สุดในสถานการณ์“การย้าย”การแก้ไขระหว่างสาขา release
สาระสำคัญ
Cherry-pick — คือคําสั่ง Git ที่“คัดลอก”การเปลี่ยนแปลงจากคอมมิตที่ระบุและ“นํา”ไปใช้เป็นคอมมิตใหม่ในสาขาปัจจุบัน ชื่อมาจากคําอุปมาว่า “”เลือกเชอร์รี่””: นักพัฒนาจะเลือกเฉพาะคอมมิตที่ต้องการ โดยไม่สนใจส่วนที่เหลือ
ต่างจาก Merge ตรงที่ cherry-pick ไม่ได้สร้าง merge commit และไม่จําเป็นต้องรวมสาขาทั้งหมด ต่างจาก Rebase ตรงที่ cherry-pick ไม่ได้“ย้าย”ลําดับของคอมมิต — เฉพาะที่ระบุเท่านั้น “ทําให้”cherry-pick เป็นเครื่องมือที่เหมาะสําหรับ“การย้าย”การแก้ไขแบบเจาะจง
ตามข้อมูลจาก Atlassian, 2025 cherry-pick ถูกใช้ใน 47% ของทีมที่“ทํางาน”กับหลายสาขา release พร้อมกัน โดยเฉพาะอย่างยิ่ง cherry-pick เป็นที่ต้องการในการพัฒนาแอปพลิเคชันมือถือ ซึ่งต้องสนับสนุนหลายเวอร์ชันของแอป (LTS releases) พร้อมกัน และจําเป็นต้อง“ย้าย”การแก้ไขระหว่างเวอร์ชันเหล่านั้น
เมื่อ“ดําเนินการ”cherry-pick Git จะ“คํานวณ” diff ระหว่างคอมมิตที่ระบุกับคอมมิตต้นทาง จากนั้น“นํา”diff นี้ไปใช้กับสาขาปัจจุบัน หาก“การเปลี่ยนแปลง”ถูก“นํา”ไปใช้โดยไม่มีการขัดแย้ง — Git จะสร้างคอมมิตใหม่ที่มีข้อความเดียวกัน แต่ SHA ใหม่ หากมีการขัดแย้ง — cherry-pick จะหยุดชั่วคราวเพื่อให้แก้ไขด้วยตนเอง
ไวยากรณ์ ของ cherry-pick ง่าย: ระบุแฮชของคอมมิตที่ต้องการ“ย้าย” Git จะ“คัดลอก”“การเปลี่ยนแปลง”ไปยังสาขาปัจจุบันเป็นคอมมิตใหม่ รองรับ“การย้าย”หลายคอมมิตในครั้งเดียวและช่วงทั้งหมด
# ย้ายคอมมิตเดียวไปยังสาขาปัจจุบัน
git cherry-pick a1b2c3d4
# ย้ายหลายคอมมิต
git cherry-pick a1b2c3d4 e5f6g7h8
# ย้ายช่วงของคอมมิต (จาก a1b2 ถึง f9e8, ไม่รวม a1b2)
git cherry-pick a1b2c3d4..f9e8d7c6
หลังจาก“ดําเนินการ”cherry-pick สาขาปัจจุบัน จะได้รับคอมมิตใหม่ที่มี“การเปลี่ยนแปลง”จากต้นฉบับ ข้อความของคอมมิตโดยค่าเริ่มต้นจะ“คัดลอก”จากต้นฉบับ แต่สามารถ“เปลี่ยนแปลง”ได้ด้วยแฟล็ก -n (ไม่สร้างคอมมิต) หรือ --edit (แก้ไขข้อความ)
ลอง“พิจารณา” สถานการณ์ทั่วไป: ใน develop พบและแก้ไขบั๊กที่ร้ายแรง ซึ่งมีอยู่ในสาขา release release/v2.0 เช่นกัน จําเป็นต้อง“ย้าย”เฉพาะ“การแก้ไข”นี้ โดยไม่ต้องรวมทั้ง develop ไปยังสาขา release
# ค้นหาแฮชคอมมิตที่มีการแก้ไขใน develop
git log --oneline develop
# a1b2c3d fix: ตรวจสอบ null ในการประมวลผลการชำระเงิน
# สลับไปยังสาขา release
git checkout release/v2.0
# นำการแก้ไขไปใช้
git cherry-pick a1b2c3d4
# หากมีการขัดแย้ง — ให้แก้ไขและดำเนินการต่อ
git add src/payment/PaymentProcessor.kt
git cherry-pick --continue
แฟล็ก -x จะเพิ่ม“การอ้างอิง”ถึง SHA ต้นฉบับในข้อความคอมมิต: “(cherry picked from commit a1b2c3d4)”d ซึ่งช่วยให้ติดตามได้ง่ายว่าคอมมิตถูก“ย้าย”มาจากที่ไหน แนะนําให้ใช้ -x ในทุกสถานการณ์ยกเว้นแบบร่างชั่วคราว
เมื่อเกิด “การขัดแย้ง” cherry-pick จะ“ทํางาน”เหมือน merge: Git จะหยุดและ“ทําเครื่องหมาย”ไฟล์ที่มี“การขัดแย้ง” นักพัฒนาแก้ไข“การขัดแย้ง” “ทํา”git add และ“ดําเนินการ”git cherry-pick --continue หากต้องการ“ยกเลิก” — ใช้ git cherry-pick --abort แฟล็ก --strategy อนุญาตให้ระบุกลยุทธ์“การรวม” (เช่น recursive พร้อมตัวเลือก)
# การแก้ไขการขัดแย้งเมื่อใช้ cherry-pick
# Git แสดงไฟล์ที่มีการขัดแย้ง
git status
# แก้ไขด้วยตนเอง จากนั้น:
git เพิ่ม ไฟล์_ที่อนุญาต.kt
git cherry-pick --continue
# หรือยกเลิก cherry-pick:
git cherry-pick --abort
Cherry-pick เหมาะที่สุดในสถานการณ์ที่ต้องการ“การย้าย”“การเปลี่ยนแปลง”แบบเจาะจงโดยไม่ต้องรวมทั้งสาขา มาดูห้ากรณีหลักที่ cherry-pick เป็นตัวเลือกที่ดีที่สุด
สําหรับ “การพัฒนา”แอปพลิเคชันมือถือ cherry-pick มี“ความสําคัญ”อย่างยิ่งเมื่อต้องสนับสนุนหลายเวอร์ชันของแอป ตัวอย่างเช่น หากพบข้อบกพร่องในเวอร์ชัน 3.2 ที่เผยแพร่ใน Google Play แล้ว ในขณะที่ develop มีโค้ดสําหรับเวอร์ชัน 4.0 — cherry-pick ช่วยให้“ย้าย”“การแก้ไข”ไปยังสาขา v3.x โดยไม่ต้องรวม“การเปลี่ยนแปลง”ที่“ทําลาย”“ความเข้ากันได้”ทั้งหมด โดยเฉพาะอย่างยิ่งสําหรับโปรเจกต์ที่ต้องสนับสนุนสองเวอร์ชันหลักขึ้นไปพร้อมกันที่มี API และ dependencies ต่างกัน
ตัวอย่างจากปฏิบัติจริง: ในแอปพลิเคชันมือถือพบ crash เมื่อเข้าสู่ระบบผ่าน Google Sign-In บน Android 12 “การแก้ไข”ถูก“นําเข้า”ใน develop และผ่าน“การตรวจสอบ”แล้ว อย่างไรก็ตาม สาขา release ปัจจุบัน v2.5 อยู่ในขั้นตอน beta-testing “การใช้”cherry-pick คอมมิต“การแก้ไข”จาก develop ไปยัง release/v2.5 ช่วยให้รวม“การแก้ไข”ใน release ถัดไป โดยไม่ต้อง“ย้าย”“การเปลี่ยนแปลง”อื่นที่ยังไม่พร้อมสําหรับ“การเผยแพร่”
เมื่อใช้ cherry-pick ใน โปรเจกต์มือถือ สิ่งสําคัญที่ต้อง“พิจารณา”คือ dependencies: หาก“การแก้ไข”กระทบไฟล์ที่ถูก“เปลี่ยนแปลง”ใน develop หลังจากจุดที่สาขา release แยกออกไป cherry-pick อาจ“นํา”ชุด“การเปลี่ยนแปลง”ที่ไม่สมบูรณ์มา ในกรณีเช่นนี้จําเป็นต้องตรวจสอบว่า“การเปลี่ยนแปลง”ที่เกี่ยวข้องทั้งหมดถูก“ย้าย”แล้ว มิฉะนั้นแอปพลิเคชันอาจไม่สามารถ build หรือ“ทํางาน”ไม่ถูกต้อง ควรตรวจสอบ build หลังจาก cherry-pick เสมอก่อนที่จะ push “การเปลี่ยนแปลง”ไปยังสาขาร่วม
เครื่องมือหลักสามอย่าง สําหรับ“การรวม”“การเปลี่ยนแปลง”ใน Git — merge, rebase และ cherry-pick — แก้ปัญหาที่แตกต่างกัน “การเลือก”ขึ้นอยู่กับปริมาณ“การเปลี่ยนแปลง”ที่ต้องการ“ย้าย”และลักษณะของประวัติที่ต้องการ
| เกณฑ์ | Merge | Rebase | Cherry-pick |
|---|---|---|---|
| ปริมาณ | ทั้งสาขา | ชุดของคอมมิต | คอมมิตที่เลือก |
| ประวัติ | “คง”“การแตกกิ่ง” | เชิงเส้น | เชิงเส้น |
| Merge commit | ใช่ (ยกเว้น ff) | ไม่ | ไม่ |
| อัตโนมัติ | เต็มรูปแบบ | ตามลําดับ | เฉพาะที่ระบุ |
| สําหรับสาขาสาธารณะ | ปลอดภัย | อันตราย | ปลอดภัย |
Merge — เมื่อต้องการรวมสองสาขาทั้งหมดและเก็บข้อมูล“การแตกกิ่ง” Rebase — เมื่อต้องการอัปเดตสาขาส่วนตัวให้เป็นสถานะปัจจุบันด้วยประวัติที่สะอาด Cherry-pick — เมื่อต้องการเพียงคอมมิตเดียวหรือหลายคอมมิตที่เลือก
ในทางปฏิบัติ เครื่องมือเหล่านี้ ใช้ร่วมกัน: ฟีเจอร์ถูก“พัฒนา”ด้วย“การ”rebase บน develop เป็นระยะ จากนั้นรวมผ่าน --no-ff merge และเมื่อจําเป็นต้อง“ย้าย”“การแก้ไข”ไปยังสาขาอื่น จะใช้ cherry-pick แต่ละเครื่องมือแก้ปัญหาของตัวเองในแต่ละขั้นตอน
Cherry-pick เป็นเครื่องมือที่มีประโยชน์ แต่อาจเป็นอันตรายหากใช้ไม่ถูกต้องหรือมากเกินไป “ความเสี่ยง”หลักเกี่ยวข้องกับ“การทํา”คอมมิตซ้ำ “การสูญเสีย”บริบท และ“การขัดแย้ง”ใน“การรวม”ในภายหลัง
คําแนะนําใน“การลด”“ความเสี่ยง”: ใช้แฟล็ก -x เสมอเพื่อระบุ SHA ต้นฉบับ บันทึกเหตุผลของ cherry-pick ในข้อความคอมมิต และหากเป็นไปได้ ใช้ merge แทน cherry-pick เมื่อบริบทเอื้ออํานวย หากมี cherry-pick มากเกินไป — ให้“พิจารณา”“การปรับ”โครงสร้างสาขา
CI pipelines ควร“พิจารณา”cherry-pick เป็นสถานการณ์แยกต่างหาก แนะนําให้ตั้งค่า“การตรวจสอบ”อัตโนมัติ: เมื่อสร้างคอมมิต cherry-pick CI จะตรวจสอบว่าไฟล์ที่“เปลี่ยนแปลง”ตรงกับชุดที่คาดหวัง และรันทดสอบสําหรับโมดูลที่เกี่ยวข้อง ซึ่งช่วยลด“ความเสี่ยง”ของ“การถดถอย”เมื่อ“ย้าย”“การเปลี่ยนแปลง”แบบเจาะจงระหว่างสาขา
คําถามที่พบบ่อย
Cherry-pick “ย้าย”“การเปลี่ยนแปลง”จากคอมมิตไปยังสาขาอื่น Revert สร้างคอมมิตใหม่ที่“ยกเลิก”“การเปลี่ยนแปลง”ของคอมมิตที่ระบุในสาขาเดียวกัน Revert ไม่ได้ลบประวัติ — มันเพิ่ม“การเปลี่ยนแปลง”ย้อนกลับ
ได้: git cherry-pick A B C — “ย้าย”คอมมิต A, B และ C ตามลําดับ หรือ git cherry-pick A..C — “ย้าย”คอมมิตทั้งหมดจาก A ถึง C (ไม่รวม A) ลําดับ“การย้าย”สอดคล้องกับลําดับในคําสั่ง
โดยค่าเริ่มต้น cherry-pick merge commit ไม่“ทํางาน” เพราะ merge commit มีสอง parents ให้ใช้แฟล็ก -m 1 เพื่อระบุว่าจะเปรียบเทียบกับ parent ใด -m 1 จะ“นํา”diff เทียบกับ parent แรก
“ยกเลิก” cherry-pick ได้ผ่าน git reset --hard HEAD~1 หากเป็นคอมมิตล่าสุด หากคอมมิตถูก push แล้ว — ใช้ git revert <SHA> เพื่อสร้างคอมมิต“ยกเลิก”
ไม่มีประโยชน์ แต่ทางเทคนิคสามารถ“ทํา”ได้ หากคอมมิตมีอยู่ในสาขานั้นแล้ว Git จะพบว่ามี“การเปลี่ยนแปลง”อยู่แล้ว และแจ้งว่า: “The previous cherry-pick is now empty, possibly due to conflict resolution.” คอมมิตจะไม่ถูกสร้างซ้ำ
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม