Nhặt đúng commit với git cherry-pick: Ứng dụng thực tế khi Hotfix trên Production
Hướng dẫn git cherry-pick qua quy trình hotfix production thực tế: chọn commit, dùng -x, xử lý conflict, cherry-pick nhiều commit, abort, revert và tránh duplicate fix.
ShanverseCập nhật 9 phút đọc— lượt xemĐang tải lượt xem
Git
Developer Tools
Hãy tưởng tượng production đang chạy từ branch main, trong khi develop đã có nhiều tính năng chưa sẵn sàng release. Một lỗi thanh toán nghiêm trọng được sửa bằng một commit rõ ràng. Thay vì merge toàn bộ develop, bạn có thể cherry-pick đúng commit hotfix vào branch release phù hợp.
Chiều ngược lại cũng phổ biến: hotfix được tạo trực tiếp từ production, sau khi deploy cần đưa cùng bản vá trở lại develop để lỗi không xuất hiện trong release kế tiếp.
git cherry-pick thực sự làm gì?
Giả sử commit F nằm trên branch
Bình luận
develop
:
Đứng trên main và chạy:
Git lấy patch của F, áp dụng lên main và tạo commit mới F':
F và F' có thể tạo thay đổi tương đương, nhưng là hai commit khác nhau với hash khác nhau.
Khi nào nên dùng cherry-pick?
Đưa một hotfix cụ thể vào production/release branch.
Đồng bộ hotfix từ production trở lại develop.
Lấy một commit hữu ích từ branch chưa sẵn sàng merge.
Khôi phục một thay đổi đã bị revert nhầm trong bối cảnh phù hợp.
Chuyển một thay đổi được commit nhầm branch sang branch đúng.
Không nên dùng cherry-pick để:
Thay thế merge cho toàn bộ feature có nhiều commit phụ thuộc.
Đồng bộ branch dài hạn thường xuyên.
Sao chép hàng loạt commit mà không hiểu dependency.
Né tránh quy trình review, CI hoặc release.
Quy trình Hotfix Production an toàn
Có hai hướng chính. Chọn theo nơi bản vá được tạo.
Hướng A — Sửa từ production rồi đưa lại vào develop
Đây thường là hướng dễ kiểm soát nhất khi production cần phản ứng khẩn cấp.
Mermaid
Loading diagram…
Hướng B — Bản vá đã có trên develop, lấy sang production
Chỉ nên dùng khi commit độc lập, đã review và không phụ thuộc code chưa release.
Mermaid
Loading diagram…
Kịch bản A: Tạo hotfix từ production
1. Cập nhật remote refs
2. Tạo branch từ đúng trạng thái production
Nếu production theo main:
Nếu production được đánh dấu bằng tag:
Đảm bảo bạn bắt đầu từ đúng commit đang deploy, không chỉ branch có tên giống production.
3. Sửa lỗi và tạo commit độc lập
Một hotfix commit tốt nên:
Chỉ chứa bản vá và test liên quan.
Không trộn refactor lớn.
Không nâng dependency không cần thiết.
Có message mô tả nguyên nhân hoặc hành vi đã sửa.
4. Review, CI và deploy
Mở Pull Request vào production branch, chạy CI, review và deploy theo quy trình của team.
5. Đưa hotfix trở lại develop
Sau khi commit hotfix đã ổn định:
-x thêm dòng tham chiếu vào commit message:
Điều này hữu ích cho hotfix public vì giúp truy vết nguồn gốc.
6. Kiểm tra và push
Nếu develop đã có thay đổi tương đương, cherry-pick có thể conflict hoặc trở thành empty. Hãy xác minh thay vì cố tạo duplicate fix.
Kịch bản B: Lấy một fix từ develop sang production
1. Xác định commit chính xác
Xem nội dung commit:
Kiểm tra:
Commit có chỉ chứa hotfix không?
Có phụ thuộc commit trước đó trên develop không?
API, schema hoặc config cần thiết đã tồn tại trên production chưa?
Test có áp dụng được trên code production không?
2. Tạo branch từ production
3. Cherry-pick có truy vết
4. Chạy đầy đủ kiểm tra
5. Review và deploy
Không push thẳng vào protected production branch nếu team yêu cầu Pull Request và CI.
Cú pháp cơ bản
Cherry-pick một commit:
Thêm nguồn gốc vào message:
Không tự commit ngay, chỉ đưa thay đổi vào staging area:
Dạng ngắn:
-n hữu ích khi cần kết hợp nhiều commit thành một commit có kiểm soát.
Cherry-pick nhiều commit
Nhiều commit riêng lẻ theo thứ tự
Git áp dụng theo thứ tự được truyền.
Một khoảng commit liên tiếp
Bao gồm cả commit đầu và cuối:
Ví dụ:
Lấy các commit sau A đến C, không gồm A:
Luôn xem trước phạm vi:
Gộp nhiều commit thành một hotfix commit
Việc gộp làm lịch sử production gọn hơn nhưng giảm khả năng truy vết từng commit. Dùng theo policy của team.
Xử lý conflict khi cherry-pick
Nếu patch không áp dụng sạch:
Mở file và xử lý marker:
Tạo phiên bản cuối đúng, rồi stage:
Tiếp tục:
Hủy toàn bộ thao tác hiện tại:
Bỏ qua commit hiện tại trong một chuỗi:
Khi cherry-pick trở thành empty
Git có thể báo commit rỗng khi thay đổi đã tồn tại trên branch đích hoặc conflict resolution loại bỏ toàn bộ patch.
Kiểm tra:
Nếu fix đã tồn tại, thường có thể:
Không tạo commit rỗng chỉ để “đủ quy trình” trừ khi team cần marker lịch sử có chủ đích.
Cherry-pick một merge commit
Merge commit có nhiều parent, nên Git cần biết parent nào là mainline:
-m 1 không có nghĩa “chọn commit đầu tiên trong log”; nó chọn parent số 1 làm mainline để tính patch.
Kiểm tra parent:
Cherry-pick merge commit dễ tạo kết quả bất ngờ. Thường tốt hơn khi lấy commit fix cụ thể bên trong Pull Request hoặc tạo một commit hotfix độc lập.
Chuyển commit đã tạo nhầm branch
Bạn commit trên main nhưng đáng ra thuộc feature/profile.
1. Ghi lại hash
2. Chuyển sang branch đúng và cherry-pick
3. Xử lý branch sai
Nếu commit chưa push và bạn hiểu rõ lịch sử, có thể quay branch cũ về trước commit. Nếu đã push hoặc branch dùng chung, ưu tiên revert thay vì rewrite.
Đừng reset shared branch chỉ để xóa commit đã công khai.
Hoàn tác một cherry-pick đã push
Cherry-pick tạo commit bình thường, nên có thể revert:
Điều này tạo commit mới đảo thay đổi và phù hợp với branch chung.
Nếu chưa push và commit mới nhất chỉ là cherry-pick sai, có thể dùng reset sau khi kiểm tra, nhưng revert thường an toàn hơn trong quy trình cộng tác.
Tránh áp dụng trùng một fix
Vì cherry-pick tạo hash mới, Git không chỉ dựa vào hash để biết patch đã tồn tại.
So sánh patch tương đương:
Xem commit ở branch nguồn nhưng chưa có ở branch đích:
Tìm tham chiếu -x trong log:
Trước khi cherry-pick, luôn kiểm tra code đích và lịch sử Pull Request/hotfix.
cherry-pick vs merge vs rebase
Nếu bạn thường xuyên cherry-pick hàng chục commit giữa hai branch, có thể mô hình branch hoặc release flow đang cần xem lại.
Checklist Hotfix Production
Đã xác định đúng commit đang chạy trên production.
Hotfix branch được tạo từ đúng production commit/tag.
Source commit chỉ chứa bản vá cần thiết.
Đã kiểm tra dependency với commit khác.
Dùng -x để truy vết khi phù hợp.
Conflict được xử lý theo logic production, không chọn một phía máy móc.
Lint, test và build đã chạy.
Có Pull Request/review theo policy.
Có kế hoạch rollback hoặc revert.
Hotfix đã được đồng bộ sang các branch còn lại cần bản vá.
Không tạo duplicate fix.
Release note hoặc incident record tham chiếu đúng commit.
Quy trình lệnh rút gọn
Nếu hotfix được tạo từ production rồi cần đồng bộ lại:
Tổng kết
git cherry-pick phù hợp khi bạn cần một thay đổi cụ thể, đặc biệt trong hotfix production. Quy trình an toàn gồm:
Xác định đúng source commit và production base.
Kiểm tra dependency trước khi áp dụng.
Dùng -x để giữ traceability.
Xử lý conflict, chạy đầy đủ test và review.
Đồng bộ bản vá tới mọi branch cần thiết mà không tạo duplicate.
Mục lục(36)
Codeplain text
1A---B---C main2 \3 D---E---F develop
Codeplain text
1A---B---C---F' main2 \3 D---E---F develop
Codeplain text
1(cherry picked from commit abc123...)
Codeplain text
1<<<<<<< HEAD2Nội dung branch đích3=======4Nội dung từ commit đang cherry-pick5>>>>>>> commit message
1# Tạo hotfix từ production2gitfetchorigin--prune3gitswitch-chotfix/payment-timeoutorigin/main45# Nếu fix đã có ở develop6gitshow<fix-hash>7gitcherry-pick-x<fix-hash>89# Kiểm tra10npmrunlint11npmtest12npmrunbuild1314# Đẩy lên review15gitpush-uoriginhotfix/payment-timeout
Hướng dẫn Git Aliases và .gitconfig thực chiến: alias an toàn, log đẹp, cấu hình pull/push/rebase, includeIf cho tài khoản work/personal, bảo mật và chia sẻ dotfiles.
Phân tích Gitflow vs GitHub Flow vs Trunk-Based Development: cấu trúc branch, ưu nhược điểm, điều kiện áp dụng, ma trận quyết định và lộ trình chuyển đổi cho từng loại dự án.
Hướng dẫn git worktree từ cơ bản đến thực tế: tạo nhiều working tree, làm feature và hotfix song song, review PR, quản lý list/remove/prune/lock/repair và tránh lỗi phổ biến.