我正在使用 Rust git2 crate 来克隆这样的 Git 存储库

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.
}

我希望能够 check out 分支、提交或标签。

我查看了以下文档,但仍然不确定使用哪种方法
  • https://docs.rs/git2/0.8.0/git2/struct.Repository.html#method.checkout_head
  • https://docs.rs/git2/0.8.0/git2/struct.Repository.html#method.checkout_tree
  • https://docs.rs/git2/0.8.0/git2/struct.Repository.html#method.checkout_index

  • 我可以执行以下操作,但它只会更改文件
    let object = repo
        .revparse_single("mybranch")
        .expect("failed to find identifier");
    repo.checkout_tree(&object, None)
        .expect(&format!("failed to checkout '{:?}'", object));
    

    如果我进行重置,它会更改 HEAD 而不是当前分支
    repo.reset(&object, git2::ResetType::Soft, None)
        .expect(&format!("failed to checkout '{:?}'", object));
    

    最佳答案

    下面的例子是 Rust v1.34 和 git2 v0.8。

    要结帐分支:

    use git2::*;
    
    fn main() {
        let repo = Repository::clone(
            "https://github.com/rossmacarthur/dotfiles",
            "dotfiles"
        ).expect("failed to clone repository");
    
        let branch_name = "my_branch";
    
        let head = repo.head().unwrap();
        let oid = head.target().unwrap();
        let commit = repo.find_commit(oid).unwrap();
    
        let branch = repo.branch(
            branch_name,
            &commit,
            false,
        );
    
        let obj = repo.revparse_single(&("refs/heads/".to_owned() +
            branch_name)).unwrap();
    
        repo.checkout_tree(
            &obj,
            None
        );
    
        repo.set_head(&("refs/heads/".to_owned() + branch_name));
    }
    

    要 checkout 提交:
    use git2::*;
    
    fn main() {
        let repo = Repository::clone(
            "https://github.com/rossmacarthur/dotfiles",
            "dotfiles"
        ).expect("failed to clone repository");
    
        let my_oid_str = "9411953f92d100f767e6de6325b17afae5231779";
    
        let oid = Oid::from_str(my_oid_str).unwrap();
        let commit = repo.find_commit(oid).unwrap();
    
        let branch = repo.branch(
            my_oid_str,
            &commit,
            false,
        );
    
        let obj = repo.revparse_single(&("refs/heads/".to_owned() + my_oid_str)).unwrap();
    
        repo.checkout_tree(
            &obj,
            None,
        );
    
        repo.set_head(&("refs/heads/".to_owned() + my_oid_str));
    
    }
    

    要 checkout 标签,请尝试以下操作:
    use git2::*;
    
    fn main() {
        // No relation to the example project below.
        // It looks interesting and it has tags!
        let repo = Repository::clone(
            "https://github.com/narke/colorForth.git",
            "colorforth"
        ).expect("failed to clone repository");
    
        let tag_name = "v2012";
    
        let references = repo.references().unwrap();
    
        for reference in references {
            let _reference = reference.unwrap();
    
            if _reference.is_tag() == true {
                let tag = _reference.peel_to_tag().unwrap();
                if tag.name().unwrap() == tag_name {
                    let target_oid = tag.target().unwrap().id();
                    let commit = repo.find_commit(target_oid).unwrap();
    
                    let branch = repo.branch(
                        tag_name,
                        &commit,
                        false,
                    );
    
                    let obj = repo.revparse_single(&("refs/heads/".to_owned() + tag_name)).unwrap();
    
                    repo.checkout_tree(
                        &obj,
                        None,
                    );
    
                    repo.set_head(&("refs/heads/".to_owned() + tag_name));
                }
            }
    
        }
    }
    

    我敢打赌,通常有更好的方法,但这个问题几个月来一直没有得到解答,这就是我刚才想出来的方法。

    关于git - 如何在 Rust git2 中获取 `git checkout ...` 的行为,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55141013/

    10-13 09:17