github GitoxideLabs/gitoxide gix-utils-v0.5.0
gix-utils v0.5.0

5 hours ago

Bug Fixes

  • avoid redundant Unicode precomposition work

    We now preserve macOS conversion failures per filename, but splitting
    every path adds work even for ASCII. In the initial benchmark, ASCII paths
    took about 2.6-2.8 times as long as before. The existing is_nfc()
    check can also perform a full NFC conversion before our compatibility
    composer performs its own decomposition and composition.

    Use is_nfc_quick() and detect non-BMP characters through the same iterator.
    Only scan its unvisited suffix if quick-check stops early. ASCII strings
    return immediately; ASCII paths also avoid UTF-8 validation and splitting.
    Process BMP-only paths together, reserving component splitting for paths
    with conversion failures. Specialize filename and path handling at compile
    time to keep the path fallback out of the filename loop.

    Skip combining-class and composition lookups for ASCII starters, use byte
    lengths for buffer capacities instead of counting characters, and reserve
    the output string before encoding it. Keep noncanonical mark order, Hangul
    composition, component-local fallback, and the original Cow when unchanged.

    The capacity estimate can reserve more space than the previous character
    count. Inconclusive NFC checks can now use a temporary buffer even if the
    result is unchanged; the benchmark explicitly covers that case. There are
    no new runtime dependencies; Criterion is already used in this workspace.

    Add a Criterion benchmark covering filenames and paths with ASCII, NFC,
    NFD, Hangul, noncanonical marks, and mixed emoji/decomposed components.

    Case Original HEAD median (ns) This commit median (ns)
    filename/ascii 6.46 2.55
    filename/emoji_first 63.54 3.17
    filename/emoji_last 57.95 15.80
    filename/hangul_nfc 12.20 11.88
    filename/hangul_nfd 141.87 70.28
    filename/nfc 16.60 15.78
    filename/nfc_quick_check_maybe 70.32 32.75
    filename/nfc_with_mark 11.03 11.89
    filename/nfd 303.23 70.96
    filename/noncanonical_marks 46.98 32.58
    filename/several_nfd 139.12 58.56
    path/ascii 34.71 2.69
    path/ascii_long 98.55 4.23
    path/mixed 403.60 134.15
    path/nfc 50.75 26.13
    path/nfd 378.76 234.88
    path/reported 106.27 37.88
    path/several_nfd 343.42 101.15

    The NFC string with an uncomposable mark costs about 0.9 ns more; the
    other measured cases improved. These are normalization microbenchmarks,
    not measurements of complete status operations.

    To compare subsequent changes:

    cargo bench -p gix-utils --bench precompose -- --save-baseline before --sample-size 100 --warm-up-time 1 --measurement-time 2 --noplot
    # Apply the change being measured, then:
    cargo bench -p gix-utils --bench precompose -- --baseline before --sample-size 100 --warm-up-time 1 --measurement-time 2 --noplot
  • preserve filenames rejected by macOS precomposition

    The original Starship report states that a tracked filename
    containing both an emoji and a decomposed umlaut is reported
    as untracked by gix status.

    Git's macOS UTF-8-MAC conversion rejects characters outside the Basic
    Multilingual Plane. When conversion fails, Git keeps the entire original
    input, including any decomposed umlauts before or after the rejected
    character. Our precomposition instead changed those umlauts, preventing
    the directory walk from matching Git's index entries.

    Preserve inputs containing non-BMP characters in the shared precomposition
    helper. Apply that rule separately to each filesystem-path component,
    preserving path separators and borrowing unchanged paths. Reference packing
    and lookup also use component-wise precomposition, consistent with loose
    reference iteration.

    Explicit file roots in the directory walk use the same path helper, so
    their emitted spelling agrees with ordinary traversal beneath emoji
    directories. Extend the existing root-precomposition test to cover an
    emoji parent and an emoji filename, with precomposition enabled and disabled.

    An emoji outside a reference name must not suppress that name's
    precomposition: otherwise loose and packed versions of an umlaut branch
    can be emitted twice. Cover that review finding, packing and lookup below
    an emoji component, both emoji/umlaut orderings, another supplementary-plane
    character, the reported Teaching/🎥 Überwachung im digitalen Zeitalter.md
    filename, and BMP-only controls.

    Restore the requested reference spelling after lookup instead of
    decomposing the entire returned name. Whole-name decomposition could alter
    an untouched emoji/umlaut component and make the returned name unusable
    for another lookup or deletion. Cover mixed composition, loose and packed
    references, full names, and worktree-qualified lookup round trips.
    Keep canonical pseudo-ref names when precomposition changes their
    classification, including worktree-qualified pseudo-refs.

    Both the helper regression and macOS status regression failed before the
    fix and now pass, as do the reference regressions added for the review
    finding. Validated the gix-utils, gix-fs, gix-dir, gix-status, and
    gix-ref suites, the gix status tests with default features and with
    --no-default-features --features basic,extras,comfort, targeted Clippy
    with warnings denied, and cargo fmt --all -- --check.

    Git reference: Apple Git 2.54.0 with core.precomposeUnicode=true leaves
    the repository clean. /usr/bin/iconv -f UTF-8-MAC -t UTF-8 rejects these
    non-BMP characters. compat/precompose_utf8.c::precompose_utf8_readdir()
    and precompose_string_if_needed() at
    d38352cd43ab9745686d697872408bc3249a153f retain the original input on
    conversion failure.

    Refs starship/starship#6881

Commit Statistics

  • 6 commits contributed to the release over the course of 13 calendar days.
  • 13 days passed between releases.
  • 2 commits were understood as conventional.
  • 0 issues like '(#ID)' were seen in commit messages

Commit Details

view details
  • Uncategorized
    • Prepare changelogs prior to release (794eeef)
    • Merge pull request #3032 from GitoxideLabs/sec-audit (1d7bac7)
    • Merge pull request #3026 from GitoxideLabs/status-fix (3f6fcda)
    • Avoid redundant Unicode precomposition work (fbcb262)
    • Preserve filenames rejected by macOS precomposition (4f7454a)
    • Merge pull request #3020 from GitoxideLabs/report-september (5fb3dcf)

Don't miss a new gitoxide release

NewReleases is sending notifications on new releases.