diff options
author | Edward Thomson <ethomson@github.com> | 2016-12-07 17:44:25 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-12-07 17:44:25 +0000 |
commit | 8339c66068c8e964f8bf1eca10745db730bf62fa (patch) | |
tree | 90c4dcd70d32f52b3941c3b9b0e0bc1143128574 | |
parent | 15769731a2411933bb9236d06c5f15e2c4e7929b (diff) | |
parent | 4db1fc7e5ead5c29ffb6594b229b84f4392b40f1 (diff) | |
download | libgit2-8339c66068c8e964f8bf1eca10745db730bf62fa.tar.gz |
Merge pull request #4020 from novalis/rebase-detached
git_rebase_init: correctly handle detached HEAD
-rw-r--r-- | src/rebase.c | 2 | ||||
-rw-r--r-- | tests/rebase/merge.c | 53 |
2 files changed, 54 insertions, 1 deletions
diff --git a/src/rebase.c b/src/rebase.c index e86312e7e..0af2b3cf4 100644 --- a/src/rebase.c +++ b/src/rebase.c @@ -630,7 +630,7 @@ static int rebase_init_merge( rebase->state_path = git_buf_detach(&state_path); GITERR_CHECK_ALLOC(rebase->state_path); - if (branch->ref_name) { + if (branch->ref_name && strcmp(branch->ref_name, "HEAD")) { rebase->orig_head_name = git__strdup(branch->ref_name); GITERR_CHECK_ALLOC(rebase->orig_head_name); } else { diff --git a/tests/rebase/merge.c b/tests/rebase/merge.c index 0f06ed153..8492c638f 100644 --- a/tests/rebase/merge.c +++ b/tests/rebase/merge.c @@ -1,4 +1,5 @@ #include "clar_libgit2.h" +#include "git2/checkout.h" #include "git2/rebase.h" #include "posix.h" #include "signature.h" @@ -475,6 +476,58 @@ void test_rebase_merge__finish(void) git_rebase_free(rebase); } +void test_rebase_merge__detached_finish(void) +{ + git_rebase *rebase; + git_reference *branch_ref, *upstream_ref, *head_ref; + git_annotated_commit *branch_head, *upstream_head; + git_rebase_operation *rebase_operation; + git_oid commit_id; + git_reflog *reflog; + const git_reflog_entry *reflog_entry; + git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; + int error; + + cl_git_pass(git_reference_lookup(&branch_ref, repo, "refs/heads/gravy")); + cl_git_pass(git_reference_lookup(&upstream_ref, repo, "refs/heads/veal")); + + 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_repository_set_head_detached_from_annotated(repo, branch_head)); + opts.checkout_strategy = GIT_CHECKOUT_FORCE; + git_checkout_head(repo, &opts); + + cl_git_pass(git_rebase_init(&rebase, repo, NULL, upstream_head, NULL, NULL)); + + cl_git_pass(git_rebase_next(&rebase_operation, rebase)); + cl_git_pass(git_rebase_commit(&commit_id, rebase, NULL, signature, + NULL, NULL)); + + cl_git_fail(error = git_rebase_next(&rebase_operation, rebase)); + cl_assert_equal_i(GIT_ITEROVER, error); + + cl_git_pass(git_rebase_finish(rebase, signature)); + + cl_assert_equal_i(GIT_REPOSITORY_STATE_NONE, git_repository_state(repo)); + + cl_git_pass(git_reference_lookup(&head_ref, repo, "HEAD")); + cl_assert_equal_i(GIT_REF_OID, git_reference_type(head_ref)); + + /* 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(upstream_head), git_reflog_entry_id_old(reflog_entry)); + cl_assert_equal_oid(&commit_id, git_reflog_entry_id_new(reflog_entry)); + + git_reflog_free(reflog); + 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); +} + void test_rebase_merge__finish_with_ids(void) { git_rebase *rebase; |