Local configuration overrides glab-managed keys that glab writes only globally
Problem to solve
A repository's local configuration (.git/glab-cli/config.yml) can override keys that glab sets automatically, but glab writes those keys only to the global configuration. A stale local value then wins on every read, while every write goes to a file that's never read.
For the Duo CLI, this makes glab duo cli update download the same version on every run in that repository:
$ glab duo cli update
Update available: 9.5.0 → 9.26.0
Downloading duo-darwin-arm64 version 9.26.0...
✓ Successfully updated to version 9.26.0
$ glab duo cli update
Update available: 9.5.0 → 9.26.0
...The local file held duo_cli_binary_version: "9.5.0", probably left over from simulating an old install. binarymgr.Runner.SaveBinaryInfo writes 9.26.0 to ~/.config/glab-cli/config.yml, but the next run reads 9.5.0 from the local file again.
glab config set writes to the local file by default inside a repository. That's the easy way to end up here: glab config set duo_cli_binary_version 9.5.0 run in a checkout.
Steps to reproduce
cd "$(mktemp -d)" && git init -q
export GLAB_CONFIG_DIR="$(mktemp -d)"
glab config set duo_cli_binary_version 9.5.0 # writes .git/glab-cli/config.yml
glab config set --global duo_cli_binary_version 9.26.0
glab config get duo_cli_binary_version # 9.5.0Affected keys
The keys described as "automatically set" in internal/config/schema.go:
duo_cli_binary_path,duo_cli_binary_version,duo_cli_binary_checksum,duo_cli_last_update_checkorbit_cli_binary_path,orbit_cli_binary_version,orbit_cli_binary_checksum,orbit_cli_last_update_check- the post-upgrade banner and
glab whatsnewversion keys
Scope: ScopeGlobal doesn't cover this. It means "not per host", and ordinary ScopeGlobal keys such as git_protocol and branch_prefix are meant to be set per repository.
Proposal
Add a KeyDef attribute (for example GlobalOnly) for glab-managed state, and set it on the keys above. For those keys:
- Reads skip the local configuration.
glab config setwithout--globalwrites them to the global file, or rejects the local write with an error that names--global.
Either change alone breaks the loop. Doing both also stops new local values from being written.
Related
glab config get --globalregisters--globalbut never reads it (internal/commands/config/get/config_get.go), so in the reproduction above it also returns9.5.0. Worth a separate fix.- #8568 (closed): local config is not shared across Git worktrees.
- Found while reviewing !3981 (merged).