These options make it convenient to construct commit messages for use with 'rebase --autosquash'. The resulting commit message will be "fixup! ..." or "squash! ..." where "..." is the subject line of the specified commit message. Example usage: $ git commit --fixup HEAD~2 $ git commit --squash HEAD~5 Signed-off-by: Pat Notz <patnotz@xxxxxxxxx> --- Documentation/git-commit.txt | 18 ++++++++++++++---- builtin/commit.c | 37 +++++++++++++++++++++++++++++++++---- 2 files changed, 47 insertions(+), 8 deletions(-) diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt index 42fb1f5..1d1e0c8 100644 --- a/Documentation/git-commit.txt +++ b/Documentation/git-commit.txt @@ -9,10 +9,10 @@ SYNOPSIS -------- [verse] 'git commit' [-a | --interactive] [-s] [-v] [-u<mode>] [--amend] [--dry-run] - [(-c | -C) <commit>] [-F <file> | -m <msg>] [--reset-author] - [--allow-empty] [--allow-empty-message] [--no-verify] [-e] [--author=<author>] - [--date=<date>] [--cleanup=<mode>] [--status | --no-status] [--] - [[-i | -o ]<file>...] + [(-c | -C | --fixup | --squash ) <commit>] [-F <file> | -m <msg>] + [--reset-author] [--allow-empty] [--allow-empty-message] [--no-verify] + [-e] [--author=<author>] [--date=<date>] [--cleanup=<mode>] + [--status | --no-status] [--] [[-i | -o ]<file>...] DESCRIPTION ----------- @@ -70,6 +70,16 @@ OPTIONS Like '-C', but with '-c' the editor is invoked, so that the user can further edit the commit message. +--fixup=<commit>:: + Construct a commit message for use with `rebase --autosquash`. + The commit message will be the subject line from the specified + commit with a prefix of "fixup! ". + +--squash=<commit>:: + Construct a commit message for use with `rebase --autosquash`. + The commit message will be the subject line from the specified + commit with a prefix of "squash! ". + --reset-author:: When used with -C/-c/--amend options, declare that the authorship of the resulting commit now belongs of the committer. diff --git a/builtin/commit.c b/builtin/commit.c index 66fdd22..e525e78 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -57,6 +57,7 @@ static const char empty_amend_advice[] = static unsigned char head_sha1[20]; static char *use_message_buffer; +static char *fixup_message_buffer; static const char commit_editmsg[] = "COMMIT_EDITMSG"; static struct lock_file index_lock; /* real index */ static struct lock_file false_lock; /* used only for partial commits */ @@ -69,6 +70,7 @@ static enum { static const char *logfile, *force_author; static const char *template_file; static char *edit_message, *use_message; +static char *fixup_message, *squash_message; static char *author_name, *author_email, *author_date; static int all, edit_flag, also, interactive, only, amend, signoff; static int quiet, verbose, no_verify, allow_empty, dry_run, renew_authorship; @@ -124,6 +126,8 @@ static struct option builtin_commit_options[] = { OPT_CALLBACK('m', "message", &message, "MESSAGE", "specify commit message", opt_parse_m), OPT_STRING('c', "reedit-message", &edit_message, "COMMIT", "reuse and edit message from specified commit"), OPT_STRING('C', "reuse-message", &use_message, "COMMIT", "reuse message from specified commit"), + OPT_STRING(0, "fixup", &fixup_message, "COMMIT", "use autosquash formatted message to fixup specified commit"), + OPT_STRING(0, "squash", &squash_message, "COMMIT", "use autosquash formatted message to squash specified commit"), OPT_BOOLEAN(0, "reset-author", &renew_authorship, "the commit is authored by me now (used with -C-c/--amend)"), OPT_BOOLEAN('s', "signoff", &signoff, "add Signed-off-by:"), OPT_FILENAME('t', "template", &template_file, "use specified template file"), @@ -586,6 +590,10 @@ static int prepare_to_commit(const char *index_file, const char *prefix, strbuf_add(&sb, buffer + 2, strlen(buffer + 2)); hook_arg1 = "commit"; hook_arg2 = use_message; + } else if (fixup_message || squash_message) { + strbuf_addstr(&sb, fixup_message_buffer); + free(fixup_message_buffer); + hook_arg1 = "message"; } else if (!stat(git_path("MERGE_MSG"), &statbuf)) { if (strbuf_read_file(&sb, git_path("MERGE_MSG"), 0) < 0) die_errno("could not read MERGE_MSG"); @@ -863,7 +871,7 @@ static int parse_and_validate_options(int argc, const char *argv[], if (force_author && renew_authorship) die("Using both --reset-author and --author does not make sense"); - if (logfile || message.len || use_message) + if (logfile || message.len || use_message || fixup_message || squash_message) use_editor = 0; if (edit_flag) use_editor = 1; @@ -883,15 +891,19 @@ static int parse_and_validate_options(int argc, const char *argv[], f++; if (edit_message) f++; + if (fixup_message) + f++; + if (squash_message) + f++; if (logfile) f++; if (f > 1) - die("Only one of -c/-C/-F can be used."); + die("Only one of -c/-C/-F/--fixup/--squash can be used."); if (message.len && f > 0) - die("Option -m cannot be combined with -c/-C/-F."); + die("Option -m cannot be combined with -c/-C/-F/--fixup/--squash."); if (edit_message) use_message = edit_message; - if (amend && !use_message) + if (amend && (!use_message && !fixup_message && !squash_message)) use_message = "HEAD"; if (!use_message && renew_authorship) die("--reset-author can be used only with -C, -c or --amend."); @@ -932,6 +944,23 @@ static int parse_and_validate_options(int argc, const char *argv[], if (enc != utf8) free(enc); } + if (fixup_message || squash_message) { + unsigned char sha1[20]; + struct commit *commit; + const char * target_message = fixup_message ? fixup_message : squash_message; + const char * msg_fmt = fixup_message ? "fixup! %s" : "squash! %s"; + struct strbuf buf = STRBUF_INIT; + struct pretty_print_context ctx = {0}; + + if (get_sha1(target_message, sha1)) + die("could not lookup commit %s", target_message); + commit = lookup_commit_reference(sha1); + if (!commit || parse_commit(commit)) + die("could not parse commit %s", target_message); + + format_commit_message(commit, msg_fmt, &buf, &ctx); + fixup_message_buffer = strbuf_detach(&buf, NULL); + } if (!!also + !!only + !!all + !!interactive > 1) die("Only one of --include/--only/--all/--interactive can be used."); -- 1.7.2.3 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html