Git và GitHub cho lập trình viên Python

Bạn có thể viết Python rất giỏi, nhưng nếu không biết dùng Git và GitHub, bạn sẽ gặp khó khăn ngay khi bước vào môi trường làm việc thực tế. Mọi team phần mềm — từ startup nhỏ đến công ty lớn — đều dùng Git để quản lý code. GitHub là nơi lưu trữ, review và triển khai phần mềm trên toàn thế giới.
Bài viết này là hướng dẫn toàn diện dành riêng cho lập trình viên Python: từ cài đặt, lệnh cơ bản, branching, Pull Request, .gitignore, GitHub Actions CI, đến cách xây dựng portfolio thu hút nhà tuyển dụng.
1. Giới thiệu: Git, GitHub và tại sao Python developer cần học ngay
Git là gì?
Git là hệ thống quản lý phiên bản phân tán (Distributed Version Control System). Mỗi lần bạn thay đổi code, Git lưu lại một "snapshot" — gọi là commit — kèm thông tin ai sửa, sửa gì, và khi nào. Bạn có thể quay lại bất kỳ phiên bản nào trong quá khứ, so sánh thay đổi, hoặc thử nghiệm trên nhánh riêng mà không ảnh hưởng code chính.
GitHub là gì?
GitHub là nền tảng hosting code trên cloud, xây dựng trên Git. Ngoài lưu trữ, GitHub còn cung cấp:
- Pull Request (PR): Cơ chế review code trước khi merge.
- Issues: Theo dõi bug, feature request.
- GitHub Actions: CI/CD tự động chạy test, lint, deploy.
- GitHub Pages: Host website tĩnh miễn phí.
- Portfolio: Profile công khai cho nhà tuyển dụng xem.
Tại sao lập trình viên Python cần Git ngay từ đầu?
| Lý do | Giải thích |
|---|---|
| Khôi phục code | Undo khi làm hỏng file, xóa nhầm module |
| Làm việc nhóm | Nhiều người cùng sửa models.py mà không ghi đè |
| Theo dõi lịch sử | Biết commit nào gây bug trong api/routes.py |
| Code review | Senior review logic xử lý dữ liệu trước khi merge |
| CI/CD | Tự động chạy pytest mỗi khi push |
| Portfolio | GitHub profile là "CV sống" cho Python developer |
Lưu ý: Git học trên mọi ngôn ngữ, nhưng bài viết này tập trung vào workflow và cấu trúc project Python trên GitHub.
2. Cài đặt và cấu hình ban đầu
Cài Git
macOS: Git thường đã có sẵn. Kiểm tra bằng git --version. Nếu chưa có, cài qua Xcode Command Line Tools hoặc Homebrew:
brew install git
Windows: Tải Git for Windows — bao gồm Git Bash terminal.
Linux (Ubuntu/Debian):
sudo apt update && sudo apt install git
Cấu hình danh tính (chỉ làm một lần)
git config --global user.name "Nguyen Van A"
git config --global user.email "nguyenvana@email.com"
# Kiểm tra cấu hình
git config --list
Email nên trùng với email đăng ký GitHub để commit được gắn đúng profile.
Cấu hình editor và line ending
# Dùng VS Code làm editor mặc định khi commit
git config --global core.editor "code --wait"
# Windows: tránh lỗi line ending khi làm việc với macOS/Linux
git config --global core.autocrlf true # Windows
git config --global core.autocrlf input # macOS/Linux
Tạo tài khoản GitHub và kết nối SSH
- Đăng ký tại github.com.
- Tạo SSH key (khuyến nghị hơn HTTPS vì không cần nhập password mỗi lần push):
ssh-keygen -t ed25519 -C "nguyenvana@email.com"
# Nhấn Enter để dùng đường dẫn mặc định (~/.ssh/id_ed25519)
# Khởi động ssh-agent và thêm key
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
# Copy public key
cat ~/.ssh/id_ed25519.pub
- Vào GitHub → Settings → SSH and GPG keys → New SSH key → dán nội dung public key.
- Kiểm tra kết nối:
ssh -T git@github.com
# Kết quả mong đợi: "Hi username! You've successfully authenticated..."
Tạo repository Python đầu tiên trên GitHub
- GitHub → New repository → đặt tên
my-python-project. - Chọn Public, tick Add a README file.
- Clone về máy:
git clone git@github.com:username/my-python-project.git
cd my-python-project
3. Các lệnh Git cơ bản
Ba vùng làm việc của Git
Working Directory → Staging Area → Repository
(file đang sửa) (git add) (git commit)
- Working Directory: File bạn đang chỉnh sửa trên máy.
- Staging Area: File đã chọn để đưa vào commit tiếp theo.
- Repository: Lịch sử commit đã lưu vĩnh viễn.
Khởi tạo và commit
# Tạo repo mới trong thư mục hiện tại
git init
# Xem file nào đã thay đổi
git status
# Stage file cụ thể hoặc tất cả
git add src/main.py
git add tests/
git add . # Stage tất cả thay đổi
# Tạo commit với message mô tả
git commit -m "feat: thêm module xử lý CSV"
# Xem lịch sử commit
git log
git log --oneline --graph # Dạng compact, có biểu đồ nhánh
Xem và so sánh thay đổi
# So sánh working directory với staging area
git diff
# So sánh staging area với commit gần nhất
git diff --staged
# Xem nội dung file ở commit cụ thể
git show abc1234:src/main.py
Hoàn tác thay đổi
# Bỏ thay đổi chưa stage (cẩn thận — mất dữ liệu!)
git restore filename.py
# Unstage file (giữ thay đổi trong working directory)
git restore --staged filename.py
# Hoàn tác commit gần nhất, giữ thay đổi
git reset --soft HEAD~1
Làm việc với remote (GitHub)
# Thêm remote
git remote add origin git@github.com:username/my-python-project.git
# Xem remote đã cấu hình
git remote -v
# Push lần đầu (tạo tracking branch)
git push -u origin main
# Push các lần sau
git push
# Pull code mới từ GitHub
git pull origin main
# Fetch (tải về nhưng chưa merge)
git fetch origin
Clone và fork
# Clone project open source để học hoặc đóng góp
git clone https://github.com/pallets/flask.git
# Clone nhánh cụ thể
git clone -b develop git@github.com:username/project.git
4. Branching — Làm việc trên nhánh riêng
Branch (nhánh) cho phép phát triển tính năng mới song song mà không ảnh hưởng nhánh main ổn định.
Tạo và chuyển nhánh
# Xem danh sách nhánh
git branch
git branch -a # Bao gồm remote branches
# Tạo nhánh mới
git branch feature/user-auth
# Chuyển sang nhánh (cách cũ)
git checkout feature/user-auth
# Tạo và chuyển nhánh (cách mới, khuyến nghị)
git switch -c feature/user-auth
# Push nhánh mới lên GitHub
git push -u origin feature/user-auth
Quy ước đặt tên nhánh cho Python project
| Pattern | Ví dụ | Dùng khi |
|---|---|---|
feature/ | feature/jwt-auth | Tính năng mới |
fix/ | fix/csv-encoding-bug | Sửa bug |
refactor/ | refactor/database-layer | Tái cấu trúc code |
docs/ | docs/api-readme | Cập nhật tài liệu |
test/ | test/add-pytest-coverage | Thêm hoặc sửa test |
Merge nhánh
# Đảm bảo main đã cập nhật
git switch main
git pull origin main
# Merge nhánh feature vào main
git merge feature/user-auth
# Xóa nhánh local sau khi merge
git branch -d feature/user-auth
# Xóa nhánh trên GitHub
git push origin --delete feature/user-auth
Xử lý conflict khi merge
Khi hai người sửa cùng dòng code, Git báo merge conflict:
git merge feature/data-pipeline
# CONFLICT (content): Merge conflict in src/processor.py
Mở file conflict, bạn sẽ thấy:
<<<<<<< HEAD
def process(data):
return data.dropna()
=======
def process(data):
return data.fillna(0)
>>>>>>> feature/data-pipeline
Sửa thủ công, giữ code đúng, xóa marker <<<<<<<, =======, >>>>>>>, rồi:
git add src/processor.py
git commit -m "fix: resolve merge conflict in processor.py"
Rebase — Giữ lịch sử commit sạch
git switch feature/user-auth
git rebase main # Đặt commit của feature lên đầu main
# Nếu conflict, sửa xong rồi:
git add .
git rebase --continue
Quy tắc: Không rebase nhánh đã push và có người khác đang làm việc. Rebase phù hợp cho nhánh cá nhân trước khi tạo PR.
5. Pull Request workflow — Làm việc nhóm chuyên nghiệp
Pull Request (PR) là quy trình chuẩn trong team: bạn đề xuất merge thay đổi, đồng nghiệp review, rồi mới merge vào main.
Quy trình PR từ A đến Z
- Tạo Issue mô tả bug hoặc feature (ví dụ: "Thêm endpoint export CSV").
- Tạo branch từ
main:git switch -c feature/export-csv. - Code và commit thường xuyên với message rõ ràng.
- Push branch lên GitHub:
git push -u origin feature/export-csv. - Trên GitHub, nhấn Compare & pull request.
- Viết mô tả PR:
- Tóm tắt thay đổi.
- Link issue:
Closes #42. - Cách test:
pytest tests/test_export.py -v. - Screenshot nếu có thay đổi UI.
- Request review từ teammate.
- Nhận feedback → sửa → push thêm commit (PR tự cập nhật).
- Khi được approve → Squash and merge hoặc Merge pull request.
- Xóa branch sau khi merge.
Quy tắc commit message (Conventional Commits)
<type>: <mô tả ngắn gọn>
[body tùy chọn — giải thích chi tiết]
[footer — ví dụ: Closes #42]
Các type phổ biến:
| Type | Ý nghĩa | Ví dụ |
|---|---|---|
feat | Tính năng mới | feat: thêm API đăng nhập JWT |
fix | Sửa bug | fix: sửa crash khi CSV rỗng |
docs | Tài liệu | docs: cập nhật hướng dẫn cài đặt |
refactor | Tái cấu trúc | refactor: tách service layer |
test | Test | test: thêm unit test cho parser |
chore | Việc lặt vặt | chore: cập nhật requirements.txt |
Code review checklist cho Python
- Code có pass
flake8/ruffkhông? - Có unit test cho logic mới không?
- Type hints đã đầy đủ chưa?
- Có hardcode secret (API key, password) không?
- Docstring cho hàm public chưa?
- Performance: có N+1 query hoặc đọc file lớn vào RAM không?
Fork workflow (đóng góp open source)
Khi không có quyền write vào repo gốc:
- Fork repo trên GitHub (nút Fork góc phải).
- Clone fork về máy:
git clone git@github.com:yourname/flask.git. - Thêm upstream:
git remote add upstream git@github.com:pallets/flask.git. - Tạo branch, code, push lên fork.
- Tạo PR từ fork → repo gốc.
- Sync fork khi upstream cập nhật:
git fetch upstream
git switch main
git merge upstream/main
git push origin main
6. .gitignore cho Python — Không commit nhầm file rác
File .gitignore nằm ở root project, liệt kê pattern file/thư mục Git sẽ bỏ qua.
.gitignore chuẩn cho Python project
# Bytecode và cache
__pycache__/
*.py[cod]
*$py.class
*.so
# Virtual environment
.venv/
venv/
env/
.env/
# Environment variables — QUAN TRỌNG: không commit secret!
.env
.env.local
.env.*.local
# Distribution / packaging
*.egg
*.egg-info/
dist/
build/
eggs/
.eggs/
*.manifest
*.spec
# Testing
.pytest_cache/
.coverage
htmlcov/
.tox/
.nox/
# Jupyter Notebook
.ipynb_checkpoints/
*.ipynb_checkpoints
# IDE
.idea/
.vscode/
*.swp
*.swo
*~
# Database local
*.sqlite3
*.db
# Log files
*.log
logs/
# OS files
.DS_Store
Thumbs.db
# MyPy
.mypy_cache/
# Ruff
.ruff_cache/
Các lỗi thường gặp
| Lỗi | Hậu quả | Cách tránh |
|---|---|---|
Commit .env | Lộ API key, database password | Thêm .env vào .gitignore ngay từ đầu |
Commit venv/ | Repo phình to hàng trăm MB | Luôn ignore virtual environment |
Commit __pycache__/ | File binary vô nghĩa trong history | Dùng template Python .gitignore của GitHub |
| Commit dataset lớn | Push chậm, tốn dung lượng | Dùng Git LFS hoặc link download trong README |
Đã commit nhầm file? Gỡ khỏi Git nhưng giữ trên máy
# Gỡ file khỏi tracking, giữ file local
git rm --cached .env
git commit -m "chore: remove .env from tracking"
# Thêm vào .gitignore để không bị track lại
echo ".env" >> .gitignore
git add .gitignore
git commit -m "chore: add .env to gitignore"
Cảnh báo: Nếu đã push secret lên GitHub, coi như secret đã bị lộ. Rotate (đổi) key ngay lập tức, không chỉ xóa commit.
Cấu trúc project Python chuẩn trên GitHub
my-python-project/
├── .gitignore
├── .github/
│ └── workflows/
│ └── ci.yml
├── README.md
├── requirements.txt
├── pyproject.toml # Hoặc setup.py
├── src/
│ └── myapp/
│ ├── __init__.py
│ ├── main.py
│ └── utils.py
├── tests/
│ ├── __init__.py
│ └── test_main.py
├── docs/
│ └── api.md
└── LICENSE
7. GitHub Actions CI — Tự động test Python mỗi khi push
CI (Continuous Integration) chạy test, lint tự động mỗi khi có push hoặc PR — đảm bảo code broken không vào main.
CI workflow cơ bản với pytest
Tạo file .github/workflows/ci.yml:
name: Python CI
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.10', '3.11', '3.12']
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install pytest pytest-cov flake8
- name: Lint with flake8
run: |
flake8 src/ tests/ --max-line-length=120 --exclude=__pycache__
- name: Run tests with pytest
run: |
pytest tests/ -v --cov=src --cov-report=term-missing
- name: Upload coverage report
uses: codecov/codecov-action@v4
if: matrix.python-version == '3.12'
with:
fail_ci_if_error: false
CI nâng cao: thêm type checking và security scan
lint-and-security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- run: pip install ruff mypy bandit
- run: ruff check src/ tests/
- run: mypy src/ --ignore-missing-imports
- run: bandit -r src/ -ll
Badge trên README
Sau khi CI chạy thành công, thêm badge vào README:


Deploy tự động với GitHub Actions (bonus)
deploy:
needs: test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- name: Deploy to server
run: |
echo "Deploy script here — rsync, docker push, etc."
8. Xây dựng Portfolio trên GitHub
GitHub profile là thứ nhà tuyển dụng xem đầu tiên sau CV. Một profile chuyên nghiệp có thể quyết định bạn được gọi phỏng vấn hay không.
Profile README
Tạo repository cùng tên với username GitHub (ví dụ: github.com/nguyenvana/nguyenvana). README trong repo đó hiển thị trên profile.
# Xin chào, tôi là Nguyễn Văn A 👋
🐍 **Python Developer** | Data Analyst | Backend Engineer
Đam mê xây dựng ứng dụng Python hiệu quả, từ API backend đến pipeline phân tích dữ liệu.
## 🛠 Kỹ năng




## 📂 Projects nổi bật
| Project | Mô tả | Tech |
|---------|-------|------|
| [Sales Analytics](https://github.com/nguyenvana/sales-analytics) | Dashboard phân tích doanh số | pandas, Streamlit |
| [Library API](https://github.com/nguyenvana/library-api) | REST API quản lý sách | FastAPI, SQLAlchemy |
| [ML Churn Predictor](https://github.com/nguyenvana/churn-predictor) | Dự đoán khách hàng rời bỏ | scikit-learn |
## 📫 Liên hệ
- LinkedIn: [linkedin.com/in/nguyenvana](https://linkedin.com)
- Email: nguyenvana@email.com
README cho từng project — Template chuẩn
# Tên Project
Mô tả ngắn: project giải quyết vấn đề gì, cho ai.
## Tính năng
- Feature 1
- Feature 2
## Cài đặt
\`\`\`bash
git clone git@github.com:username/project.git
cd project
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
\`\`\`
## Sử dụng
\`\`\`bash
python -m src.main
# hoặc
uvicorn src.app:app --reload
\`\`\`
## Test
\`\`\`bash
pytest tests/ -v
\`\`\`
## Cấu trúc thư mục
\`\`\`
project/
├── src/
├── tests/
└── requirements.txt
\`\`\`
## License
MIT
Dự án nên có trên portfolio Python
- Web API (FastAPI hoặc Django REST) — CRUD, authentication, test.
- Data Analysis — Jupyter Notebook + visualization + insight rõ ràng.
- Automation/CLI tool — Script giải quyết vấn đề thực tế.
- ML project — End-to-end: EDA → train → evaluate → README giải thích.
- Open source contribution — Ít nhất 1-2 merged PR vào project có stars.
Pin repository và GitHub Stats
- Pin tối đa 6 repo tốt nhất lên profile (Settings → Profile → Pin).
- Bật GitHub Achievements bằng cách commit đều đặn.
- Dùng github-readme-stats để hiển thị thống kê (tùy chọn).
Đóng góp open source — Bắt đầu từ đâu?
| Repo | Lý do phù hợp beginner |
|---|---|
| good-first-issue | Issue được tag sẵn cho người mới |
| flask | Codebase Python sạch, cộng đồng lớn |
| fastapi | Modern Python, tài liệu tốt |
| scikit-learn | ML, nhiều issue documentation |
9. Lệnh Git nâng cao hữu ích
Stash — Cất thay đổi tạm thời
# Đang code dở, cần switch branch gấp
git stash
git switch hotfix/urgent-bug
# ... sửa xong ...
git switch feature/my-feature
git stash pop # Lấy lại thay đổi đã cất
Cherry-pick — Lấy commit cụ thể
# Lấy commit abc1234 từ nhánh khác sang nhánh hiện tại
git cherry-pick abc1234
Git blame — Ai sửa dòng nào?
git blame src/parser.py
git blame -L 10,30 src/parser.py # Chỉ xem dòng 10-30
Git bisect — Tìm commit gây bug
git bisect start
git bisect bad # Commit hiện tại có bug
git bisect good v1.0.0 # Tag/commit cũ chạy tốt
# Git checkout commit giữa, bạn test và đánh dấu good/bad
git bisect good # hoặc git bisect bad
# Lặp cho đến khi tìm ra commit gây bug
git bisect reset
Interactive rebase — Sửa lịch sử commit
# Gộp 3 commit gần nhất thành 1
git rebase -i HEAD~3
# Trong editor: đổi "pick" thành "squash" cho commit muốn gộp
Git tags — Đánh dấu phiên bản release
git tag -a v1.0.0 -m "Release version 1.0.0"
git push origin v1.0.0
# Xem tất cả tags
git tag -l
Git worktree — Làm việc trên nhiều nhánh song song
# Checkout nhánh khác vào thư mục riêng, không cần stash
git worktree add ../hotfix-workspace hotfix/urgent-bug
Alias hữu ích
git config --global alias.st status
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.lg "log --oneline --graph --all"
10. Tài nguyên học tập
Miễn phí — Khuyến nghị học theo thứ tự
- Git Handbook (GitHub) — Đọc trong 30 phút, nắm khái niệm cốt lõi.
- Learn Git Branching — Học branching qua game tương tác, có tiếng Việt.
- Atlassian Git Tutorial — Chi tiết, có diagram trực quan.
- GitHub Skills — Học qua thực hành trực tiếp trên GitHub.
- Pro Git (Scott Chacon) — Sách miễn phí, có bản tiếng Việt.
Khóa học video
- freeCodeCamp — Git and GitHub for Beginners: YouTube, ~1.5 giờ, thực hành từ đầu.
- Git & GitHub Crash Course (Traversy Media): Ngắn gọn, đi thẳng vào thực hành.
Thực hành mỗi ngày
- Tạo repo cho mỗi bài tập Python — quen commit thường xuyên.
- Tham gia Hacktoberfest (tháng 10) — đóng góp open source có cấu trúc.
- Dùng Git cho mọi project cá nhân, kể cả script nhỏ.
- Review PR của người khác trên GitHub — học cách viết code sạch.
Cheat sheet nhanh
| Tình huống | Lệnh |
|---|---|
| Bắt đầu project mới | git init → git add . → git commit |
| Đẩy lên GitHub | git remote add origin URL → git push -u origin main |
| Tạo tính năng mới | git switch -c feature/ten |
| Cập nhật code mới nhất | git pull origin main |
| Xem ai sửa file | git blame filename.py |
| Cất code tạm | git stash → git stash pop |
11. FAQ — Câu hỏi thường gặp
Git và GitHub khác nhau thế nào?
Git là phần mềm quản lý phiên bản chạy trên máy bạn. GitHub là dịch vụ online lưu trữ repo Git, thêm tính năng collaboration. Tương tự: Git = engine, GitHub = garage có thêm camera an ninh và hệ thống mời bạn bè.
Nên dùng HTTPS hay SSH?
SSH khuyến nghị cho hàng ngày — không cần nhập password/token mỗi lần push. HTTPS tiện khi SSH bị chặn (một số mạng công ty). Cả hai đều an toàn nếu cấu hình đúng.
Commit bao nhiêu lần là đủ?
Commit thường xuyên, mỗi commit là một thay đổi logic hoàn chỉnh. Ví dụ: thêm hàm xử lý CSV → 1 commit. Sửa bug encoding → 1 commit riêng. Tránh commit cả ngày làm việc trong 1 commit khổng lồ.
main hay master?
GitHub mặc định dùng main từ 2020. Repo cũ có thể còn master. Cả hai đều là nhánh chính — quan trọng là team thống nhất tên.
Lỡ push secret (API key) lên GitHub thì sao?
- Rotate key ngay — tạo key mới, vô hiệu key cũ.
- Xóa file khỏi Git history bằng
git filter-repohoặc BFG Repo Cleaner. - Dùng GitHub Secret Scanning để được cảnh báo.
- Phòng ngừa: luôn dùng
.env+.gitignore, không hardcode secret.
Merge commit, Squash merge, Rebase merge — chọn cái nào?
| Cách | Khi nào dùng |
|---|---|
| Merge commit | Giữ nguyên lịch sử, phù hợp team lớn |
| Squash merge | Gộp tất cả commit PR thành 1 — history sạch |
| Rebase merge | Commit thẳng hàng, không tạo merge commit |
Team Python thường dùng Squash merge cho PR feature, giữ main gọn gàng.
Tôi mới học Python, có cần học Git ngay không?
Có. Học song song từ tuần đầu. Mỗi bài tập Python, hãy git init và commit. Thói quen này tiết kiệm hàng trăm giờ sau này.
Làm sao để GitHub profile nổi bật với nhà tuyển dụng?
- 4-6 repo chất lượng > 50 repo tutorial copy.
- Mỗi repo có README rõ ràng, CI badge xanh, test pass.
- Commit đều đặn (green squares trên contribution graph).
- 1-2 đóng góp open source thực sự (merged PR).
Kết luận
Git và GitHub không chỉ là công cụ kỹ thuật — chúng là kỹ năng nền tảng định hình cách bạn làm việc chuyên nghiệp với Python. Từ quản lý phiên bản cá nhân, hợp tác qua Pull Request, tự động hóa test với GitHub Actions, đến xây dựng portfolio thu hút nhà tuyển dụng — tất cả bắt đầu bằng git init.
Hành động ngay hôm nay:
- Tạo GitHub account (nếu chưa có).
git initcho project Python bạn đang học.- Tạo
.gitignorechuẩn Python. - Commit và push lên GitHub.
- Thêm GitHub Actions CI chạy
pytest.
Mỗi dòng code Python bạn viết từ hôm nay — hãy để Git theo dõi.