rust-lang / git2-rs

libgit2 bindings for Rust
https://docs.rs/git2
Apache License 2.0
1.71k stars 389 forks source link

Cloning with specifying a branch fails with `NotFound` #856

Open cetra3 opened 2 years ago

cetra3 commented 2 years ago

I'm using git2 to clone information from Subsurface. Subsurface uses a branch equal to the email/username for storing info, but doesn't change the default branch from master.

Historically this has been fine, but now I've been running into the following error & can't work out what's happening:

an unknown git error occurred; code=NotFound (-3)

By using the git2::build::RepoBuilder::branch() & specifying the branch when cloning, it fails and the directory does not even contain the .git/ folder. If I set the head & checkout after cloning it doesn't fail.

Here's the code that is failing (that used to work, not sure what broke here!):

fn clone_git(path: &Path, email: &str, password: &str) -> Result<(), git2::Error> {

    let mut callbacks = RemoteCallbacks::new();

    callbacks.credentials(|_, _, _| Cred::userpass_plaintext(email, password));

    let mut fo = git2::FetchOptions::new();
    fo.remote_callbacks(callbacks);

    let mut builder = git2::build::RepoBuilder::new();
    builder.fetch_options(fo);

    builder.branch(email);

    builder.clone(
        &format!("https://cloud.subsurface-divelog.org/git/{}", email),
        path,
    )?;

    Ok(())
}

This code works:

fn clone_git(path: &Path, email: &str, password: &str) -> Result<(), git2::Error> {

    let mut callbacks = RemoteCallbacks::new();

    callbacks.credentials(|_, _, _| Cred::userpass_plaintext(email, password));

    let mut fo = git2::FetchOptions::new();
    fo.remote_callbacks(callbacks);

    let mut builder = git2::build::RepoBuilder::new();
    builder.fetch_options(fo);

    let repo = builder.clone(
        &format!("https://cloud.subsurface-divelog.org/git/{}", email),
        path,
    )?;

    repo.set_head(&format!("refs/remotes/origin/{email}"))?;
    repo.checkout_head(None)?;

    Ok(())
}

Running what I think also the equivalent command via CLI works fine:

 git clone https://cloud.subsurface-divelog.org/user@example.com --branch "user@example.com"

This could totally be a non-issue obviously & maybe the second code is more "correct" but thought I'd document it here to see if anyone runs into it.