My thinking was fuzzy in regards to what’s wrong with git submodules. So I finally opened up an editor window and started typing how I think an Ideal Submodule System should work. I wound up with this:
The subproject is copied into the super-project’s repo. At least a snapshot of it, if not the entire history. It’s a fact of life external resources have a habit of disappearing — this helps makes your project resilient.
git clone foo is enough. None of this
git clone --recursive foo or
git submodule init && git submodule update business.
Can easily pull subproject updates.
Can easily push subproject updates.
Can easily handle super-project branching.
Super-project’s commits don’t wind up in subproject’s history.
Subproject’s commits don’t wind up in super-project’s history.
Armed with clearer thinking, I reexamined my options and have settled on Avery Pennarun’s git-subtree.
Unfortunately its CLI UX is lacking (you have to specify the subproject’s entire remote repo URL each time you pull or push) and Avery hasn’t accepted pull requests or budged the project for a year. Fortunately Helmo forked Avery’s repo, added
.gittrees support and
pull-all subcommands, and generally seems to be keeping on top of pull requests and moving the project forward.
I just started using
git-subtree, but so far it’s making my life better than before.
P.S. Here’s a short primer on using git-subtree.
Update: Hmm, I discovered and turned to Helmo’s fork after I got tired of reentering my remote repo URL each time I wanted to push or pull a subtree. Turns out Helmo’s fork is currently unstable — the tests don’t pass and there’s a definite bug in it when adding a repo as a subtree that doesn’t show up until you attempt push it back. So I recommend using Avery’s original repo until it’s fixed.
Update 2: I fixed the bug and tests are passing in my git-subtree fork.
git subtree push-all away!