Example #1
0
/**
 * 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;
}
Example #2
0
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;
}