Skip to main content

Scenario: clone-from-submodule

A submodule, turned into a splice with git splice clone --from-submodule.

  • Monorepo, on main: vendor/a/ is a submodule of the upstream, checked out at seed.
  • Upstream ($UPSTREAM, reached as https://git.example.com/a.git): seed, then newer on main: it moved on since the submodule's commit.

The splice keeps the submodule's URL and the commit it points to. What it follows from then on depends on the submodule's branch in .gitmodules, the branch git submodule update --remote follows:

branch in .gitmodulesThe submodule.splice recordsThe splice on main
none, as herestays at its commitdefault-pin <commit>stays at it (submodule-without-branch)
stablefollows stabledefault-branch stablefollows stable (submodule-with-branch)
.follows the branch named like the monorepo'sneitherfollows main (submodule-with-branch-dot)

Attributes above the submodule that change a checkout, such as line endings, never applied to its files. Where they would once it's a folder, the conversion refuses, and names the line that keeps them off: for those of the monorepo (monorepo-line-endings), or of a splice above it (line-endings-in-splice-above). A macro upstream's own .gitattributes defines would be lost, and no such line helps (upstream-macro).

Output​

setup.bash builds this state:

$ build_scenario scenario_clone_from_submodule https://git.example.com/a.git
$ cat .gitmodules
[submodule "vendor/a"]
path = vendor/a
url = https://git.example.com/a.git
$ git splice clone --from-submodule vendor/a
=== vendor/a: fetching https://git.example.com/a.git
ok vendor/a: cloned bde4164 from the submodule
=== vendor/a: pinned at bde4164, as the submodule was -- pull brings in nothing and push refuses on main until it follows a branch: git config --file vendor/a/.splice --unset upstream.origin.default-pin
=== vendor/a: the submodule's repository stays in .*/monorepo/\.git/modules/vendor/a -- remove it once you don't need it (regex)

One commit replaces the submodule with its files and a .splice, and removes it from .gitmodules, here the whole file:

$ git show --stat --format=%s
splice: clone vendor/a from submodule at bde4164

.gitmodules | 3 ---
vendor/a | 1 -
vendor/a/.splice | 6 ++++++
vendor/a/file.txt | 1 +
4 files changed, 7 insertions(+), 4 deletions(-)