github GitoxideLabs/gitoxide gix-diff-v0.67.0
gix-diff v0.67.0

one hour ago

Changed (BREAKING)

  • Refactor tree-merge change matching and resolution.
    Breaking because of added ResolutionFailure variants.

    The tree-merge implementation previously combined side-diff collection,
    path matching, scheduling, and the complete conflict-resolution matrix in a
    single function. It also duplicated change collection for both sides and
    represented pair outcomes with independent boolean flags.

    Keep the public tree() entry point as a small facade and move the merge
    engine into focused private modules. Collect each ancestor-to-side diff
    through one helper that constructs a SideState containing the flat change
    list and its matching tree together. Isolate path and rename candidate
    matching, including identical-change suppression, from classification into
    pairs that the resolution matrix understands.

    Represent the result of handling each paired change explicitly as a
    ChangeDisposition. This preserves the important distinction between a
    change that was merely processed and one whose effect is present in the
    editor, without duplicating the final state transition in the scheduler.
    Replace the type-specific side-picking helpers with generic pick() and
    pick_mut() helpers as well.

    These boundaries make the state machine easier to review and reduce the
    chance that a future rename or forced-resolution fix accidentally changes
    collection, matching, and application at once. They also remove duplicated
    setup while keeping the exhaustive resolution match in one place, where
    its symmetry remains visible. The public API and all recorded merge results
    remain unchanged.

    Fixes and Improvements

    Tree merging combines a flat change schedule with per-side path indexes. Valid
    Git operations can therefore arrive in different orders or expose structural
    relationships before the leaf changes that ultimately apply them. Several
    resolver branches treated those relationships as physical occupancy or as
    content changes for the same identity, leading to hangs, assertions, duplicate
    entries, lost siblings, or merge results that depended on diff and side order.

    Separate unique-path occupancy from PassedRewrittenDirectory scheduling so a
    side-qualified name can terminate below directory rewrites. Prune empty path
    nodes back to the root, and allow a deferred rewrite to insert only its new
    destination because its source is already indexed.

    Resolve the structural cases at their actual identity boundaries:

    • handle an added file blocking an added directory before mode-specific add/add
      resolution and defer early descendants until their parent deletion runs;
    • keep explicit file renames ahead of inferred directory renames, and keep
      directory replacements at their explicit sources;
    • treat file replacements of incompatible non-blob ancestors as additions with
      an empty compatible merge base;
    • pair shared deletions before descendants and allow file renames into paths
      vacated by directory renames;
    • preserve unrelated nested or overlapping rename destinations by keeping the
      directory in place and moving only the blocking file;
    • reject incompatible same-destination rewrites before blob merging, while
      collapsing identical rewrites to one clean shared destination; and
    • defer file-to-directory children until the parent rename/delete decision is
      made exactly once.

    Forced Ancestor and Ours resolution continues to apply only the selected side.
    Git-backed baselines cover both directions, forced policies, modes, symlinks,
    gitlinks, nested directories, and documented index-only deviations. The
    resulting suite contains 155 directional baseline cases, and the Cartesian
    model reaches 210/210 Git/gix agreement for trees and path/mode results.

    More Hardening

    Deferred tree changes may be reconsidered after another conflict has already
    consumed or pruned the same path-tree node. This is valid when rename detection
    has ambiguous identical sources, when structural conflicts overlap, or when a
    change follows a detected directory rename. The editor and conflict records
    still contain the required state, but strict bookkeeping removals and older
    same-path assertions turned these schedules into debug panics, hangs, or
    side-order-dependent duplicate content.

    Make cleanup idempotent wherever absence is already the required end state:
    add/add type conflicts, same-source rewrites, blocking conflict destinations,
    delete/rewrite sources, and changes deferred through directory renames. Accept
    cross-path structural matches from ambiguous rewrite candidates and let the
    existing conservative unknown-conflict fallback handle them.

    Preserve each rewrite input mode when blob content is identical so executable
    mode changes remain visible to the merge. Make unique-path selection respect
    childless tracked directories and qualify the first blocking file component,
    which guarantees termination instead of varying an ineffective descendant
    suffix forever. Finally, when a deferred addition is relocated to a unique
    conflict path, remove its temporary original path from the side index before
    marking it processed so a later descendant cannot relocate the same content a
    second time.

    The minimized and accumulated fuzz inputs now complete without failure.
    Git-backed regressions cover ambiguous sources, consumed nodes, repeated
    rename/delete candidates, mode-only rewrite collisions, unique paths below
    files, and nested rename destinations in both side orderings. The final tree
    baseline contains 165 directional cases with 130 intentionally skipped forced
    resolution checks, and reversing the nested relocation case retains exactly
    a/a/a and a~A without inventing a~A_0.

Test

  • add test for binary diff with textconv
    I want to add similar tests for gix-blame as well, but first I want to
    properly understand this part of the gix-diff machinery.

Bug Fixes

  • support shell commands in external blob diffs

    Treat configured external diff commands as shell command lines instead of
    executable paths that require manual argument splitting.

    Git diff drivers may contain a program followed by arguments. Passing such
    values through the shell-aware gix-command preparation path preserves that
    configuration while still appending Git diff arguments and environment variables
    in the established platform code.

    Add coverage for a configured command containing an argument so custom diff
    drivers and text-conversion commands are launched as configured.

Commit Statistics

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

Commit Details

view details
  • Uncategorized
    • Update manifests prior to release (ebe9095)
    • Merge pull request #2930 from GitoxideLabs/gix-notes (7424676)
    • Thanks clippy (5c8d935)
    • Merge pull request #2928 from cruessler/add-git-diff-textconv-test (227619a)
    • Review (5e600cb)
    • Add test for binary diff with textconv (6ade0d4)
    • Merge pull request #2905 from GitoxideLabs/various-improvements (f3bbfad)
    • Support shell commands in external blob diffs (752f16f)
    • Adapt to changes in gix-testtools (0cbe539)
    • Use gix_object::tree::name_order instead of copy of the same function (db1f7d4)
    • Merge pull request #2901 from cruessler/switch-to-gix-odb-at-opts (2a4d996)
    • Introduce Store::at() where possible (17fea2a)
    • Merge pull request #2843 from GitoxideLabs/deleted-file-added-dir (f33e250)
    • Refactor tree-merge change matching and resolution. (43cf77f)
    • Merge pull request #2867 from GitoxideLabs/fix-url-authority-parsing (cc3ee80)
    • Release gix-path v0.12.4, gix-command v0.9.2, gix-config-value v0.19.1, gix-url v0.37.1, gix-credentials v0.39.1, gix-transport v0.58.1 (ab4fcb0)
    • Merge pull request #2812 from GitoxideLabs/report-july (ae8845a)

Don't miss a new gitoxide release

NewReleases is sending notifications on new releases.