Skip to content

config: --get-regexp rejects dotless patterns with misleading error; --get/--unset value-pattern operand ignored; --replace-all missing; --show-origin silently ignored on --get; --file/--show-scope absent; t1300 coverage gaps #475

Description

@genedna

Summary

Per the agreed framing, libra config is intentionally backed by SQLite + a settings file rather than Git's INI files; this issue only evaluates behavioral consistency at the CLI surface (0.22.5 vs git 2.55) and test coverage. The subcommand layer (config set/get/list/unset) is solid; the Git-compat flag layer has real drift.

Behavior differences

  1. --get-regexp <pattern> requires the pattern to contain a literal dot (P1)
    libra validates the pattern with the "key must contain a section" rule before treating it as a regex:

    $ libra config --get-regexp '^user'       # valid regex, matches user.name/user.email
    error: key does not contain a section: ^user  (LBR-INTERNAL-001, exit 1)
    $ libra config --get-regexp '^user\.'     # works
    user.email = a@b ...
    

    Git: git config --get-regexp '^user' lists all user.* keys (exit 0); a non-matching pattern exits 1. Also note the error is tagged category=internal (LBR-INTERNAL-001) for what is a user-input issue.
    The same bug hits --get-all nosuchkey (Git: silent, exit 1; libra: "does not contain a section" — misleading) and value-position patterns.

  2. git config <key> <value-pattern> (the third positional) semantics diverge
    Git treats the middle positional as a value regex for get/unset and refuses single-value overwrite when multiple values exist ("Use a regexp, --add or --replace-all"):

    • git config --get multi.k two → prints two.
    • git config --unset multi.k one → removes only the one entry.
    • git config multi.k three with 2 existing values → fatal, suggests --add/--replace-all.
      libra:
    • --get multi.k two → ignores the pattern, prints last value (two by accident).
    • --unset multi.k one → error cannot unset 'multi.k': 2 values exist (pattern ignored).
    • multi.k three (bare set) → error cannot set: 2 values exist — matches Git's refusal but libra has no --replace-all to resolve it, so a multi-valued key can only be cleared with --unset-all. --replace-all is simply missing from the compat surface.
  3. --show-origin output format

    • --list --show-origin: libra prints local core.bare = false (scope label); Git prints file:/path/to/config<TAB>core.bare=false. For the file-backed upgrade.* keys libra does print file:{path} (tested), so the two formats coexist. Scripts parsing origin will break either way; undocumented in COMPATIBILITY.md.
    • --show-origin is silently ignored by --get/--get-all/--get-regexp — libra prints the bare value with no origin and exit 0, while Git prefixes every match with file:.... Confirmed for --get (plain value only) and --get-regexp.
  4. --show-scope and --file <path> are not implementedunexpected argument. --file is how Git does one-off script config; nothing in help/COMPATIBILITY.md says "use subcommands instead".

  5. --type support is a strict subset: bool|int|path work (verified: --type=bool x.y true canonicalizes; --get --type=path expands ~/x — matches Git). Missing: bool-or-str, color, expiry-date, int size suffixes like 1k on read canonicalization. Error message is clear, so this is a gap note, not a bug.

  6. config edit — libra: error: config edit is not supported (SQLite storage does not support text-based editing), exit 128. Git opens $EDITOR. Intentional (storage), but exit 128 + no hint pointing to config set makes it a dead end; also GIT_EDITOR=true git config --edit is used in countless CI scripts that will hard-fail.

  7. Exit-code drift: libra config --get nonexistent.key exits 1 (matches Git). --get-regexp no-match exits 1 (matches). But --get-regexp 'user' (the "no dot" bug) also exits 1 — with a wrong error. config edit exits 128 vs Git's success. --system on a non-root box: libra fails reads with fatal: failed to read system config ... where Git just skips a missing/unreadable file.

  8. Verified-consistent areas (no issue): -z/--null record format for --get-regexp/--list matches key\nvalue\0; --get-all ordering; --add allowing duplicates; --unset-all count reporting; --remove-section/--rename-section; --bool/--int/--path shortcuts; -d/--default (Git actually rejects --get --default without --get in older versions — libra's broader support is a superset); spell-correction hints (did you mean) are a libra-only UX improvement.

Test gaps vs Git

t/t1300-config.sh is Git's largest config suite (~200 cases). libra's tests/command/config_test.rs has 79 tests, and the following behaviors are untested (all verified to be wrong or undocumented above):

  • --get-regexp with a dotless pattern (current behavior: misleading error).
  • --get <key> <value-pattern> / --unset <key> <value-pattern> positional semantics.
  • --show-origin with --get/--get-all/--get-regexp (currently silently ignored).
  • --type unsupported-values error path (bool-or-str/color/expiry-date).
  • exit-code table for config edit / --file / --show-scope rejections.
  • --get-all for a missing key without a dot (current: "does not contain a section" instead of clean exit 1).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions