/** * Perform a normal merge * * @param merge_result S4 class git_merge_result * @param merge_heads The merge heads to merge * @param n The number of merge heads * @param repository The repository * @param message The commit message of the merge * @param merger Who is performing the merge * @param commit_on_success Commit merge commit, if one was created * @param merge_opts Merge options * @return 0 on success, or error code */ static int git2r_normal_merge( SEXP merge_result, const git_annotated_commit **merge_heads, size_t n, git_repository *repository, const char *message, git_signature *merger, int commit_on_success, const git_checkout_options *checkout_opts, const git_merge_options *merge_opts) { int err; git_commit *commit = NULL; git_index *index = NULL; SET_SLOT(merge_result, Rf_install("fast_forward"), ScalarLogical(0)); err = git_merge( repository, merge_heads, n, merge_opts, checkout_opts); if (err) goto cleanup; err = git_repository_index(&index, repository); if (err) goto cleanup; if (git_index_has_conflicts(index)) { SET_SLOT(merge_result, Rf_install("conflicts"), ScalarLogical(1)); } else { SET_SLOT(merge_result, Rf_install("conflicts"), ScalarLogical(0)); if (commit_on_success) { char sha[GIT_OID_HEXSZ + 1]; git_oid oid; err = git2r_commit_create( &oid, repository, index, message, merger, merger); if (err) goto cleanup; git_oid_fmt(sha, &oid); sha[GIT_OID_HEXSZ] = '\0'; SET_SLOT(merge_result, Rf_install("sha"), mkString(sha)); } } cleanup: if (commit) git_commit_free(commit); if (index) git_index_free(index); return err; }
/** * Commit * * @param repo S4 class git_repository * @param message The message for the commit * @param author S4 class git_signature * @param committer S4 class git_signature * @return S4 class git_commit */ SEXP git2r_commit( SEXP repo, SEXP message, SEXP author, SEXP committer) { int err; SEXP result = R_NilValue; git_signature *c_author = NULL; git_signature *c_committer = NULL; git_index *index = NULL; git_oid oid; git_repository *repository = NULL; git_commit *commit = NULL; if (git2r_arg_check_string(message)) git2r_error(git2r_err_string_arg, __func__, "message"); if (git2r_arg_check_signature(author)) git2r_error(git2r_err_signature_arg, __func__, "author"); if (git2r_arg_check_signature(committer)) git2r_error(git2r_err_signature_arg, __func__, "committer"); repository = git2r_repository_open(repo); if (!repository) git2r_error(git2r_err_invalid_repository, __func__, NULL); err = git2r_signature_from_arg(&c_author, author); if (GIT_OK != err) goto cleanup; err = git2r_signature_from_arg(&c_committer, committer); if (GIT_OK != err) goto cleanup; err = git2r_any_changes_in_index(repository); if (GIT_OK != err) goto cleanup; err = git_repository_index(&index, repository); if (GIT_OK != err) goto cleanup; err = git2r_commit_create( &oid, repository, index, CHAR(STRING_ELT(message, 0)), c_author, c_committer); if (GIT_OK != err) goto cleanup; err = git_commit_lookup(&commit, repository, &oid); if (GIT_OK != err) goto cleanup; PROTECT(result = NEW_OBJECT(MAKE_CLASS("git_commit"))); git2r_commit_init(commit, repo, result); cleanup: if (c_author) git_signature_free(c_author); if (c_committer) git_signature_free(c_committer); if (index) git_index_free(index); if (repository) git_repository_free(repository); if (commit) git_commit_free(commit); if (R_NilValue != result) UNPROTECT(1); if (GIT_OK != err) git2r_error(git2r_err_from_libgit2, __func__, giterr_last()->message); return result; }