如何切换到指定版本

How to switch to specified version

我想将我的克隆存储库切换到某个指定版本。当我 运行 这段代码时,它无法正常工作。它意识到我落后或高于 master 的提交次数,但它并没有真正切换项目。

例如,如果我的 1.0 版包含一些 txt 文档,而 1.1 版不包含此 txt 文档。 Master 指向版本 1.1

首先我克隆了整个存储库,(目标文件夹不包含 txt 文档)。

然后我执行这段代码,我希望 txt 文档出现在目标文件夹中。

当我尝试这个时:

Download a specific tag with Git

它正在运行,我希望我的代码也能运行,

        git_libgit2_init();
        const char * REPO_PATH = path.c_str();
        git_repository * repo = nullptr;
        git_repository_open(&repo, REPO_PATH);

        git_reference *ref;
        git_reference_lookup(&ref, repo, "refs/heads/master");      // "refs/remotes/origin/HEAD"

        git_reference *new_ref;
        git_reference_lookup(&new_ref, repo, tag.c_str());

        git_revwalk *walker;
        git_revwalk_new(&walker, repo);
        git_revwalk_push_ref(walker, tag.c_str());

        git_oid id;
        git_revwalk_next(&id, walker);

        git_reference_set_target(&new_ref, ref, &id, NULL);

        if (0 != git_repository_set_head_detached(repo, &id)) cerr << "problem occured while detaching head" << endl;

        git_revwalk_free(walker);
        git_repository_free(repo);
        git_libgit2_shutdown();

我也尝试过类似的方法,但是在 git_annotated_commit_from_ref()

失败了

这是我的第二个实现:

    git_libgit2_init();

    const char * REPO_PATH = path.c_str();
    git_repository * repo = nullptr;
    git_repository_open(&repo, REPO_PATH);

    git_reference *ref;
    git_reference_lookup(&ref, repo, tag.c_str());

    git_annotated_commit *out;

    if (0 != git_annotated_commit_from_ref(&out,repo,ref)) cerr << "error creating annotated commit" << endl;

    if (0 != git_repository_set_head_detached_from_annotated(repo, out)) cerr << "problem occured while detaching head" << endl;

    git_repository_free(repo);

    git_libgit2_shutdown();

我知道了

需要将结帐策略设置为 GIT_CHECKOUT_FORCE

git_libgit2_init();
const char * REPO_PATH = path.c_str();
git_repository * repo = nullptr;
git_repository_open(&repo, REPO_PATH);

git_reference *ref;
git_reference_lookup(&ref, repo, "refs/heads/master");      

git_reference *new_ref;
git_reference_lookup(&new_ref, repo, tag.c_str());

git_revwalk *walker;
git_revwalk_new(&walker, repo);
git_revwalk_push_ref(walker, tag.c_str());

git_oid id;
git_revwalk_next(&id, walker);

git_reference_set_target(&new_ref, ref, &id,NULL);

if (0 != git_repository_set_head_detached(repo, &id)) cerr << "problem occured while detaching head" << endl;


git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
opts.checkout_strategy = GIT_CHECKOUT_FORCE;
if (0 != git_checkout_head(repo, &opts)) cout << "problem checkout head" << endl;

git_revwalk_free(walker);
git_repository_free(repo);
git_libgit2_shutdown();
void checkout_progress(
        const char *path,
        size_t cur,
        size_t tot,
        void *payload)
{
    printf("Checking out: %s    %d/%d \n",
        path, (int)cur, (int)tot);
}

std::string path = "/some/repo/dir";
std::string sha = "a9e1e91f";
git_repository *repo = NULL;

err = git_repository_open(&repo, path.c_str());

git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT;
checkout_opts.checkout_strategy = GIT_CHECKOUT_FORCE ;
checkout_opts.progress_cb = checkout_progress;
git_object * treeish = NULL;

auto git_path = std::string("refs/heads/master/").append(sha);

err = git_revparse_single(&treeish, repo,sha.c_str());

err = git_repository_set_head(repo, git_path.c_str());

err = git_checkout_tree(repo, treeish, &checkout_opts);

git_object_free(treeish);
git_repository_free(repo);