Skip to content

Wrong refs returned by repo.references()?.local_branches()? sometimes in non-garbage-collected repos #1850

Closed
@ilyagr

Description

@ilyagr

Current behavior 😯

I'm not sure how to have a minimal example, but I'll attach the repo where I saw this problem.

TLDR, I have these two branches:

$  git branch -v | rg pr4021
  ig-pr4021                      4dec14596 minor fixups (clippy, UI)
  old-ig-pr4021                  21b572308 minor fixups (clippy, UI)

However, when I use gix to get the list of references, it lists "refs/heads/ig-pr4021" twice, with different ids:

[src/main.rs:10:13] b = Reference {
    name: FullName(
        "refs/heads/ig-pr4021",
    ),
    target: Object(
        Sha1(21b57230833a1733f6685e14eabe936a09689a1b),
    ),
    peeled: None,
}
[src/main.rs:10:13] b = Reference {
    name: FullName(
        "refs/heads/ig-pr4021",
    ),
    target: Object(
        Sha1(4dec145966c546402c5a9e28b932e7c8c939e01e),
    ),
    peeled: None,
}
[src/main.rs:10:13] b = Reference {
    name: FullName(
        "refs/heads/old-ig-pr4021",
    ),
    target: Object(
        Sha1(21b57230833a1733f6685e14eabe936a09689a1b),
    ),
    peeled: None,
}

As the names suggest, ig-pr4021 used to point to 21b57, but that was a long time ago.

The program that generated the above output is:

use std::path::Path;

use gix::bstr::{B, BString, ByteSlice};

fn main() -> anyhow::Result<()> {
    let repo = gix::discover(Path::new("/path/to/repo"))?;
    for b in repo.references()?.local_branches()? {
        let b = b.unwrap();
        if b.name().as_bstr().find(b"pr4021").is_some() {
            dbg!(b);
        }
    }
    Ok(())
}

I'm using gix v0.70.0 on ARM Mac OS. I can send you my lockfile, but I just populated it today; I'm hoping you can easily reproduce this (if you're OK with downloading my repo).

Workaround

Running git gc fixed this.

Expected behavior 🤔

The program should only print

[src/main.rs:10:13] b = Reference {
    name: FullName(
        "refs/heads/ig-pr4021",
    ),
    target: Object(
        Sha1(4dec145966c546402c5a9e28b932e7c8c939e01e),
    ),
    peeled: None,
}
[src/main.rs:10:13] b = Reference {
    name: FullName(
        "refs/heads/old-ig-pr4021",
    ),
    target: Object(
        Sha1(21b57230833a1733f6685e14eabe936a09689a1b),
    ),
    peeled: None,
}

Git behavior

See above

Steps to reproduce 🕹

See above. (I will upload the repo in a bit and edit this message) (done).

The repo is at https://drive.google.com/file/d/14pheDpbYL8u9p8VWKWIIO4gbv3xjy35t/view?usp=sharing (150MB). Sorry for the size but, again, running git gc makes the bug go away.

Metadata

Metadata

Assignees

Labels

acknowledgedan issue is accepted as shortcoming to be fixed

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions