Skip to content

Repository files navigation

mise config_roots: dotfiles composition cases

Fixture trees for the [bootstrap].config_roots dotfiles composition. Run:

./run.sh                          # uses `mise` from PATH
MISE_BIN=/path/to/mise ./run.sh   # any version; behavior per the table

Every case is a materialized tree under case*/. run.sh copies each into a throwaway sandbox (mktemp -d) and runs mise with an isolated HOME — nothing touches the real home. The script asserts the 2026.8.10 column of the table: on current mise it exits 0. Cases 1 and 3 guard the jdx/mise#12190 fix (they fail if the conflict returns), case 5 asserts the open bug (it fails when mise starts rejecting that collision — the fix detector), and 2, 4, 6 are controls pinning documented behavior.

case layout 2026.8.9 2026.8.10
1 two roots declare "~/.config/mise/" symlink-each, sources hold disjoint leaves bug: hard error conflicting dotfile declarations composes — fixed by jdx/mise#12190
2 same bundles, distinct targets composes composes
3 case 1 tree, mise bootstrap invoked from bundles/a bug: same hard error composes — the parent's config_roots is live in child invocations
4 two roots write managed blocks with distinct ids into one file merges, keyed by (path, id) merges, keyed by (path, id)
5 root a: directory copy whose source contains collide.txt; root b: whole-file copy at <dir>/collide.txt bug: silent last-wins bug (open): silent last-wins — no conflict; entries apply in glob order and b silently overwrites a's file; a's status reports differs forever; unapply --force from a removes both entries' files
6 two roots claim the same target with copy documented error conflicting dotfile declarations, both origins named same — documented on https://mise.jdx.dev/bootstrap.html

Case 5 reproduces identically on 2026.8.9 and 2026.8.10: the collision check has always been exact-path and never considered a directory entry's source footprint. #12190 (landed in 2026.8.10) fixed the same-target symlink-each conflict but did not close this gap — case 5 is not a regression from that fix.

The ask (case 5)

Two whole-path entries with identical targets are rejected before any mutation (case 6), and same-target symlink-each composes by disjoint leaf (case 1) — but nothing checks a directory entry's source footprint. When one root's directory copy contains a file that another root declares exactly, composition applies both and resolves the collision silently by config order — against the documented "Independent roots never acquire precedence from their order in config_roots".

Reject this footprint collision before any mutation, the way #12190 already does for same-target symlink-each leaves ("reject duplicate leaves and file/directory footprint collisions before any mutation") — or, if silent last-writer-wins is intended, document the nesting exception explicitly, including on https://mise.jdx.dev/dotfiles.html, whose modes table ("Directory copies are additive") currently reads as if such overlap is safe.

History

This repo originally reproduced the 2026.8.9 behavior of cases 1 and 3 (same-target symlink-each, disjoint leaves → hard error); jdx/mise#12190 fixed that in 2026.8.10 and those cases now serve as regression guards. Case 5, added later, was verified to reproduce on both versions. The discovering dotfiles repo migrated to per-bundle scoped copy targets (disjoint by construction); rendering one template next to a copied directory exposed case 5's shape.

About

Minimal repro: mise [bootstrap].config_roots composition errors on same-target symlink-each declarations with disjoint leaves (2026.8.9)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages