From 622a0469a4970c5daac0c0323e2d6a77b3bebbdb Mon Sep 17 00:00:00 2001 From: Vegard Nossum Date: Sat, 5 Oct 2019 16:15:59 +0200 Subject: [PATCH 1/3] format-patch: add --complete Include the raw commit data between the changelog and the diffstat. This will allow 'git am' to reconstruct the commit exactly to the point where the sha1 will be the same. Signed-off-by: Vegard Nossum --- commit 622a0469a4970c5daac0c0323e2d6a77b3bebbdb tree 8f09d9d6ed78f8617b2fe54fe9712990ba808546 parent 108b97dc372828f0e72e56bbb40cae8e1e83ece6 author Vegard Nossum 1570284959 +0200 committer Vegard Nossum 1571219301 +0200 --- builtin/log.c | 12 ++++++++++++ log-tree.c | 17 +++++++++++++++++ revision.h | 3 ++- 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/builtin/log.c b/builtin/log.c index c4b35fdaf9..81c1164ae5 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -1545,6 +1545,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) char *branch_name = NULL; char *base_commit = NULL; struct base_tree_info bases; + int complete = 0; int show_progress = 0; struct progress *progress = NULL; struct oid_array idiff_prev = OID_ARRAY_INIT; @@ -1622,6 +1623,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) N_("add a signature")), OPT_STRING(0, "base", &base_commit, N_("base-commit"), N_("add prerequisite tree info to the patch series")), + OPT_BOOL(0, "complete", &complete, + N_("include all the information necessary to reconstruct commit exactly")), OPT_FILENAME(0, "signature-file", &signature_file, N_("add a signature from a file")), OPT__QUIET(&quiet, N_("don't print the patch filenames")), @@ -1905,6 +1908,15 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) prepare_bases(&bases, base, list, nr); } + if (complete) { + /* + * We need the commit buffer so that we can output the exact + * sequence of bytes that gets hashed as part of a commit. + */ + save_commit_buffer = 1; + rev.show_raw_buffer = 1; + } + if (in_reply_to || thread || cover_letter) rev.ref_message_ids = xcalloc(1, sizeof(struct string_list)); if (in_reply_to) { diff --git a/log-tree.c b/log-tree.c index 923a299e70..2c9788b25a 100644 --- a/log-tree.c +++ b/log-tree.c @@ -774,6 +774,22 @@ void show_log(struct rev_info *opt) memcpy(&diff_queued_diff, &dq, sizeof(diff_queued_diff)); } + + if (opt->show_raw_buffer) { + const char *buffer = get_commit_buffer(commit, NULL); + const char *subject; + + fprintf(opt->diffopt.file, "---\n"); + fprintf(opt->diffopt.file, "commit %s\n", oid_to_hex(&commit->object.oid)); + + /* + * TODO: hex-encode to avoid mailer mangling? + */ + if (find_commit_subject(buffer, &subject)) + fprintf(opt->diffopt.file, "%.*s", (int) (subject - buffer), buffer); + else + fprintf(opt->diffopt.file, "%s", buffer); + } } int log_tree_diff_flush(struct rev_info *opt) @@ -791,6 +807,7 @@ int log_tree_diff_flush(struct rev_info *opt) if (opt->loginfo && !opt->no_commit_id) { show_log(opt); + if ((opt->diffopt.output_format & ~DIFF_FORMAT_NO_OUTPUT) && opt->verbose_header && opt->commit_format != CMIT_FMT_ONELINE && diff --git a/revision.h b/revision.h index 4134dc6029..5297dc9f3c 100644 --- a/revision.h +++ b/revision.h @@ -190,7 +190,8 @@ struct rev_info { use_terminator:1, missing_newline:1, date_mode_explicit:1, - preserve_subject:1; + preserve_subject:1, + show_raw_buffer:1; unsigned int disable_stdin:1; /* --show-linear-break */ unsigned int track_linear:1, -- 2.23.0.718.g3120370db8