Skip to content

feat(config): add config.override.toml so global config can override project config - #14610

Merged
jdx merged 4 commits into
mainfrom
config-override-file
Oct 17, 2026
Merged

jdx merged 4 commits into
mainfrom
config-override-file

Conversation

@jdx

@jdx jdx commented Oct 17, 2026 •

Copy link
Copy Markdown
Owner

https://entire.io/gh/jdx/mise/trails/833

A project's mise.toml or mise.local.toml always beats your global config, so a repo can replace the node version, an env var like AWS_PROFILE, or a setting you chose for yourself. The only escape hatch today is the special-case settings.env_file. This adds a global-only override file that outranks all project config for any section.

# ~/.config/mise/config.override.toml
[env]
AWS_PROFILE = "personal"

[tools]
node = "24"

[settings]
jobs = 8

[tasks.lint]
run = "my-lint --strict"

In any project, AWS_PROFILE, the node request, jobs and the lint task now come from this file, even when the project's mise.toml or mise.local.toml sets them. Anything the override file does not mention still comes from the project and your other global config.

Behavior

  • Files: config.override.toml and config.<env>.override.toml in the global config dir (MISE_ENV variants follow the usual order, later envs win). The env-specific file beats the base override file, and the whole tier ranks above every project file, including mise.<env>.toml and mise.local.toml. It is not MISE_OVERRIDE_CONFIG_FILENAMES, which only renames the files mise reads.
  • All sections: [env], [tools], [tasks], [settings] (applied during settings load, not afterwards), hooks, etc. fall out of the same ordered merge.
  • Global config: the files are trusted by path and get global-config safe-mode treatment, so the paranoid-mode _.file/_.source operator-owned check also covers them.
  • Never a default write target. mise use, mise set, mise settings set, mise trust/untrust, mise unuse (first declaring config), mise config get|set default and the --global existing-declaration lookups skip it. Writing needs an explicit long-only --override flag (with --env selecting config.<env>.override.toml) on use, unuse, set, unset, settings set|add|unset and config get|set. It conflicts with --global and --path (--local for settings).
  • Lockfiles: a tool declared in the override file shadows the project's pin. It resolves from the global mise.lock, never from the project's mise.lock, and --locked does not require the project lock to pin it. Other tools are still enforced.
  • MISE_GLOBAL_CONFIG_FILE means "this is the only global config", so no override files load and --override errors.
  • Visibility: mise config ls adds a Tier column (override) when an override file is loaded, mise config ls --json gains "override": true|false, and mise doctor labels the files.
$ mise config ls
~/proj/mise.toml                     (none)
~/proj/mise.local.toml               (none)
~/.config/mise/config.override.toml  (none)  override

settings.env_file is unchanged.

Testing

New e2e tests cover env/tools/tasks/settings precedence over project config (including mise.<env>.toml and mise.local.toml), the MISE_ENV variant order, --override writes and conflicts, that default writes and trust/unuse never touch the file, the lockfile rule (checked by mutation: it fails without the --locked exemption), and MISE_GLOBAL_CONFIG_FILE. Docs: a new "Global override files" section in the configuration page. cargo clippy --workspace --all-features --all-targets -- -D warnings is clean. cli/test_doctor and cli/test_unuse fail in this sandbox on unmodified main too (empty-PATH doctor, a system jq).

AI-assisted β€” Tool: Claude Code; model: anthropic/claude-sonnet-5-5; version: 2.1.299.

πŸ€– Generated with Claude Code


Note

Medium Risk
Changes config merge order, default write targets, and lockfile/--locked semantics across many commands; mistakes could surprise users who rely on project pins or implicit file selection.

Overview
Adds global override files (config.override.toml and config.<env>.override.toml under ~/.config/mise) that load above all project config, including mise.local.toml, for env, tools, settings, tasks, and other merged sections.

Override files are never chosen by default for writes or implicit targets (mise use, mise set, mise unuse, trust, default config get|set, etc.). A new --override flag (conflicts with --global / --path / --local where applicable) targets those files; with --env it writes config.<ENV>.override.toml. MISE_GLOBAL_CONFIG_FILE disables the whole override tier and makes --override error.

Lockfile behavior: tools declared in an override file shadow the project pin, resolve against the global mise.lock, and are exempt from project --locked enforcement; other tools stay locked as before.

Visibility: mise config ls adds a Tier column when overrides are loaded; JSON output includes "override": true; mise doctor annotates override paths. Docs, usage specs, and e2e tests cover precedence, writes, conflicts, and lockfile rules. Minor Cargo.toml metadata tweak (removed homepage).

Reviewed by Cursor Bugbot for commit e648a76. Bugbot is set up for automated code reviews on this repo. Configure here.

Summary by CodeRabbit

  • New Features
    • Added global config.override.toml files, which take precedence over project configuration. Environment-specific overrides use config.<ENV>.override.toml.
    • Added --override options to select override files when reading or changing configuration, tools, settings, and tasks.
    • mise config ls and mise doctor now identify override files.
  • Documentation
    • Updated command references and configuration guidance to explain override precedence and file selection.

…m global config

Global config normally loses to project config. `config.override.toml` and
`config.<env>.override.toml` in the global config directory form a tier that
outranks all project config, including mise.<env>.toml and mise.local.toml, for
every section ([env], [tools], [tasks], [settings], hooks, ...).

- The override files are global config (trusted by path) but sit outside the
  base global set, so default write targets are unchanged.
- `--override` writes to them from `use`, `unuse`, `set`, `unset`,
  `settings set|add|unset` and `config get|set`; it conflicts with `--global`
  and `--path`.
- Tools declared there resolve from the global lockfile and are exempt from
  `--locked`; other tools are still enforced.
- `MISE_GLOBAL_CONFIG_FILE` disables the tier.
- `mise config ls` and `mise doctor` label the tier.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Entire-Checkpoint: 01M55GZWRK273EFFQ993Q07CK8
@coderabbitai

coderabbitai Bot commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack β†’

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 1 minute.

Check out review usage here.

View limit details

Limit details: You’ve used all 10 included reviews currently available.

Learn how review limits work.

Review configuration:

βš™οΈ Run configuration
  • Configuration used: Repository YAML (base), Central YAML (inherited), Organization UI (inherited)
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: fb7a9335-abca-4a18-bca8-906a05c51c9a
πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between 2e227af and e648a76.

πŸ“’ Files selected for processing: 37
  • Cargo.toml
  • docs/cli/config/get.md
  • docs/cli/config/ls.md
  • docs/cli/config/set.md
  • docs/cli/set.md
  • docs/cli/settings.md
  • docs/cli/settings/add.md
  • docs/cli/settings/set.md
  • docs/cli/settings/unset.md
  • docs/cli/unset.md
  • docs/cli/unuse.md
  • docs/cli/use.md
  • docs/configuration.md
  • e2e/config/test_config_override_file
  • e2e/config/test_config_override_file_writes
  • e2e/lockfile/test_lockfile_config_override
  • man/man1/mise.1
  • mise.usage.kdl
  • src/cli/config/get.rs
  • src/cli/config/keys.rs
  • src/cli/config/ls.rs
  • src/cli/config/mod.rs
  • src/cli/config/set.rs
  • src/cli/doctor/mod.rs
  • src/cli/set.rs
  • src/cli/settings/add.rs
  • src/cli/settings/mod.rs
  • src/cli/settings/set.rs
  • src/cli/settings/unset.rs
  • src/cli/system/import.rs
  • src/cli/system/use.rs
  • src/cli/unset.rs
  • src/cli/unuse.rs
  • src/cli/use.rs
  • src/config/mod.rs
  • src/config/settings.rs
  • src/lockfile.rs
✨ Finishing Touches: πŸ’‘ 1
πŸ› οΈ Fix failing CI checks: πŸ’‘
  • Commit to this branch
  • Create a new PR
  • Autofix Β· Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❀️ Share

Comment @coderabbitai help to get the list of available commands.

It duplicates package.documentation, and newer cargo warns about it, which
failed the cargo-check pre-commit step.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Entire-Checkpoint: 01M55H74A4STB3XF269Y120HBN

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit ac15693. Configure here.

Comment thread src/cli/config/set.rs Resolved
Comment thread src/lockfile.rs Resolved
…e it before it exists

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Entire-Checkpoint: 01M55HFBNEG37T8GW12SX143AF
@greptile-apps

greptile-apps Bot commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; all three previous findings are fixed, with no new actionable issues found.

Summary

Adds global override files that take priority over project config, with explicit read and write flags.

  • Global override files take precedence over project config.
  • Commands write to override files only when --override is selected.
  • Override-declared tools use the global lockfile instead of the project lockfile.
  • Config listings and doctor output identify override files.
  • The package manifest no longer lists a homepage URL.

Reviews (2) Β· Last reviewed commit: "fix(config): keep global task scripts ou..." Β· Reviewed by Greptile

Comment thread src/config/mod.rs Resolved
Comment thread src/cli/config/keys.rs Resolved
Comment thread docs/cli/use.md Resolved
…mplete --override keys

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Entire-Checkpoint: 01M55HZ72XBVZJKXW0TDVX0FB7
@jdx
jdx enabled auto-merge (squash) October 17, 2026 19:01
@jdx
jdx merged commit c571d2c into main Oct 17, 2026
77 of 80 checks passed
@jdx
jdx deleted the config-override-file branch October 17, 2026 19:18
@github-actions

Copy link
Copy Markdown
Contributor

Instruction counts

Nothing was compared, and so nothing was gated. No series appears on both sides: either the base has no measurements recorded, or the two were measured on different runner classes, which are deliberately not comparable β€” counts shift between machine types by more than a real regression does.

New, nothing to compare against: env on jdx-perf-v1-ubuntu24.04-x64-mise-rust1.97.1-img5263c143, hook-env on jdx-perf-v1-ubuntu24.04-x64-mise-rust1.97.1-img5263c143, ls on jdx-perf-v1-ubuntu24.04-x64-mise-rust1.97.1-img5263c143, registry on jdx-perf-v1-ubuntu24.04-x64-mise-rust1.97.1-img5263c143, startup on jdx-perf-v1-ubuntu24.04-x64-mise-rust1.97.1-img5263c143

Only instruction counts gate. Wall clock is shown for context β€” on identical hardware it moves 4-20% run to run.

Measured by tak β€” instruction-counted CLI benchmarks, stored in this repository's git notes.

e648a7699b21 vs 2e227af44291 Β· measured on the runner, not pushed to the history.

jdx pushed a commit that referenced this pull request Oct 18, 2026
<!-- entire-trail-link-start -->
https://entire.io/gh/jdx/mise/trails/826
<!-- entire-trail-link-end -->

### πŸš€ Features

- **(backend)** reject tool options a backend does not read by @jdx in
[#14629](#14629)
- **(config)** let env_file take several filenames by @jdx in
[#14606](#14606)
- **(config)** add config.override.toml so global config can override
project config by @jdx in
[#14610](#14610)
- **(config)** let paranoid take a list of categories by @jdx in
[#14609](#14609)
- **(env)** let a find_up env._.file entry search several names together
by @jdx in [#14620](#14620)
- **(task)** read #MISE headers through TaskDecl by @jdx in
[#14637](#14637)

### πŸ› Bug Fixes

- **(activate)** stop fish not-found recursion after mise implode by
@jdx in [#14594](#14594)
- **(bootstrap)** find nix installed by a pre-packages hook by @jdx in
[#14596](#14596)
- **(bootstrap)** parse [bootstrap.linux.firewall] on every OS by @jdx
in [#14615](#14615)
- **(cargo)** honor rename_exe for cargo-installed tools by @jdx in
[#14626](#14626)
- **(config)** require content-bound trust for env files in paranoid
mode by @jdx in [#14604](#14604)
- **(hooks)** don't report git rewrites when HEAD stayed on the same
commit by @JamBalaya56562 in
[#14585](#14585)
- **(npm)** report an unusable TLS root store instead of aborting by
@jdx in [#14595](#14595)
- **(pipx)** bind the real python for locked uv installs by @jdx in
[#14593](#14593)
- **(rust)** don't put an external rustup's directory ahead of mise's
tools by @jdx in [#14597](#14597)
- **(schema)** generate [bootstrap] from its parser types by @jdx in
[#14616](#14616)

### 🚜 Refactor

- **(config)** move doctor, tool_config, watch_files and wrappers into
mise-config by @jdx in [#14617](#14617)
- **(config)** move the oci and daemons declarations into mise-config by
@jdx in [#14618](#14618)
- **(config)** move alias, min_version and monorepo into mise-config by
@jdx in [#14627](#14627)
- **(config)** declare [tools] in mise-config, keyed by string by @jdx
in [#14631](#14631)
- **(config)** parse mise.toml through MiseTomlDecl by @jdx in
[#14638](#14638)
- **(env)** move env directives and the [env] parser into mise-config by
@jdx in [#14621](#14621)
- **(task)** move the task declaration field types into mise-config by
@jdx in [#14622](#14622)
- **(task)** split TaskDecl from Task by @jdx in
[#14624](#14624)
- rename mise-system-config to mise-config by @jdx in
[#14608](#14608)

### πŸ“š Documentation

- **(env)** explain env_file and _.file find_up are different features
by @jdx in [#14602](#14602)

### ⚑ Performance

- **(dotfiles)** build snapshot trees without a git process per tracked
file by @waynehoover in [#14607](#14607)

### πŸ§ͺ Testing

- **(npm)** install a popular package in the dependency check by @jdx in
[#14633](#14633)
- **(schema)** check schema/mise.json against the config parser by @jdx
in [#14613](#14613)

### πŸ“¦οΈ Dependency Updates

- bump mbx to 1.24.1 by @jdx in
[#14635](#14635)

### Chore

- **(schema)** generate the [history] schema from mise-config by @jdx in
[#14611](#14611)
- **(schema)** generate the task schema from TaskDecl and TaskTemplate
by @jdx in [#14625](#14625)
- **(schema)** generate the whole schema from a top-level MiseTomlDecl
by @jdx in [#14632](#14632)

### Ci

- restore the nextest timeout for the mise-oci blob test by @jdx in
[#14619](#14619)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant