Sau Bài 11 tự động hoá quy trình, bài áp chót của series xoay quanh 2 công cụ nhỏ nhưng dùng hàng ngày: tag — đánh dấu vĩnh viễn 1 commit làm mốc release, và alias/config — cá nhân hoá cách gõ lệnh Git cho riêng bạn.

1. Lightweight vs Annotated Tag

git tag v1.0 tạo 1 lightweight tag — về bản chất giống hệt branch, chỉ là 1 con trỏ trỏ thẳng tới 1 commit, khác biệt duy nhất là nó không bao giờ tự di chuyển theo commit mới. Không có object nào khác được tạo ra.

git tag -a v1.1 -m "Release 1.1" tạo 1 annotated tag — Git tạo hẳn 1 tag object mới (loại object thứ 4 bên cạnh blob/tree/commit đã học ở Bài 1), lưu tagger, ngày tháng, message, và tuỳ chọn chữ ký GPG. Ref v1.1 trỏ tới tag object này, rồi tag object đó mới trỏ tiếp tới commit — thêm 1 tầng gián tiếp so với lightweight tag.

Lightweight tag Annotated tag
Lưu trong object database? Không — chỉ 1 ref trỏ thẳng tới commit Có — tạo 1 tag object riêng, ref trỏ tới object đó
Metadata (tagger/ngày/message) Không có Đầy đủ
Có thể ký GPG? Không Có (-s)
Dùng khi nào Đánh dấu tạm, mốc cá nhân Release chính thức, cần lưu vết ai/khi nào/vì sao
ℹ️ Tag không tự di chuyển như branch
Khác với branch — luôn cập nhật theo commit mới nhất — tag trỏ cố định vào đúng 1 commit tại thời điểm tạo. Muốn gán lại tag cho commit khác phải xoá rồi tạo lại (git tag -f), và thao tác này nên tránh với tag đã publish vì nó thay đổi ý nghĩa của 1 mốc mà người khác có thể đã dựa vào.
🕳️ Cạm bẫy thường gặp: git push KHÔNG tự đẩy tag lên remote
Mặc định, git push chỉ đẩy commit/branch — tag được tạo cục bộ vẫn nằm im trên máy bạn. Phải dùng git push --tags (đẩy tất cả) hoặc git push origin <tên-tag> (đẩy đúng 1 tag) để đồng nghiệp/CI thấy được release bạn vừa đánh dấu.

2. Semantic Versioning & Quy Ước Tag Release

Chuẩn Semantic Versioning đặt tên tag theo vMAJOR.MINOR.PATCH (VD v2.4.1): tăng MAJOR khi có breaking change, MINOR khi thêm tính năng tương thích ngược, PATCH khi chỉ sửa lỗi. Annotated tag gần như luôn được dùng cho các mốc này, vì CI/CD và changelog tự động thường dựa vào chính message + ngày tháng lưu trong tag object.

Sân chơi tương tác: Tag Comparison Visualizer

Tạo cả 2 loại tag trên cùng 1 lịch sử commit và quan sát khác biệt trực quan: lightweight tag là 1 pill gắn thẳng vào commit, annotated tag có thêm 1 "hộp object" riêng phía trên, nối xuống commit.

🏷️ Sân chơi tương tác: Tag Comparison Visualizer

Terminal giả lập

  • git commit -m "..."
  • git tag <tên> (lightweight)
  • git tag -a <tên> -m "..." (annotated)
  • git tag (liệt kê)
  • git show <tên>
  • git tag -d <tên>

Nhật ký

git-tags-live.js

3. git alias: Rút Gọn Lệnh Dài

git config --global alias.co checkout đăng ký git co như 1 shortcut cho git checkout — lưu vào file ~/.gitconfig (toàn cục, áp dụng mọi repo trên máy bạn) dưới mục [alias]. Alias có thể nhận thêm tham số phía sau y hệt lệnh gốc, ví dụ git co main chạy đúng git checkout main.

4. git config: Tuỳ Biến Hành Vi Mặc Định

Ngoài alias, git config còn chỉnh được hành vi lõi: core.editor (trình soạn message commit), pull.rebase true (mặc định pull dùng rebase thay vì merge, xem lại Bài 9), init.defaultBranch (tên branch mặc định khi init)... Mọi cấu hình này đều nằm trong cùng file ~/.gitconfig (hoặc .git/config nếu chỉ áp dụng 1 repo, dùng --local thay --global).

🔬 Đào sâu: alias có thể gọi cả script shell
Nếu giá trị alias bắt đầu bằng dấu !, Git hiểu đó là 1 lệnh shell đầy đủ thay vì 1 subcommand Git — ví dụ git config --global alias.amend '!git commit --amend --no-edit'. Điều này cho phép ghép nhiều lệnh Git (hoặc cả lệnh hệ điều hành) thành 1 alias duy nhất, vượt xa khả năng của alias "rút gọn subcommand" thông thường.
💡 Mẹo: vài config phổ biến đáng thiết lập ngay
git config --global core.editor "code --wait" (dùng VS Code viết message commit), git config --global pull.rebase true (lịch sử tuyến tính khi pull, xem lại Bài 9), và git config --global init.defaultBranch main (đồng bộ tên branch mặc định với quy ước hiện đại).

Sân chơi tương tác: Alias Builder

Ghép 1 lệnh Git dài thành alias ngắn, rồi thử gõ lại bằng alias đó — xem Git "mở rộng" alias thành lệnh gốc trước khi thực thi, và quan sát file ~/.gitconfig cập nhật theo thời gian thực.

⚙️ Sân chơi tương tác: Alias Builder

Terminal giả lập

  • git config --global alias.<tên> <lệnh gốc>
  • git status / git branch
  • git checkout <tên>
  • git log --oneline --graph --all
  • git <alias-của-bạn> [tham số]

Nhật ký

git-alias-live.js

Trắc nghiệm ôn tập

Câu 1: Khác biệt CỐT LÕI giữa lightweight tag và annotated tag là gì?

Trắc nghiệm ôn tập

Câu 2: Sau khi tạo tag cục bộ bằng git tag v1.0, điều gì cần làm để đồng nghiệp thấy được tag đó trên remote?

Trắc nghiệm ôn tập

Câu 3: git config --global alias.co checkout lưu cấu hình này ở đâu?

📖 Tài liệu tham khảo / References

Bài viết liên quan trong series

Bài 13: Dự Án — Git Kata Trainer Bài 11: Hooks & Worktree Quay lại Lộ trình Series Git