Quy trình hotfix Git: Sửa lỗi prod và đồng bộ an toàn với dev
Technical Guide

Hướng dẫn hai flow hotfix với Git: lên prod trước hoặc kiểm thử dev trước, đồng bộ bản sửa giữa production và main, tránh kéo code chưa release lên prod.
Quy trình hotfix
Giả sử dự án sử dụng hai nhánh môi trường:
production: chứa code đã release, dùng để deploy môi trường prod.main: chứa code đang phát triển, dùng để deploy môi trường dev.
Hotfix dùng để sửa lỗi đang xảy ra trên prod. Luôn tạo nhánh hotfix từ origin/production, dù chọn deploy prod trước hay dev trước.
Chọn flow phù hợp
| Flow | Trường hợp sử dụng |
|---|---|
| Prod trước → đồng bộ về dev | Lỗi nghiêm trọng, bản sửa có phạm vi nhỏ và đã được kiểm tra đủ để deploy ngay. |
| Dev trước → đưa lên prod | Cần kiểm thử trên môi trường dev hoặc cần QA xác nhận trước khi deploy prod. |
Ở cả hai flow, hotfix chỉ hoàn tất khi bản sửa đã có trên cả production và main, đồng thời prod đã được deploy và xác nhận hết lỗi.
Flow 1: Hotfix lên prod trước
Bước 1: Tạo nhánh từ production mới nhất
Lấy thông tin mới nhất từ remote rồi tạo nhánh:
git fetch origin
git switch -c hotfix/UC-1234-mo-ta-ngan origin/productionThay UC-1234 bằng mã ticket và mo-ta-ngan bằng mô tả ngắn của lỗi.
Không tạo từ main vì nhánh này có thể chứa code chưa release. Không tạo từ nhánh production local cũ vì có thể chưa được cập nhật.
Bước 2: Sửa lỗi và kiểm tra
Chỉ thay đổi những phần cần thiết để sửa lỗi:
- Không refactor ngoài phạm vi lỗi.
- Không format lại cả file.
- Không nâng dependency nếu không cần cho bản sửa.
Kiểm tra lỗi đã được xử lý và các chức năng liên quan vẫn hoạt động. Giữ diff nhỏ để dễ review và giảm conflict.
Bước 3: Commit và mở PR vào production
Commit và push bản sửa:
git add <cac-file-da-sua>
git commit -m "fix(UC-1234): mô tả lỗi"
git push -u origin hotfix/UC-1234-mo-ta-nganMở PR:
gh pr create \
--base production \
--head hotfix/UC-1234-mo-ta-ngan \
--title "hotfix(UC-1234): mô tả lỗi"Kiểm tra hướng PR:
hotfix/UC-1234-mo-ta-ngan → production
Mô tả PR cần nêu lỗi, cách sửa và kết quả kiểm tra.
Bước 4: Review, merge và deploy prod
Sau khi PR được review và các kiểm tra đã đạt:
- Merge bằng Create a merge commit.
- Deploy môi trường prod.
- Kiểm tra trên prod để xác nhận lỗi đã hết.
Không dùng Squash and merge hoặc Rebase and merge. Quy trình này cần giữ nguyên SHA của các commit sửa lỗi khi đưa vào hai nhánh.
Giữ lại nhánh hotfix cho bước tiếp theo. Nếu GitHub tự động xoá nhánh sau khi merge, khôi phục nhánh đó.
Bước 5: Đồng bộ về main ngay
Mở PR từ chính nhánh hotfix vào main:
gh pr create \
--base main \
--head hotfix/UC-1234-mo-ta-ngan \
--title "chore: đồng bộ hotfix UC-1234 về main"Hướng PR:
hotfix/UC-1234-mo-ta-ngan → main
Review, chạy các kiểm tra cần thiết và merge bằng Create a merge commit.
Nếu có conflict, giải quyết trên nhánh hotfix. Vì nhánh này đã được merge vào production, các commit bổ sung sau đó không tự động thay đổi prod.
Phải hoàn tất đồng bộ trong cùng phiên xử lý, không để sang hôm sau. Khi main chưa nhận bản sửa, release tiếp theo có thể bỏ sót hotfix.
Nếu bị chặn bởi conflict hoặc CI, ghi rõ người phụ trách và chặn release tiếp theo cho đến khi đồng bộ xong.
Bước 6: Xác nhận và xoá nhánh
Thực hiện phần Kiểm tra hoàn tất ở cuối tài liệu, sau đó xoá nhánh hotfix.
Flow 2: Hotfix lên dev trước
Flow này dùng khi cần kiểm thử bản sửa trên dev trước khi đưa lên prod.
Lên dev trước không có nghĩa là tạo nhánh từ main. Nhánh hotfix vẫn phải xuất phát từ production để tránh đưa kèm code chưa release lên prod.
Bước 1: Tạo nhánh từ production mới nhất
git fetch origin
git switch -c hotfix/UC-1234-mo-ta-ngan origin/productionBước 2: Sửa lỗi, kiểm tra và push
Giữ phạm vi sửa nhỏ như flow 1, sau đó commit và push:
git add <cac-file-da-sua>
git commit -m "fix(UC-1234): mô tả lỗi"
git push -u origin hotfix/UC-1234-mo-ta-nganBước 3: Mở PR vào main
gh pr create \
--base main \
--head hotfix/UC-1234-mo-ta-ngan \
--title "hotfix(UC-1234): kiểm thử bản sửa trên dev"Hướng PR:
hotfix/UC-1234-mo-ta-ngan → main
Sau khi review và kiểm tra đạt, merge bằng Create a merge commit. Giữ lại nhánh hotfix để đưa lên prod sau khi kiểm thử.
Nếu PR vào main có conflict
Không merge main vào nhánh hotfix sẽ đưa lên prod. Việc này có thể kéo theo code chưa release.
Thay vào đó, tạo nhánh tích hợp riêng:
git switch -c integration/UC-1234-dev origin/main
git merge --no-ff hotfix/UC-1234-mo-ta-nganGiải quyết conflict, kiểm tra rồi commit nếu Git yêu cầu:
git add <cac-file-da-giai-quyet-conflict>
git commit
git push -u origin integration/UC-1234-devMở PR từ nhánh tích hợp vào main:
gh pr create \
--base main \
--head integration/UC-1234-dev \
--title "hotfix(UC-1234): tích hợp bản sửa vào dev"Dùng PR này thay cho PR hotfix → main, rồi merge bằng Create a merge commit.
Nhánh hotfix gốc tiếp tục được giữ riêng để đưa vào production.
Bước 4: Deploy dev và kiểm thử
Deploy main lên môi trường dev, rồi kiểm tra:
- Lỗi ban đầu đã được xử lý.
- Các chức năng liên quan vẫn hoạt động.
- Bản sửa đáp ứng yêu cầu xác nhận của QA hoặc người phụ trách.
Nếu cần sửa thêm:
- Commit bản sửa bổ sung trên nhánh hotfix gốc.
- Mở PR bổ sung vào
main; dùng nhánh tích hợp riêng nếu có conflict. - Merge bằng merge commit, deploy dev và kiểm thử lại.
Những thay đổi chỉ phục vụ tương thích với code mới trên main được xử lý ở nhánh tích hợp. Những thay đổi cần để sửa lỗi trên prod phải nằm trên nhánh hotfix gốc.
Dev có thể chứa code chưa release, nên ngoài kiểm thử trên dev, cần kiểm tra bản sửa cũng hoạt động với code nền của production, đặc biệt khi hai nhánh khác nhau nhiều.
Bước 5: Mở PR vào production
Khi kiểm thử đạt, mở PR từ nhánh hotfix gốc vào production:
gh pr create \
--base production \
--head hotfix/UC-1234-mo-ta-ngan \
--title "hotfix(UC-1234): mô tả lỗi"Hướng PR:
hotfix/UC-1234-mo-ta-ngan → production
Kiểm tra diff chỉ chứa các thay đổi cần cho hotfix, rồi review và merge bằng Create a merge commit.
Không dùng nhánh tích hợp dev hoặc toàn bộ main để đưa lên prod.
Nếu phải sửa thêm khi review hoặc giải quyết conflict với production, đưa các thay đổi cần thiết đó về main và kiểm thử lại trước khi hoàn tất hotfix.
Bước 6: Deploy prod, xác nhận và xoá nhánh
Deploy môi trường prod và kiểm tra lỗi đã hết.
Thực hiện phần Kiểm tra hoàn tất bên dưới, rồi xoá nhánh hotfix và nhánh tích hợp nếu có.
Kiểm tra hoàn tất
Áp dụng cho cả hai flow.
1. Cập nhật thông tin remote
git fetch origin2. Kiểm tra các commit còn thiếu trên main
git rev-list --count --no-merges origin/main..origin/productionKết quả mong đợi là 0: không còn commit thường nào trên production chưa có trong lịch sử của main.
Nếu kết quả lớn hơn 0, xem các commit còn thiếu:
git log --oneline --no-merges origin/main..origin/productionLệnh này kiểm tra toàn bộ lịch sử hai nhánh, nên có thể hiển thị commit tồn đọng từ trước. Cần xử lý hoặc làm rõ các chênh lệch đó và xác nhận toàn bộ bản sửa hotfix đã có trên main.
Lệnh kiểm tra lịch sử không thay thế việc kiểm thử: bản sửa vẫn cần hoạt động đúng trên cả hai môi trường.
3. Xoá các nhánh tạm
Xoá nhánh hotfix:
git push origin --delete hotfix/UC-1234-mo-ta-nganNếu có nhánh tích hợp dev và PR đã merge, xoá nhánh đó:
git push origin --delete integration/UC-1234-devĐiều kiện hoàn tất
- Bản sửa đã có trên cả
productionvàmain. - Prod đã được deploy và xác nhận hết lỗi.
- Các chênh lệch lịch sử còn lại đã được xử lý hoặc làm rõ.
- Các nhánh hotfix và tích hợp đã được xoá.
Vì sao không mở PR production → main?
Khi dùng nút Resolve conflicts trên GitHub, phần giải quyết conflict được commit vào nhánh nguồn của PR.
Nếu nhánh nguồn là production, thao tác này có thể đưa code chưa release từ main vào production. Vì vậy, đồng bộ bằng nhánh hotfix hoặc nhánh tích hợp riêng.


