Hướng dẫn chi tiết quy trình sử dụng Git cho một nhóm lập trình viên- Feature Branch Workflow

Bài viết này hướng dẫn chi tiết quy trình sử dụng Git cho một nhóm lập trình viên, từ việc tạo branch, commit, push của các lập trình viên đến bước kiểm tra và merge code của team leader vào nhánh main (nhánh production). Quy trình dựa trên Feature Branch Workflow, một mô hình phổ biến và hiệu quả, kết hợp với các phương pháp tốt nhất để tránh conflict, đảm bảo mã nguồn sạch, và hỗ trợ phát triển liên tục (CI/CD).


Tổng Quan

  • Mô hình: Feature Branch Workflow, trong đó mỗi lập trình viên làm việc trên một nhánh riêng (feature branch) cho từng tính năng hoặc nhiệm vụ. Nhánh này được gửi qua pull request (PR) để team leader xem xét và merge vào nhánh main.
  • Vai trò:
  • Lập trình viên (Coder): Tạo branch, viết mã, commit, push, và tạo pull request.
  • Team Leader: Xem xét pull request, kiểm tra mã, giải quyết conflict (nếu có), và merge vào nhánh main.
  • Mục tiêu: Đảm bảo mã nguồn ổn định, không bị mất code, và giảm thiểu lỗi conflict.
  • Công cụ đề xuất: GitHub, GitLab, hoặc Bitbucket, kết hợp với CI/CD (GitHub Actions, GitLab CI).

Chuẩn Bị Ban Đầu

1. Cài Đặt Git

  • Tải và cài đặt Git từ git-scm.com (phiên bản mới nhất, ví dụ: Git 2.44 hoặc cao hơn).
  • Cấu hình thông tin cá nhân:
git config --global user.name "Tên của bạn"
git config --global user.email "email@example.com"
git config --global core.editor "code --wait"  # Nếu dùng VS Code

Giải thích: Thiết lập tên, email để gắn vào commit, và cấu hình trình soạn thảo mặc định (VD: VS Code) cho các tác vụ như commit hoặc rebase.

2. Tạo Repository

  • Team leader tạo repository trên GitHub/GitLab/Bitbucket.
  • Khởi tạo nhánh main:
  git init
  git checkout -b main
  touch README.md
  git add README.md
  git commit -m "Initial commit"
  git push origin main

Giải thích: Nhánh main là nhánh chính chứa mã ổn định, sẵn sàng triển khai.

  • Thêm thành viên vào repository với quyền collaborator.
  • Bật protected branch trên GitHub/GitLab để yêu cầu pull request và phê duyệt trước khi merge vào main.

3. Clone Repository

  • Mỗi lập trình viên clone repository về máy:
  git clone <URL-repository>
  cd <tên-thư-mục>

Giải thích: Tải mã nguồn từ repository từ xa về máy cục bộ.

  • Cấu hình fetch để lấy tất cả nhánh từ xa:
  git fetch origin

Lưu ý:

  • Sao lưu dự án trước khi bắt đầu (hoặc sử dụng Git để quản lý phiên bản).
  • Sử dụng SSH key để xác thực thay vì HTTPS cho bảo mật và tiện lợi:
  ssh-keygen -t ed25519 -C "email@example.com"
  cat ~/.ssh/id_ed25519.pub  # Thêm key vào GitHub/GitLab

Quy Trình Làm Việc

Vai Trò: Lập Trình Viên (Coder)

Bước 1: Tạo Branch Mới

  • Tạo nhánh riêng cho từng tính năng hoặc nhiệm vụ:
  git checkout main
  git pull origin main
  git checkout -b feature/<tên-tính-năng>

Giải thích:

  • git checkout main: Chuyển sang nhánh main.
  • git pull origin main: Cập nhật nhánh main với phiên bản mới nhất từ xa.
  • git checkout -b feature/<tên-tính-năng>: Tạo nhánh mới (VD: feature/login).
    Lưu ý:
  • Đặt tên nhánh rõ ràng: feature/add-login, bugfix/fix-crash, hotfix/update-api.
  • Luôn pull main trước để đảm bảo nhánh mới dựa trên mã mới nhất.

Bước 2: Viết Mã và Commit

  • Chỉnh sửa mã, sau đó commit thay đổi:
  git add <tên-file>  # Hoặc git add . để thêm tất cả
  git commit -m "Mô tả thay đổi cụ thể"

Giải thích:

  • git add: Thêm file đã chỉnh sửa vào staging area.
  • git commit: Ghi lại thay đổi với thông điệp mô tả.
    Lưu ý:
  • Viết thông điệp commit rõ ràng, ví dụ: “Thêm API đăng nhập với OAuth” thay vì “Cập nhật“.
  • Commit theo từng thay đổi logic (atomic commit) để dễ rollback nếu cần.
  • Kiểm tra trạng thái trước khi commit:
bash git status

Bước 3: Đồng Bộ Với Nhánh main (Nếu Cần)

  • Nếu nhánh feature mất nhiều thời gian, đồng bộ với main để tránh conflict:
  git fetch origin
  git merge origin/main

Giải thích: Merge các thay đổi mới từ main vào nhánh feature.
Lưu ý:

  • Nếu có conflict, giải quyết ngay (xem phần giải quyết conflict bên dưới).
  • Có thể dùng rebase thay vì merge để giữ lịch sử sạch:
bash git rebase origin/main

Bước 4: Push Nhánh Lên Repository

  • Đẩy nhánh lên repository từ xa:
  git push origin feature/<tên-tính-năng>

Giải thích: Gửi nhánh feature lên repository để lưu trữ và chia sẻ.
Lưu ý:

Nếu nhánh chưa được tracking, dùng:

bash git push --set-upstream origin feature/<tên-tính-năng>

Chạy test/lint trước khi push:

<code>bash flutter test # Nếu là dự án Flutter</code>

Bước 5: Tạo Pull Request (PR)

  • Truy cập GitHub/GitLab/Bitbucket, vào tab Pull Requests hoặc Merge Requests.
  • Tạo PR từ feature/<tên-tính-năng> sang main:
  • Tiêu đề: Mô tả ngắn gọn (VD: “Thêm tính năng đăng nhập”).
  • Mô tả: Chi tiết thay đổi, liên kết issue (VD: “Closes #123”).
  • Reviewer: Gán team leader hoặc thành viên khác.
  • Gửi PR và chờ phê duyệt.

Lưu ý:

  • Đảm bảo mã đạt tiêu chuẩn (chạy test, lint, format code).
  • Nếu team leader yêu cầu sửa đổi:
  git add .
  git commit -m "Sửa theo feedback"
  git push origin feature/<tên-tính-năng>
  • Sử dụng tính năng Draft PR (GitHub) nếu PR chưa hoàn thiện.

Mẹo từ kinh nghiệm:

  • Tự động hóa kiểm tra: Cấu hình linter (VD: flutter_lints) và unit test để đảm bảo mã chất lượng.
  • Commit nhỏ và thường xuyên: Giảm rủi ro mất code và dễ debug.
  • Sử dụng Git alias: Tạo shortcut cho lệnh thường dùng:
  git config --global alias.co checkout
  git config --global alias.cm "commit -m"

Sau đó, dùng git co main thay vì git checkout main.


Vai Trò: Team Leader

Bước 1: Thiết Lập Quy Tắc Repository

  • Bảo vệ nhánh main:
  • Trên GitHub: Vào Settings > Branches > Add rule:
    • Bật “Require pull request reviews before merging“.
    • Bật “Require status checks to pass” (nếu dùng CI/CD).
  • Trên GitLab: Vào Settings > Repository > Protected branches.
  • Tích hợp CI/CD:
    • Cấu hình GitHub Actions hoặc GitLab CI để chạy test, lint, và build tự động khi có PR.
    • Ví dụ file GitHub Actions (/.github/workflows/ci.yml):
yaml name: CI
on:
  pull_request:
    branches: [main]
  jobs:
    build:
      runs-on: ubuntu-latest
      steps:
        - uses: actions/checkout@v4
        - uses: subosito/flutter-action@v2 
          with: flutter-version: '3.22.x'
        - run: flutter pub get
        - run: flutter test

Bước 2: Xem Xét Pull Request

  • Truy cập PR trên GitHub/GitLab.
  • Kiểm tra:
    • Chất lượng mã: Tuân thủ coding standards, không có code dư thừa.
    • Chức năng: Chạy ứng dụng/test để xác minh tính năng.
    • CI/CD status: Đảm bảo tất cả kiểm tra (test, lint) pass.
  • Gửi feedback:
    • Nếu cần sửa, bình luận trên PR và yêu cầu lập trình viên cập nhật.
    • Nếu mã đạt yêu cầu, phê duyệt PR.

Lưu ý:

  • Sử dụng tính năng Suggested Changes (GitHub) để đề xuất sửa mã trực tiếp.
  • Yêu cầu ít nhất 1-2 reviewer để đảm bảo chất lượng.

Bước 3: Giải Quyết Conflict (Nếu Có)

  • Nếu PR có conflict:

Kéo nhánh về máy:

git checkout main
git pull origin main
git checkout -b temp-merge-<tên-tính-năng>
git pull origin feature/<tên-tính-năng>

Merge nhánh main:

bash git merge main

Giải quyết conflict:

Mở file conflict, chỉnh sửa để giữ mã mong muốn, xóa ký hiệu <<<<<<<, =======, >>>>>>>.

Đánh dấu file đã giải quyết:

git add <tên-file>
git commit -m "Giải quyết conflict khi merge feature/<tên-tính-năng>"

Push nhánh tạm:

bash git push origin temp-merge-<tên-tính-năng>

Tạo PR mới:

Tạo PR từ temp-merge-<tên-tính-năng> sang main.

Lưu ý:

  • Nếu conflict phức tạp, làm việc trực tiếp với lập trình viên.
  • Sử dụng công cụ mergetool:
  git mergetool
  • Cân nhắc yêu cầu lập trình viên rebase nhánh feature để giảm conflict:
  git checkout feature/<tên-tính-năng>
  git rebase origin/main
  git push --force-with-lease origin feature/<tên-tính-năng>

Bước 4: Merge PR Vào Nhánh main

Trên GitHub/GitLab:

  • Chọn Merge Pull Request:
    • Create a merge commit: Giữ lịch sử đầy đủ.
    • Squash and merge: Gộp tất cả commit thành một (nếu muốn lịch sử gọn).
  • Xóa nhánh feature sau merge.
  • Hoặc merge cục bộ:
  git checkout main
  git pull origin main
  git merge --no-ff feature/<tên-tính-năng>
  git push origin main

Giải thích: –no-ff tạo merge commit để giữ lịch sử rõ ràng.

Lưu ý:

  • Đảm bảo CI/CD pass trước khi merge.
  • Thông báo nhóm sau khi merge để mọi người pull main.

Bước 5: Kiểm Tra Sau Merge

  • Chạy test trên nhánh main:
  flutter test
  • Triển khai ứng dụng nếu cần (deploy lên production).

Mẹo từ kinh nghiệm:

  • Tự động hóa merge: Sử dụng Dependabot (GitHub) để cập nhật dependencies, giảm conflict do thư viện.
  • Audit lịch sử: Sử dụng git log –graph để kiểm tra lịch sử merge:
  git log --graph --oneline --all
  • Sử dụng Git hooks: Cấu hình pre-commit hook để chạy lint/test trước khi commit:
  echo "flutter lint ." > .git/hooks/pre-commit
  chmod +x .git/hooks/pre-commit

Quy Trình Tổng Thể (Tóm Tắt)

Lập Trình Viên:

  1. Cập nhật nhánh main:
   git checkout main
   git pull origin main
  1. Tạo nhánh feature:
   git checkout -b feature/<tên-tính-năng>
  1. Viết mã, commit:
   git add .
   git commit -m "Mô tả thay đổi"
  1. Đồng bộ với main (nếu cần):
   git merge origin/main
  1. Push nhánh:
   git push origin feature/<tên-tính-năng>
  1. Tạo PR và sửa theo feedback.

Team Leader:

  1. Thiết lập protected branch và CI/CD.
  2. Xem xét PR, kiểm tra mã/test/CI status.
  3. Giải quyết conflict (nếu có):
   git checkout -b temp-merge-<tên-tính-năng>
   git pull origin feature/<tên-tính-năng>
   git merge main
   git push origin temp-merge-<tên-tính-năng>
  1. Merge PR vào main:
   git checkout main
   git merge --no-ff feature/<tên-tính-năng>
   git push origin main
  1. Kiểm tra và triển khai.

Lưu Ý Quan Trọng

Đối Với Lập Trình Viên:

  • Không làm việc trên main: Luôn tạo nhánh feature.
  • Cập nhật thường xuyên: Pull main trước khi tạo branch hoặc push.
  • Commit rõ ràng: Sử dụng thông điệp mô tả cụ thể.
  • Kiểm tra trước push: Chạy test, lint, format code.

Đối Với Team Leader:

  • Quy tắc nghiêm ngặt: Yêu cầu PR, review, và CI pass trước khi merge.
  • Giải quyết conflict cẩn thận: Liên hệ lập trình viên nếu cần.
  • Tự động hóa: Sử dụng CI/CD để giảm lỗi con người.
  • Theo dõi lịch sử: Đảm bảo lịch sử commit dễ hiểu và có thể truy vết.

Tránh Conflict:

  • Giao tiếp tốt: Thông báo khi merge hoặc push lên main.
  • Branch ngắn hạn: Merge nhánh feature sớm để tránh tích lũy thay đổi lớn.
  • Đồng bộ thường xuyên: Merge/rebase main vào nhánh feature trong quá trình phát triển.

Ví Dụ Thực Tế

Giả sử nhóm có 2 lập trình viên (Coder A, Coder B) và 1 Team Leader:

1. Coder A:

Tạo nhánh feature/login:

bash git checkout main
git pull origin main
git checkout -b feature/login

Viết mã, commit, push:

bash git add .
git commit -m "Thêm giao diện và API đăng nhập"
git push origin feature/login

Tạo PR trên GitHub.

2. Coder B:

Tạo nhánh feature/profile:

bash git checkout main
git pull origin main
git checkout -b feature/profile

Viết mã, commit, push:

bash git add .
git commit -m "Thêm giao diện hồ sơ người dùng"
git push origin feature/profile

Tạo PR.

3. Team Leader:

Xem xét PR feature/login:

Kiểm tra mã, chạy test, xác nhận CI pass.

Merge trực tiếp trên GitHub (squash and merge).

Xem xét PR feature/profile:

Phát hiện conflict ở main.dart.

Giải quyết:

bash git checkout main
git pull origin main
git checkout -b temp-merge-profile
git pull origin feature/profile
git merge main # Sửa conflict trong main.dart git add main.dart
git commit -m "Giải quyết conflict khi merge feature/profile"
git push origin temp-merge-profile

Tạo PR từ temp-merge-profile sang main và merge.

Xóa nhánh feature/loginfeature/profile.


Kết Luận

Quy trình Feature Branch Workflow kết hợp với các công cụ hiện đại (GitHub Actions, protected branches) giúp nhóm quản lý mã nguồn hiệu quả, giảm lỗi conflict, và đảm bảo chất lượng mã. Việc giao tiếp rõ ràng, sử dụng CI/CD, và tuân thủ quy tắc là chìa khóa để thành công.

Tham khảo thêm cách thức Git Flow trong teamwork:

Lead đẩy lên branch master ban đầu.

Các developer thực hiện:

  • Nếu thực hiện fix một tính năng nào đó, checkout 1 branch tên hotfix/, ví dụ hotfix/popup
  • Nếu thực hiện 1 feature mới, checkout branch với tên features/, ví dụ features/header
  • Nếu tiến hành release một tính năng, checkout branch với tên release/, thông thường là mã SHA (dạng v1.1.0), chẳng hạn: release/v1.1.0

Sau khi tạo branch, developer đẩy commit lên branch này.

Trong quá trình làm việc, Lead sẽ làm việc với các developer:

Giai đoạn 1: Sau khi hoàn thành tính năng và sẵn sàng để QA (thường đã qua 1 round QA của riêng developer đó), developer tạo pull-request để yêu cầu xác nhận. Trong quá trình này, Lead/QA Team sẽ review và cho feedback.

Giai đoạn 2: Developer thực hiện các bản fix nếu có. Quá trình sẽ bắt đầu deploy và test toàn bộ phần công việc trên staging.

Giai đoạn 3: Sau khi hoàn thành test trên staging, sẽ chuyên qua gửi yêu cầu merge-request:

Categories: Dev & DevOPS
Tags: , ,
X