使用libgit2检出分支

7

我正在尝试在两个分支之间实现简单的结账操作。代码执行没有错误。

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检查时,该分支并未更改。 我已查看了libgit2的101示例,它说:

git_checkout_options 实际上并不是可选的。默认设置在大多数情况下都没用。最好的例子就是 checkout_strategy; 默认值对工作目录没有任何影响。因此,如果您想要将文件检出,请选择适当的策略。

NONE 相当于干运行;不会检出任何文件。

SAFE 类似于 git checkout;未修改的文件会被更新,已修改的文件则保持不变。如果某个文件在旧 HEAD 中存在但不存在,则视为删除,并且不会创建该文件。

RECREATE_MISSING 类似于 git checkout-index,或者在克隆之后发生的情况。未修改的文件会被更新,并会创建缺失的文件,但具有修改的文件则保持不变。

FORCE 类似于 git checkout --force;所有修改都将被覆盖,所有缺失的文件都将被创建。

在我的情况下,我正在使用非常小的 repo 进行测试,其中没有未提交的更改,并且这两个分支之间也没有任何冲突。 git log 我做错了什么?我期望这段代码能像git checkout master一样有所作为。
1个回答

13

git checkout 命令具有异常重载的特性。它既用于将文件放到磁盘上(checking out),也用于切换分支。特别地,git checkout <branch> 将会更新工作目录以匹配给定分支的内容并进行切换。

libgit2 APIs 不混淆这两个操作。 git_checkout_*函数仅用于将文件检出到磁盘上。

文档应明确说明:

在 libgit2 中,checkout 用于更新工作目录和索引以匹配目标树。与 git checkout 不同,它不会移动 HEAD 的提交位置——请使用 git_repository_set_head 或类似命令来完成该操作。

因此,你所编写的代码(如上所述)将更新工作目录以匹配分支的内容。之后,你需要将分支更新到想要切换的分支。

你可以使用 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();

1
谢谢!现在它按预期工作了!我还会将您的答案添加到此问题(https://stackoverflow.com/a/30469509/4942153),以避免“git_checkout_options上的无效版本0”错误。 - Abdelilah El Aissaoui

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接