builtin/history: split out extended function to create commits
In the next commit we're about to introduce a new command that splits up a commit into two. Most of the logic will be shared with rewording commits, except that we also need to have control over the parents and the old/new trees. Extract a new function `commit_tree_with_edited_message_ext()` to prepare for this commit. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Patrick Steinhardt committed
Mar 2, 2026 at 13:13 UTC
98f839425db94eb8d4c1f773e923ba1cff622d66
1 file changed
+40
-27
builtin/history.c
+40
-27
@@ -83,10 +83,13 @@ static int fill_commit_message(struct repository *repo,
83
return 0;
84
}
85
86
-static int commit_tree_with_edited_message(struct repository *repo,
87
- const char *action,
88
- struct commit *original,
89
- struct commit **out)
86
+static int commit_tree_with_edited_message_ext(struct repository *repo,
87
+ const char *action,
88
+ struct commit *commit_with_message,
89
+ const struct commit_list *parents,
90
+ const struct object_id *old_tree,
91
+ const struct object_id *new_tree,
92
+ struct commit **out)
93
{
94
const char *exclude_gpgsig[] = {
95
/* We reencode the message, so the encoding needs to be stripped. */
@@ -100,44 +103,27 @@ static int commit_tree_with_edited_message(struct repository *repo,
103
struct commit_extra_header *original_extra_headers = NULL;
104
struct strbuf commit_message = STRBUF_INIT;
105
struct object_id rewritten_commit_oid;
103
- struct object_id original_tree_oid;
104
- struct object_id parent_tree_oid;
106
char *original_author = NULL;
106
- struct commit *parent;
107
size_t len;
108
int ret;
109
110
- original_tree_oid = repo_get_commit_tree(repo, original)->object.oid;
111
-
112
- parent = original->parents ? original->parents->item : NULL;
113
- if (parent) {
114
- if (repo_parse_commit(repo, parent)) {
115
- ret = error(_("unable to parse parent commit %s"),
116
- oid_to_hex(&parent->object.oid));
117
- goto out;
118
- }
119
-
120
- parent_tree_oid = repo_get_commit_tree(repo, parent)->object.oid;
121
- } else {
122
- oidcpy(&parent_tree_oid, repo->hash_algo->empty_tree);
123
- }
124
-
110
/* We retain authorship of the original commit. */
126
- original_message = repo_logmsg_reencode(repo, original, NULL, NULL);
111
+ original_message = repo_logmsg_reencode(repo, commit_with_message, NULL, NULL);
112
ptr = find_commit_header(original_message, "author", &len);
113
if (ptr)
114
original_author = xmemdupz(ptr, len);
115
find_commit_subject(original_message, &original_body);
116
132
- ret = fill_commit_message(repo, &parent_tree_oid, &original_tree_oid,
117
+ ret = fill_commit_message(repo, old_tree, new_tree,
118
original_body, action, &commit_message);
119
if (ret < 0)
120
goto out;
121
137
- original_extra_headers = read_commit_extra_headers(original, exclude_gpgsig);
122
+ original_extra_headers = read_commit_extra_headers(commit_with_message,
123
+ exclude_gpgsig);
124
139
- ret = commit_tree_extended(commit_message.buf, commit_message.len, &original_tree_oid,
140
- original->parents, &rewritten_commit_oid, original_author,
125
+ ret = commit_tree_extended(commit_message.buf, commit_message.len, new_tree,
126
+ parents, &rewritten_commit_oid, original_author,
127
NULL, NULL, original_extra_headers);
128
if (ret < 0)
129
goto out;
@@ -151,6 +137,33 @@ out:
137
return ret;
138
}
139
140
+static int commit_tree_with_edited_message(struct repository *repo,
141
+ const char *action,
142
+ struct commit *original,
143
+ struct commit **out)
144
+{
145
+ struct object_id parent_tree_oid;
146
+ const struct object_id *tree_oid;
147
+ struct commit *parent;
148
+
149
+ tree_oid = &repo_get_commit_tree(repo, original)->object.oid;
150
+
151
+ parent = original->parents ? original->parents->item : NULL;
152
+ if (parent) {
153
+ if (repo_parse_commit(repo, parent)) {
154
+ return error(_("unable to parse parent commit %s"),
155
+ oid_to_hex(&parent->object.oid));
156
+ }
157
+
158
+ parent_tree_oid = repo_get_commit_tree(repo, parent)->object.oid;
159
+ } else {
160
+ oidcpy(&parent_tree_oid, repo->hash_algo->empty_tree);
161
+ }
162
+
163
+ return commit_tree_with_edited_message_ext(repo, action, original, original->parents,
164
+ &parent_tree_oid, tree_oid, out);
165
+}
166
+
167
enum ref_action {
168
REF_ACTION_DEFAULT,
169
REF_ACTION_BRANCHES,