无法创建提交:当前提示不是 libgit2 中提交期间的第一个父错误
failed to create commit: current tip is not the first parent error during commit in libgit2
我正在使用 libgit2 v0.23.0 库进行 git 拉取和提交操作。我正在调用 git_merge(repo,their_heads,1,&merge_opt,&checkout_opts);
方法,它工作正常并将更改从远程存储库合并到本地存储库。但是在那之后,当我调用 git_commit_create()
方法时,它会抛出错误,因为 无法创建提交:当前提示不是第一个父 ,错误代码为 -15 。
我调查并发现 FETCH_HEAD 和 MERGE_HEAD 文件包含更新的 oid,但 ORIG_HEAD 仍然包含 previous/outdated oid。我不确定这是我在 git_commit_create() 期间遇到的错误原因。
int fetch()
{
qDebug()<<"Fetch";
git_remote *remote = NULL;
const git_transfer_progress *stats;
struct dl_data data;
git_fetch_options fetch_opts = GIT_FETCH_OPTIONS_INIT;
git_repository *repo = NULL;
QString repoPath = "repopath/.git";
int error = git_repository_open(&repo, repoPath.toStdString().c_str());
if (git_remote_lookup(&remote, repo, "origin") < 0) {
if (git_remote_create_anonymous(&remote, repo,"repoURL") < 0)
return -1;
}
fetch_opts.callbacks.update_tips = &update_cb;
fetch_opts.callbacks.sideband_progress = &progress_cb;
fetch_opts.callbacks.credentials = cred_acquire_cb;
data.remote = remote;
data.fetch_opts = &fetch_opts;
data.ret = 0;
data.finished = 0;
stats = git_remote_stats(remote);
download(&data);
if (stats->local_objects > 0) {
printf("\rReceived %d/%d objects in % bytes (used %d local objects)\n",
stats->indexed_objects, stats->total_objects, stats->received_bytes, stats->local_objects);
} else{
printf("\rReceived %d/%d objects in %bytes\n",
stats->indexed_objects, stats->total_objects, stats->received_bytes);
}
git_remote_disconnect(remote);
if (git_remote_update_tips(remote, &fetch_opts.callbacks, 1, fetch_opts.download_tags, NULL) < 0)
return -1;
const git_remote_head **head = NULL;
size_t size = 0;
(git_remote_ls(&head, &size, remote));
git_oid oid = head[0]->oid;
char * commit_id1 = new char[41]; //Commit ID
qDebug()<<"oid:"<<git_oid_tostr(commit_id1, 41, &oid);
git_annotated_commit *anno_out ;
git_annotated_commit_lookup(&anno_out,repo,&oid);
git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT;
checkout_opts.checkout_strategy = GIT_CHECKOUT_FORCE;
const git_annotated_commit **their_heads = const_cast<const git_annotated_commit**>(&anno_out);
git_merge_options merge_opt = GIT_MERGE_OPTIONS_INIT;
merge_opt.file_favor = GIT_MERGE_FILE_FAVOR_UNION;
error = git_merge(repo,their_heads,1,&merge_opt,&checkout_opts);
if(error!=0){
//Error handling
}
else{
qDebug()<<"Merge successfully";
}
git_repository_state_cleanup(repo);
/* Create signature */
git_signature *me = NULL;
(git_signature_now(&me, "username", "username@gmail.com"));
//Tree Lookup
git_tree *tree;
git_object *tree_obj;
(git_revparse_single(&tree_obj, repo, "HEAD^{tree}"));
// Get parent commit
git_oid parentCommitId;
git_commit *parent;
git_oid remoteParentCommitId;
git_commit *remoteParent;
int nparents;
int err;
(git_reference_name_to_id( &parentCommitId, repo, "ORIG_HEAD" ));
(git_commit_lookup( &parent, repo, &parentCommitId ));
(git_reference_name_to_id( &remoteParentCommitId, repo, "MERGE_HEAD" ));
(git_commit_lookup( &remoteParent, repo, &remoteParentCommitId ));
const git_commit *parents [1] = {remoteParent };
git_oid new_commit_id;
err = (git_commit_create(
&new_commit_id,
repo,
"HEAD", /* name of ref to update */
me, /* author */
me, /* committer */
"UTF-8", /* message encoding */
"pull fetch", /* message */
(git_tree *) tree_obj, /* root tree */
1, /* parent count */
parents)); /* parents */
if(err !=0){
//I am getting error here
}
git_remote_free(remote);
return 0;
}
请建议我如何解决此问题?
通常,您看到此错误是因为您正在一个 parent 不是分支的当前提示的分支上构建新提交。实际上,您正在构建一个新提交,其 parent 是 远程 提交而不是本地提交。
有几个问题:
建议对所有函数进行一些错误检查。我看到一些功能可能会失败,但没有对此进行检查。例如:
不要在操作过程中调用 git_repository_state_cleanup
。这将中止合并并清除您稍后尝试读取的状态文件。喜欢MERGE_HEAD
.
您正在进行合并。您应该有两个 parent 提交(您正在合并的两个提交)到新提交。您应该将 { parent, remoteParent }
作为 parent 传递。
我正在使用 libgit2 v0.23.0 库进行 git 拉取和提交操作。我正在调用 git_merge(repo,their_heads,1,&merge_opt,&checkout_opts);
方法,它工作正常并将更改从远程存储库合并到本地存储库。但是在那之后,当我调用 git_commit_create()
方法时,它会抛出错误,因为 无法创建提交:当前提示不是第一个父 ,错误代码为 -15 。
我调查并发现 FETCH_HEAD 和 MERGE_HEAD 文件包含更新的 oid,但 ORIG_HEAD 仍然包含 previous/outdated oid。我不确定这是我在 git_commit_create() 期间遇到的错误原因。
int fetch()
{
qDebug()<<"Fetch";
git_remote *remote = NULL;
const git_transfer_progress *stats;
struct dl_data data;
git_fetch_options fetch_opts = GIT_FETCH_OPTIONS_INIT;
git_repository *repo = NULL;
QString repoPath = "repopath/.git";
int error = git_repository_open(&repo, repoPath.toStdString().c_str());
if (git_remote_lookup(&remote, repo, "origin") < 0) {
if (git_remote_create_anonymous(&remote, repo,"repoURL") < 0)
return -1;
}
fetch_opts.callbacks.update_tips = &update_cb;
fetch_opts.callbacks.sideband_progress = &progress_cb;
fetch_opts.callbacks.credentials = cred_acquire_cb;
data.remote = remote;
data.fetch_opts = &fetch_opts;
data.ret = 0;
data.finished = 0;
stats = git_remote_stats(remote);
download(&data);
if (stats->local_objects > 0) {
printf("\rReceived %d/%d objects in % bytes (used %d local objects)\n",
stats->indexed_objects, stats->total_objects, stats->received_bytes, stats->local_objects);
} else{
printf("\rReceived %d/%d objects in %bytes\n",
stats->indexed_objects, stats->total_objects, stats->received_bytes);
}
git_remote_disconnect(remote);
if (git_remote_update_tips(remote, &fetch_opts.callbacks, 1, fetch_opts.download_tags, NULL) < 0)
return -1;
const git_remote_head **head = NULL;
size_t size = 0;
(git_remote_ls(&head, &size, remote));
git_oid oid = head[0]->oid;
char * commit_id1 = new char[41]; //Commit ID
qDebug()<<"oid:"<<git_oid_tostr(commit_id1, 41, &oid);
git_annotated_commit *anno_out ;
git_annotated_commit_lookup(&anno_out,repo,&oid);
git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT;
checkout_opts.checkout_strategy = GIT_CHECKOUT_FORCE;
const git_annotated_commit **their_heads = const_cast<const git_annotated_commit**>(&anno_out);
git_merge_options merge_opt = GIT_MERGE_OPTIONS_INIT;
merge_opt.file_favor = GIT_MERGE_FILE_FAVOR_UNION;
error = git_merge(repo,their_heads,1,&merge_opt,&checkout_opts);
if(error!=0){
//Error handling
}
else{
qDebug()<<"Merge successfully";
}
git_repository_state_cleanup(repo);
/* Create signature */
git_signature *me = NULL;
(git_signature_now(&me, "username", "username@gmail.com"));
//Tree Lookup
git_tree *tree;
git_object *tree_obj;
(git_revparse_single(&tree_obj, repo, "HEAD^{tree}"));
// Get parent commit
git_oid parentCommitId;
git_commit *parent;
git_oid remoteParentCommitId;
git_commit *remoteParent;
int nparents;
int err;
(git_reference_name_to_id( &parentCommitId, repo, "ORIG_HEAD" ));
(git_commit_lookup( &parent, repo, &parentCommitId ));
(git_reference_name_to_id( &remoteParentCommitId, repo, "MERGE_HEAD" ));
(git_commit_lookup( &remoteParent, repo, &remoteParentCommitId ));
const git_commit *parents [1] = {remoteParent };
git_oid new_commit_id;
err = (git_commit_create(
&new_commit_id,
repo,
"HEAD", /* name of ref to update */
me, /* author */
me, /* committer */
"UTF-8", /* message encoding */
"pull fetch", /* message */
(git_tree *) tree_obj, /* root tree */
1, /* parent count */
parents)); /* parents */
if(err !=0){
//I am getting error here
}
git_remote_free(remote);
return 0;
}
请建议我如何解决此问题?
通常,您看到此错误是因为您正在一个 parent 不是分支的当前提示的分支上构建新提交。实际上,您正在构建一个新提交,其 parent 是 远程 提交而不是本地提交。
有几个问题:
建议对所有函数进行一些错误检查。我看到一些功能可能会失败,但没有对此进行检查。例如:
不要在操作过程中调用
git_repository_state_cleanup
。这将中止合并并清除您稍后尝试读取的状态文件。喜欢MERGE_HEAD
.您正在进行合并。您应该有两个 parent 提交(您正在合并的两个提交)到新提交。您应该将
{ parent, remoteParent }
作为 parent 传递。