checkout of a specific branch, tag or revision does not work
Current behavior 😯
In https://github.com/cargo-generate/cargo-generate/pull/1460 we try to get away from git2 and migrate to gix. It looks all promising so far, only one thing does not work. It is checking out a specific branch, tag or revision.
What gix does, (see the code https://github.com/cargo-generate/cargo-generate/pull/1460/files#diff-dbcccd0cf247f619f177ddeb85fe8dfc4eb4c71c0de0bb47ec839764c7d4918dR82) it checks out the default branch (in our test case it is main).
Expected behavior 🤔
when we configure the prepare_clone with the refsepc like in https://github.com/cargo-generate/cargo-generate/pull/1460/files#diff-dbcccd0cf247f619f177ddeb85fe8dfc4eb4c71c0de0bb47ec839764c7d4918dR72
or here the excerpt:
let (mut prepare_checkout, _) = if let Some(branch) = self.branch {
let mut opts = Options::default();
let ref_spec = gix::refspec::parse(branch.as_str().into(), Operation::Fetch).unwrap();
dbg!(ref_spec);
opts.extra_refspecs.push(ref_spec.to_owned());
prepare_clone.with_fetch_options(opts)
Then I would expect that calling
let (repo, _) = prepare_checkout
.main_worktree(gix::progress::Discard, &gix::interrupt::IS_INTERRUPTED)?;
would check out the specific branch, tag or revision.
Git behavior
git2 has a .checkout_tree that does behave exactly as described above
here is some sample code: https://github.com/cargo-generate/cargo-generate/blob/0e9471d4991764270de8940c7695d13f932c086b/src/git/clone_tool.rs#L183
Steps to reproduce 🕹
- in cargo-generate you can checkout the PR #1460 (
gh pr checkout 1460) - let the tests run simply
cargo test - all failing tests (2) relate to this problem
gix::tests::test_cloning_a_repo_at_revision
gix::tests::test_cloning_a_repo_with_a_specific_branch
Thanks for reporting.
gitoxide doesn't have a way to checkout a branch yet akin to git2_repo.checkout_*(), and the choice of ref to checkout after cloning is definitely specified differently.
gix clone --ref <name> … is able to clone and checkout a specific branch. I recommend looking at the source to see how this is specified - it should work for you.
Please do feel free to post your findings here, maybe they are useful for others as well.
I'm migrating a project from go to rust which is supposed to fetch and checkout a single commit sha for a CI build.
Originally, I thought it would work after seeing https://github.com/GitoxideLabs/gitoxide/pull/1403, but I ran into this error
we map by name only and have no object-id in refspec
For now I'll continue to use the go code (example go usage and resolved issue), but looking forward to revisit this and migrate to Rust! 🦀
It looks like this can easily be reproduced by providing an object hash as reference:
> gix clone --ref 4b7008c929494c7764f3ddffa998ca0c8cab9806 https://github.com/Byron/small
thread 'main' panicked at gix/src/clone/fetch/util.rs:217:18:
we map by name only and have no object-id in refspec
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
It looks like this should be prevented to not run into this assertion, or one could try to actually make this work. Then it feels like --ref should be renamed to something that more officially allows object hashes (both in the CLI and in the API).