本文介绍了如何在 Rust git2 中获取`git checkout ...` 的行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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));

如果我进行重置,它会更改 HEAD 而不是当前分支

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));

推荐答案

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

The examples below are Rust v1.34 and 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));
}

要检查提交:

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));

}

要检查标签,请尝试以下操作:

To checkout a tag try something like this:

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));
            }
        }

    }
}

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

I bet there is generally a better way but the question has been unanswered for months and this is how I figured it out moments ago.

这篇关于如何在 Rust git2 中获取`git checkout ...` 的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-14 17:33