Skip to main content

Comparisons

git submodule and git subtree are what Git offers for a library inside a monorepo. These pages run both side by side with git-splice, on the same library and monorepo, and show where each one's model gets in the way of fixing a library together with your app and sending the fix back. Each also says where it is the better tool.

  • git submodule: the monorepo doesn't see the library's files, every fix takes two commits and two pushes in the right order, and a second worktree has its own submodule clones but shares the monorepo's submodule.* settings for them.
  • git subtree: either the library's whole history comes into the monorepo, or split walks the monorepo's whole history on every push. Either way, the history isn't linear. A splice's sync point survives a squash merge, and a merge in the monorepo reaches the upstream as one commit.
git submodulegit subtreegit-splice
Library files in the monorepono, a gitlinkyesyes
status, diff, log of library filesstatus: never; diff, log -p: with --submodule=diff; log -- <file>: neveryesyes
Fix to app and librarytwo commits, two pushes, library firstone commitone commit
Library history in the monorepononewhole, or squashed into a mergenone, one commit per sync
Monorepo historylinearmergeslinear
Push walksnothing, the library is its own repositorythe monorepo's history since the last known library committhe commits since the boundary
Second worktreeinitialize again, submodule.* settings shared, can't be movedworksworks
Best forlibraries kept apart, with their own accessmoving a repository in for good, history includedchanging a library in the monorepo and sending the changes back

Third-party tools compares git-subrepo, Josh, splitsh-lite and Copybara.

The output is real​

As on every page with output, scrut runs the commands. Here scrut-setup.sh builds the library and the monorepo, and the work directory shows as $COMPARISON.