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 statusthườ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:
mainnê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