Не удалось создать коммит: текущий совет не является первой родительской ошибкой во время коммита в libgit2
Я использую библиотеку libgit2 v0.23.0 для операции git pull & commit. я звоню git_merge(repo,their_heads,1,&merge_opt,&checkout_opts);
Метод работает нормально и объединяет изменения из удаленного хранилища в локальное хранилище. Но после этого, когда я звоню git_commit_create()
метод, он выдает ошибку, поскольку не удалось создать коммит: текущий совет не является первым родителем с кодом ошибки -15.
Я исследовал и обнаружил, что файл FETCH_HEAD и MERGE_HEAD содержит обновленный oid, но ORIG_HEAD все еще содержит предыдущий / устаревший 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;
}
Пожалуйста, предложите мне, что я должен сделать, чтобы решить эту проблему?
1 ответ
Как правило, вы видите эту ошибку, потому что вы строите новый коммит на ветке, чей родитель не является текущим кончиком ветви. Действительно, вы создаете новый коммит, чьим родителем является удаленный коммит, а не локальный.
Есть несколько проблем:
Рекомендуется некоторая проверка ошибок на всех функциях. Я вижу некоторые функции, которые, вероятно, не работают, но нет проверки для этого. Например:
Не звони
git_repository_state_cleanup
в середине вашей операции. Это прервет объединение и очистит файлы состояния, которые вы пытаетесь прочитать позже. подобноMERGE_HEAD
,Вы делаете слияние. У вас должно быть два родительских коммита (два коммита, которые вы объединяете) с новым коммитом. Вы должны пройти
{ parent, remoteParent }
как родители.