Submodules let you include other repositories inside your project while keeping them separate.
Overview
Use submodules when you need to:
Include a library as a subdirectory
Share code between projects
Pin external dependencies to specific versions
Keep separate repositories for components
Commands
Add Submodule
wit submodule add < ur l > < pat h >
Example:
wit submodule add https://github.com/lib/utils.git vendor/utils
This:
Clones the repository to vendor/utils
Records the submodule in .witmodules
Stages the changes
Initialize Submodules
After cloning a repo with submodules:
This registers submodules from .witmodules.
Update Submodules
Fetch and checkout the recorded commits for all submodules.
Combined initialize and update:
wit submodule init
wit submodule update
# Or in one command
wit submodule update --init
Status
Output:
a1b2c3d vendor/utils (v1.2.3)
e5f6g7h vendor/logger (heads/main)
+i9j0k1l vendor/config (modified)
Prefix Meaning (none) Checked out at recorded commit +Different commit than recorded -Not initialized UHas merge conflicts
Run Command in Submodules
wit submodule foreach < comman d >
Examples:
# Install dependencies in all submodules
wit submodule foreach "npm install"
# Pull latest in all submodules
wit submodule foreach "wit pull"
# Check status
wit submodule foreach "wit status"
Configuration File
Submodules are recorded in .witmodules:
[submodule "vendor/utils"]
path = vendor/utils
url = https://github.com/lib/utils.git
branch = main
[submodule "vendor/logger"]
path = vendor/logger
url = https://github.com/lib/logger.git
Workflow
Adding a Submodule
# Add the submodule
wit submodule add https://github.com/org/lib.git libs/mylib
# Commit the addition
wit commit -m "Add mylib submodule"
Cloning a Repo with Submodules
# Clone the main repo
wit clone https://github.com/org/project.git
# Initialize and update submodules
cd project
wit submodule init
wit submodule update
Updating a Submodule
# Enter the submodule
cd vendor/utils
# Pull latest changes
wit pull
# Go back to main repo
cd ../..
# Commit the update
wit add vendor/utils
wit commit -m "Update utils submodule"
Removing a Submodule
# Remove from index and config
wit submodule deinit vendor/utils
wit rm vendor/utils
# Commit the removal
wit commit -m "Remove utils submodule"
Directory Structure
my-project/
├── .wit/
├── .witmodules # Submodule configuration
├── src/
├── vendor/
│ ├── utils/ # Submodule (its own .wit)
│ │ ├── .wit/
│ │ └── src/
│ └── logger/ # Another submodule
│ ├── .wit/
│ └── src/
└── package.json
Use Cases
Shared Libraries
# Add your shared library
wit submodule add git@github.com:company/shared-ui.git packages/shared-ui
# Use in your code
import { Button } from './packages/shared-ui' ;
Pinned Dependencies
# Add at specific version
wit submodule add https://github.com/lib/framework.git vendor/framework
cd vendor/framework
wit checkout v2.1.0
cd ../..
wit commit -m "Pin framework to v2.1.0"
Multi-repo Project
project/
├── frontend/ # submodule: git@company:frontend.git
├── backend/ # submodule: git@company:backend.git
├── shared/ # submodule: git@company:shared.git
└── deploy/ # main repo scripts
Best Practices
Always commit submodule updates When you update a submodule, commit the change to the parent: wit add vendor/lib
wit commit -m "Update lib to v2.0"
Use branches for tracking In .witmodules, specify a branch: [submodule "vendor/lib"]
branch = main
Be careful with submodule changes Changes inside a submodule must be committed there first, then recorded in the parent.
Troubleshooting
Run init and update: wit submodule init
wit submodule update
Submodule has modifications
Either commit them in the submodule: cd vendor/lib
wit commit -am "Fix bug"
Or discard: cd vendor/lib
wit restore .
Can't push submodule changes
Ensure you have push access to the submodule’s repository, then push from within the submodule: