Cherry-pick là lệnh Git áp dụng các thay đổi từ một hoặc nhiều commit hiện có vào nhánh hiện tại. Không giống như Merge (chuyển toàn bộ nhánh) và Rebase (chuyển một chuỗi commit), cherry-pick chỉ chọn các commit được chỉ định. Theo git-scm.com, 2025, cherry-pick được ưa chuộng nhất trong các tình huống chuyển bản sửa lỗi giữa các nhánh phát hành.
Những điểm chính
Cherry-pick là lệnh Git sao chép các thay đổi từ một commit được chỉ định và áp dụng chúng như một commit mới trong nhánh hiện tại. Tên gọi bắt nguồn từ phép ẩn dụ “hái anh đào”: nhà phát triển chỉ chọn những commit cần thiết, bỏ qua phần còn lại.
Không giống như Merge, cherry-pick không tạo commit hợp nhất và không yêu cầu hợp nhất toàn bộ nhánh. Không giống như Rebase, cherry-pick không chuyển một chuỗi commit — chỉ những commit được chỉ định. Điều này làm cho cherry-pick trở thành công cụ lý tưởng để chuyển các bản sửa lỗi có mục tiêu.
Theo Atlassian, 2025, cherry-pick được 47% nhóm làm việc với nhiều nhánh phát hành đồng thời sử dụng. Cherry-pick đặc biệt được ưa chuộng trong phát triển di động, nơi nhiều phiên bản của ứng dụng (bản phát hành LTS) được duy trì đồng thời và cần chuyển các bản sửa lỗi giữa chúng.
Khi thực hiện cherry-pick, Git tính toán diff giữa commit được chỉ định và commit cha của nó, sau đó áp dụng diff này vào nhánh hiện tại. Nếu các thay đổi được áp dụng không xung đột — Git tạo một commit mới với cùng thông điệp nhưng SHA mới. Nếu có xung đột — cherry-pick tạm dừng để giải quyết thủ công.
Cú pháp cherry-pick rất đơn giản: chỉ định hash của commit cần chuyển. Git sao chép các thay đổi vào nhánh hiện tại như một commit mới. Hỗ trợ chuyển nhiều commit cùng lúc và toàn bộ phạm vi.
# Chuyển một commit vào nhánh hiện tại
git cherry-pick a1b2c3d4
# Chuyển nhiều commit
git cherry-pick a1b2c3d4 e5f6g7h8
# Chuyển một phạm vi commit (từ a1b2 đến f9e8, không bao gồm a1b2)
git cherry-pick a1b2c3d4..f9e8d7c6
Sau khi thực hiện cherry-pick, nhánh hiện tại nhận được một commit mới với các thay đổi từ nguồn. Thông điệp commit được sao chép từ nguồn theo mặc định, nhưng có thể được sửa đổi bằng cờ -n (không tạo commit) hoặc --edit (chỉnh sửa thông điệp).
Hãy xem xét một tình huống điển hình: một lỗi nghiêm trọng được tìm thấy và sửa trong develop, lỗi này cũng tồn tại trong nhánh phát hành release/v2.0. Chỉ cần chuyển bản sửa lỗi này mà không hợp nhất toàn bộ develop vào nhánh phát hành.
# Tìm hash commit có bản sửa lỗi trong develop
git log --oneline develop
# a1b2c3d fix: null check in payment processing
# Chuyển sang nhánh phát hành
git checkout release/v2.0
# Áp dụng bản sửa lỗi
git cherry-pick a1b2c3d4
# Nếu có xung đột — giải quyết và tiếp tục
git add src/payment/PaymentProcessor.kt
git cherry-pick --continue
Cờ -x thêm tham chiếu đến SHA gốc trong thông điệp commit: “(cherry picked from commit a1b2c3d4)”. Điều này giúp dễ dàng theo dõi nguồn gốc của commit đã được chuyển. Khuyến nghị sử dụng -x trong mọi tình huống trừ các bản nháp tạm thời.
Khi có xung đột, cherry-pick hoạt động như merge: Git dừng lại và đánh dấu các tệp xung đột. Nhà phát triển giải quyết xung đột, chạy git add và sau đó git cherry-pick --continue. Để hủy bỏ — git cherry-pick --abort. Cờ --strategy cho phép chỉ định chiến lược hợp nhất (ví dụ: recursive với các tùy chọn).
# Giải quyết xung đột khi cherry-pick
# Git hiển thị tệp xung đột
git status
# Giải quyết thủ công, sau đó:
git add tep_duoc_phep.kt
git cherry-pick --continue
# Hoặc hủy bỏ cherry-pick:
git cherry-pick --abort
Cherry-pick là tối ưu trong các tình huống cần chuyển thay đổi có mục tiêu mà không hợp nhất toàn bộ nhánh. Hãy xem xét năm trường hợp chính mà cherry-pick trở thành lựa chọn tốt nhất.
Đối với phát triển di động, cherry-pick rất quan trọng khi hỗ trợ nhiều phiên bản của ứng dụng. Ví dụ, nếu một lỗi được tìm thấy trong phiên bản 3.2 đã phát hành trên Google Play, và develop chứa mã cho phiên bản 4.0 — cherry-pick cho phép chuyển bản sửa lỗi sang nhánh v3.x mà không hợp nhất tất cả các thay đổi phá vỡ. Điều này đặc biệt phù hợp với các dự án duy trì đồng thời hai hoặc nhiều phiên bản chính với API và phụ thuộc khác nhau.
Ví dụ thực tế: trong ứng dụng di động, phát hiện sự cố khi xác thực qua Google Sign-In trên Android 12. Bản sửa lỗi được thực hiện trong develop và vượt qua đánh giá mã. Tuy nhiên, nhánh phát hành hiện tại v2.5 đã ở giai đoạn thử nghiệm beta. Cherry-pick commit sửa lỗi từ develop sang release/v2.5 cho phép đưa bản sửa lỗi vào bản phát hành sắp tới mà không chuyển các thay đổi khác chưa sẵn sàng phát hành.
Khi sử dụng cherry-pick trong dự án di động, cần xem xét các phụ thuộc: nếu bản sửa lỗi ảnh hưởng đến các tệp đã được thay đổi trong develop sau điểm phân kỳ của nhánh phát hành, cherry-pick có thể mang theo một tập thay đổi không đầy đủ. Trong những trường hợp như vậy, cần xác minh rằng tất cả các thay đổi liên quan cũng đã được chuyển, nếu không ứng dụng có thể không biên dịch được hoặc hoạt động không chính xác. Luôn kiểm tra bản dựng sau cherry-pick trước khi đẩy thay đổi lên nhánh dùng chung.
Ba công cụ chính để tích hợp thay đổi trong Git — merge, rebase và cherry-pick — giải quyết các tác vụ khác nhau. Sự lựa chọn phụ thuộc vào lượng thay đổi cần chuyển và lịch sử mong muốn.
| Tiêu chí | Merge | Rebase | Cherry-pick |
|---|---|---|---|
| Phạm vi | Toàn bộ nhánh | Chuỗi commit | Commit được chọn |
| Lịch sử | Giữ phân nhánh | Tuyến tính | Tuyến tính |
| Commit hợp nhất | Có (trừ ff) | Không | Không |
| Tự động hóa | Hoàn toàn | Theo chuỗi | Chỉ được chỉ định |
| Cho nhánh công khai | An toàn | Nguy hiểm | An toàn |
Merge — khi bạn cần hợp nhất hai nhánh hoàn toàn và giữ thông tin phân nhánh. Rebase — khi bạn cần cập nhật nhánh cá nhân lên trạng thái mới nhất với lịch sử sạch. Cherry-pick — khi bạn chỉ cần một commit hoặc vài commit được chọn.
Trong thực tế, các công cụ này được kết hợp: một tính năng được phát triển với rebase định kỳ lên develop, sau đó được hợp nhất qua --no-ff merge, và khi cần chuyển bản sửa lỗi sang nhánh khác, cherry-pick được sử dụng. Mỗi công cụ giải quyết nhiệm vụ riêng ở giai đoạn riêng.
Cherry-pick là công cụ hữu ích nhưng có thể nguy hiểm khi sử dụng sai cách hoặc quá mức. Các rủi ro chính liên quan đến trùng lặp commit, mất ngữ cảnh và xung đột trong các lần hợp nhất sau này.
Khuyến nghị giảm thiểu rủi ro: luôn sử dụng cờ -x để chỉ SHA gốc, ghi lại lý do cherry-pick trong thông điệp commit, và khi có thể, hãy sử dụng merge thay vì cherry-pick nếu ngữ cảnh cho phép. Nếu cherry-pick trở nên nhiều — hãy xem xét tái cấu trúc nhánh.
Đường ống CI nên coi cherry-pick như một tình huống riêng biệt. Khuyến nghị thiết lập kiểm tra tự động: khi một commit cherry-pick được tạo, CI xác minh rằng các tệp đã thay đổi khớp với tập dự kiến và chạy kiểm tra cho các mô-đun bị ảnh hưởng. Điều này giảm nguy cơ hồi quy khi chuyển thay đổi giữa các nhánh.
Câu hỏi thường gặp
Cherry-pick chuyển thay đổi từ commit này sang nhánh khác. Revert tạo commit mới hoàn tác thay đổi của commit được chỉ định trong cùng nhánh. Revert không xóa lịch sử — nó thêm thay đổi ngược lại.
Có: git cherry-pick A B C — chuyển commit A, B và C theo thứ tự. Hoặc git cherry-pick A..C — chuyển tất cả commit từ A đến C (không bao gồm A). Thứ tự chuyển tương ứng với thứ tự trong lệnh.
Mặc định, cherry-pick commit hợp nhất không hoạt động vì commit hợp nhất có hai cha. Sử dụng cờ -m 1 để chỉ định cha nào để so sánh. -m 1 lấy diff tương đối so với cha đầu tiên.
Hủy bỏ cherry-pick qua git reset --hard HEAD~1 nếu đó là commit cuối. Nếu commit đã được đẩy — sử dụng git revert <SHA> để tạo commit hoàn tác.
Không có ý nghĩa, nhưng về mặt kỹ thuật có thể. Nếu commit đã tồn tại trong nhánh, Git sẽ phát hiện các thay đổi đã được áp dụng và báo cáo: “The previous cherry-pick is now empty, possibly due to conflict resolution.” Commit sẽ không được tạo lại.
Tổng kết
Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay
IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.
Đọc thêm