Scenario: after-pull
A pull merged local commits that were never pushed. The pull's commit is
the newest that changed .splice, but the rebuild starts further back,
at B: the newest such commit whose folder is the upstream commit it
recorded, U(B)
(sync model). The commits are
named as in the drawing there.
Output
setup.bash builds this state:
$ build_scenario scenario_after_pull
The monorepo:
$ git log --format=%s
e
d
c
b
a
initial commit
$ git -C "$UPSTREAM" log --format='%h %s' main
df79a48 n
d34c417 m
5ba0fc7 l
ae8b31f k
U(H)
e is the newest commit that changed .splice. It records n as U(H):
$ git log --first-parent -1 --format=%s -- lib/.splice
e
$ git log -1 --format='%h %s' "$(git config --file lib/.splice splice.commit)"
df79a48 n
B
But e's folder isn't n: it has b's and d's files too, which the upstream lacks. A rebuild starting at e would send them as one commit, under e's message:
$ git diff --stat "$(git config --file lib/.splice splice.commit)" HEAD:lib -- ':!.splice'
b.txt | 1 +
d.txt | 1 +
2 files changed, 2 insertions(+)
So the rebuild goes back to the commit before e that changed .splice.
All of them, newest first:
$ git log --first-parent --format=%s -- lib/.splice
e
a
a's folder is the commit it recorded, k. It's HEAD~4:
$ k="$(git config --blob 'HEAD~4:lib/.splice' splice.commit)" &&
> git diff --quiet "$k" HEAD~4:lib -- ':!.splice' &&
> echo "a's folder is k"
a's folder is k
So a is B, what git splice boundary prints, and U(B) = k:
$ git log -1 --format=%s "$(git splice boundary lib)"
a
The commits since B that change the folder are the ones the rebuild copies, newest first:
$ git log --first-parent --format=%s "$(git splice boundary lib)"..HEAD -- lib
e
d
b
R
From B, the rebuild copies b and d on top of U(B) = k, as b' and d', and
skips c. Then it copies e as e', a merge of d' and n, with e's message.
log --graph draws R and T down to n, where they meet. k shows up as
the parent of b':
$ git splice log --graph lib
=== lib (main)
< 8430dba (R) e (Test <test@example.com>)
|\
< | d4da194 d (Test <test@example.com>)
< | 9ec734f b (Test <test@example.com>)
o | ae8b31f k (Test <test@example.com>)
/
o df79a48 (T) n (Test <test@example.com>)
After the push
The push sends b', d' and e', and T moves to e':
$ git splice push lib
ok lib: pushed 8430dba to main
A pull right after it has nothing to bring in, and leaves .splice as it
was. So B is still a: every rebuild still walks from a, and rebuilds b',
d' and e' with the same hashes.
$ git splice pull lib
ok lib fetched
ok lib: nothing to pull
$ git log -1 --format=%s "$(git splice boundary lib)"
a
After a bump
git splice pull --bump records e' as U(H), in a new commit:
$ git splice pull --bump -m f lib
ok lib fetched
ok lib: bumped the synced commit to 8430dba
Its folder is e', so it's the new B, U(B) = e', and rebuilds start there (pushed draws this state):
$ git log -1 --format=%s "$(git splice boundary lib)"
f