0

Lab 11 — Git Branching & Collaboration

1. Mục tiêu

Ở Lab 10, chúng ta đã biết workflow cơ bản:

Edit
 ↓
git add
 ↓
git commit
 ↓
git push

Nhưng trong thực tế, nhiều Developer/DevOps không thể cùng sửa trực tiếp main.

Một workflow phổ biến:

                 main
                  │
        ┌─────────┴─────────┐
        ▼                   ▼
 feature/login        feature/payment
        │                   │
        ▼                   ▼
      Commit              Commit
        │                   │
        └─────────┬─────────┘
                  ▼
             Pull Request
                  │
                  ▼
             Code Review
                  │
                  ▼
                main

Sau lab này, bạn sẽ hiểu:

  • Branch là gì.
  • Tạo/xóa/chuyển branch.
  • Merge.
  • Resolve conflict.
  • Rebase cơ bản.
  • Remote branch.
  • Pull Request.
  • Git workflow trong team.
  • Một số nguyên tắc Git thường dùng trong production.

2. Branch là gì?

Branch có thể hiểu đơn giản là:

Một dòng phát triển riêng của repository.

Ví dụ:

main
 │
 ├── feature/login
 │
 ├── feature/payment
 │
 └── fix/nginx

Thay vì tất cả cùng sửa:

main

mỗi người làm việc trên branch riêng.


3. Tại sao cần Branch?

Giả sử Developer A đang làm:

Login

Developer B đang sửa:

Payment

Nếu cả hai cùng commit vào main:

main
 │
 ├── login
 ├── payment
 ├── login
 ├── payment
 └── ...

rất khó kiểm soát.

Thay vào đó:

main
 │
 ├── feature/login
 │
 └── feature/payment

Mỗi người làm việc độc lập.

Sau khi hoàn thành:

feature/login
      │
      ▼
Pull Request
      │
      ▼
main

4. Kiểm tra Branch hiện tại

Trong repository Lab 10:

git branch

Ví dụ:

* main

Dấu * cho biết branch hiện tại.

Hoặc:

git status

có thể thấy:

On branch main

5. Tạo Branch

Tạo branch:

git branch feature/login

Kiểm tra:

git branch

Kết quả:

  feature/login
* main

Branch đã được tạo nhưng bạn vẫn đang ở main.


6. Chuyển Branch

Dùng:

git switch feature/login

Hoặc cách cũ:

git checkout feature/login

Hiện tại nên ưu tiên:

git switch

vì rõ nghĩa hơn.

Kiểm tra:

git branch
* feature/login
  main

7. Tạo và chuyển Branch cùng lúc

Thường dùng:

git switch -c feature/login

Tương đương:

git branch feature/login
git switch feature/login

Đây là command bạn sẽ dùng rất nhiều.


8. Thực hành Feature Branch

Tạo branch:

git switch -c feature/login

Tạo file:

echo "Login feature" > login.txt

Commit:

git add login.txt
git commit -m "feat: add login feature"

Kiểm tra:

git log --oneline

Bạn sẽ thấy commit mới.


9. Branch độc lập như thế nào?

Chuyển về:

git switch main

Kiểm tra:

ls

Bạn có thể thấy login.txt không tồn tại trên main.

Quay lại:

git switch feature/login
ls

login.txt xuất hiện.

Có thể hình dung:

main
 │
 └── README.md


feature/login
 │
 ├── README.md
 └── login.txt

Đây chính là sức mạnh của branch.


10. Merge

Khi feature hoàn thành:

feature/login
      │
      ▼
     main

Trước tiên chuyển về main:

git switch main

Sau đó:

git merge feature/login

Kiểm tra:

git log --oneline --graph

Feature đã được đưa vào main.


11. Hiểu đúng git merge

Ví dụ:

        B---C
       /
A-----D

Trong đó:

A = main
B,C = feature

Merge:

        B---C
       /     \
A-----D-------M

M là merge commit.

Không cần quá ám ảnh với việc nhớ graph.

Chỉ cần hiểu:

Merge kết hợp lịch sử của hai branch.


12. Fast-forward Merge

Nếu main không có commit mới:

main
 │
 A
 │
 B
 │
 C
feature

Merge có thể trở thành:

A → B → C

Không cần tạo merge commit.

Đây gọi là:

Fast-forward


13. Delete Branch

Sau khi merge:

git branch -d feature/login

Kiểm tra:

git branch

Branch local đã được xóa.

Thông thường chỉ nên xóa branch feature sau khi đã merge và không còn cần dùng.


14. Merge Conflict

Đây là phần rất quan trọng.

Giả sử main có:

Hello DevOps

Branch A sửa thành:

Hello Linux

Branch B sửa cùng dòng thành:

Hello Kubernetes

Khi merge, Git không biết chọn cái nào.

Conflict


15. Tạo Conflict

Tạo branch:

git switch -c feature/a

Sửa:

echo "Hello Linux" > conflict.txt

Commit:

git add conflict.txt
git commit -m "feat: add linux message"

Quay về main:

git switch main

Tạo file khác nội dung:

echo "Hello Kubernetes" > conflict.txt

Commit:

git add conflict.txt
git commit -m "feat: add kubernetes message"

16. Merge và tạo Conflict

Merge branch:

git merge feature/a

Git có thể báo:

CONFLICT

Kiểm tra:

git status

Git sẽ cho biết file conflict.


17. Conflict trông như thế nào?

Mở file:

<<<<<<< HEAD
Hello Kubernetes
=======
Hello Linux
>>>>>>> feature/a

Ý nghĩa:

<<<<<<< HEAD
Current branch
=======
Incoming branch
>>>>>>> feature/a

Bạn phải tự quyết định nội dung cuối cùng.

Ví dụ:

Hello DevOps

Xóa toàn bộ:

<<<<<<<
=======
>>>>>>>

chỉ giữ nội dung đúng.


18. Hoàn thành Conflict

Sau khi sửa:

git add conflict.txt

Sau đó:

git commit

Hoặc Git có thể mở editor để tạo merge commit.

Kiểm tra:

git status

Nếu:

nothing to commit

thì conflict đã được xử lý.


19. Workflow xử lý Conflict

Nhớ flow:

git merge
   │
   ▼
CONFLICT
   │
   ▼
git status
   │
   ▼
Sửa file
   │
   ▼
git add
   │
   ▼
git commit

Nếu không chắc file nào conflict:

git status

Đừng cố đoán. git status thường cho bạn biết chính xác Git đang chờ gì.


20. git merge --abort

Nếu conflict quá phức tạp và bạn muốn hủy merge:

git merge --abort

Repository quay lại trạng thái trước khi merge.

Đây là một command rất hữu ích khi bạn đang thử nghiệm.


21. Rebase là gì?

Ngoài merge, Git có:

git rebase

Ví dụ:

main:
A---B---C

feature:
     \
      D---E

Rebase:

A---B---C---D'---E'

Git lấy commit của feature và đặt lại trên đầu main.


22. Merge vs Rebase

Merge

A---B---C
     \
      D---E
           \
            M

Giữ lịch sử branch.

Rebase

A---B---C---D'---E'

Lịch sử tuyến tính hơn.

Có thể hiểu đơn giản:

Merge ưu tiên giữ lịch sử. Rebase ưu tiên lịch sử sạch, tuyến tính.


23. Khi nào dùng Rebase?

Ví dụ branch của bạn tồn tại vài ngày.

Trong thời gian đó main liên tục thay đổi:

main
A---B---C---D---E

feature
     \
      F---G

Bạn có thể cập nhật branch:

git fetch origin
git rebase origin/main

Kết quả:

A---B---C---D---E---F'---G'

Feature của bạn nằm trên code mới nhất.


24. Cẩn thận với Rebase

Một nguyên tắc quan trọng:

Không rebase branch mà nhiều người khác đang cùng sử dụng nếu bạn chưa hiểu rõ hậu quả.

Ví dụ:

Team
 │
 └── shared branch

Bạn rebase rồi force push có thể làm lịch sử của người khác bị thay đổi.

Đặc biệt tránh tùy tiện:

git push --force

Nếu bắt buộc force push, thường an toàn hơn:

git push --force-with-lease

25. Remote Branch

Khi push:

git push -u origin feature/login

Git tạo branch trên remote:

Local
feature/login
      │
      │ push
      ▼
Remote
feature/login

Kiểm tra:

git branch -a

Có thể thấy:

main
feature/login
remotes/origin/main
remotes/origin/feature/login

26. Checkout Remote Branch

Nếu branch đã tồn tại trên remote:

git fetch origin

Sau đó:

git switch feature/login

Nếu local branch chưa tồn tại, Git có thể tự tạo tracking branch tùy tình huống.

Cách rõ ràng:

git switch -c feature/login --track origin/feature/login

27. Pull Request

Trong môi trường team, thường không merge trực tiếp:

feature → main

Mà:

feature
   │
   ▼
Push
   │
   ▼
Pull Request
   │
   ▼
Code Review
   │
   ▼
CI
   │
   ▼
Approval
   │
   ▼
Merge

Pull Request thường dùng trên GitHub/GitLab/Azure DevOps.


28. Pull Request dùng để làm gì?

PR không chỉ để merge code.

Nó giúp team:

Code Review

Người khác kiểm tra:

Logic
Security
Performance
Style
Bug

CI

Pipeline tự động:

Build
Test
Lint
Security Scan

Audit

Có thể biết:

Ai tạo PR?
Ai approve?
Ai merge?
Khi nào?

Đây là lý do PR rất quan trọng trong production.


29. Một Git Workflow thực tế

Một workflow đơn giản:

main
 │
 ├── feature/login
 │
 └── feature/payment

Developer:

git switch main
git pull
git switch -c feature/login

Làm việc:

git add .
git commit -m "feat: add login"

Push:

git push -u origin feature/login

Sau đó tạo:

Pull Request

CI chạy:

Build
Test
Lint
Security Scan

Review:

Approve

Cuối cùng:

Merge → main

30. Không nên làm việc trực tiếp trên main

Không nên:

git switch main

# sửa code

git add .
git commit
git push

Trong project production, thường:

main
 ↓
feature branch
 ↓
Pull Request
 ↓
Review
 ↓
CI
 ↓
Merge

main nên được bảo vệ.


31. Branch Naming Convention

Không nên:

test
abc
new
fix
branch1

Nên:

feature/login
feature/payment
fix/nginx-timeout
fix/database-connection
chore/upgrade-node
docs/update-readme

Tên branch nên nói rõ mục đích.


32. Commit nhỏ và có ý nghĩa

Không nên làm:

feature/login
   │
   └── 50 files changed

với một commit:

update everything

Tốt hơn:

feat: add login API
test: add login tests
docs: document login API
fix: handle invalid credentials

Lợi ích:

Review dễ
Debug dễ
Rollback dễ
Cherry-pick dễ

33. git cherry-pick

Đây là command rất hữu ích.

Giả sử:

main
A---B---C

feature
     \
      D---E

Bạn chỉ muốn lấy D:

git cherry-pick <commit-id>

Kết quả:

main
A---B---C---D'

Dùng khi bạn muốn lấy một commit cụ thể thay vì merge toàn bộ branch.

Ví dụ thực tế:

Production
   │
   └── cần gấp một bug fix

Bạn có thể cherry-pick commit fix đó.


34. Challenge 1 — Feature Workflow

Tạo branch:

git switch main
git switch -c feature/monitoring

Tạo:

echo "Prometheus" > monitoring.txt

Commit:

git add monitoring.txt
git commit -m "feat: add monitoring configuration"

Push:

git push -u origin feature/monitoring

Sau đó tạo Pull Request.


35. Challenge 2 — Merge Conflict

Tạo:

feature/nginx
feature/docker

Cho cả hai branch sửa cùng một dòng trong:

config.txt

Sau đó:

git switch main
git merge feature/nginx

Tiếp tục:

git merge feature/docker

Xử lý conflict.

Mục tiêu:

CONFLICT
   ↓
git status
   ↓
Sửa
   ↓
git add
   ↓
git commit

36. Challenge 3 — Rebase

Tạo:

git switch -c feature/rebase

Tạo commit:

echo "Feature 1" >> rebase.txt
git add .
git commit -m "feat: add feature 1"

Quay về main và tạo commit mới:

git switch main
echo "Main change" >> main.txt
git add .
git commit -m "feat: update main"

Quay lại feature:

git switch feature/rebase

Thực hiện:

git rebase main

Xem graph:

git log --oneline --graph --all

Quan sát sự khác biệt giữa lịch sử trước và sau rebase.


37. Challenge 4 — Team Workflow

Mô phỏng hai Developer:

Developer A
    │
    └── feature/login

Developer B
    │
    └── feature/payment

Cả hai:

git switch main
git pull
git switch -c feature/...

Sau đó:

Developer A
   ↓
commit
   ↓
push
   ↓
Pull Request

Developer B
   ↓
commit
   ↓
push
   ↓
Pull Request

Cuối cùng merge cả hai vào main.

Mục tiêu là hiểu:

Mỗi feature có một branch và branch chỉ được merge thông qua workflow review/CI.


38. Những lỗi thường gặp

Quên branch hiện tại

Trước khi sửa:

git status

hoặc:

git branch

Đang ở sai branch

Ví dụ tưởng đang ở:

feature/login

nhưng thực tế:

main

→ Có thể commit nhầm vào main.


Pull trước khi làm việc

Trước khi tạo feature:

git switch main
git pull

Sau đó:

git switch -c feature/xxx

Giúp branch bắt đầu từ code mới nhất.


Merge conflict nhưng hoảng

Không cần xóa repository.

Làm:

git status

→ Xác định file conflict.

Sửa.

git add .
git commit

Nếu muốn bỏ merge:

git merge --abort

39. Một số command cần nhớ

Command Mục đích
git branch Xem branch
git switch Chuyển branch
git switch -c Tạo + chuyển branch
git merge Merge branch
git merge --abort Hủy merge
git rebase Rebase branch
git branch -d Xóa branch local
git push -u Push branch mới
git fetch Cập nhật remote refs
git cherry-pick Lấy một commit
git log --graph Xem lịch sử dạng graph

40. Git Workflow cần nhớ

Hãy ghi nhớ workflow này:

                 main
                  │
                  │ git pull
                  ▼
          git switch -c feature
                  │
                  ▼
               Coding
                  │
                  ▼
              git diff
                  │
                  ▼
              git add
                  │
                  ▼
             git commit
                  │
                  ▼
              git push
                  │
                  ▼
          Pull Request
                  │
             ┌────┴────┐
             ▼         ▼
          Review       CI
             │         │
             └────┬────┘
                  ▼
                Merge
                  │
                  ▼
                 main

41. Git trong môi trường DevOps

Sau này workflow sẽ không dừng ở:

Developer
   ↓
Git
   ↓
main

Mà trở thành:

Developer
    │
    ▼
Git Branch
    │
    ▼
Pull Request
    │
    ├── Code Review
    │
    └── CI
         │
         ├── Build
         ├── Test
         ├── Security Scan
         └── Docker Build
              │
              ▼
           Registry
              │
              ▼
             CD
              │
              ▼
         Kubernetes

Và khi học GitOps:

Git
 │
 │ Desired State
 ▼
ArgoCD
 │
 ▼
Kubernetes

Do đó, Git branching và collaboration không chỉ là kiến thức dành cho Developer. Đây là nền móng để bạn hiểu CI/CD, Azure DevOps, ArgoCD và GitOps ở các lab sau.


42. Checklist

Sau Lab 11, bạn cần trả lời được:

✓ Branch là gì?
✓ Tại sao không nên code trực tiếp trên main?
✓ git switch -c dùng để làm gì?
✓ Merge là gì?
✓ Fast-forward là gì?
✓ Merge conflict xảy ra khi nào?
✓ Xử lý conflict thế nào?
✓ git merge --abort dùng để làm gì?
✓ Rebase là gì?
✓ Merge và Rebase khác nhau thế nào?
✓ Remote branch là gì?
✓ Pull Request dùng để làm gì?
✓ git cherry-pick dùng để làm gì?
✓ Vì sao không nên tùy tiện git push --force?

Kết quả cuối cùng

Bạn cần thành thạo workflow:

main
 │
 ├── feature/xxx
 │       │
 │       ├── commit
 │       ├── commit
 │       └── push
 │
 └──────────────► Pull Request
                       │
                 Code Review
                       │
                      CI
                       │
                    Merge
                       │
                       ▼
                      main

Kinh nghiệm thực tế quan trọng nhất:

main nên là branch ổn định. Mọi thay đổi lớn nên đi qua feature branch → Pull Request → Review → CI → Merge.

Đây chính là workflow bạn sẽ gặp khi làm việc với Azure DevOps, GitHub/GitLab CI/CD và GitOps/ArgoCD.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí