int git_rebase_init( git_rebase **out, git_repository *repo, const git_annotated_commit *branch, const git_annotated_commit *upstream, const git_annotated_commit *onto, const git_signature *signature, const git_rebase_options *given_opts) { git_rebase *rebase = NULL; git_rebase_options opts; git_reference *head_ref = NULL; git_buf reflog = GIT_BUF_INIT; git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT; int error; assert(repo && branch && (upstream || onto)); *out = NULL; GITERR_CHECK_VERSION(given_opts, GIT_REBASE_OPTIONS_VERSION, "git_rebase_options"); if (!onto) onto = upstream; checkout_opts.checkout_strategy = GIT_CHECKOUT_FORCE; if ((error = rebase_normalize_opts(repo, &opts, given_opts)) < 0 || (error = git_repository__ensure_not_bare(repo, "rebase")) < 0 || (error = rebase_ensure_not_in_progress(repo)) < 0 || (error = rebase_ensure_not_dirty(repo)) < 0) return error; rebase = git__calloc(1, sizeof(git_rebase)); GITERR_CHECK_ALLOC(rebase); if ((error = rebase_init(rebase, repo, branch, upstream, onto, &opts)) < 0 || (error = rebase_setupfiles(rebase)) < 0 || (error = git_buf_printf(&reflog, "rebase: checkout %s", rebase_onto_name(onto))) < 0 || (error = git_reference_create(&head_ref, repo, GIT_HEAD_FILE, git_annotated_commit_id(onto), 1, signature, reflog.ptr)) < 0 || (error = git_checkout_head(repo, &checkout_opts)) < 0) goto done; *out = rebase; done: if (error < 0) { rebase_cleanup(rebase); git_rebase_free(rebase); } git_reference_free(head_ref); git_buf_free(&reflog); rebase_opts_free(&opts); return error; }
static int rebase_commit_merge( git_oid *commit_id, git_rebase *rebase, const git_signature *author, const git_signature *committer, const char *message_encoding, const char *message) { git_rebase_operation *operation; git_reference *head = NULL; git_commit *head_commit = NULL, *commit = NULL; git_index *index = NULL; char old_idstr[GIT_OID_HEXSZ], new_idstr[GIT_OID_HEXSZ]; int error; operation = git_array_get(rebase->operations, rebase->current); assert(operation); if ((error = rebase_ensure_not_dirty(rebase->repo, false, true, GIT_EUNMERGED)) < 0 || (error = git_repository_head(&head, rebase->repo)) < 0 || (error = git_reference_peel((git_object **)&head_commit, head, GIT_OBJ_COMMIT)) < 0 || (error = git_repository_index(&index, rebase->repo)) < 0 || (error = rebase_commit__create(&commit, rebase, index, head_commit, author, committer, message_encoding, message)) < 0 || (error = git_reference__update_for_commit( rebase->repo, NULL, "HEAD", git_commit_id(commit), "rebase")) < 0) goto done; git_oid_fmt(old_idstr, &operation->id); git_oid_fmt(new_idstr, git_commit_id(commit)); if ((error = rebase_setupfile(rebase, REWRITTEN_FILE, O_CREAT|O_WRONLY|O_APPEND, "%.*s %.*s\n", GIT_OID_HEXSZ, old_idstr, GIT_OID_HEXSZ, new_idstr)) < 0) goto done; git_oid_cpy(commit_id, git_commit_id(commit)); done: git_index_free(index); git_reference_free(head); git_commit_free(head_commit); git_commit_free(commit); return error; }
int git_rebase_init( git_rebase **out, git_repository *repo, const git_annotated_commit *branch, const git_annotated_commit *upstream, const git_annotated_commit *onto, const git_rebase_options *given_opts) { git_rebase *rebase = NULL; git_annotated_commit *head_branch = NULL; git_reference *head_ref = NULL; bool inmemory = (given_opts && given_opts->inmemory); int error; assert(repo && (upstream || onto)); *out = NULL; if (!onto) onto = upstream; if ((error = rebase_check_versions(given_opts)) < 0) goto done; if (!inmemory) { if ((error = git_repository__ensure_not_bare(repo, "rebase")) < 0 || (error = rebase_ensure_not_in_progress(repo)) < 0 || (error = rebase_ensure_not_dirty(repo, true, true, GIT_ERROR)) < 0) goto done; } if (!branch) { if ((error = git_repository_head(&head_ref, repo)) < 0 || (error = git_annotated_commit_from_ref(&head_branch, repo, head_ref)) < 0) goto done; branch = head_branch; } if (rebase_alloc(&rebase, given_opts) < 0) return -1; rebase->repo = repo; rebase->inmemory = inmemory; rebase->type = GIT_REBASE_TYPE_MERGE; if ((error = rebase_init_operations(rebase, repo, branch, upstream, onto)) < 0) goto done; if (inmemory) error = rebase_init_inmemory(rebase, repo, branch, upstream, onto); else rebase_init_merge(rebase, repo, branch ,upstream, onto); if (error == 0) *out = rebase; done: git_reference_free(head_ref); git_annotated_commit_free(head_branch); if (error < 0) { rebase_cleanup(rebase); git_rebase_free(rebase); } return error; }