Bài 01
Git hằng ngày: clone, commit, branch, gitignore
Bài 01 — Git hằng ngày: clone, commit, branch, gitignore
Bạn vừa được nhận vào team. Sếp bảo "clone repo, làm task, push lên". Bạn đã từng git commit -m "fix" đại khái — nhưng chưa chắc làm đúng. Bài này gói 90% Git mà DevOps gõ hằng ngày.
Mental model — đủ để hiểu, không thừa
Git lưu snapshot của code, mỗi snapshot có 1 SHA hash 40 ký tự.
3 khu vực phải biết:
Working dir → Staging → Repo (.git) → Remote
(edit) (git add) (git commit) (git push)Branch = con trỏ trỏ vào 1 commit. Không phải "thư mục code". Tạo/xoá branch = tạo/xoá file 41 byte. Đây là toàn bộ lý thuyết bạn cần.
Hệ quả: xoá branch không xoá commit. Commit vẫn còn trong .git, chỉ mất con trỏ. Reflog (Bài 03) sẽ tìm lại.
Setup 1 lần
git config --global user.name "Tên Bạn"
git config --global user.email "ban@example.com"
# Pull mặc định rebase — history sạch hơn
git config --global pull.rebase true
# Branch mặc định khi init repo mới
git config --global init.defaultBranch mainSSH key cho GitHub/GitLab:
ssh-keygen -t ed25519 -C "ban@example.com"
cat ~/.ssh/id_ed25519.pub
# Paste vào GitHub: Settings → SSH and GPG keys → New SSH keyTest:
ssh -T git@github.com
# Hi <username>! You've successfully authenticated...Workflow hằng ngày — 6 bước
# 1. Clone (lần đầu) hoặc pull (sau)
git clone git@github.com:org/repo.git
cd repo
# (lần sau) git pull
# 2. Tạo branch cho task
git switch -c feat/add-login
# 3. Edit code, xem trạng thái
git status
# 4. Stage + commit
git add file1.js file2.js # add file cụ thể
# hoặc git add . # add hết (cẩn thận file lạ)
git commit -m "feat(auth): add login form"
# 5. Push (lần đầu cần -u, sau đó push thuần)
git push -u origin feat/add-login
# 6. Tiếp tục commit, push
git commit -am "feat(auth): handle errors" # -a: auto add file đã track
git push-u (set-upstream) chỉ cần lần đầu. Sau đó git push không argument.
Commit message: Conventional Commits
Format:
type(scope): subjectTypes hay dùng:
feat:tính năng mớifix:sửa bugchore:việc lặt vặt (deps, config)docs:chỉ docrefactor:refactor không đổi behaviorci:CI/CD
Ví dụ:
feat(auth): add JWT refresh token
fix(payment): handle null response from gateway
chore(deps): bump terraform to 1.6.0Đừng viết: fix, update, wip, asdf. 6 tháng sau chính bạn không hiểu commit của mình làm gì.
Atomic commit: 1 commit = 1 ý đồ. Đừng gộp "fix bug + format code + thêm feature" vào 1 commit. Khi cần revert hoặc bisect (Bài 03), bạn sẽ cảm ơn bản thân.
Xem history & diff
git log --oneline -20 # 20 commit gần nhất
git log --oneline --graph --all # cây nhánh
git log --author="Hung" # commit của ai
git log -p file.js # lịch sử 1 file kèm diff
git diff # working vs staging
git diff --staged # staging vs commit cuối
git diff main..feat/login # khác biệt 2 branch
git diff HEAD~3 # so với 3 commit trướcHọc git log --oneline --graph --all cho thuộc — lệnh xem thiên hạ đang làm gì.
Branch — gọn, ngắn ngày
git branch # local
git branch -a # cả remote
git switch main # chuyển nhánh
git switch -c feat/x # tạo + chuyển
git branch -d feat/x # xoá nếu đã merge (an toàn)
git branch -D feat/x # xoá force (cẩn thận, mất commit)
git push origin --delete feat/x # xoá branch trên remoteQuy ước đặt tên (chọn 1, dùng nhất quán):
feat/short-desc— tính năngfix/issue-x— bughotfix/critical— khẩn cấpchore/update-deps— vặt
Tránh: temp, test, my-branch, hung-branch. Không scale.
Branch sống ≤ 5 ngày. Feature lớn → split nhỏ. Branch sống 2 tuần = mega conflict khi merge (Bài 02).
Cleanup định kỳ:
# Fetch + xoá local ref của branch đã xoá ở remote
git fetch --prune
# Xoá branch local đã merge
git branch --merged main | grep -v main | xargs -r git branch -d.gitignore — cài ngay từ commit đầu tiên
Quan trọng nhất: không bao giờ commit secret. .gitignore template gọn cho DevOps:
# Secrets
.env
.env.*
*.key
*.pem
credentials*
# Dependencies
node_modules/
.venv/
__pycache__/
*.pyc
# Build / artifact
dist/
build/
# IDE
.vscode/
.idea/
.DS_Store
# Terraform / IaC
*.tfstate
*.tfstate.backup
.terraform/Test xem file có bị ignore không:
git check-ignore -v .env
# .gitignore:2:.env .envLỡ commit secret rồi
git rm --cached .env # gỡ tracking, giữ file local
echo ".env" >> .gitignore
git commit -m "chore: stop tracking .env"⚠️ History vẫn còn secret. Bot scan GitHub liên tục tìm AWS key, GitHub token. Quy trình đúng:
- Rotate secret NGAY. Coi như đã leak. Disable AWS key, tạo cái mới, update vào secret manager.
- (Tuỳ chọn) Rewrite history:
pip install git-filter-repo git filter-repo --path .env --invert-paths --force git push --force --all - Notify team pull lại.
Câu chuyện thực tế
Tháng 3/2024, intern mới lỡ commit .env chứa AWS_ACCESS_KEY_ID lên repo private. 6 tiếng sau, AWS bill nhảy từ $50 → $2000/ngày — bot scan tìm thấy key, launch 50 EC2 GPU đào crypto.
Action: disable key, terminate instance, rotate, rewrite history. AWS sau refund vì là fraud, nhưng 4 tiếng sự cố lúc 11h đêm.
Bài học: .gitignore từ commit ĐẦU TIÊN. Pre-commit hook (gitleaks, detect-secrets) chặn tự động — đừng tin discipline cá nhân (Bài 03 setup hook).
Lab — chạy thử
mkdir /tmp/git-daily && cd /tmp/git-daily
git init
# .gitignore từ đầu
cat > .gitignore <<EOF
.env
*.key
node_modules/
EOF
echo "# Project" > README.md
git add . && git commit -m "chore: initial commit"
# Workflow
git switch -c feat/greeting
echo 'echo "Hello"' > hello.sh
git add hello.sh
git commit -m "feat(greeting): add hello script"
# Edit thêm
echo 'echo "World"' >> hello.sh
git diff
git commit -am "feat(greeting): add world line"
# Atomic: 2 thay đổi không liên quan → 2 commit
echo "Hello world" >> README.md
echo 'echo "Bye"' >> hello.sh
git add README.md
git commit -m "docs: update readme"
git add hello.sh
git commit -m "feat(greeting): add bye line"
# Xem history
git log --oneline --graph --all
# Test gitignore
echo "secret123" > .env
git status
# .env không xuất hiện trong "Untracked files" — đã ignorePitfalls — chốt lại
git add .lúc đang edit nhiều thứ → add nhầm secret/build. Add file cụ thể hoặc dùnggit add -p(interactive, chọn từng đoạn).- Commit message "fix", "wip" → vô dụng cho future you và teammate. Dùng Conventional Commits.
- Branch sống quá lâu → conflict tệ. ≤ 5 ngày, sync main mỗi ngày (Bài 02).
- Commit
.envdù 1 lần → rotate ngay, không "private repo nên an toàn". -Dthay vì-dkhi xoá branch chưa merge → mất commit. Dùng-dmặc định,-Dchỉ khi chắc chắn.
Tóm tắt
- Setup 1 lần: name, email,
pull.rebase=true, SSH key. - Workflow: clone → branch → edit → add → commit → push (
-ulần đầu). - Commit: Conventional Commits format, atomic (1 ý đồ).
- Branch ngắn ngày, naming rõ ràng,
-dmặc định. .gitignoretừ commit đầu. Lỡ commit secret → rotate ngay.
Bài tiếp: 02 — Làm việc team: merge, rebase, conflict, PR, GitFlow vs Trunk-based.