Merge branch 'pn/commit-autosquash'
* pn/commit-autosquash: add tests of commit --squash commit: --squash option for use with rebase --autosquash add tests of commit --fixup commit: --fixup option for use with rebase --autosquash pretty.c: teach format_commit_message() to reencode the output commit: helper methods to reduce redundant blocks of code Conflicts: Documentation/git-commit.txt t/t3415-rebase-autosquash.sh
This commit is contained in:
@ -69,6 +69,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 +125,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"),
|
||||
@ -565,6 +568,25 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
|
||||
if (!no_verify && run_hook(index_file, "pre-commit", NULL))
|
||||
return 0;
|
||||
|
||||
if (squash_message) {
|
||||
/*
|
||||
* Insert the proper subject line before other commit
|
||||
* message options add their content.
|
||||
*/
|
||||
if (use_message && !strcmp(use_message, squash_message))
|
||||
strbuf_addstr(&sb, "squash! ");
|
||||
else {
|
||||
struct pretty_print_context ctx = {0};
|
||||
struct commit *c;
|
||||
c = lookup_commit_reference_by_name(squash_message);
|
||||
if (!c)
|
||||
die("could not lookup commit %s", squash_message);
|
||||
ctx.output_encoding = get_commit_output_encoding();
|
||||
format_commit_message(c, "squash! %s\n\n", &sb,
|
||||
&ctx);
|
||||
}
|
||||
}
|
||||
|
||||
if (message.len) {
|
||||
strbuf_addbuf(&sb, &message);
|
||||
hook_arg1 = "message";
|
||||
@ -586,6 +608,16 @@ 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) {
|
||||
struct pretty_print_context ctx = {0};
|
||||
struct commit *commit;
|
||||
commit = lookup_commit_reference_by_name(fixup_message);
|
||||
if (!commit)
|
||||
die("could not lookup commit %s", fixup_message);
|
||||
ctx.output_encoding = get_commit_output_encoding();
|
||||
format_commit_message(commit, "fixup! %s\n\n",
|
||||
&sb, &ctx);
|
||||
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");
|
||||
@ -607,6 +639,16 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
|
||||
else if (in_merge)
|
||||
hook_arg1 = "merge";
|
||||
|
||||
if (squash_message) {
|
||||
/*
|
||||
* If squash_commit was used for the commit subject,
|
||||
* then we're possibly hijacking other commit log options.
|
||||
* Reset the hook args to tell the real story.
|
||||
*/
|
||||
hook_arg1 = "message";
|
||||
hook_arg2 = "";
|
||||
}
|
||||
|
||||
fp = fopen(git_path(commit_editmsg), "w");
|
||||
if (fp == NULL)
|
||||
die_errno("could not open '%s'", git_path(commit_editmsg));
|
||||
@ -863,7 +905,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)
|
||||
use_editor = 0;
|
||||
if (edit_flag)
|
||||
use_editor = 1;
|
||||
@ -878,48 +920,35 @@ static int parse_and_validate_options(int argc, const char *argv[],
|
||||
die("You have nothing to amend.");
|
||||
if (amend && in_merge)
|
||||
die("You are in the middle of a merge -- cannot amend.");
|
||||
|
||||
if (fixup_message && squash_message)
|
||||
die("Options --squash and --fixup cannot be used together");
|
||||
if (use_message)
|
||||
f++;
|
||||
if (edit_message)
|
||||
f++;
|
||||
if (fixup_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 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.");
|
||||
if (edit_message)
|
||||
use_message = edit_message;
|
||||
if (amend && !use_message)
|
||||
if (amend && !use_message && !fixup_message)
|
||||
use_message = "HEAD";
|
||||
if (!use_message && renew_authorship)
|
||||
die("--reset-author can be used only with -C, -c or --amend.");
|
||||
if (use_message) {
|
||||
unsigned char sha1[20];
|
||||
static char utf8[] = "UTF-8";
|
||||
const char *out_enc;
|
||||
char *enc, *end;
|
||||
struct commit *commit;
|
||||
|
||||
if (get_sha1(use_message, sha1))
|
||||
commit = lookup_commit_reference_by_name(use_message);
|
||||
if (!commit)
|
||||
die("could not lookup commit %s", use_message);
|
||||
commit = lookup_commit_reference(sha1);
|
||||
if (!commit || parse_commit(commit))
|
||||
die("could not parse commit %s", use_message);
|
||||
|
||||
enc = strstr(commit->buffer, "\nencoding");
|
||||
if (enc) {
|
||||
end = strchr(enc + 10, '\n');
|
||||
enc = xstrndup(enc + 10, end - (enc + 10));
|
||||
} else {
|
||||
enc = utf8;
|
||||
}
|
||||
out_enc = git_commit_encoding ? git_commit_encoding : utf8;
|
||||
|
||||
if (strcmp(out_enc, enc))
|
||||
use_message_buffer =
|
||||
reencode_string(commit->buffer, out_enc, enc);
|
||||
out_enc = get_commit_output_encoding();
|
||||
use_message_buffer = logmsg_reencode(commit, out_enc);
|
||||
|
||||
/*
|
||||
* If we failed to reencode the buffer, just copy it
|
||||
@ -929,8 +958,6 @@ static int parse_and_validate_options(int argc, const char *argv[],
|
||||
*/
|
||||
if (use_message_buffer == NULL)
|
||||
use_message_buffer = xstrdup(commit->buffer);
|
||||
if (enc != utf8)
|
||||
free(enc);
|
||||
}
|
||||
|
||||
if (!!also + !!only + !!all + !!interactive > 1)
|
||||
|
||||
Reference in New Issue
Block a user