/** * Retrieve parents of the commit under construction * * @param parents The vector of parents to create and populate. * @param n_parents The length of parents vector * @param repository The repository * @return 0 on succes, or error code */ static int git2r_retrieve_parents( git_commit ***parents, size_t *n_parents, git_repository *repository) { int err; git_oid oid; git2r_merge_head_cb_data cb_data = {0, NULL, NULL}; git_repository_state_t state; err = git_repository_head_unborn(repository); if (1 == err) { *n_parents = 0; return GIT_OK; } else if (0 != err) { return err; } state = git_repository_state(repository); if (state == GIT_REPOSITORY_STATE_MERGE) { /* Count number of merge heads */ err = git_repository_mergehead_foreach( repository, git2r_repository_mergehead_foreach_cb, &cb_data); if (GIT_OK != err) return err; } *parents = calloc(cb_data.n + 1, sizeof(git_commit*)); if (!parents) { giterr_set_str(GITERR_NONE, git2r_err_alloc_memory_buffer); return GIT_ERROR; } *n_parents = cb_data.n + 1; err = git_reference_name_to_id(&oid, repository, "HEAD"); if (GIT_OK != err) return err; err = git_commit_lookup(&**parents, repository, &oid); if (GIT_OK != err) return err; if (state == GIT_REPOSITORY_STATE_MERGE) { /* Append merge heads to parents */ cb_data.n = 0; cb_data.repository = repository; cb_data.parents = *parents + 1; err = git_repository_mergehead_foreach( repository, git2r_repository_mergehead_foreach_cb, &cb_data); if (GIT_OK != err) return err; } return GIT_OK; }
bool PmrWorkspace::commitMerge() { // Get the number of merge heads so we can allocate an array for parents MergeheadForeachCallbackData data = { 0, nullptr, nullptr }; git_repository_mergehead_foreach(mGitRepository, mergeheadForeachCallback, &data); size_t parentsCount = data.size+1; auto parents = new git_commit*[parentsCount](); // HEAD is always a parent bool res = false; git_oid parentId; if ( (git_reference_name_to_id(&parentId, mGitRepository, "HEAD") == GIT_OK) && (git_commit_lookup(parents, mGitRepository, &parentId) == GIT_OK)) { res = true; // Populate the list of commit parents if (parentsCount > 1) { data.size = 0; data.repository = mGitRepository; data.parents = &(parents[1]); if (git_repository_mergehead_foreach(mGitRepository, mergeheadForeachCallback, &data) != GIT_OK) { res = false; } } if (res) { std::string message = std::string("Merge branch 'master' of "); if (commit(message.c_str(), parentsCount, const_cast<const git_commit **>(parents))) { git_repository_state_cleanup(mGitRepository); } else { res = false; } } } for (size_t n = 0; n < parentsCount; ++n) { git_commit_free(parents[n]); } delete[] parents; if (!res) { emitGitError(tr("An error occurred while trying to commit the merge.")); } return res; }