Làm chủ git format-patch và git am: Quy trình gửi code chuyên nghiệp qua Email

Git tutorial - IT technology blog
Git tutorial - IT technology blog

Gửi code qua email: Cũ nhưng không hề lỗi thời

Nếu bạn đã quen nhấn nút “Create Pull Request” trên GitHub, việc gửi code qua email nghe có vẻ hơi… thủ công. Tuy nhiên, những tượng đài công nghệ như Linux Kernel, Git hay PostgreSQL vẫn vận hành hàng chục năm qua dựa trên mailing list và các file patch. Đây không phải là sự bảo thủ, mà là sự lựa chọn về tính phi tập trung và hiệu quả.

Tôi từng tham gia một dự án tài chính với yêu cầu bảo mật cực cao. Server Git nằm trong vùng mạng cô lập (air-gapped), không có kết nối Internet. Việc push code lên một server trung tâm là điều không thể. Khi đó, git format-patchgit am trở thành công cụ duy nhất để team trao đổi code mà vẫn giữ trọn vẹn lịch sử commit cùng thông tin tác giả.

So sánh nhanh: Pull Request và Email Patch

Tại sao các “lão làng” Open Source vẫn ưu tiên dùng email thay vì các nền tảng hiện đại?

1. Pull Request (GitHub/GitLab)

  • Ưu điểm: Giao diện web trực quan, dễ review dòng code và tích hợp sẵn CI/CD.
  • Nhược điểm: Phụ thuộc hoàn toàn vào nền tảng (Vendor lock-in). Bạn buộc phải có tài khoản và thực hiện thao tác fork repo khá rườm rà.

2. Email Patch (format-patch & am)

  • Ưu điểm: Tính phi tập trung tuyệt đối. Bạn chỉ cần địa chỉ email của maintainer để gửi đóng góp. File patch rất nhẹ (thường chỉ vài KB) nhưng chứa đầy đủ metadata như tác giả, ngày tháng và commit message.
  • Nhược điểm: Đường cong học tập dốc hơn, đòi hỏi kỹ năng dòng lệnh (CLI) tốt để quản lý luồng thảo luận.

3 kịch bản thực tế cần dùng đến Patch

Không chỉ dùng cho Linux Kernel, bộ đôi này cực kỳ hữu dụng trong các trường hợp sau:

  1. Môi trường offline: Khi làm việc trong mạng nội bộ bị chặn kết nối ra ngoài hoặc server Git chung gặp sự cố.
  2. Gửi bản vá nhanh: Thay vì tạo một branch tạm trên server, bạn chỉ cần xuất file patch và gửi qua Slack cho đồng nghiệp test nhanh trong 30 giây.
  3. Dự án Open Source thuần túy: Những cộng đồng ưu tiên sự tinh gọn và muốn tránh phụ thuộc vào các tập đoàn lớn như Microsoft (GitHub).

Bước 1: Xuất file patch với git format-patch

Giả sử bạn vừa hoàn thành tính năng trên branch feature-fix. Để đóng gói các commit thành file, hãy sử dụng lệnh sau:

# Xuất duy nhất commit mới nhất
git format-patch -1 HEAD

# Xuất tất cả commit từ branch feature so với main
git format-patch main..feature-fix

Git sẽ tạo ra các file dạng 0001-ten-commit.patch. Điểm khác biệt của file này với lệnh git diff thông thường là nó bao gồm cả chữ ký số, email tác giả và nội dung commit message.

Kinh nghiệm: Nếu gửi một chuỗi gồm nhiều file (series), hãy thêm flag --cover-letter. Nó tạo ra file 0000 để bạn viết tóm tắt tổng quan về toàn bộ thay đổi, giúp maintainer dễ nắm bắt ngữ cảnh hơn.

git format-patch main -o outgoing/ --cover-letter

Bước 2: Gửi patch bằng git send-email

Một sai lầm phổ biến là đính kèm file patch vào Gmail hoặc Outlook theo cách thủ công. Các trình duyệt email thường tự động chèn thêm ký tự hoặc thay đổi định dạng văn bản (như đổi tab thành space). Việc này sẽ làm hỏng cấu trúc file patch, khiến phía người nhận không thể áp dụng được.

Công cụ chuẩn nhất là git send-email. Đầu tiên, hãy cấu hình SMTP (ví dụ với Gmail):

git config --global sendemail.smtpserver smtp.gmail.com
git config --global sendemail.smtpserverport 587
git config --global sendemail.smtpencryption tls
git config --global sendemail.smtpuser [email protected]

Sau đó, gửi patch đi bằng một câu lệnh duy nhất:

git send-email --to="[email protected]" outgoing/*.patch

Bước 3: Áp dụng patch với git am

Khi nhận được file patch, maintainer sẽ dùng lệnh git am (Apply Mail) để tích hợp code vào dự án.

# Kiểm tra tính toàn vẹn của patch trước khi áp dụng
git apply --check 0001-fix-bug-logic.patch

# Áp dụng patch và tự động tạo commit tương ứng
git am 0001-fix-bug-logic.patch

Sau khi chạy lệnh, commit của bạn sẽ xuất hiện trong lịch sử Git của dự án với đầy đủ thông tin gốc, y như bạn vừa thực hiện lệnh commit trực tiếp trên máy của họ.

Xử lý xung đột (Conflict) như thế nào?

Nếu code gốc đã thay đổi quá nhiều, git am sẽ thất bại. Đừng lo lắng, hãy sử dụng flag --3way để Git cố gắng thực hiện merge 3 chiều, giúp giảm thiểu tỷ lệ lỗi thủ công.

git am --3way 0001-fix-bug-logic.patch

Nếu vẫn còn conflict, Git sẽ dừng lại để bạn sửa tay. Sau khi hoàn tất, bạn chỉ cần thực hiện:

git add .
git am --continue

Lời kết

Ban đầu, quy trình này có vẻ rắc rối hơn việc click chuột trên UI. Tuy nhiên, khi đã thành thạo, bạn sẽ thấy nó mang lại sự tự do rất lớn. Mọi thứ chỉ là văn bản thuần túy. Bạn không cần lo lắng về việc server downtime hay giao diện GitHub thay đổi.

Một lưu ý cuối: Khi gửi patch, hãy viết commit message thật rõ ràng. Trong thế giới email, commit message chính là tài liệu duy nhất giúp người khác hiểu được tư duy của bạn. Chúc các bạn áp dụng thành công!

Share: