尝试使用 libgit2 快进时"cannot set OID on symbolic reference"
"cannot set OID on symbolic reference" when trying to fast-forward with libgit2
注意:我标记了 C 和C++,因为libgit2是一个C库,我正在为常见的 git 命令编写一个C++包装器。我们将在这里看到 C 和 C++代码,就我而言,我是否获得面向C或C++的解决方案并不重要(如果需要,我会自己调整它(。
当分支可快进(使用libgit2(时,我正在尝试在gitPull()
函数中对存储库执行快进更新。我只想在必要时执行合并。
我的策略如下所示(我删除了错误检查,...为了仅针对基本要素并使代码尽可能简单(:
// INFO: I assume here I already have an open repository in a "repo" variable.
// Do the fetch --> works fine
// ...
// Compare HEAD and FETCH_HEAD
git_oid head_id;
git_reference_name_to_id(&head_id, repo, "HEAD");
git_oid fetch_head_id;
git_reference_name_to_id(&fetch_head_id, repo, "FETCH_HEAD");
if(!git_oid_equal(&fetch_head_id, &head_id)) // A pull is needed
{
// Check if we can fast-forward or need a merge
git_annotated_commit * fetch_head_annotated_commit = nullptr;
git_annotated_commit_lookup(&fetch_head_annotated_commit, repo, &fetch_head_id);
git_merge_analysis_t an_out;
git_merge_preference_t pref_out;
git_merge_analysis(&an_out, &pref_out, repo, const_cast<const git_annotated_commit **>(&fetch_head_annotated_commit),1);
if(an_out & GIT_MERGE_ANALYSIS_FASTFORWARD) // A fast-forward is possible
{
git_reference * head_ref = nullptr;
git_reference_lookup(&head_ref, repo, "HEAD");
git_reference * new_head_ref = nullptr;
git_reference_set_target(&new_head_ref, head_ref, &fetch_head_id, "");
git_checkout_head(repo, nullptr);
git_reference_free(new_head_ref);
git_reference_free(head_ref);
}
else // A merge is needed
{
// Do the merge and create the related commit
// ...
}
git_annotated_commit_free(fetch_head_annotated_commit);
}
奇怪的是,条件if(an_out & GIT_MERGE_ANALYSIS_FASTFORWARD)
true
但是当我git_reference_set_target(&new_head_ref, head_ref, &fetch_head_id, "");
运行函数时,我收到以下错误:
"无法在符号引用上设置 OID">
我做了一个研究,我在refs.c的libgit2源代码中找到了你可以在下面看到的内容:
static int ensure_is_an_updatable_direct_reference(git_reference *ref) { if (ref->type == GIT_REFERENCE_DIRECT) return 0; git_error_set(GIT_ERROR_REFERENCE, "cannot set OID on symbolic reference"); return -1; } int git_reference_set_target( git_reference **out, git_reference *ref, const git_oid *id, const char *log_message) { int error; git_repository *repo; assert(out && ref && id); repo = ref->db->repo; if ((error = ensure_is_an_updatable_direct_reference(ref)) < 0) return error; return git_reference_create_matching(out, repo, ref->name, id, 1, &ref->target.oid, log_message); }
通过阅读此代码,我们可以看到问题在于ref
参数(在我的例子中是"HEAD">引用(不是"可更新的直接引用"。
换句话说,没有找到从"HEAD"到"FETCH_HEAD">的直接路径(因为我通过了fetch_head_id
(。
我不明白的是,如果我是对的,检查分支是否可以快进的方法是验证它是否存在"HEAD"和"FETCH_HEAD">之间的直接路径。
因此,输入条件并听到它说它不是"可更新的直接参考",在我看来似乎是矛盾的。
我的问题是:我错过了什么?我误解了什么?(我知道相当广泛的问题,这就是为什么我提供了尽可能多的细节(。
我将非常感谢任何有助于我摆脱问题并使其发挥作用的提示。
今天早上我才意识到我很愚蠢:)
在我的情况下,"HEAD"是对"refs/heads/master">的象征性引用。因此,错误通知的是我需要传递直接引用,而不是别名。
- 为什么我无法更改"set<set>"循环中的值<int>
- 对于set上的循环-获取next元素迭代器
- 在声明中合并两个常量"std::set"(不是在运行时)
- 有没有办法对std::unordered_set、std::unrdered_map、std::set、std::map
- 将 std::set 与基于键的比较器一起使用
- 如何使用set实现无序数据结构?
- 赛通"Cannot take address of memoryview slice"
- 使用运算符调用 void 函数时出错<set>
- C++:如何将 unix 时间的字符串转换为 *tm?(使用时间错误:"cannot convert 'String' to 'tm*' ")
- 修改"std::set"中用户定义类型的值
- /usr/bin/ld: cannot find -lc++
- 生成提升::hana::set 的常量表达式问题
- 如何在构造函数参数中初始化"std::set"?
- 如何使用 lower_bound/upper_bound 从 std::set 获取索引号?
- 如何在 C++ 中转发声明 std::set?
- Cannot find -lglad
- "Cannot find -l<directory>"错误 - CMake
- 重构使用动态强制转换的 std::set 的比较运算符
- 尝试使用 libgit2 快进时"cannot set OID on symbolic reference"
- Visual Studio xtree _STL_VERIFY(this->_Getcont(), "cannot increment value-initialized map/set ite