Hướng Dẫn Git Workflow: Branching, Merging và Cộng Tác Nhóm
Nắm vững các chiến lược branching trong Git, thực hành commit đúng chuẩn, so sánh rebase và merge, cùng các workflow được các nhóm kỹ thuật chuyên nghiệp sử dụng.
Git là nền tảng trong workflow của mọi nhóm phát triển phần mềm hiện đại. Tuy nhiên, nhiều lập trình viên chỉ dùng commit, push và pull — bỏ qua những tính năng giúp quá trình cộng tác trở nên trơn tru và hạn chế xung đột. Hướng dẫn này đề cập đến các chiến lược branching, thực hành commit và những lệnh thường dùng hàng ngày của các nhóm chuyên nghiệp.
Mô hình tư duy cốt lõi
Git là một đồ thị có hướng không chu trình (directed acyclic graph) của các snapshot (commit). Mỗi commit trỏ đến commit cha của nó. Branch chỉ đơn giản là các con trỏ được đặt tên trỏ đến commit — nhẹ và dễ tạo.
main: A → B → C → D
feature: C → E → F
Tạo branch không sao chép file — nó chỉ tạo một con trỏ mới. Đó là lý do tại sao việc tạo một branch chỉ mất vài mili giây bất kể kích thước repository.
Các chiến lược branching
GitHub Flow (đơn giản, triển khai liên tục)
Phù hợp nhất với các nhóm triển khai thường xuyên:
mainluôn sẵn sàng để triển khai- Tạo một feature branch cho mỗi thay đổi
- Mở pull request khi sẵn sàng để review
- Merge vào
mainsau khi được phê duyệt - Triển khai ngay lập tức
git checkout -b feature/add-user-auth
# ... thực hiện thay đổi ...
git push origin feature/add-user-auth
# Mở PR → review → merge → deploy
Git Flow (phát hành có cấu trúc)
Phù hợp nhất với các sản phẩm có phiên bản phát hành (ứng dụng, thư viện):
main— chỉ chứa code productiondevelop— branch tích hợpfeature/*— tính năng mới (tạo từdevelop)release/*— chuẩn bị phát hành (tạo từdevelop)hotfix/*— sửa lỗi khẩn cấp trên production (tạo từmain)
Có cấu trúc hơn nhưng cũng phức tạp hơn. Hãy dùng GitHub Flow trừ khi bạn thực sự cần quản lý nhiều phiên bản song song.
Trunk-Based Development
Lập trình viên commit trực tiếp vào main (hoặc các branch ngắn hạn < 1 ngày). Feature flags kiểm soát những gì người dùng thấy. Yêu cầu CI/CD mạnh và độ phủ test cao. Được sử dụng bởi Google, Facebook và các nhóm có tốc độ phát triển cao.
Viết commit message chất lượng
Commit message là một bức thư gửi cho chính bạn trong tương lai (và đồng đội). Hãy tuân theo định dạng Conventional Commits:
<type>(<scope>): <tóm tắt ngắn gọn>
<phần thân tùy chọn — what và why, không phải how>
<phần cuối tùy chọn — breaking changes, tham chiếu issue>
Các loại (Types):
feat— tính năng mớifix— sửa lỗidocs— chỉ thay đổi tài liệurefactor— thay đổi code không sửa lỗi cũng không thêm tính năngtest— thêm hoặc sửa testchore— quy trình build, dependencies, tooling
Ví dụ:
feat(auth): add JWT refresh token rotation
Implements sliding session windows using refresh token rotation.
Previous tokens are invalidated on use to detect theft.
Closes #142
fix(api): return 404 instead of 500 for missing user
The /users/:id endpoint was throwing an unhandled exception when
the user didn't exist. Now returns a proper 404 with error message.
Nguyên tắc chung: Nếu commit message của bạn là
fix stuffhayWIP, đồng đội của bạn sẽ không vui. Hãy viết rõ ràng và có ý nghĩa.
Merge vs. Rebase
Merge
git checkout main
git merge feature/my-feature
Tạo ra một merge commit kết hợp hai branch. Lưu giữ toàn bộ lịch sử — bạn có thể thấy chính xác khi nào các branch phân kỳ và hội tụ.
A → B → C → M (merge commit)
↑ ↑
E → F (feature)
Dùng merge khi: tích hợp các branch tồn tại lâu dài, muốn bảo toàn ngữ cảnh trong lịch sử.
Rebase
git checkout feature/my-feature
git rebase main
Áp lại các commit của bạn lên trên branch đích. Tạo ra lịch sử tuyến tính — trông như thể tính năng được xây dựng trực tiếp trên phiên bản mới nhất của main.
Before: A → B → C (main)
↑
D → E (feature, based off B)
After: A → B → C → D' → E' (feature rebased onto C)
Dùng rebase khi: dọn dẹp các commit cục bộ trước khi mở PR, giữ cho feature branch luôn cập nhật.
Quy tắc vàng: Không bao giờ rebase các commit đã được push lên branch dùng chung. Rebase ghi đè lịch sử — điều này sẽ làm hỏng branch cục bộ của người khác.
Interactive rebase: dọn dẹp lịch sử
Trước khi mở PR, hãy squash và fixup các commit lộn xộn trong quá trình làm việc:
git rebase -i HEAD~4 # chỉnh sửa tương tác 4 commit cuối
Các tùy chọn trong trình soạn thảo tương tác:
pick— giữ commitsquash— gộp vào commit trước, kết hợp messagefixup— gộp vào commit trước, bỏ messagereword— giữ thay đổi, chỉnh sửa messagedrop— xóa hoàn toàn commit
Xử lý xung đột
Xung đột xảy ra khi hai branch cùng chỉnh sửa một dòng. Git sẽ đánh dấu chúng:
<<<<<<< HEAD (your branch)
const timeout = 5000;
=======
const timeout = 3000;
>>>>>>> feature/update-timeouts
Giải quyết bằng cách chỉnh sửa file về trạng thái đúng (xóa các marker), sau đó:
git add src/config.ts
git merge --continue # hoặc git rebase --continue
Phòng bệnh hơn chữa bệnh:
- Thường xuyên pull từ
mainđể giữ branch ngắn hạn - Trao đổi với đồng đội khi cùng làm việc trên các file giống nhau
- Giữ PR nhỏ — PR lớn có nhiều xung đột hơn và khó review hơn
Các lệnh thiết yếu hàng ngày
# Bắt đầu tính năng mới
git checkout -b feature/my-feature
# Stage các thay đổi cụ thể (không phải toàn bộ file)
git add -p
# Xem các thay đổi chưa được stage
git diff
# Xem các thay đổi đã được stage
git diff --staged
# Chỉnh sửa commit cuối (trước khi push)
git commit --amend --no-edit
# Lưu tạm thời các thay đổi chưa commit
git stash
git stash pop
# Tìm commit nào gây ra lỗi (tìm kiếm nhị phân)
git bisect start
git bisect bad # commit hiện tại có lỗi
git bisect good v1.2.0 # commit cuối cùng được biết là tốt
# Khôi phục branch đã xóa hoặc commit bị mất
git reflog
# Xem đồ thị trực quan của các branch
git log --oneline --graph --all
Thực hành tốt nhất khi tạo pull request
Một PR tốt:
- Chỉ làm một việc — reviewer có thể hiểu toàn bộ thay đổi
- Có mô tả rõ ràng — những gì đã thay đổi, tại sao, và cách kiểm tra
- Có kích thước nhỏ — < 400 dòng diff là mục tiêu tham khảo
- Vượt qua CI — không bao giờ yêu cầu review khi build đang lỗi
- Liên kết đến issue —
Closes #42tự động đóng issue khi merge
Sử dụng README Generator của chúng tôi để tạo khung tài liệu song song với các thay đổi code của bạn.
Những điều cần biết về .gitignore
Luôn thêm những mục sau vào .gitignore:
# Biến môi trường
.env
.env.local
.env.*.local
# Dependencies
node_modules/
vendor/
# Build output
dist/
build/
.next/
# File hệ điều hành
.DS_Store
Thumbs.db
# File editor
.vscode/settings.json
.idea/
*.swp
Tạo .gitignore phù hợp với dự án tại gitignore.io — công cụ này hỗ trợ hàng trăm ngôn ngữ và công cụ khác nhau.
Sự thành thạo Git được tích lũy theo thời gian. Hãy nắm vững mô hình tư duy, áp dụng thói quen commit tốt, và sự cộng tác của nhóm bạn sẽ trở nên hiệu quả hơn đáng kể.