Commit b6b636a7 by Edward Thomson

rebase: init/open a git_rebase object

parent 18b439b9
......@@ -114,9 +114,12 @@ GIT_EXTERN(int) git_rebase_init_options(
unsigned int version);
/**
* Sets up a rebase operation to rebase the changes in ours relative to
* upstream onto another branch.
* Initializes a rebase operation to rebase the changes in `ours`
* relative to `upstream` onto another branch. To begin the rebase
* process, call `git_rebase_next`. When you have finished with this
* object, call `git_rebase_free`.
*
* @param out Pointer to store the rebase object
* @param repo The repository to perform the rebase
* @param branch The terminal commit to rebase
* @param upstream The commit to begin rebasing from, or NULL to rebase all
......@@ -127,7 +130,8 @@ GIT_EXTERN(int) git_rebase_init_options(
* @param opts Options to specify how rebase is performed
* @return Zero on success; -1 on failure.
*/
GIT_EXTERN(int) git_rebase(
GIT_EXTERN(int) git_rebase_init(
git_rebase **out,
git_repository *repo,
const git_merge_head *branch,
const git_merge_head *upstream,
......@@ -136,6 +140,16 @@ GIT_EXTERN(int) git_rebase(
const git_rebase_options *opts);
/**
* Opens an existing rebase that was previously started by either an
* invocation of `git_rebase_init` or by another client.
*
* @param out Pointer to store the rebase object
* @param reop The repository that has a rebase in-progress
* @return Zero on success; -1 on failure.
*/
GIT_EXTERN(int) git_rebase_open(git_rebase **out, git_repository *repo);
/**
* Performs the next rebase operation and returns the information about it.
* If the operation is one that applies a patch (which is any operation except
* GIT_REBASE_OPERATION_EXEC) then the patch will be applied and the index and
......@@ -143,13 +157,13 @@ GIT_EXTERN(int) git_rebase(
* you will need to address those before committing the changes.
*
* @param out The rebase operation that is to be performed next
* @param repo The repository with a rebase in progress
* @param repo The rebase in progress
* @param checkout_opts Options to specify how the patch should be checked out
* @return Zero on success; -1 on failure.
*/
GIT_EXTERN(int) git_rebase_next(
git_rebase_operation *operation,
git_repository *repo,
git_rebase *rebase,
git_checkout_options *checkout_opts);
/**
......@@ -158,7 +172,7 @@ GIT_EXTERN(int) git_rebase_next(
* invocation.
*
* @param id Pointer in which to store the OID of the newly created commit
* @param repo The repository with the in-progress rebase
* @param repo The rebase that is in-progress
* @param author The author of the updated commit, or NULL to keep the
* author from the original commit
* @param committer The committer of the rebase
......@@ -176,7 +190,7 @@ GIT_EXTERN(int) git_rebase_next(
*/
GIT_EXTERN(int) git_rebase_commit(
git_oid *id,
git_repository *repo,
git_rebase *rebase,
const git_signature *author,
const git_signature *committer,
const char *message_encoding,
......@@ -186,29 +200,36 @@ GIT_EXTERN(int) git_rebase_commit(
* Aborts a rebase that is currently in progress, resetting the repository
* and working directory to their state before rebase began.
*
* @param repo The repository with the in-progress rebase
* @param rebase The rebase that is in-progress
* @param signature The identity that is aborting the rebase
* @return Zero on success; GIT_ENOTFOUND if a rebase is not in progress,
* -1 on other errors.
*/
GIT_EXTERN(int) git_rebase_abort(
git_repository *repo,
git_rebase *rebase,
const git_signature *signature);
/**
* Finishes a rebase that is currently in progress once all patches have
* been applied.
*
* @param repo The repository with the in-progress rebase
* @param rebase The rebase that is in-progress
* @param signature The identity that is finishing the rebase
* @param opts Options to specify how rebase is finished
* @param Zero on success; -1 on error
*/
GIT_EXTERN(int) git_rebase_finish(
git_repository *repo,
git_rebase *rebase,
const git_signature *signature,
const git_rebase_options *opts);
/**
* Frees the `git_rebase` object.
*
* @param rebase The rebase that is in-progress
*/
GIT_EXTERN(void) git_rebase_free(git_rebase *rebase);
/** @} */
GIT_END_DECL
#endif
......@@ -183,6 +183,8 @@ typedef struct git_merge_result git_merge_result;
/** Representation of a status collection */
typedef struct git_status_list git_status_list;
/** Representation of a rebase */
typedef struct git_rebase git_rebase;
/** Basic type of any Git reference. */
typedef enum {
......
......@@ -20,14 +20,16 @@ void test_rebase_abort__cleanup(void)
static void test_abort(git_merge_head *branch, git_merge_head *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", "rebaser@example.com", 1404157834, -400));
cl_git_pass(git_rebase_abort(repo, signature));
cl_git_pass(git_rebase_abort(rebase, signature));
cl_assert_equal_i(GIT_REPOSITORY_STATE_NONE, git_repository_state(repo));
......@@ -58,10 +60,12 @@ static void test_abort(git_merge_head *branch, git_merge_head *onto)
git_reference_free(head_ref);
git_reference_free(branch_ref);
git_signature_free(signature);
git_rebase_free(rebase);
}
void test_rebase_abort__merge(void)
{
git_rebase *rebase;
git_reference *branch_ref, *onto_ref;
git_signature *signature;
git_merge_head *branch_head, *onto_head;
......@@ -74,7 +78,7 @@ void test_rebase_abort__merge(void)
cl_git_pass(git_signature_new(&signature, "Rebaser", "rebaser@example.com", 1404157834, -400));
cl_git_pass(git_rebase(repo, branch_head, NULL, onto_head, signature, NULL));
cl_git_pass(git_rebase_init(&rebase, repo, branch_head, NULL, onto_head, signature, NULL));
cl_assert_equal_i(GIT_REPOSITORY_STATE_REBASE_MERGE, git_repository_state(repo));
test_abort(branch_head, onto_head);
......@@ -86,10 +90,12 @@ void test_rebase_abort__merge(void)
git_reference_free(branch_ref);
git_reference_free(onto_ref);
git_rebase_free(rebase);
}
void test_rebase_abort__detached_head(void)
{
git_rebase *rebase;
git_oid branch_id;
git_reference *onto_ref;
git_signature *signature;
......@@ -103,7 +109,7 @@ void test_rebase_abort__detached_head(void)
cl_git_pass(git_signature_new(&signature, "Rebaser", "rebaser@example.com", 1404157834, -400));
cl_git_pass(git_rebase(repo, branch_head, NULL, onto_head, signature, NULL));
cl_git_pass(git_rebase_init(&rebase, repo, branch_head, NULL, onto_head, signature, NULL));
cl_assert_equal_i(GIT_REPOSITORY_STATE_REBASE_MERGE, git_repository_state(repo));
test_abort(branch_head, onto_head);
......@@ -114,10 +120,12 @@ void test_rebase_abort__detached_head(void)
git_merge_head_free(onto_head);
git_reference_free(onto_ref);
git_rebase_free(rebase);
}
void test_rebase_abort__old_style_head_file(void)
{
git_rebase *rebase;
git_reference *branch_ref, *onto_ref;
git_signature *signature;
git_merge_head *branch_head, *onto_head;
......@@ -130,7 +138,7 @@ void test_rebase_abort__old_style_head_file(void)
cl_git_pass(git_signature_new(&signature, "Rebaser", "rebaser@example.com", 1404157834, -400));
cl_git_pass(git_rebase(repo, branch_head, NULL, onto_head, signature, NULL));
cl_git_pass(git_rebase_init(&rebase, repo, branch_head, NULL, onto_head, signature, NULL));
cl_assert_equal_i(GIT_REPOSITORY_STATE_REBASE_MERGE, git_repository_state(repo));
p_rename("rebase-merge/.git/rebase-merge/orig-head",
......@@ -145,4 +153,5 @@ void test_rebase_abort__old_style_head_file(void)
git_reference_free(branch_ref);
git_reference_free(onto_ref);
git_rebase_free(rebase);
}
......@@ -27,6 +27,7 @@ void test_rebase_setup__cleanup(void)
* git checkout beef ; git rebase --merge master */
void test_rebase_setup__blocked_when_in_progress(void)
{
git_rebase *rebase;
git_reference *branch_ref, *upstream_ref;
git_merge_head *branch_head, *upstream_head;
......@@ -38,11 +39,11 @@ void test_rebase_setup__blocked_when_in_progress(void)
cl_git_pass(git_merge_head_from_ref(&branch_head, repo, branch_ref));
cl_git_pass(git_merge_head_from_ref(&upstream_head, repo, upstream_ref));
cl_git_pass(git_rebase(repo, branch_head, upstream_head, NULL, signature, NULL));
cl_git_pass(git_rebase_init(&rebase, repo, branch_head, upstream_head, NULL, signature, NULL));
cl_assert_equal_i(GIT_REPOSITORY_STATE_REBASE_MERGE, git_repository_state(repo));
cl_git_fail(git_rebase(repo, branch_head, upstream_head, NULL, signature, NULL));
cl_git_fail(git_rebase_init(&rebase, repo, branch_head, upstream_head, NULL, signature, NULL));
git_merge_head_free(branch_head);
git_merge_head_free(upstream_head);
......@@ -53,6 +54,7 @@ void test_rebase_setup__blocked_when_in_progress(void)
/* git checkout beef ; git rebase --merge master */
void test_rebase_setup__merge(void)
{
git_rebase *rebase;
git_reference *branch_ref, *upstream_ref;
git_merge_head *branch_head, *upstream_head;
git_reference *head;
......@@ -67,7 +69,7 @@ void test_rebase_setup__merge(void)
cl_git_pass(git_merge_head_from_ref(&branch_head, repo, branch_ref));
cl_git_pass(git_merge_head_from_ref(&upstream_head, repo, upstream_ref));
cl_git_pass(git_rebase(repo, branch_head, upstream_head, NULL, signature, NULL));
cl_git_pass(git_rebase_init(&rebase, repo, branch_head, upstream_head, NULL, signature, NULL));
cl_assert_equal_i(GIT_REPOSITORY_STATE_REBASE_MERGE, git_repository_state(repo));
......@@ -94,11 +96,13 @@ void test_rebase_setup__merge(void)
git_merge_head_free(upstream_head);
git_reference_free(branch_ref);
git_reference_free(upstream_ref);
git_rebase_free(rebase);
}
/* git checkout beef && git rebase --merge --root --onto master */
void test_rebase_setup__merge_root(void)
{
git_rebase *rebase;
git_reference *branch_ref, *onto_ref;
git_merge_head *branch_head, *onto_head;
git_reference *head;
......@@ -113,7 +117,7 @@ void test_rebase_setup__merge_root(void)
cl_git_pass(git_merge_head_from_ref(&branch_head, repo, branch_ref));
cl_git_pass(git_merge_head_from_ref(&onto_head, repo, onto_ref));
cl_git_pass(git_rebase(repo, branch_head, NULL, onto_head, signature, NULL));
cl_git_pass(git_rebase_init(&rebase, repo, branch_head, NULL, onto_head, signature, NULL));
git_oid_fromstr(&head_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00");
cl_git_pass(git_repository_head(&head, repo));
......@@ -140,11 +144,13 @@ void test_rebase_setup__merge_root(void)
git_merge_head_free(onto_head);
git_reference_free(branch_ref);
git_reference_free(onto_ref);
git_rebase_free(rebase);
}
/* git checkout gravy && git rebase --merge --onto master veal */
void test_rebase_setup__merge_onto_and_upstream(void)
{
git_rebase *rebase;
git_reference *branch1_ref, *branch2_ref, *onto_ref;
git_merge_head *branch1_head, *branch2_head, *onto_head;
git_reference *head;
......@@ -161,7 +167,7 @@ void test_rebase_setup__merge_onto_and_upstream(void)
cl_git_pass(git_merge_head_from_ref(&branch2_head, repo, branch2_ref));
cl_git_pass(git_merge_head_from_ref(&onto_head, repo, onto_ref));
cl_git_pass(git_rebase(repo, branch1_head, branch2_head, onto_head, signature, NULL));
cl_git_pass(git_rebase_init(&rebase, repo, branch1_head, branch2_head, onto_head, signature, NULL));
git_oid_fromstr(&head_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00");
cl_git_pass(git_repository_head(&head, repo));
......@@ -186,12 +192,14 @@ void test_rebase_setup__merge_onto_and_upstream(void)
git_reference_free(branch1_ref);
git_reference_free(branch2_ref);
git_reference_free(onto_ref);
git_rebase_free(rebase);
}
/* Ensure merge commits are dropped in a rebase */
/* git checkout veal && git rebase --merge master */
void test_rebase_setup__branch_with_merges(void)
{
git_rebase *rebase;
git_reference *branch_ref, *upstream_ref;
git_merge_head *branch_head, *upstream_head;
git_reference *head;
......@@ -206,7 +214,7 @@ void test_rebase_setup__branch_with_merges(void)
cl_git_pass(git_merge_head_from_ref(&branch_head, repo, branch_ref));
cl_git_pass(git_merge_head_from_ref(&upstream_head, repo, upstream_ref));
cl_git_pass(git_rebase(repo, branch_head, upstream_head, NULL, signature, NULL));
cl_git_pass(git_rebase_init(&rebase, repo, branch_head, upstream_head, NULL, signature, NULL));
cl_assert_equal_i(GIT_REPOSITORY_STATE_REBASE_MERGE, git_repository_state(repo));
......@@ -233,11 +241,13 @@ void test_rebase_setup__branch_with_merges(void)
git_merge_head_free(upstream_head);
git_reference_free(branch_ref);
git_reference_free(upstream_ref);
git_rebase_free(rebase);
}
/* git checkout barley && git rebase --merge master */
void test_rebase_setup__orphan_branch(void)
{
git_rebase *rebase;
git_reference *branch_ref, *upstream_ref;
git_merge_head *branch_head, *upstream_head;
git_reference *head;
......@@ -252,7 +262,7 @@ void test_rebase_setup__orphan_branch(void)
cl_git_pass(git_merge_head_from_ref(&branch_head, repo, branch_ref));
cl_git_pass(git_merge_head_from_ref(&upstream_head, repo, upstream_ref));
cl_git_pass(git_rebase(repo, branch_head, upstream_head, NULL, signature, NULL));
cl_git_pass(git_rebase_init(&rebase, repo, branch_head, upstream_head, NULL, signature, NULL));
cl_assert_equal_i(GIT_REPOSITORY_STATE_REBASE_MERGE, git_repository_state(repo));
......@@ -279,10 +289,12 @@ void test_rebase_setup__orphan_branch(void)
git_merge_head_free(upstream_head);
git_reference_free(branch_ref);
git_reference_free(upstream_ref);
git_rebase_free(rebase);
}
static int rebase_is_blocked(void)
{
git_rebase *rebase = NULL;
int error;
git_reference *branch_ref, *upstream_ref;
......@@ -296,13 +308,14 @@ static int rebase_is_blocked(void)
cl_git_pass(git_merge_head_from_ref(&branch_head, repo, branch_ref));
cl_git_pass(git_merge_head_from_ref(&upstream_head, repo, upstream_ref));
error = git_rebase(repo, branch_head, upstream_head, NULL, signature, NULL);
error = git_rebase_init(&rebase, repo, branch_head, upstream_head, NULL, signature, NULL);
git_merge_head_free(branch_head);
git_merge_head_free(upstream_head);
git_reference_free(branch_ref);
git_reference_free(upstream_ref);
git_rebase_free(rebase);
return error;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment