Theory

Updated

October 30, 2026

Theory: Submodules Pin a Hash; Worktrees Share an Object Store

A submodule is a second repository whose current commit is recorded in the parent as a gitlink (mode 160000). A worktree is a second working directory for the same repository: one .git, several checkouts, one branch per worktree.

Invariants

  1. The superproject stores a URL (.gitmodules) and a gitlink hash, not the child’s files as blobs.
  2. git clone of the parent does not fetch submodule objects unless --recurse-submodules / submodule update --init.
  3. Two worktrees cannot check out the same branch (indexes would fight).
  4. Worktree .git is a file pointing at the main repo’s worktrees/ metadata.
  submodule                         worktrees

  desk-api tree                     ~/desk-api        HEAD → main
    src/desk-lib → gitlink 9fce     ~/desk-api-hf     HEAD → hotfix
  desk-lib repo  A ← 9fce                 \              /
                                           shared objects/refs

Why not always submodule

If two projects always change together, you are paying pin-and-update tax for a monorepo’s job. If they have separate release cycles, the pin is the feature.

What can break

  • Committing in a submodule and forgetting to push it (parent points at a hash nobody has).
  • Detached HEAD in the submodule by default after update.
  • rm -rf a worktree directory without git worktree remove.

How to read this chapter

Mechanics, worktrees, when to use which, lab; then foreach/sync, deinit, locks.