无法创建提交:当前提示不是 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 是 远程 提交而不是本地提交。

有几个问题:

  1. 建议对所有函数进行一些错误检查。我看到一些功能可能会失败,但没有对此进行检查。例如:

  2. 不要在操作过程中调用 git_repository_state_cleanup。这将中止合并并清除您稍后尝试读取的状态文件。喜欢MERGE_HEAD.

  3. 您正在进行合并。您应该有两个 parent 提交(您正在合并的两个提交)到新提交。您应该将 { parent, remoteParent } 作为 parent 传递。