Skip to main content

Splice identity

Git has no such thing as a splice id. git-splice writes one into each .splice it creates, because it needs to recognize a splice when its path can't identify it. That matters in three situations.

A move carries the commits along​

git mv changes a splice's path. Here commit m moves vendor/a/ to libs/a/, and .splice, with the id in it, moves along:

$ git mv vendor/a libs/a &&
> git commit -q -m "m: reorganize folders"
$ git show --summary --format=%s HEAD
m: reorganize folders

rename {vendor => libs}/a/.splice (100%)
rename {vendor => libs}/a/file.txt (100%)

Commit b changed the splice before the move and wasn't pushed yet. It still belongs to the splice, so a push follows the id back to the old path:

After the move m: the monorepo commits a, b and m, where m is H and a is B; in the lane libs/a/, R is b prime on top of k, and m has no copy

$ git splice log libs/a
=== libs/a (main)
< e859a6b local change (Test <test@example.com>)

Where a .splice is new at a path, or has another id, and no move explains it, the splice's history starts there. Nothing older is published (scenario).

Same id, same splice​

Two paths with the same id are one splice in two places, mirrors. Splices with different ids can move independently, even when they hold the same library at different versions:

In the monorepo, app-1/lib/ and app-2/lib/ both have id 224f and lib v2: they are mirrors, meant to stay alike. old-app/lib/ has id a841 and lib v1: it is independent and may differ

When mirrors have different files, they have drifted, and that's something to fix. Mirrors shows how that happens.

A repeated id exposes a cycle​

With nesting, a .splice with the same id as one above it means a splice contains itself. The id is what makes that visible, though nothing refuses it yet (cycle).

What an id is​

An id names a splice. It names neither a path nor an upstream:

What happensThe id
clone or initis new, even for an upstream another splice already uses
git mv of the splicemoves along with .splice
a new URL, or another upstreamstays
cp -r of the splice, or a nested .splice reaching the monorepo twiceis copied: now two paths have it

Each clone is a new splice​

$ git splice clone https://git.example.com/a.git vendor/a
=== vendor/a: fetching https://git.example.com/a.git
ok vendor/a: cloned bde4164 from main
$ cat vendor/a/.splice
[splice]
id = 224f2c2563d3b6f7
commit = bde416459fbcc09c9b585f3b65a94cab3f68bfcd
[upstream "origin"]
url = https://git.example.com/a.git

A second clone of the same upstream, at the same commit, gets another id:

$ git splice clone https://git.example.com/a.git libs/a
=== libs/a: fetching https://git.example.com/a.git
ok libs/a: cloned bde4164 from main
$ git grep 'id = ' -- '*/.splice' | tr '\t' ' '
libs/a/.splice: id = a841bb3c200928e9
vendor/a/.splice: id = 224f2c2563d3b6f7

The two share the upstream's fetched refs (upstreams), and nothing else.

Read more​