Git hooks và submodules
Git Hooks and Submodules
Hai tính năng nâng cao này phục vụ hai nhu cầu khác nhau: hook để tự động hóa kiểm tra quanh các thao tác Git, còn submodule để nhúng một repo vào trong repo khác.
Git hooks là gì
Git hook là các script Git tự chạy khi một sự kiện xảy ra. Chúng nằm trong thư mục .git/hooks/; chỉ cần đặt file thực thi đúng tên là hook kích hoạt.
| Hook | Chạy khi | Dùng để |
|---|---|---|
pre-commit | Trước khi tạo commit | Lint, format, chạy test nhanh, chặn secret |
commit-msg | Sau khi nhập message | Ép định dạng message (vd. conventional commits) |
pre-push | Trước khi push lên remote | Chạy full test suite, chặn push lỗi |
post-merge | Sau khi merge | Tự cài lại dependency khi lockfile đổi |
# Ví dụ .git/hooks/pre-commit
#!/bin/bash
npm run lint || exit 1 # exit khác 0 sẽ HỦY commit
Hook trả về exit code khác 0 sẽ chặn thao tác (vd. pre-commit fail thì commit bị hủy).
Hook không tự chia sẻ qua Git
Thư mục .git/hooks/ không được commit, nên hook không tự đến với cả team. Giải pháp phổ biến là dùng công cụ như Husky (cho Node.js) hoặc pre-commit framework để lưu cấu hình hook trong repo và cài tự động.
Hook chỉ là tuyến phòng thủ đầu
Hook chạy ở máy local nên dev có thể bỏ qua bằng --no-verify. Đừng coi hook là cổng bảo mật duy nhất — luôn lặp lại các kiểm tra quan trọng trong CI/CD ở phía server.
Submodules là gì
Submodule cho phép nhúng một repo Git khác vào một thư mục con của repo hiện tại, mà vẫn giữ lịch sử riêng. Repo cha chỉ ghi nhớ submodule đang trỏ tới đúng một commit cụ thể.
# Thêm submodule
git submodule add https://github.com/org/shared-lib libs/shared
# Sau khi clone repo cha, kéo nội dung submodule về
git submodule update --init --recursive
# Cập nhật submodule lên commit mới nhất của nó
git submodule update --remote
Khi git submodule add, Git tạo file .gitmodules (lưu URL và đường dẫn) và ghi commit hash của submodule vào repo cha.
Khi nào nên dùng submodule
- Nên dùng khi cần ghim một thư viện/repo dùng chung ở một phiên bản cố định, và muốn giữ lịch sử của nó tách biệt.
- Cân nhắc thay thế bằng package manager (npm, pip...) hoặc monorepo khi chỉ cần phụ thuộc thông thường — submodule khá phiền: dễ quên
--init, dễ commit nhầm con trỏ.
Submodule dễ gây bối rối
Sau khi clone repo có submodule, nếu quên git submodule update --init thì thư mục submodule rỗng. Mọi người trong team phải nhớ bước này, nếu không sẽ build hỏng.
Trọng tâm thi
Hook = script tự chạy theo sự kiện Git (pre-commit chặn commit xấu, pre-push chặn push lỗi); nằm trong .git/hooks, không tự chia sẻ, bỏ qua được bằng --no-verify. Submodule = repo lồng trong repo, repo cha ghim một commit; nhớ git submodule update --init sau khi clone.
Tóm tắt
- Git hooks là script tự chạy theo sự kiện:
pre-commit,commit-msg,pre-push,post-merge... exit khác 0 sẽ chặn thao tác. - Hook nằm trong
.git/hooks, không commit theo repo — dùng Husky/pre-commit framework để chia sẻ cho team. - Hook chỉ là tuyến phòng thủ đầu (bỏ qua được bằng
--no-verify) — vẫn cần kiểm tra ở CI/CD. - Submodule nhúng một repo vào repo khác, repo cha ghim đúng một commit; file
.gitmoduleslưu cấu hình. - Sau clone phải
git submodule update --init --recursive; cân nhắc package manager nếu chỉ cần phụ thuộc thường.