}
}
-enum todo_item_flags {
- TODO_EDIT_MERGE_MSG = (1 << 0),
- TODO_REPLACE_FIXUP_MSG = (1 << 1),
- TODO_EDIT_FIXUP_MSG = (1 << 2),
-};
-
static const char first_commit_msg_str[] = N_("This is the 1st commit message:");
static const char nth_commit_msg_fmt[] = N_("This is the commit message #%d:");
static const char skip_first_commit_msg_str[] = N_("The 1st commit message will be skipped:");
static const char skip_nth_commit_msg_fmt[] = N_("The commit message #%d will be skipped:");
static const char combined_commit_msg_fmt[] = N_("This is a combination of %d commits.");
+void add_squash_combination_header(struct strbuf *buf, int n)
+{
+ strbuf_addf(buf, "%s ", comment_line_str);
+ strbuf_addf(buf, _(combined_commit_msg_fmt), n);
+}
+
+void add_squash_message_header(struct strbuf *buf, int n, int skip)
+{
+ strbuf_addf(buf, "%s ", comment_line_str);
+ if (n == 1)
+ strbuf_addstr(buf, skip ? _(skip_first_commit_msg_str) :
+ _(first_commit_msg_str));
+ else
+ strbuf_addf(buf, skip ? _(skip_nth_commit_msg_fmt) :
+ _(nth_commit_msg_fmt), n);
+}
+
+size_t squash_subject_comment_len(const char *body, int squashing)
+{
+ if (starts_with(body, "amend!") ||
+ (squashing && (starts_with(body, "squash!") ||
+ starts_with(body, "fixup!"))))
+ return commit_subject_length(body);
+ return 0;
+}
+
static int is_fixup_flag(enum todo_command command, unsigned flag)
{
return command == TODO_FIXUP && ((flag & TODO_REPLACE_FIXUP_MSG) ||
{
struct replay_ctx *ctx = opts->ctx;
const char *fixup_msg;
- size_t commented_len = 0, fixup_off;
- /*
- * amend is non-interactive and not normally used with fixup!
- * or squash! commits, so only comment out those subjects when
- * squashing commit messages.
- */
- if (starts_with(body, "amend!") ||
- ((command == TODO_SQUASH || seen_squash(ctx)) &&
- (starts_with(body, "squash!") || starts_with(body, "fixup!"))))
- commented_len = commit_subject_length(body);
+ size_t commented_len, fixup_off;
+
+ commented_len = squash_subject_comment_len(body,
+ command == TODO_SQUASH || seen_squash(ctx));
- strbuf_addf(buf, "\n%s ", comment_line_str);
- strbuf_addf(buf, _(nth_commit_msg_fmt),
- ++ctx->current_fixup_count + 1);
+ strbuf_addch(buf, '\n');
+ add_squash_message_header(buf, ++ctx->current_fixup_count + 1, 0);
strbuf_addstr(buf, "\n\n");
strbuf_add_commented_lines(buf, body, commented_len, comment_line_str);
/* buf->buf may be reallocated so store an offset into the buffer */
eol = !starts_with(buf.buf, comment_line_str) ?
buf.buf : strchrnul(buf.buf, '\n');
- strbuf_addf(&header, "%s ", comment_line_str);
- strbuf_addf(&header, _(combined_commit_msg_fmt),
- ctx->current_fixup_count + 2);
+ add_squash_combination_header(&header,
+ ctx->current_fixup_count + 2);
strbuf_splice(&buf, 0, eol - buf.buf, header.buf, header.len);
strbuf_release(&header);
if (is_fixup_flag(command, flag) && !seen_squash(ctx))
repo_unuse_commit_buffer(r, head_commit, head_message);
return error(_("cannot write '%s'"), rebase_path_fixup_msg());
}
- strbuf_addf(&buf, "%s ", comment_line_str);
- strbuf_addf(&buf, _(combined_commit_msg_fmt), 2);
- strbuf_addf(&buf, "\n%s ", comment_line_str);
- strbuf_addstr(&buf, is_fixup_flag(command, flag) ?
- _(skip_first_commit_msg_str) :
- _(first_commit_msg_str));
+ add_squash_combination_header(&buf, 2);
+ strbuf_addch(&buf, '\n');
+ add_squash_message_header(&buf, 1, is_fixup_flag(command, flag));
strbuf_addstr(&buf, "\n\n");
if (is_fixup_flag(command, flag))
strbuf_add_commented_lines(&buf, body, strlen(body),
if (command == TODO_SQUASH || is_fixup_flag(command, flag)) {
res = append_squash_message(&buf, body, command, opts, flag);
} else if (command == TODO_FIXUP) {
- strbuf_addf(&buf, "\n%s ", comment_line_str);
- strbuf_addf(&buf, _(skip_nth_commit_msg_fmt),
- ++ctx->current_fixup_count + 1);
+ strbuf_addch(&buf, '\n');
+ add_squash_message_header(&buf, ++ctx->current_fixup_count + 1, 1);
strbuf_addstr(&buf, "\n\n");
strbuf_add_commented_lines(&buf, body, strlen(body),
comment_line_str);
TODO_COMMENT
};
+/* Bits for the "flags" member of struct todo_item */
+enum todo_item_flags {
+ TODO_EDIT_MERGE_MSG = (1 << 0),
+ TODO_REPLACE_FIXUP_MSG = (1 << 1),
+ TODO_EDIT_FIXUP_MSG = (1 << 2),
+};
+
struct todo_item {
enum todo_command command;
struct commit *commit;
*/
void append_signoff(struct strbuf *msgbuf, size_t ignore_footer, unsigned flag);
+/*
+ * Append the "This is a combination of N commits." banner that "git rebase
+ * -i" writes at the top of a squashed commit's message, commented out with
+ * the comment character.
+ */
+void add_squash_combination_header(struct strbuf *buf, int n);
+
+/*
+ * Append the header (1-based N) that "git rebase -i" writes above each message
+ * when squashing, commented out with the comment character. With SKIP it reads
+ * "The ... commit message will be skipped" for a message that is dropped (a
+ * fixup), otherwise "This is the ... commit message".
+ */
+void add_squash_message_header(struct strbuf *buf, int n, int skip);
+
+/*
+ * Return the length of the leading subject of BODY when it should be commented
+ * out in a squash message, or 0 otherwise. An "amend!" subject always
+ * qualifies; "squash!" and "fixup!" subjects only when SQUASHING, since a
+ * plain fixup chain keeps them.
+ */
+size_t squash_subject_comment_len(const char *body, int squashing);
+
void append_conflicts_hint(struct index_state *istate,
struct strbuf *msgbuf, enum commit_msg_cleanup_mode cleanup_mode);
enum commit_msg_cleanup_mode get_cleanup_mode(const char *cleanup_arg,