git/list[1] front-page[2] threads[3] people[4] search[5] about
wed 2026-10-07 17:27 UTC

[PATCH 7/8] builtin/history: split out extended function to create commits

From
Patrick Steinhardt <ps@pks.im>
Date
Mar 2, 2026, 12:13 UTC
Message-ID
<20260302-pks-history-split-v1-7-444fc987a324@pks.im>
In-Reply-To
<20260302-pks-history-split-v1-0-444fc987a324@pks.im>

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>
---
 builtin/history.c | 67 +++++++++++++++++++++++++++++++++----------------------
 1 file changed, 40 insertions(+), 27 deletions(-)
diff --git a/builtin/history.c b/builtin/history.c
index 1cf6c668cf..80726ce14b 100644
--- a/builtin/history.c
+++ b/builtin/history.c
@@ -83,10 +83,13 @@ static int fill_commit_message(struct repository *repo,
 	return 0;
 }
 
-static int commit_tree_with_edited_message(struct repository *repo,
-					   const char *action,
-					   struct commit *original,
-					   struct commit **out)
+static int commit_tree_with_edited_message_ext(struct repository *repo,
+					       const char *action,
+					       struct commit *commit_with_message,
+					       const struct commit_list *parents,
+					       const struct object_id *old_tree,
+					       const struct object_id *new_tree,
+					       struct commit **out)
 {
 	const char *exclude_gpgsig[] = {
 		/* 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,
 	struct commit_extra_header *original_extra_headers = NULL;
 	struct strbuf commit_message = STRBUF_INIT;
 	struct object_id rewritten_commit_oid;
-	struct object_id original_tree_oid;
-	struct object_id parent_tree_oid;
 	char *original_author = NULL;
-	struct commit *parent;
 	size_t len;
 	int ret;
 
-	original_tree_oid = repo_get_commit_tree(repo, original)->object.oid;
-
-	parent = original->parents ? original->parents->item : NULL;
-	if (parent) {
-		if (repo_parse_commit(repo, parent)) {
-			ret = error(_("unable to parse parent commit %s"),
-				    oid_to_hex(&parent->object.oid));
-			goto out;
-		}
-
-		parent_tree_oid = repo_get_commit_tree(repo, parent)->object.oid;
-	} else {
-		oidcpy(&parent_tree_oid, repo->hash_algo->empty_tree);
-	}
-
 	/* We retain authorship of the original commit. */
-	original_message = repo_logmsg_reencode(repo, original, NULL, NULL);
+	original_message = repo_logmsg_reencode(repo, commit_with_message, NULL, NULL);
 	ptr = find_commit_header(original_message, "author", &len);
 	if (ptr)
 		original_author = xmemdupz(ptr, len);
 	find_commit_subject(original_message, &original_body);
 
-	ret = fill_commit_message(repo, &parent_tree_oid, &original_tree_oid,
+	ret = fill_commit_message(repo, old_tree, new_tree,
 				  original_body, action, &commit_message);
 	if (ret < 0)
 		goto out;
 
-	original_extra_headers = read_commit_extra_headers(original, exclude_gpgsig);
+	original_extra_headers = read_commit_extra_headers(commit_with_message,
+							   exclude_gpgsig);
 
-	ret = commit_tree_extended(commit_message.buf, commit_message.len, &original_tree_oid,
-				   original->parents, &rewritten_commit_oid, original_author,
+	ret = commit_tree_extended(commit_message.buf, commit_message.len, new_tree,
+				   parents, &rewritten_commit_oid, original_author,
 				   NULL, NULL, original_extra_headers);
 	if (ret < 0)
 		goto out;
@@ -151,6 +137,33 @@ static int commit_tree_with_edited_message(struct repository *repo,
 	return ret;
 }
 
+static int commit_tree_with_edited_message(struct repository *repo,
+					   const char *action,
+					   struct commit *original,
+					   struct commit **out)
+{
+	struct object_id parent_tree_oid;
+	const struct object_id *tree_oid;
+	struct commit *parent;
+
+	tree_oid = &repo_get_commit_tree(repo, original)->object.oid;
+
+	parent = original->parents ? original->parents->item : NULL;
+	if (parent) {
+		if (repo_parse_commit(repo, parent)) {
+			return error(_("unable to parse parent commit %s"),
+				     oid_to_hex(&parent->object.oid));
+		}
+
+		parent_tree_oid = repo_get_commit_tree(repo, parent)->object.oid;
+	} else {
+		oidcpy(&parent_tree_oid, repo->hash_algo->empty_tree);
+	}
+
+	return commit_tree_with_edited_message_ext(repo, action, original, original->parents,
+						   &parent_tree_oid, tree_oid, out);
+}
+
 enum ref_action {
 	REF_ACTION_DEFAULT,
 	REF_ACTION_BRANCHES,
-- 
2.53.0.697.g625c4fb2da.dirty
Previous: Patrick SteinhardtNext: Patrick Steinhardt
Message 8 of 16 in “history: introduce "split" subcommand”
  1. 0/8 history: introduce "split" subcommandPatrick Steinhardt, Mar 2, 2026
  2. 1/8 add-patch: split out header from "add-interactive.h"Patrick Steinhardt, Mar 2, 2026
  3. 2/8 add-patch: split out `struct interactive_options`Patrick Steinhardt, Mar 2, 2026
  4. 3/8 add-patch: remove dependency on "add-interactive" subsystemPatrick Steinhardt, Mar 2, 2026
  5. 4/8 add-patch: add support for in-memory index patchingPatrick Steinhardt, Mar 2, 2026
  6. 5/8 add-patch: allow disabling editing of hunksPatrick Steinhardt, Mar 2, 2026
  7. 6/8 cache-tree: allow writing in-memory index as treePatrick Steinhardt, Mar 2, 2026
  8. 7/8 builtin/history: split out extended function to create commitsPatrick Steinhardt, Mar 2, 2026
  9. 8/8 builtin/history: implement "split" subcommandPatrick Steinhardt, Mar 2, 2026
  10. D. Ben KnobleMar 3, 2026
  11. D. Ben KnobleMar 3, 2026
  12. D. Ben KnobleMar 3, 2026
  13. Patrick SteinhardtMar 11, 2026
  14. Patrick SteinhardtMar 11, 2026
  15. Junio C HamanoMar 13, 2026
  16. Patrick SteinhardtMar 16, 2026

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.