使用 libgit2 签出分支

Checkout branch with libgit2

我正在尝试在 2 个分支机构之间实现一个简单的结帐操作。代码执行无误。

git_libgit2_init();
git_object *treeish = NULL;
git_checkout_options opts;
opts.checkout_strategy = GIT_CHECKOUT_SAFE;

/* branchName in this case is "master" */
handleError(git_revparse_single(&treeish, repo, branchName));
handleError(git_checkout_tree(repo, treeish, &opts));

git_object_free(treeish);
git_libgit2_shutdown();

但是,当我使用 git status 检查时,分支并没有改变。 我检查了 101 examples of libgit2,它说:

git_checkout_options isn’t actually very optional. The defaults won’t be useful outside of a small number of cases. The best example of this is checkout_strategy; the default value does nothing to the work tree. So if you want your checkout to check files out, choose an appropriate strategy.

NONE is the equivalent of a dry run; no files will be checked out.

SAFE is similar to git checkout; unmodified files are updated, and modified files are left alone. If a file was present in the old HEAD but is missing, it’s considered deleted, and won’t be created.

RECREATE_MISSING is similar to git checkout-index, or what happens after a clone. Unmodified files are updated, and missing files are created, but files with modifications are left alone.

FORCE is similar to git checkout --force; all modifications are overwritten, and all missing files are created.

在我的例子中,我正在使用一个非常小的 repo 测试它,没有未提交的更改,并且这两个分支之间没有任何冲突。

我做错了什么?我希望这段代码能做类似 git checkout master

的事情

git checkout 命令异常超载。它处理将文件放在磁盘上(签出) 切换分支。特别是,git checkout <branch> 将更新工作目录以匹配给定分支的内容 并切换到它

libgit2 API 不会混淆这两个操作。 git_checkout_* 函数只会检出磁盘上的文件。

文档应该阐明这一点:

In libgit2, checkout is used to update the working directory and index to match a target tree. Unlike git checkout, it does not move the HEAD commit for you - use git_repository_set_head or the like to do that.

所以你所写的(以上)将更新工作目录以匹配分支的内容。之后,您需要将您的分支更新为您要切换到的分支。

一旦文件被签出,您可以使用 git_repository_set_head 来更新 HEAD 以指向给定的分支。请务必指定完全限定的分支名称(例如,refs/heads/master)。

git_object *treeish = NULL;
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
opts.checkout_strategy = GIT_CHECKOUT_SAFE;

git_libgit2_init();

handleError(git_revparse_single(&treeish, repo, "master"));
handleError(git_checkout_tree(repo, treeish, &opts));

handleError(git_repository_set_head(g_repo, "refs/heads/master"));

git_object_free(treeish);
git_libgit2_shutdown();