diff options
-rw-r--r-- | src/commit.c | 36 | ||||
-rw-r--r-- | src/rebase.c | 12 | ||||
-rw-r--r-- | src/refs.c | 35 | ||||
-rw-r--r-- | src/refs.h | 9 | ||||
-rw-r--r-- | tests/rebase/merge.c | 10 |
5 files changed, 67 insertions, 35 deletions
diff --git a/src/commit.c b/src/commit.c index 227d5c4a5..78c4b9de3 100644 --- a/src/commit.c +++ b/src/commit.c @@ -16,6 +16,7 @@ #include "commit.h" #include "signature.h" #include "message.h" +#include "refs.h" void git_commit__free(void *_commit) { @@ -34,35 +35,6 @@ void git_commit__free(void *_commit) git__free(commit); } -static int update_ref_for_commit(git_repository *repo, git_reference *ref, const char *update_ref, const git_oid *id, const git_signature *committer) -{ - git_reference *ref2 = NULL; - int error; - git_commit *c; - const char *shortmsg; - git_buf reflog_msg = GIT_BUF_INIT; - - if ((error = git_commit_lookup(&c, repo, id)) < 0) { - return error; - } - - shortmsg = git_commit_summary(c); - git_buf_printf(&reflog_msg, "commit%s: %s", - git_commit_parentcount(c) == 0 ? " (initial)" : "", - shortmsg); - git_commit_free(c); - - if (ref) { - error = git_reference_set_target(&ref2, ref, id, committer, git_buf_cstr(&reflog_msg)); - git_reference_free(ref2); - } else { - error = git_reference__update_terminal(repo, update_ref, id, committer, git_buf_cstr(&reflog_msg)); - } - - git_buf_free(&reflog_msg); - return error; -} - int git_commit_create_from_callback( git_oid *id, git_repository *repo, @@ -131,7 +103,8 @@ int git_commit_create_from_callback( git_buf_free(&commit); if (update_ref != NULL) { - error = update_ref_for_commit(repo, ref, update_ref, id, committer); + error = git_reference__update_for_commit( + repo, ref, update_ref, id, committer, "commit"); git_reference_free(ref); return error; } @@ -321,7 +294,8 @@ int git_commit_amend( &tree_id, commit_parent_for_amend, (void *)commit_to_amend); if (!error && update_ref) { - error = update_ref_for_commit(repo, ref, NULL, id, committer); + error = git_reference__update_for_commit( + repo, ref, NULL, id, committer, "commit"); git_reference_free(ref); } diff --git a/src/rebase.c b/src/rebase.c index 101dfb107..60c3dd02b 100644 --- a/src/rebase.c +++ b/src/rebase.c @@ -686,10 +686,11 @@ static int rebase_commit_merge( { git_index *index = NULL; git_reference *head = NULL; - git_commit *head_commit = NULL; + git_commit *head_commit = NULL, *commit = NULL; git_tree *head_tree = NULL, *tree = NULL; git_diff *diff = NULL; git_oid tree_id; + git_buf reflog_msg = GIT_BUF_INIT; char old_idstr[GIT_OID_HEXSZ], new_idstr[GIT_OID_HEXSZ]; int error; @@ -732,9 +733,12 @@ static int rebase_commit_merge( message = git_commit_message(state->merge.current); } - if ((error = git_commit_create(commit_id, repo, "HEAD", author, + if ((error = git_commit_create(commit_id, repo, NULL, author, committer, message_encoding, message, tree, 1, - (const git_commit **)&head_commit)) < 0) + (const git_commit **)&head_commit)) < 0 || + (error = git_commit_lookup(&commit, repo, commit_id)) < 0 || + (error = git_reference__update_for_commit( + repo, NULL, "HEAD", commit_id, committer, "rebase")) < 0) goto done; git_oid_fmt(old_idstr, git_commit_id(state->merge.current)); @@ -744,6 +748,8 @@ static int rebase_commit_merge( "%.*s %.*s\n", GIT_OID_HEXSZ, old_idstr, GIT_OID_HEXSZ, new_idstr); done: + git_buf_free(&reflog_msg); + git_commit_free(commit); git_diff_free(diff); git_tree_free(tree); git_tree_free(head_tree); diff --git a/src/refs.c b/src/refs.c index 08e407e48..43c7333f2 100644 --- a/src/refs.c +++ b/src/refs.c @@ -22,6 +22,7 @@ #include <git2/refdb.h> #include <git2/sys/refs.h> #include <git2/signature.h> +#include <git2/commit.h> GIT__USE_STRMAP; @@ -1090,6 +1091,40 @@ int git_reference__update_terminal( return reference__update_terminal(repo, ref_name, oid, 0, signature, log_message); } +int git_reference__update_for_commit( + git_repository *repo, + git_reference *ref, + const char *ref_name, + const git_oid *id, + const git_signature *committer, + const char *operation) +{ + git_reference *ref_new = NULL; + git_commit *commit = NULL; + git_buf reflog_msg = GIT_BUF_INIT; + int error; + + if ((error = git_commit_lookup(&commit, repo, id)) < 0 || + (error = git_buf_printf(&reflog_msg, "%s%s: %s", + operation ? operation : "commit", + git_commit_parentcount(commit) == 0 ? " (initial)" : "", + git_commit_summary(commit))) < 0) + goto done; + + if (ref) + error = git_reference_set_target( + &ref_new, ref, id, committer, git_buf_cstr(&reflog_msg)); + else + error = git_reference__update_terminal( + repo, ref_name, id, committer, git_buf_cstr(&reflog_msg)); + +done: + git_reference_free(ref_new); + git_buf_free(&reflog_msg); + git_commit_free(commit); + return error; +} + int git_reference_has_log(git_repository *repo, const char *refname) { int error; diff --git a/src/refs.h b/src/refs.h index c6ec429a5..5f48efc41 100644 --- a/src/refs.h +++ b/src/refs.h @@ -100,4 +100,13 @@ int git_reference_lookup_resolved( int git_reference__log_signature(git_signature **out, git_repository *repo); +/** Update a reference after a commit. */ +int git_reference__update_for_commit( + git_repository *repo, + git_reference *ref, + const char *ref_name, + const git_oid *id, + const git_signature *committer, + const char *operation); + #endif diff --git a/tests/rebase/merge.c b/tests/rebase/merge.c index fa37e89e6..0d4dca489 100644 --- a/tests/rebase/merge.c +++ b/tests/rebase/merge.c @@ -178,6 +178,8 @@ void test_rebase_merge__commit(void) git_oid commit_id, tree_id, parent_id; git_signature *author; git_commit *commit; + git_reflog *reflog; + const git_reflog_entry *reflog_entry; checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE; @@ -211,8 +213,14 @@ void test_rebase_merge__commit(void) cl_assert(git_signature__equal(signature, git_commit_committer(commit))); - cl_assert_equal_file("da9c51a23d02d931a486f45ad18cda05cf5d2b94 776e4c48922799f903f03f5f6e51da8b01e4cce0\n", 82, "rebase/.git/rebase-merge/rewritten"); + /* 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(&parent_id, git_reflog_entry_id_old(reflog_entry)); + cl_assert_equal_oid(&commit_id, git_reflog_entry_id_new(reflog_entry)); + cl_assert_equal_s("rebase: Modification 1 to beef", git_reflog_entry_message(reflog_entry)); + git_reflog_free(reflog); git_signature_free(author); git_commit_free(commit); git_merge_head_free(branch_head); |