Commit 1aa14921 by Carlos Martín Nieto

Merge pull request #3615 from ethomson/rebase_bare

rebase: persist a single in-memory index
parents 5a296ad0 f28bae0c
...@@ -142,12 +142,6 @@ typedef struct { ...@@ -142,12 +142,6 @@ typedef struct {
* be populated for operations of type `GIT_REBASE_OPERATION_EXEC`. * be populated for operations of type `GIT_REBASE_OPERATION_EXEC`.
*/ */
const char *exec; const char *exec;
/**
* The index that is the result of an operation.
* This is set only for in-memory rebases.
*/
git_index *index;
} git_rebase_operation; } git_rebase_operation;
/** /**
...@@ -248,6 +242,21 @@ GIT_EXTERN(int) git_rebase_next( ...@@ -248,6 +242,21 @@ GIT_EXTERN(int) git_rebase_next(
git_rebase *rebase); git_rebase *rebase);
/** /**
* Gets the index produced by the last operation, which is the result
* of `git_rebase_next` and which will be committed by the next
* invocation of `git_rebase_commit`. This is useful for resolving
* conflicts in an in-memory rebase before committing them. You must
* call `git_index_free` when you are finished with this.
*
* This is only applicable for in-memory rebases; for rebases within
* a working directory, the changes were applied to the repository's
* index.
*/
GIT_EXTERN(int) git_rebase_inmemory_index(
git_index **index,
git_rebase *rebase);
/**
* Commits the current patch. You must have resolved any conflicts that * Commits the current patch. You must have resolved any conflicts that
* were introduced during the patch application from the `git_rebase_next` * were introduced during the patch application from the `git_rebase_next`
* invocation. * invocation.
......
...@@ -71,8 +71,8 @@ struct git_rebase { ...@@ -71,8 +71,8 @@ struct git_rebase {
size_t current; size_t current;
/* Used by in-memory rebase */ /* Used by in-memory rebase */
git_index *index;
git_commit *last_commit; git_commit *last_commit;
git_index *last_index;
/* Used by regular (not in-memory) merge-style rebase */ /* Used by regular (not in-memory) merge-style rebase */
git_oid orig_head_id; git_oid orig_head_id;
...@@ -856,10 +856,13 @@ static int rebase_next_inmemory( ...@@ -856,10 +856,13 @@ static int rebase_next_inmemory(
(error = git_merge_trees(&index, rebase->repo, parent_tree, head_tree, current_tree, &rebase->options.merge_options)) < 0) (error = git_merge_trees(&index, rebase->repo, parent_tree, head_tree, current_tree, &rebase->options.merge_options)) < 0)
goto done; goto done;
git_index_free(rebase->last_index); if (!rebase->index) {
rebase->last_index = index; rebase->index = index;
operation->index = index; index = NULL;
index = NULL; } else {
if ((error = git_index_read_index(rebase->index, index)) < 0)
goto done;
}
*out = operation; *out = operation;
...@@ -895,6 +898,18 @@ int git_rebase_next( ...@@ -895,6 +898,18 @@ int git_rebase_next(
return error; return error;
} }
int git_rebase_inmemory_index(
git_index **out,
git_rebase *rebase)
{
assert(out && rebase && rebase->index);
GIT_REFCOUNT_INC(rebase->index);
*out = rebase->index;
return 0;
}
static int rebase_commit__create( static int rebase_commit__create(
git_commit **out, git_commit **out,
git_rebase *rebase, git_rebase *rebase,
...@@ -1018,17 +1033,13 @@ static int rebase_commit_inmemory( ...@@ -1018,17 +1033,13 @@ static int rebase_commit_inmemory(
operation = git_array_get(rebase->operations, rebase->current); operation = git_array_get(rebase->operations, rebase->current);
assert(operation); assert(operation);
assert(operation->index); assert(rebase->index);
assert(rebase->last_commit); assert(rebase->last_commit);
if ((error = rebase_commit__create(&commit, rebase, operation->index, if ((error = rebase_commit__create(&commit, rebase, rebase->index,
rebase->last_commit, author, committer, message_encoding, message)) < 0) rebase->last_commit, author, committer, message_encoding, message)) < 0)
goto done; goto done;
git_index_free(rebase->last_index);
operation->index = NULL;
rebase->last_index = NULL;
git_commit_free(rebase->last_commit); git_commit_free(rebase->last_commit);
rebase->last_commit = commit; rebase->last_commit = commit;
...@@ -1313,7 +1324,7 @@ void git_rebase_free(git_rebase *rebase) ...@@ -1313,7 +1324,7 @@ void git_rebase_free(git_rebase *rebase)
if (rebase == NULL) if (rebase == NULL)
return; return;
git_index_free(rebase->last_index); git_index_free(rebase->index);
git_commit_free(rebase->last_commit); git_commit_free(rebase->last_commit);
git__free(rebase->onto_name); git__free(rebase->onto_name);
git__free(rebase->orig_head_name); git__free(rebase->orig_head_name);
......
...@@ -54,7 +54,7 @@ void test_rebase_inmemory__can_resolve_conflicts(void) ...@@ -54,7 +54,7 @@ void test_rebase_inmemory__can_resolve_conflicts(void)
git_status_list *status_list; git_status_list *status_list;
git_oid pick_id, commit_id, expected_commit_id; git_oid pick_id, commit_id, expected_commit_id;
git_signature *signature; git_signature *signature;
git_index *repo_index; git_index *rebase_index, *repo_index;
git_index_entry resolution = {{0}}; git_index_entry resolution = {{0}};
git_rebase_options opts = GIT_REBASE_OPTIONS_INIT; git_rebase_options opts = GIT_REBASE_OPTIONS_INIT;
...@@ -86,7 +86,8 @@ void test_rebase_inmemory__can_resolve_conflicts(void) ...@@ -86,7 +86,8 @@ void test_rebase_inmemory__can_resolve_conflicts(void)
cl_assert_equal_i(0, git_status_list_entrycount(status_list)); cl_assert_equal_i(0, git_status_list_entrycount(status_list));
/* but that the index returned from rebase does have conflicts */ /* but that the index returned from rebase does have conflicts */
cl_assert(git_index_has_conflicts(rebase_operation->index)); cl_git_pass(git_rebase_inmemory_index(&rebase_index, rebase));
cl_assert(git_index_has_conflicts(rebase_index));
cl_git_fail_with(GIT_EUNMERGED, git_rebase_commit(&commit_id, rebase, NULL, signature, NULL, NULL)); cl_git_fail_with(GIT_EUNMERGED, git_rebase_commit(&commit_id, rebase, NULL, signature, NULL, NULL));
...@@ -94,8 +95,8 @@ void test_rebase_inmemory__can_resolve_conflicts(void) ...@@ -94,8 +95,8 @@ void test_rebase_inmemory__can_resolve_conflicts(void)
resolution.path = "asparagus.txt"; resolution.path = "asparagus.txt";
resolution.mode = GIT_FILEMODE_BLOB; resolution.mode = GIT_FILEMODE_BLOB;
git_oid_fromstr(&resolution.id, "414dfc71ead79c07acd4ea47fecf91f289afc4b9"); git_oid_fromstr(&resolution.id, "414dfc71ead79c07acd4ea47fecf91f289afc4b9");
cl_git_pass(git_index_conflict_remove(rebase_operation->index, "asparagus.txt")); cl_git_pass(git_index_conflict_remove(rebase_index, "asparagus.txt"));
cl_git_pass(git_index_add(rebase_operation->index, &resolution)); cl_git_pass(git_index_add(rebase_index, &resolution));
/* and finally create a commit for the resolved rebase operation */ /* and finally create a commit for the resolved rebase operation */
cl_git_pass(git_rebase_commit(&commit_id, rebase, NULL, signature, NULL, NULL)); cl_git_pass(git_rebase_commit(&commit_id, rebase, NULL, signature, NULL, NULL));
...@@ -110,5 +111,6 @@ void test_rebase_inmemory__can_resolve_conflicts(void) ...@@ -110,5 +111,6 @@ void test_rebase_inmemory__can_resolve_conflicts(void)
git_reference_free(branch_ref); git_reference_free(branch_ref);
git_reference_free(upstream_ref); git_reference_free(upstream_ref);
git_index_free(repo_index); git_index_free(repo_index);
git_index_free(rebase_index);
git_rebase_free(rebase); git_rebase_free(rebase);
} }
...@@ -13,7 +13,8 @@ void test_rebase_iterator__initialize(void) ...@@ -13,7 +13,8 @@ void test_rebase_iterator__initialize(void)
{ {
repo = cl_git_sandbox_init("rebase"); repo = cl_git_sandbox_init("rebase");
cl_git_pass(git_repository_index(&_index, repo)); cl_git_pass(git_repository_index(&_index, repo));
cl_git_pass(git_signature_now(&signature, "Rebaser", "rebaser@rebaser.rb")); cl_git_pass(git_signature_new(&signature, "Rebaser",
"rebaser@rebaser.rb", 1405694510, 0));
} }
void test_rebase_iterator__cleanup(void) void test_rebase_iterator__cleanup(void)
...@@ -53,7 +54,7 @@ void test_iterator(bool inmemory) ...@@ -53,7 +54,7 @@ void test_iterator(bool inmemory)
git_reference *branch_ref, *upstream_ref; git_reference *branch_ref, *upstream_ref;
git_annotated_commit *branch_head, *upstream_head; git_annotated_commit *branch_head, *upstream_head;
git_rebase_operation *rebase_operation; git_rebase_operation *rebase_operation;
git_oid commit_id; git_oid commit_id, expected_id;
int error; int error;
opts.inmemory = inmemory; opts.inmemory = inmemory;
...@@ -77,16 +78,25 @@ void test_iterator(bool inmemory) ...@@ -77,16 +78,25 @@ void test_iterator(bool inmemory)
NULL, NULL)); NULL, NULL));
test_operations(rebase, 0); test_operations(rebase, 0);
git_oid_fromstr(&expected_id, "776e4c48922799f903f03f5f6e51da8b01e4cce0");
cl_assert_equal_oid(&expected_id, &commit_id);
cl_git_pass(git_rebase_next(&rebase_operation, rebase)); cl_git_pass(git_rebase_next(&rebase_operation, rebase));
cl_git_pass(git_rebase_commit(&commit_id, rebase, NULL, signature, cl_git_pass(git_rebase_commit(&commit_id, rebase, NULL, signature,
NULL, NULL)); NULL, NULL));
test_operations(rebase, 1); test_operations(rebase, 1);
git_oid_fromstr(&expected_id, "ba1f9b4fd5cf8151f7818be2111cc0869f1eb95a");
cl_assert_equal_oid(&expected_id, &commit_id);
cl_git_pass(git_rebase_next(&rebase_operation, rebase)); cl_git_pass(git_rebase_next(&rebase_operation, rebase));
cl_git_pass(git_rebase_commit(&commit_id, rebase, NULL, signature, cl_git_pass(git_rebase_commit(&commit_id, rebase, NULL, signature,
NULL, NULL)); NULL, NULL));
test_operations(rebase, 2); test_operations(rebase, 2);
git_oid_fromstr(&expected_id, "948b12fe18b84f756223a61bece4c307787cd5d4");
cl_assert_equal_oid(&expected_id, &commit_id);
if (!inmemory) { if (!inmemory) {
git_rebase_free(rebase); git_rebase_free(rebase);
cl_git_pass(git_rebase_open(&rebase, repo, NULL)); cl_git_pass(git_rebase_open(&rebase, repo, NULL));
...@@ -97,11 +107,17 @@ void test_iterator(bool inmemory) ...@@ -97,11 +107,17 @@ void test_iterator(bool inmemory)
NULL, NULL)); NULL, NULL));
test_operations(rebase, 3); test_operations(rebase, 3);
git_oid_fromstr(&expected_id, "d9d5d59d72c9968687f9462578d79878cd80e781");
cl_assert_equal_oid(&expected_id, &commit_id);
cl_git_pass(git_rebase_next(&rebase_operation, rebase)); cl_git_pass(git_rebase_next(&rebase_operation, rebase));
cl_git_pass(git_rebase_commit(&commit_id, rebase, NULL, signature, cl_git_pass(git_rebase_commit(&commit_id, rebase, NULL, signature,
NULL, NULL)); NULL, NULL));
test_operations(rebase, 4); test_operations(rebase, 4);
git_oid_fromstr(&expected_id, "9cf383c0a125d89e742c5dec58ed277dd07588b3");
cl_assert_equal_oid(&expected_id, &commit_id);
cl_git_fail(error = git_rebase_next(&rebase_operation, rebase)); cl_git_fail(error = git_rebase_next(&rebase_operation, rebase));
cl_assert_equal_i(GIT_ITEROVER, error); cl_assert_equal_i(GIT_ITEROVER, error);
test_operations(rebase, 4); test_operations(rebase, 4);
......
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