Upstreams
What a splice's upstream is, how it relates to the refs under
refs/splices/<key>/, and what it means when two splices of one
upstream are at different versions.
- Upstream (
$UPSTREAM):seed. The monorepo reaches it ashttps://git.example.com/s.git, and ashttps://mirror.example.com/s.gittoo. - Monorepo: one commit, no splice yet.
What an upstream is
A splice's .splice names its upstream like a Git remote:
[upstream "origin"] with a url. It can name more than one, e.g. a
company fork and the original; default-upstream then says which one
commands use unless --upstream names another
(several-upstreams). The
synced commit U(H) stays one per splice: a sync point is a commit,
whichever upstream it came from.
The monorepo knows an upstream by its URL. The first command that
fetches it gives it a key, a short name recorded in the repository's
config, and fetches its branches to refs/splices/<key>/. So:
| is one per | |
|---|---|
.splice, id, synced commit U(H) | splice |
key, refs/splices/<key>/*, fetch | upstream URL, shared by every splice that names it |
splice-refs shows what each command does to
those refs, and splice-identity what
the id names.
Output
setup.bash builds this state:
$ build_scenario scenario_upstreams
Two splices, one upstream
Two apps each get their own copy of a shared library, s. Each clone is
a splice of its own. (It would be the same if each app were a splice
with s nested in it, as in
nested-splices.)
$ git splice clone https://git.example.com/s.git app-a/s
=== app-a/s: fetching https://git.example.com/s.git
ok app-a/s: cloned bde4164 from main
$ git splice clone https://git.example.com/s.git app-b/s
=== app-b/s: fetching https://git.example.com/s.git
ok app-b/s: cloned bde4164 from main
$ cat app-a/s/.splice | tr '\t' ' '
[splice]
id = 45beeb39c3270eb1
commit = bde416459fbcc09c9b585f3b65a94cab3f68bfcd
[upstream "origin"]
url = https://git.example.com/s.git
The upstream has one key, and one set of refs:
$ git config --get-regexp '^splice\.'
splice.s.url https://git.example.com/s.git
$ git splice key app-a/s && git splice key app-b/s
s
s
$ git for-each-ref --format='%(objectname:short) %(refname)' refs/splices
bde4164 refs/splices/s/main
fetch fetches each upstream once, and reports for every splice of it:
$ seed_bare_repo "$UPSTREAM" "upstream change"
$ git splice fetch
ok app-a/s fetched (main moved bde4164..6045a98)
ok app-b/s fetched (main moved bde4164..6045a98)
One library at two versions
Only app a pulls the new version:
$ git splice pull app-a/s
ok app-a/s fetched
ok app-a/s: pulled 6045a98
$ git splice status
On branch main
behind 1 app-b/s
up to date app-a/s
$ git grep 'commit = ' -- '*/.splice' | tr '\t' ' '
app-a/s/.splice: commit = 6045a986b5afb475cd0af0caf6bb622db918a25b
app-b/s/.splice: commit = bde416459fbcc09c9b585f3b65a94cab3f68bfcd
app-a/s/ and app-b/s/ were cloned separately, so they have different
ids: they're independent
(splice identity). That
they're at different versions is fine, e.g. while app a tries the new
one first, and status reports app b's only as behind its upstream. If
both apps should always share one version, the two need to be mirrors,
with the same id. Then a difference is drift, which git-splice
doesn't report yet (mirrors).
Whether two splices differ is a matter of their files, or R in the sync model, not of their synced commits U(H). A push doesn't move U(H), so a splice that pushed a change is at an older U(H) than a copy that pulled it, with the same files (diamond).
One repository, two URLs
A URL is what the monorepo compares, not the repository behind it. The same repository under another URL, e.g. a mirror, or SSH instead of HTTPS, is another upstream to the monorepo, with a key and refs of its own:
$ git splice clone https://mirror.example.com/s.git app-c/s
=== app-c/s: fetching https://mirror.example.com/s.git
ok app-c/s: cloned 6045a98 from main
$ git config --get-regexp '^splice\.'
splice.s.url https://git.example.com/s.git
splice.mirror.example.com-s.url https://mirror.example.com/s.git
$ git splice key app-c/s
mirror.example.com-s
So comparing URLs couldn't tell that app-c/s/ splices the same
repository as the others. A splice can name both URLs as two upstreams,
but they stay two upstreams, each with a key of its own: git-splice
doesn't take them for copies of one repository.
How this compares with a package manager's names, versions and lockfile: package managers.