Mirrors
Mirrors are folders with
the same splice id, meant to have the same files.
git-splice doesn't act on that yet: each splice is pulled and pushed on
its own, and compared only with its own upstream. This page says what
mirrors would need, what of it is possible, and what can be done
meanwhile.
Where mirrors come from
- A copy in the monorepo, e.g.
cp -r vendor/a vendor/a-copy. - One nested splice, reached twice. If the upstream at
b/splices in the one ata/, which has a library nested atl/, then the monorepo hasa/l/andb/a/l/, with the same id: the one the upstream ofa/gave the library when it cloned it. The monorepo copied nothing.
Not from separate clones: if the monorepo and two of its upstreams each clone the same library, the three copies have three ids, and are independent (diamond). To declare them mirrors, a clone would need to take over the id of an existing splice. There's no command for that yet.
Because of nesting, mirrors can't be forbidden or forced to stay alike:
b/a/l/ belongs to the upstream of b/, and may lag behind a/l/
because that upstream has an older version of the one at a/. The
monorepo can't change that alone. Refusing duplicate ids would refuse
diamonds of that shape.
Nor can the rebuild tell mirrors apart.
What would be desired, and what's possible
| Desired | Status |
|---|---|
| Mirrors are stored once | Already so. Git stores identical files as one object, and identical folders as one tree (diamond). |
| A report of mirrors that drifted, with how to resolve it | Possible, not implemented: compare the folders of splices with the same id, without .splice. |
| A fork or a new version made from a copy is pointed out | Possible in part, not implemented: a copy that names another upstream than its mirrors. A new URL also keeps the id when the upstream moved, so it's a warning, not an error. |
| A pull of one mirror pulls the others | Possible for copies in the monorepo, not implemented. Not for a nested copy that another upstream owns. |
| Mirrors never differ | Impossible. Nested copies can differ for reasons the monorepo can't change. |
| Mirrors share one folder: an edit in one is an edit in all | Impossible with Git. A symlink commits a link, not files: an app's own repository would get a link that points outside of it, and a checkout without symlink support gets a text file with the link's target. And a link is a reference: the copies could never differ, not even while you work. Mirrors are values, which are alike at sync points. |
| Mirrors take disk space once | Impossible in Git's checkout, which writes every file. A file system with copy-on-write, e.g. btrfs, XFS or APFS, can share the blocks of identical files that stay separate files. |
Meanwhile: discipline
What git-splice can't do yet, a team can do by hand. A report wouldn't
take that over, only point at it: it names the mirrors that differ and
how to resolve the difference. For a mirror that's only behind, that's a
plain pull, which anyone can check. Where both changed, the pull
merges, and the difference left is for someone to resolve. That fits the design's principles: refuse rather than
guess, and make the state explicit
(design).
-
Edit one copy, e.g. the top-level
s/in the diamond. -
Push it, and pull every mirror right away, as the diamond's round trip does.
-
Compare mirrors before merging, e.g. in CI. Their folders, without
.splice, have the same tree:git diff --quiet HEAD:vendor/a HEAD:vendor/a-copy -- ':!.splice'(scenario shows it with real output.)
-
Clone, don't copy, a version of its own, so it gets an id of its own (scenario).