Git Submodules: link đến commit cụ thể của repo khác, lưu trong .gitmodules.
git submodule add https://github.com/org/shared-lib libs/shared
# .gitmodules lưu URL + path
# Clone cần: git clone --recursive hoặc git submodule update --initVấn đề thực tế của submodules:
- git clone không tự clone submodules — newbies hay quên --recursive
- Update submodule: phải cd vào, pull, cd ra, commit .gitmodules update
- Detached HEAD state thường xuyên trong submodule directory
- CI/CD phức tạp hơn
- "Why does the build fail?" → submodule pointer pointing to deleted commit
Git Subtree: copy code vào subdirectory, không có reference to external repo.
git subtree add --prefix libs/shared https://github.com/org/shared-lib main --squash
git subtree pull --prefix libs/shared https://github.com/org/shared-lib main --squashVấn đề subtree: merge history phức tạp, git log prefix cần, push changes ngược lại upstream khó.
Tại sao hầu hết teams tránh cả hai:
Như là monorepo tool: npm workspaces, Nx, Turborepo tốt hơn nhiều. Như là dependency: publish package lên npm/private registry. Như là vendor code: copy + commit (vendor) đơn giản và transparent hơn.
Git LFS là giải pháp cho binary assets — tốt hơn submodules cho design files, videos.
Git Submodules: links to a specific commit of another repo, stored in .gitmodules.
git submodule add https://github.com/org/shared-lib libs/shared
# .gitmodules stores URL + path
# Cloning requires: git clone --recursive or git submodule update --initReal-world submodule problems:
- git clone does not auto-clone submodules — beginners forget --recursive
- Updating a submodule: cd in, pull, cd out, commit .gitmodules update
- Frequent detached HEAD state inside submodule directories
- CI/CD becomes more complex
- "Why does the build fail?" → submodule pointer pointing to a deleted commit
Git Subtree: copies code into a subdirectory with no reference to an external repo.
git subtree add --prefix libs/shared https://github.com/org/shared-lib main --squash
git subtree pull --prefix libs/shared https://github.com/org/shared-lib main --squashSubtree problems: complex merge history, need --prefix in git log, pushing changes upstream is difficult.
Why most teams avoid both:
For monorepo tooling: npm workspaces, Nx, Turborepo are far better. For dependencies: publish to npm/private registry. For vendored code: copy + commit (vendoring) is simpler and more transparent.
Git LFS is the right solution for binary assets — better than submodules for design files and videos.