Re: [PATCH 7/8] builtin/history: split out extended function to create commits
- From
D. Ben Knoble <ben.knoble@gmail.com>
- Date
- Mar 3, 2026, 18:43 UTC
- Message-ID
- <CALnO6CC5FB29bHPtyKD=L5EWxTCLx3K2qd+wGySdck7tCvvs_w@mail.gmail.com>
- In-Reply-To
- <20260302-pks-history-split-v1-7-444fc987a324@pks.im>
On Mon, Mar 2, 2026 at 7:17 AM Patrick Steinhardt <ps@pks.im> wrote:
Show 8 quoted lines
> > 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.
Curious—what's the "ext" suffix mean here. Extracted? External? (Maybe I'll get a better clue in the next patch.)
Show 117 quoted lines
> 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
>
>-- D. Ben Knoble