Hands-On: Submodule and Worktree

Updated

October 30, 2026

Hands-On: A Repo with a Submodule and a Worktree

Two small Git repos on Linux, then a worktree of the parent.

Child library

mkdir -p ~/desk/desk-lib
cd ~/desk/desk-lib
git init
echo "DESK_LIB=1" > version.txt
git add version.txt
git commit -m "chore: desk-lib version pin"

Parent with submodule

cd ~/desk/desk-api
git submodule add ~/desk/desk-lib src/desk-lib
git status
git commit -m "chore: add desk-lib submodule"
ls src/desk-lib/version.txt

Worktree of the parent

git worktree add ~/desk/desk-api-wt -b feat/wt-lab
cd ~/desk/desk-api-wt
git status
echo "worktree lab" >> README.md
git add README.md
git commit -m "docs: worktree lab"
cd ~/desk/desk-api
git log --oneline feat/wt-lab -1

main in ~/desk/desk-api does not have that commit until you merge.

Cleanup

cd ~/desk/desk-api
git worktree remove ~/desk/desk-api-wt
git switch main
git merge --ff-only feat/wt-lab
git branch -d feat/wt-lab

Leave the submodule in place for later chapters, or remove it:

git rm src/desk-lib
git commit -m "chore: remove desk-lib submodule"
rm -rf ~/desk/desk-lib

Removing the submodule does not delete ~/desk/desk-lib unless you rm -rf it.

Done when

  • git worktree list shows only the main tree
  • You know whether src/desk-lib is still a gitlink (git ls-files -s src/desk-lib shows mode 160000) or is gone

Next: Git Flow, GitHub Flow, trunk-based — how teams name these branches on purpose.