git_rebase_commit: write HEAD's reflog appropriately
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
diff --git a/src/commit.c b/src/commit.c
index 227d5c4..78c4b9d 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 101dfb1..60c3dd0 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 08e407e..43c7333 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 c6ec429..5f48efc 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 fa37e89..0d4dca4 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);