I am using the Rust git2 crate to clone Git repositories like this
use git2::Repository;
fn main() {
let repo = Repository::clone(
"https://github.com/rossmacarthur/dotfiles",
"dotfiles"
).expect("failed to clone repository");
repo.checkout("mybranch"); // need something like this.
}
I want to be able to checkout a branch or a commit or a tag.
I have looked at the following documentation but am still not sure which method to use
I am able to do the following but it only changes the files
let object = repo
.revparse_single("mybranch")
.expect("failed to find identifier");
repo.checkout_tree(&object, None)
.expect(&format!("failed to checkout '{:?}'", object));
And if I do a reset it changes the HEAD but not the current branch
repo.reset(&object, git2::ResetType::Soft, None)
.expect(&format!("failed to checkout '{:?}'", object));
With a more recent version of git2
(v0.13.18
):
use git2::Repository;
fn main() {
let repo = Repository::clone("https://github.com/rossmacarthur/dotfiles", "/tmp/dots")
.expect("Failed to clone repo");
let refname = "master"; // or a tag (v0.1.1) or a commit (8e8128)
let (object, reference) = repo.revparse_ext(refname).expect("Object not found");
repo.checkout_tree(&object, None)
.expect("Failed to checkout");
match reference {
// gref is an actual reference like branches or tags
Some(gref) => repo.set_head(gref.name().unwrap()),
// this is a commit, not a reference
None => repo.set_head_detached(object.id()),
}
.expect("Failed to set HEAD");
}
Note that checkout_tree
only sets the contents of the working tree, and set_head
only sets the HEAD
. Running only one of them will leave the directory in a dirty state.