mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-02 14:37:30 +00:00
git_rebase_commit: drop already-picked commits
Already cherry-picked commits should not be re-included. If all changes included in a commit exist in the upstream, then we should error with GIT_EAPPLIED.
This commit is contained in:
parent
a35a9890b0
commit
93a7004cc2
@ -43,6 +43,7 @@ typedef enum {
|
||||
GIT_EMODIFIED = -15, /**< Reference value does not match expected */
|
||||
GIT_EAUTH = -16, /**< Authentication error */
|
||||
GIT_ECERTIFICATE = -17, /**< Server certificate is invalid */
|
||||
GIT_EAPPLIED = -18, /**< Patch/merge has already been applied */
|
||||
|
||||
GIT_PASSTHROUGH = -30, /**< Internal only */
|
||||
GIT_ITEROVER = -31, /**< Signals end of iteration with iterator */
|
||||
|
@ -99,7 +99,9 @@ GIT_EXTERN(int) git_rebase_next(
|
||||
* @param message The message for this commit, or NULL to keep the message
|
||||
* from the original commit
|
||||
* @return Zero on success, GIT_EUNMERGED if there are unmerged changes in
|
||||
* the index, -1 on failure.
|
||||
* the index, GIT_EAPPLIED if the current commit has already
|
||||
* been applied to the upstream and there is nothing to commit,
|
||||
* -1 on failure.
|
||||
*/
|
||||
GIT_EXTERN(int) git_rebase_commit(
|
||||
git_oid *id,
|
||||
|
19
src/rebase.c
19
src/rebase.c
@ -674,7 +674,8 @@ static int rebase_commit_merge(
|
||||
git_index *index = NULL;
|
||||
git_reference *head = NULL;
|
||||
git_commit *head_commit = NULL;
|
||||
git_tree *tree = NULL;
|
||||
git_tree *head_tree = NULL, *tree = NULL;
|
||||
git_diff *diff = NULL;
|
||||
git_oid tree_id;
|
||||
char old_idstr[GIT_OID_HEXSZ], new_idstr[GIT_OID_HEXSZ];
|
||||
int error;
|
||||
@ -694,11 +695,19 @@ static int rebase_commit_merge(
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* TODO: if there are no changes, error with a useful code */
|
||||
|
||||
if ((error = git_repository_head(&head, repo)) < 0 ||
|
||||
(error = git_reference_peel((git_object **)&head_commit, head, GIT_OBJ_COMMIT)) < 0 ||
|
||||
(error = git_index_write_tree(&tree_id, index)) < 0 ||
|
||||
(error = git_commit_tree(&head_tree, head_commit)) < 0 ||
|
||||
(error = git_diff_tree_to_index(&diff, repo, head_tree, index, NULL)) < 0)
|
||||
goto done;
|
||||
|
||||
if (git_diff_num_deltas(diff) == 0) {
|
||||
giterr_set(GITERR_REBASE, "This patch has already been applied");
|
||||
error = GIT_EAPPLIED;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ((error = git_index_write_tree(&tree_id, index)) < 0 ||
|
||||
(error = git_tree_lookup(&tree, repo, &tree_id)) < 0)
|
||||
goto done;
|
||||
|
||||
@ -722,7 +731,9 @@ static int rebase_commit_merge(
|
||||
"%.*s %.*s\n", GIT_OID_HEXSZ, old_idstr, GIT_OID_HEXSZ, new_idstr);
|
||||
|
||||
done:
|
||||
git_diff_free(diff);
|
||||
git_tree_free(tree);
|
||||
git_tree_free(head_tree);
|
||||
git_commit_free(head_commit);
|
||||
git_reference_free(head);
|
||||
git_index_free(index);
|
||||
|
@ -207,3 +207,41 @@ void test_rebase_merge__commit_updates_rewritten(void)
|
||||
git_reference_free(upstream_ref);
|
||||
}
|
||||
|
||||
void test_rebase_merge__commit_drops_already_applied(void)
|
||||
{
|
||||
git_reference *branch_ref, *upstream_ref;
|
||||
git_merge_head *branch_head, *upstream_head;
|
||||
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/green_pea"));
|
||||
|
||||
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_next(repo, &checkout_opts));
|
||||
cl_git_fail(error = git_rebase_commit(&commit_id, repo, NULL, signature,
|
||||
NULL, NULL));
|
||||
|
||||
cl_assert_equal_i(GIT_EAPPLIED, error);
|
||||
|
||||
cl_git_pass(git_rebase_next(repo, &checkout_opts));
|
||||
cl_git_pass(git_rebase_commit(&commit_id, repo, NULL, signature,
|
||||
NULL, NULL));
|
||||
|
||||
cl_assert_equal_file(
|
||||
"8d1f13f93c4995760ac07d129246ac1ff64c0be9 2ac4fb7b74c1287f6c792acad759e1ec01e18dae\n",
|
||||
82, "rebase/.git/rebase-merge/rewritten");
|
||||
|
||||
git_merge_head_free(branch_head);
|
||||
git_merge_head_free(upstream_head);
|
||||
git_reference_free(branch_ref);
|
||||
git_reference_free(upstream_ref);
|
||||
}
|
||||
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
tests/resources/rebase/.gitted/refs/heads/green_pea
Normal file
BIN
tests/resources/rebase/.gitted/refs/heads/green_pea
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user