Skip to content

Rename tracker shouldn't be order-dependent #1832

Open
@Byron

Description

@Byron

The same result should be produced independently of the order of input items.
If I recall correctly, it already sorts its output before returning it.

I took a look just now and noticed that the failure here seems to originate in the rename tracker, It didn't find the matching pairs.
The answer here must be that it's a problem with the order in which the entries are made known to the rename tracker, which depends on timing. A dirwalk is used in one thread to detect untracked files, whereas another thread traverses the index to find missing and changed files.

It appears that the pair-matching algorithm is to not order-independent as it would expected to be - clearly a bug in the implementation.

I think it would be possible to reproduce this with a test that runs a similar set of files through significant permutations and runs rename tracking on it.

Discussed in #1831

Originally posted by EliahKagan February 5, 2025
The i386 (32-bit x86) test-32bit job was not changed in #1830, which only changed the arm32v7 (32-bit ARM) job. But after CI passed there, the i386 job failed in the merge commit on the main branch. Although I would guess the failure might go away if the job is rerun, since it passed when it ran on the main branch of my fork when I fast-forwarded (synchronized) it, I don't know how a failure like this would plausibly happen even with low probability in the absence of a bug in gitoxide or its test suite:

        FAIL [   0.010s] gix-status-tests::status index_as_worktree_with_renames::changed_and_untracked_and_renamed
──── STDOUT:             gix-status-tests::status index_as_worktree_with_renames::changed_and_untracked_and_renamed

running 1 test
test index_as_worktree_with_renames::changed_and_untracked_and_renamed ... FAILED

failures:

failures:
    index_as_worktree_with_renames::changed_and_untracked_and_renamed

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 27 filtered out; finished in 0.00s

──── STDERR:             gix-status-tests::status index_as_worktree_with_renames::changed_and_untracked_and_renamed
thread 'index_as_worktree_with_renames::changed_and_untracked_and_renamed' panicked at gix-status/tests/status/index_as_worktree_with_renames.rs:311:5:
assertion failed: `(left == right)`

Diff < left / right > :
 [
     Rewrite {
         source_rela_path: "dir/content",
         dest_rela_path: "content-copy",
         dest_dirwalk_status: Untracked,
         diff: None,
         copy: false,
     },
     DirwalkEntry {
         rela_path: "content-copy-with-rewrite",
         status: Untracked,
         disk_kind: Some(
             File,
         ),
     },
     Rewrite {
         source_rela_path: "dir/content2",
         dest_rela_path: "content-with-rewrite",
         dest_dirwalk_status: Untracked,
         diff: Some(
             DiffLineStats {
                 removals: 0,
                 insertions: 1,
                 before: 1,
                 after: 2,
                 similarity: 0.72,
             },
         ),
         copy: false,
     },
<    DirwalkEntry {
<        rela_path: "dir/untracked",
<        status: Untracked,
<        disk_kind: Some(
<            File,
<        ),
>    Rewrite {
>        source_rela_path: "empty",
>        dest_rela_path: "dir/untracked",
>        dest_dirwalk_status: Untracked,
>        diff: None,
>        copy: true,
     },
     DirwalkEntry {
         rela_path: "plainly-renamed-content",
         status: Untracked,
         disk_kind: Some(
             File,
         ),
     },
     Rewrite {
         source_rela_path: "executable",
         dest_rela_path: "rewritten-executable",
         dest_dirwalk_status: Untracked,
         diff: Some(
             DiffLineStats {
                 removals: 0,
                 insertions: 1,
                 before: 1,
                 after: 2,
                 similarity: 0.53333336,
             },
         ),
         copy: false,
     },
<    DirwalkEntry {
<        rela_path: "untracked",
<        status: Untracked,
<        disk_kind: Some(
<            File,
<        ),
>    Rewrite {
>        source_rela_path: "empty",
>        dest_rela_path: "untracked",
>        dest_dirwalk_status: Untracked,
>        diff: None,
>        copy: true,
     },
 ]


note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Here's a colorized rendering of the diff shown in the above test failure output.

That is the only failure in that job, and there are no failures in any of the other jobs, including of that test case. This is also not related to the ongoing ARM problems we've had on CI, because that is a 32-bit x86 job.

What might have caused that, and is it something we should worry about?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions