Skip to main content

Scenario: nested-splices, three levels

Three upstreams nest: a splices b in at b/, as in the parent scenario, and b splices c in at c/. The monorepo has a at vendor/a/, so c is at vendor/a/b/c/.

  • Monorepo: a, with b and c in it, as their upstreams have them.
  • Upstreams: c has c seed; b has b seed and c spliced in; a has a seed and b spliced in.

As in spliced elsewhere, the monorepo pushes a change in c, and another monorepo splices a in. There, c's history up to the clone comes from an upstream above. But not from b's: b's .splice still names b's synced commit from before the change, since a push writes nothing to the monorepo, and b's upstream at that commit doesn't have it. a's upstream does. So the rebuild takes c's history from the splice above whose last pull is the newest, and on a tie, as here, from the outermost one: its upstream has the ones below too, at least as new as their own synced commits. Before, it took b's, made the change a new commit, and c read as diverged after its next change.

Output​

setup.bash builds this state:

$ build_scenario scenario_three_levels https://git.example.com/b.git https://git.example.com/c.git

The monorepo changes c and pushes all three, bottom-up:

$ echo "c local" >>vendor/a/b/c/file.txt && git commit -q -a -m "c local" && git splice push vendor/a/b/c vendor/a/b vendor/a
ok vendor/a/b/c: pushed 8dd94ad to main
ok vendor/a/b: pushed 50ab272 to main
ok vendor/a: pushed daa485c to main

b's .splice, as a's upstream has it now, still names b's commit from before the change:

$ git -C "$UPSTREAM" show main:b/.splice | git config --file - splice.commit | xargs git -C "$UPSTREAM-b.git" log -1 --format=%s
add c

Another monorepo splices a in​

$ git init -q -b main ../other && cd ../other && git commit -q --allow-empty -m "other monorepo"
$ git splice clone "$UPSTREAM" vendor/a && git splice fetch
=== vendor/a: fetching $UPSTREAM
ok vendor/a: cloned daa485c from main
ok vendor/a fetched
ok vendor/a/b fetched
ok vendor/a/b/c fetched

c is up to date, and its first change here is the only one to push:

$ echo "c other" >>vendor/a/b/c/file.txt && git commit -q -a -m "c other"
$ git splice status vendor/a/b/c
On branch main

ahead 1 vendor/a/b/c
$ git splice log vendor/a/b/c
=== vendor/a/b/c (main)
< 014dd58 c other (Other <other@example.com>)