diff options
author | Edward Thomson <ethomson@microsoft.com> | 2014-09-11 16:47:20 -0400 |
---|---|---|
committer | Edward Thomson <ethomson@microsoft.com> | 2014-10-26 22:59:41 -0400 |
commit | ed2c06a6a1c8725483759782f60531d582d9ec46 (patch) | |
tree | 33fb1d4506d3dda0b0e6fe9670162f9047954e84 | |
parent | f152f8ac0c6c20bf5e245e79629dc70a913496b1 (diff) | |
download | libgit2-ed2c06a6a1c8725483759782f60531d582d9ec46.tar.gz |
git_rebase: iterators for operations
-rw-r--r-- | include/git2/rebase.h | 27 | ||||
-rw-r--r-- | src/rebase.c | 21 | ||||
-rw-r--r-- | tests/rebase/iterator.c | 108 |
3 files changed, 156 insertions, 0 deletions
diff --git a/include/git2/rebase.h b/include/git2/rebase.h index 9ffdc4805..b9b0af73b 100644 --- a/include/git2/rebase.h +++ b/include/git2/rebase.h @@ -150,6 +150,33 @@ GIT_EXTERN(int) git_rebase_init( GIT_EXTERN(int) git_rebase_open(git_rebase **out, git_repository *repo); /** + * Gets the count of rebase operations that are to be applied. + * + * @param rebase The in-progress rebase + * @return The number of rebase operations in total + */ +GIT_EXTERN(size_t) git_rebase_operation_entrycount(git_rebase *rebase); + +/** + * Gets the index of the rebase operation that is currently being applied. + * + * @param rebase The in-progress rebase + * @return The index of the rebase operation currently being applied. + */ +GIT_EXTERN(size_t) git_rebase_operation_current(git_rebase *rebase); + +/** + * Gets the rebase operation specified by the given index. + * + * @param rebase The in-progress rebase + * @param idx The index of the rebase operation to retrieve + * @return The rebase operation or NULL if `idx` was out of bounds + */ +GIT_EXTERN(git_rebase_operation *) git_rebase_operation_byindex( + git_rebase *rebase, + size_t idx); + +/** * 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 diff --git a/src/rebase.c b/src/rebase.c index 635682f73..a4e9bade7 100644 --- a/src/rebase.c +++ b/src/rebase.c @@ -1087,6 +1087,27 @@ done: return error; } +size_t git_rebase_operation_entrycount(git_rebase *rebase) +{ + assert(rebase); + + return git_array_size(rebase->operations); +} + +size_t git_rebase_operation_current(git_rebase *rebase) +{ + assert(rebase); + + return rebase->current; +} + +git_rebase_operation *git_rebase_operation_byindex(git_rebase *rebase, size_t idx) +{ + assert(rebase); + + return git_array_get(rebase->operations, idx); +} + void git_rebase_free(git_rebase *rebase) { if (rebase == NULL) diff --git a/tests/rebase/iterator.c b/tests/rebase/iterator.c new file mode 100644 index 000000000..cfc6dce7b --- /dev/null +++ b/tests/rebase/iterator.c @@ -0,0 +1,108 @@ +#include "clar_libgit2.h" +#include "git2/rebase.h" +#include "posix.h" + +#include <fcntl.h> + +static git_repository *repo; +static git_index *_index; +static git_signature *signature; + +// Fixture setup and teardown +void test_rebase_iterator__initialize(void) +{ + repo = cl_git_sandbox_init("rebase"); + cl_git_pass(git_repository_index(&_index, repo)); + cl_git_pass(git_signature_now(&signature, "Rebaser", "rebaser@rebaser.rb")); +} + +void test_rebase_iterator__cleanup(void) +{ + git_signature_free(signature); + git_index_free(_index); + cl_git_sandbox_cleanup(); +} + +static void test_operations(git_rebase *rebase, size_t expected_current) +{ + size_t i, expected_count = 5; + git_oid expected_oid[5]; + git_rebase_operation *operation; + + git_oid_fromstr(&expected_oid[0], "da9c51a23d02d931a486f45ad18cda05cf5d2b94"); + git_oid_fromstr(&expected_oid[1], "8d1f13f93c4995760ac07d129246ac1ff64c0be9"); + git_oid_fromstr(&expected_oid[2], "3069cc907e6294623e5917ef6de663928c1febfb"); + git_oid_fromstr(&expected_oid[3], "588e5d2f04d49707fe4aab865e1deacaf7ef6787"); + git_oid_fromstr(&expected_oid[4], "b146bd7608eac53d9bf9e1a6963543588b555c64"); + + cl_assert_equal_i(expected_count, git_rebase_operation_entrycount(rebase)); + cl_assert_equal_i(expected_current, git_rebase_operation_current(rebase)); + + for (i = 0; i < expected_count; i++) { + operation = git_rebase_operation_byindex(rebase, i); + cl_assert_equal_i(GIT_REBASE_OPERATION_PICK, operation->type); + cl_assert_equal_oid(&expected_oid[i], &operation->id); + } +} + +void test_rebase_iterator__iterates(void) +{ + git_rebase *rebase; + git_reference *branch_ref, *upstream_ref; + git_merge_head *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_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_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_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); +} |