static void test_abort(git_annotated_commit *branch, git_annotated_commit *onto) { git_rebase *rebase; git_reference *head_ref, *branch_ref = NULL; git_signature *signature; git_status_list *statuslist; git_reflog *reflog; const git_reflog_entry *reflog_entry; cl_git_pass(git_rebase_open(&rebase, repo)); cl_git_pass(git_signature_new(&signature, "Rebaser", "*****@*****.**", 1404157834, -400)); cl_git_pass(git_rebase_abort(rebase, signature)); cl_assert_equal_i(GIT_REPOSITORY_STATE_NONE, git_repository_state(repo)); /* Make sure the refs are updated appropriately */ cl_git_pass(git_reference_lookup(&head_ref, repo, "HEAD")); if (branch->ref_name == NULL) cl_assert_equal_oid(git_annotated_commit_id(branch), git_reference_target(head_ref)); else { cl_assert_equal_s("refs/heads/beef", git_reference_symbolic_target(head_ref)); cl_git_pass(git_reference_lookup(&branch_ref, repo, git_reference_symbolic_target(head_ref))); cl_assert_equal_oid(git_annotated_commit_id(branch), git_reference_target(branch_ref)); } git_status_list_new(&statuslist, repo, NULL); cl_assert_equal_i(0, git_status_list_entrycount(statuslist)); git_status_list_free(statuslist); /* Make sure the reflogs are updated appropriately */ cl_git_pass(git_reflog_read(&reflog, repo, "HEAD")); cl_assert(reflog_entry = git_reflog_entry_byindex(reflog, 0)); cl_assert_equal_oid(git_annotated_commit_id(onto), git_reflog_entry_id_old(reflog_entry)); cl_assert_equal_oid(git_annotated_commit_id(branch), git_reflog_entry_id_new(reflog_entry)); cl_assert_equal_s("rebase: aborting", git_reflog_entry_message(reflog_entry)); git_reflog_free(reflog); git_reference_free(head_ref); git_reference_free(branch_ref); git_signature_free(signature); git_rebase_free(rebase); }
int main() { git_libgit2_init(); git_repository* rep = nullptr; git_rebase* prebase = nullptr; git_rebase_options rebase_opt = GIT_REBASE_OPTIONS_INIT; git_reference* onto_branch = nullptr; git_annotated_commit* onto = nullptr; git_rebase_operation* operation = nullptr; size_t entrycount; size_t current; git_signature* me = nullptr; git_index* index = nullptr; git_oid new_commit; int error = 0; // git open git_repository_open(&rep, path); error = git_rebase_open(&prebase, rep, &rebase_opt); // There is no rebase in progress if (error == GIT_ENOTFOUND) { git_branch_lookup(&onto_branch, rep, "new", GIT_BRANCH_LOCAL); git_annotated_commit_from_ref(&onto, rep, onto_branch); git_rebase_init(&prebase, rep, nullptr /* current branch */, nullptr /* upstream */ , onto /* branch to rebase onto */, &rebase_opt); } else if (error < 0) { const git_error *e = giterr_last(); std::cout << "Error: " << error << " / " << e->klass << " : " << e->message << std::endl; goto SHUTDOWN; } entrycount = git_rebase_operation_entrycount(prebase); std::cout<< "rebase entry count: " << entrycount << "\n"; while (git_rebase_next(&operation, prebase) != GIT_ITEROVER) { current = git_rebase_operation_current(prebase); // (called `init` but not yet `next`) then this returns `GIT_REBASE_NO_OPERATION` std::cout<< "rebase current index: " << current << "\n"; if (GIT_REBASE_NO_OPERATION == current) { std::cout<< "rebase no operation" << "\n"; } operation = git_rebase_operation_byindex(prebase, 0); } // reslove conflicts git_repository_index(&index, rep); if (git_index_has_conflicts(index)) { // git checkout --theirs git_checkout_options opt = GIT_CHECKOUT_OPTIONS_INIT; opt.checkout_strategy |= GIT_CHECKOUT_USE_THEIRS; git_checkout_index(rep, index, &opt); } // add git_index_update_all(index, nullptr, nullptr, nullptr); git_index_write(index); // commit git_signature_now(&me, "XiaochenFTX", "*****@*****.**"); git_rebase_commit(&new_commit, prebase, me, me, "UTF-8", "new rebase"); error = git_rebase_finish(prebase, me); if (error < 0) { const git_error *e = giterr_last(); std::cout << "Error: " << error << " / " << e->klass << " : " << e->message << std::endl; goto SHUTDOWN; } // git_rebase_abort(prebase); git_rebase_free(prebase); SHUTDOWN: git_repository_free(rep); git_libgit2_shutdown(); return 0; }
void test_rebase_iterator__iterates(void) { git_rebase *rebase; git_reference *branch_ref, *upstream_ref; git_annotated_commit *branch_head, *upstream_head; git_rebase_operation *rebase_operation; git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT; git_oid commit_id; int error; checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE; cl_git_pass(git_reference_lookup(&branch_ref, repo, "refs/heads/beef")); cl_git_pass(git_reference_lookup(&upstream_ref, repo, "refs/heads/master")); cl_git_pass(git_annotated_commit_from_ref(&branch_head, repo, branch_ref)); cl_git_pass(git_annotated_commit_from_ref(&upstream_head, repo, upstream_ref)); cl_git_pass(git_rebase_init(&rebase, repo, branch_head, upstream_head, NULL, signature, NULL)); test_operations(rebase, 0); git_rebase_free(rebase); cl_git_pass(git_rebase_open(&rebase, repo)); cl_git_pass(git_rebase_next(&rebase_operation, rebase, &checkout_opts)); cl_git_pass(git_rebase_commit(&commit_id, rebase, NULL, signature, NULL, NULL)); test_operations(rebase, 0); cl_git_pass(git_rebase_next(&rebase_operation, rebase, &checkout_opts)); cl_git_pass(git_rebase_commit(&commit_id, rebase, NULL, signature, NULL, NULL)); test_operations(rebase, 1); cl_git_pass(git_rebase_next(&rebase_operation, rebase, &checkout_opts)); cl_git_pass(git_rebase_commit(&commit_id, rebase, NULL, signature, NULL, NULL)); test_operations(rebase, 2); git_rebase_free(rebase); cl_git_pass(git_rebase_open(&rebase, repo)); cl_git_pass(git_rebase_next(&rebase_operation, rebase, &checkout_opts)); cl_git_pass(git_rebase_commit(&commit_id, rebase, NULL, signature, NULL, NULL)); test_operations(rebase, 3); cl_git_pass(git_rebase_next(&rebase_operation, rebase, &checkout_opts)); cl_git_pass(git_rebase_commit(&commit_id, rebase, NULL, signature, NULL, NULL)); test_operations(rebase, 4); cl_git_fail(error = git_rebase_next(&rebase_operation, rebase, &checkout_opts)); cl_assert_equal_i(GIT_ITEROVER, error); test_operations(rebase, 4); git_annotated_commit_free(branch_head); git_annotated_commit_free(upstream_head); git_reference_free(branch_ref); git_reference_free(upstream_ref); git_rebase_free(rebase); }
int cmd_rebase(git_repository *repo, int argc, char **argv) { int err = GIT_OK; int rc = EXIT_FAILURE; git_signature *sig = NULL; const char *upstream_str; git_reference *upstream_ref = NULL; git_annotated_commit *upstream = NULL; git_reference *branch_ref = NULL; git_annotated_commit *branch = NULL; git_rebase *rebase = NULL; int abort = 0; int cont = 0; if (argc < 2) { fprintf(stderr, "USAGE: %s <upstream>\n", argv[0]); fprintf(stderr, "USAGE: %s --abort|--continue\n", argv[0]); goto out; } upstream_str = argv[1]; if (!strcmp(upstream_str, "--abort")) abort = 1; else if (!strcmp(upstream_str, "--continue")) cont = 1; if ((err = sgit_get_author_signature(repo, &sig))) goto out; if (abort) { if ((err = git_rebase_open(&rebase, repo))) goto out; if ((err = git_rebase_abort(rebase, sig))) goto out; } else { git_rebase_operation *oper; git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT; git_rebase_options rebase_opts = GIT_REBASE_OPTIONS_INIT; checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE; if (cont) { if ((err = git_rebase_open(&rebase, repo))) goto out; } else { if ((err = git_reference_dwim(&upstream_ref, repo, upstream_str))) goto out; if ((err = git_annotated_commit_from_ref(&upstream, repo, upstream_ref))) goto out; if ((err = git_repository_head(&branch_ref,repo)) < 0) goto out; if ((err = git_annotated_commit_from_ref(&branch, repo, branch_ref))) goto out; if ((err = git_rebase_init(&rebase, repo, branch, upstream, NULL, NULL, NULL))) goto out; } while (!(err = git_rebase_next(&oper, rebase, &checkout_opts))) { git_oid oid; if ((err = git_rebase_commit(&oid, rebase, NULL, sig, NULL, NULL))) goto out; } if (err != GIT_ITEROVER && err != GIT_OK) goto out; if ((err = git_rebase_finish(rebase, sig, &rebase_opts))) goto out; } out: if (err != GIT_OK) libgit_error(); if (rebase) git_rebase_free(rebase); if (upstream) git_annotated_commit_free(upstream); if (upstream_ref) git_reference_free(upstream_ref); if (branch) git_annotated_commit_free(branch); if (branch_ref) git_reference_free(branch_ref); if (sig) git_signature_free(sig); return rc; }