Cherry-pick คือคำสั่ง Git ที่ใช้ปรับใช้การเปลี่ยนแปลงจากคอมมิตที่ระบุไปยังสาขาปัจจุบัน โดยไม่ต้องย้ายประวัติทั้งหมดของสาขาต้นทาง แตกต่างจาก merge หรือ rebase ตรงที่ cherry-pick ทำงานกับแต่ละคอมมิตเป็นรายบุคคล: นักพัฒนาจะเลือกคอมมิตเฉพาะตามแฮชและย้ายเฉพาะการเปลี่ยนแปลงของคอมมิตนั้นเท่านั้น ตามเอกสารของ Git (2026) cherry-pick มีประโยชน์อย่างยิ่งสำหรับการย้ายการแก้ไขแบบเจาะจงระหว่างสาขารุ่นเมื่อการ merge ทั้งหมดมากเกินไปหรือมีความเสี่ยง คำสั่งจะสร้างคอมมิตใหม่ที่มีแฮชใหม่ แต่คงข้อความต้นฉบับและผู้เขียนไว้
ประเด็นสำคัญ
Cherry-pick คือคำสั่ง git cherry-pick ที่นำการเปลี่ยนแปลงจากคอมมิตที่มีอยู่และใช้เป็นคอมมิตใหม่ในสาขาปัจจุบัน คอมมิตต้นฉบับยังคงอยู่ในสาขาของมัน ในขณะที่สำเนาของการเปลี่ยนแปลงถูกสร้างขึ้นในสาขาปลายทาง คำสั่งนี้มีประโยชน์เมื่อคุณต้องการย้ายการแก้ไขเฉพาะโดยไม่ต้องย้ายทั้งสาขา
ไวยากรณ์: git cherry-pick <commit-hash> Git จะวิเคราะห์ความแตกต่าง (diff) ของคอมมิตที่ระบุกับพาเรนต์ของมัน และใช้ความแตกต่างนั้นกับสาขาปัจจุบัน หากมีการเปลี่ยนแปลงหลายไฟล์ พวกมันทั้งหมดจะถูกย้ายพร้อมกัน คำสั่งยังยอมรับช่วง: git cherry-pick A..B — คอมมิตทั้งหมดจาก A ถึง B ไม่รวม A
แฟลกขยายความสามารถ: -n (--no-commit) ใช้การเปลี่ยนแปลงกับไดเรกทอรีทำงานและดัชนีโดยไม่สร้างคอมมิต — มีประโยชน์เมื่อคุณต้องการรวมการเปลี่ยนแปลงจากหลายคอมมิตเป็นหนึ่งเดียว แฟลก -x เพิ่มบรรทัด (cherry picked from commit ...) ในข้อความคอมมิต ทำให้ติดตามที่มาของการเปลี่ยนแปลงในประวัติได้ง่ายขึ้น
# เชอร์รีพิกคอมมิตเดียวด้วยแฮช
git cherry-pick a1b2c3d
# เชอร์รีพิกหลายคอมมิต (ตามลำดับ)
git cherry-pick a1b2c3d e4f5g6h i6j7k8l
# เชอร์รีพิกโดยไม่สร้างคอมมิตอัตโนมัติ
git cherry-pick -n a1b2c3d
# แฟลก -x เพิ่มการอ้างอิงถึงคอมมิตต้นฉบับ
git cherry-pick -x a1b2c3d
สถานการณ์หลักคือ การย้ายการแก้ไขระหว่างสาขารุ่น ลองจินตนาการ: พบบั๊กร้ายแรงใน develop และแก้ไขแล้ว สาขารุ่น release/v2.1 ถูกแยกออกไปแล้วและมีบั๊กนี้อยู่ด้วย การ merge พัฒนาทั้งหมดไปยัง release จะนำโค้ดที่ยังไม่เสร็จจำนวนมากมา ในขณะที่การ cherry-pick คอมมิตแก้ไขเพียงคอมมิตเดียวเป็นวิธีที่ปลอดภัยและแม่นยำ
สถานการณ์ที่สองคือ การยกเลิกการเปลี่ยนแปลงด้วยการกู้คืนในภายหลัง หากคอมมิตถูกยกเลิกผ่าน git revert และต่อมาพบว่าการยกเลิกนั้นผิดพลาด — การ cherry-pick คอมมิตที่ถูกยกเลิกจะกู้คืนการเปลี่ยนแปลง วิธีนี้ถูกต้องกว่าการยกเลิก revert เพราะไม่สร้างข้อขัดแย้งซ้ำ
สถานการณ์ที่สามคือ การรวมคอมมิต จากสาขาคุณสมบัติต่าง ๆ เข้าเป็นสาขาทดสอบเดียวสำหรับการทดสอบการทำงานร่วมกัน แทนที่จะ merge หลายสาขาที่ยังไม่เสร็จ (ด้วยโค้ดที่ไม่สมบูรณ์) คุณสามารถเลือกเฉพาะคอมมิตที่พร้อมจากแต่ละสาขาและทดสอบว่าพวกมันทำงานร่วมกันได้อย่างไร
Cherry-pick แตกต่างจาก rebase และ merge ตรงที่มันทำงานในระดับคอมมิตแต่ละรายการแทนที่จะเป็นทั้งสาขา ในขณะที่ rebase ย้ายคอมมิททั้งหมดของสาขาและ merge รวมสองสาขาเข้าด้วยกัน cherry-pick จะเลือกเฉพาะคอมมิตที่จำเป็นเท่านั้น สิ่งนี้ทำให้มันเป็นเครื่องมือที่แม่นยำกว่า แต่ก็ต้องใช้แรงงานคนมากกว่า
ความแตกต่างอีกประการคือ การเป็นผู้เขียน ระหว่าง cherry-pick โดยค่าเริ่มต้น Git จะคงผู้เขียนของคอมมิตต้นฉบับไว้ แต่ผู้คอมมิต (committer) จะกลายเป็นผู้ใช้ปัจจุบัน ข้อความคอมมิตสามารถติดตามที่มาได้ผ่านแฟลก -x ระหว่าง rebase ทั้งผู้เขียนและผู้คอมมิตจะกลายเป็นผู้ใช้ปัจจุบันด้วยแฮชใหม่
ประสิทธิภาพ: การ cherry-pick คอมมิตเดี่ยวเร็วกว่าการ merge สองสาขาที่มีหลายคอมมิต แต่ถ้าคุณต้องการย้ายคอมมิตหลายสิบรายการ ควรสร้างสาขาชั่วคราวและทำ rebase — จะมีประสิทธิภาพมากกว่าและไม่ต้องระบุแฮชหลายสิบรายการ
| การดำเนินการ | ขอบเขต | ผลข้างเคียง |
|---|---|---|
| Cherry-pick | คอมมิตแต่ละรายการ | แฮชใหม่ การทำซ้ำโค้ด |
| Rebase | คอมมิตทั้งหมดของสาขา | การเขียนประวัติใหม่ แฮชใหม่ |
| Merge | การรวมสาขาทั้งหมด | Merge คอมมิต การคงประวัติ |
หลายคอมมิต สามารถย้ายได้ด้วยคำสั่งเดียวโดยระบุแฮชคั่นด้วยช่องว่าง: git cherry-pick A B C Git จะใช้คอมมิตตามลำดับที่ระบุ หากคอมมิตใดทำให้เกิดข้อขัดแย้ง cherry-pick จะหยุดชั่วคราว และนักพัฒนาต้องแก้ไขข้อขัดแย้ง จากนั้นดำเนินการต่อด้วย git cherry-pick --continue
ช่วงคอมมิต: git cherry-pick A..B (คอมมิตทั้งหมดหลังจาก A ถึง B ไม่รวม A) และ git cherry-pick A^..B (คอมมิททั้งหมดตั้งแต่ A รวมถึงถึง B) ช่วงมีประโยชน์เมื่อคุณต้องการย้ายคอมมิตทั้งหมดจากสาขาหนึ่งโดยไม่มีความสัมพันธ์พาเรนต์ — ตัวอย่างเช่น เมื่อย้ายคุณสมบัติที่เสร็จสมบูรณ์จากสาขาเก่าไปยังสาขาใหม่
แฟลก --strategy กำหนดวิธีที่ Git ใช้การเปลี่ยนแปลง โดยค่าเริ่มต้นจะใช้กลยุทธ์ recursive แต่คุณสามารถระบุ ours หรือ theirs เพื่อเลือกด้านข้อขัดแย้งโดยอัตโนมัติ แฟลก --mainline ใช้เมื่อ cherry-pick คอมมิต merge — มันระบุหมายเลขพาเรนต์ (1 หรือ 2) ที่ใช้คำนวณ diff
# ช่วงคอมมิต cherry-pick
git cherry-pick develop~5..develop~2
# เชอร์รีพิกคอมมิต merge (ระบุพาเรนต์)
git cherry-pick -m 1 m9n0o1p
# ใช้กลยุทธ์ theirs
git cherry-pick --strategy=recursive \
--strategy-option=theirs a1b2c3d
# ดำเนินการต่อหลังแก้ไขข้อขัดแย้ง
git cherry-pick --continue
ข้อขัดแย้งระหว่าง cherry-pick เกิดขึ้นเมื่อการเปลี่ยนแปลงของคอมมิตที่ย้ายมีผลกับบรรทัดเดียวกันที่ถูกเปลี่ยนแปลงในสาขาปลายทาง Git หยุดการทำงานชั่วคราว ทำเครื่องหมายไฟล์ที่มีข้อขัดแย้ง และรอการแก้ไข ในสถานะ ไฟล์เหล่านี้จะแสดงเป็น both modified
ขั้นตอนการแก้ไขข้อขัดแย้ง: เปิดไฟล์ที่มีข้อขัดแย้ง หาเครื่องหมายข้อขัดแย้ง (<<<<<<<, =======, >>>>>>>) แก้ไขเนื้อหา ลบเครื่องหมาย รัน git add สำหรับไฟล์ที่แก้ไขแล้ว และรัน git cherry-pick --continue หากไม่สามารถแก้ไขข้อขัดแย้งได้ — git cherry-pick --abort จะยกเลิก cherry-pick ทั้งหมด ส่งคืนสาขากลับสู่สถานะเดิม
ปัญหาที่พบบ่อย: คอมมิตมีการเปลี่ยนแปลงที่เทียบเท่ากับที่มีอยู่แล้ว ในกรณีนี้ Git รายงาน “nothing to commit” หรือ “empty commit” เมื่อพยายาม cherry-pick แฟลก --keep-redundant-commits และ --empty=keep บังคับให้ Git สร้างคอมมิตว่างเพื่อรักษาลำดับไว้ ในขณะที่ --skip อนุญาตให้ข้ามคอมมิตดังกล่าว
# ข้อขัดแย้งระหว่าง cherry-pick — หยุด
git cherry-pick a1b2c3d
# error: ไม่สามารถใช้ a1b2c3d... ข้อความคอมมิต
# แก้ไขข้อขัดแย้ง → เพิ่มไปยังดัชนี
git add src/conflicted_file.swift
git cherry-pick --continue
# ข้ามคอมมิตว่าง (ใช้ไปแล้ว)
git cherry-pick --skip
# ยกเลิกทั้งหมด
git cherry-pick --abort
กฎข้อแรก: ตรวจสอบเสมอว่าคอมมิตที่กำลังย้ายนั้นพึ่งพาตนเองได้ หากคอมมิต A ขึ้นอยู่กับการเปลี่ยนแปลงในคอมมิต B ที่ไม่ได้ถูกย้าย การ cherry-pick A อาจทำให้บิลด์เสียหาย ก่อน cherry-pick ควรตรวจสอบว่าไฟล์ใดบ้างที่คอมมิตเปลี่ยนแปลงผ่าน git show --stat <hash>
กฎข้อที่สอง: บันทึกการดำเนินการ cherry-pick ใช้แฟลก -x เพื่อให้ข้อความคอมมิตคงการอ้างอิงถึงคอมมิตต้นฉบับ ซึ่งจะช่วยในการวิเคราะห์ประวัติภายหลังเพื่อเข้าใจว่าการเปลี่ยนแปลงมาจากไหน หากไม่มี -x cherry-pick จะดูเหมือนคอมมิตปกติ และสามารถระบุที่มาได้ผ่าน git log --graph เท่านั้น
กฎข้อที่สาม: หลีกเลี่ยง cherry-pick ระหว่างสาขาที่แยกออกจากกันมากเกินไป หากเวลาผ่านไปนานตั้งแต่คอมมิตถูกสร้างขึ้นและโค้ดเบสเปลี่ยนแปลงอย่างมีนัยสำคัญ ข้อขัดแย้งจะมีจำนวนมากและซับซ้อน ในกรณีเช่นนี้ ควรปรับใช้การแก้ไขใหม่ในสาขาปลายทาง — จะใช้เวลาน้อยกว่าการแก้ไขข้อขัดแย้งหลายสิบรายการ
คำถามที่พบบ่อย
การเชอร์รีพิก หมายถึงการนำการเปลี่ยนแปลงของคอมมิตที่ระบุไปใช้กับสาขาปัจจุบันผ่าน git cherry-pick คำสั่งจะสร้างคอมมิตใหม่ที่มีการเปลี่ยนแปลงเดียวกันแต่แฮชใหม่ คอมมิตต้นฉบับยังคงไม่เปลี่ยนแปลงในสาขาของมัน นี่เป็นทางเลือกแทนการ merge ทั้งสาขาเมื่อต้องการคอมมิตเฉพาะเพียงรายการเดียว
Cherry-pick ถูกเลือกเมื่อคุณต้องการย้ายคอมมิตเฉพาะหนึ่งรายการหรือมากกว่าโดยไม่ต้องย้ายทั้งสาขา Merge ใช้สำหรับการรวมสาขาทั้งหมด สถานการณ์ cherry-pick ทั่วไปคือการย้ายการแก้ไขบั๊กจากสาขาพัฒนาไปยังสาขารุ่นที่การเปลี่ยนแปลงอื่น ๆ ยังไม่พร้อม
ก่อนเสร็จสิ้น — git cherry-pick --abort ยกเลิกการดำเนินการทั้งหมด หลังจากเสร็จสิ้นสำเร็จ — git revert <hash> สร้างคอมมิตที่ยกเลิกการเปลี่ยนแปลงของ cherry-pick ความแตกต่างจาก --abort: revert ไม่ได้ลบคอมมิตออกจากประวัติ แต่สร้างคอมมิตยกเลิกใหม่
คอมมิตว่างเกิดขึ้นเมื่อการเปลี่ยนแปลงมีอยู่ในสาขาปลายทางแล้ว ใช้ git cherry-pick --skip เพื่อข้ามคอมมิตดังกล่าว หรือ git cherry-pick --keep-redundant-commits เพื่อสร้างคอมมิตว่างเพื่อรักษาลำดับของแฮช
Cherry-pick ย้ายคอมมิตที่เลือก (ทีละรายการหรือเป็นรายการ) ไปยังสาขาปัจจุบัน Rebase ย้ายคอมมิตทั้งหมดของสาขาไปยังฐานใหม่ Cherry-pick ไม่แก้ไขสาขาต้นทาง rebase เขียนประวัติใหม่ Cherry-pick แม่นยำแต่ต้องทำด้วยตนเอง rebase อัตโนมัติแต่อันตรายสำหรับสาขาสาธารณะ
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ