Skip to content

Commit 46d164b

Browse files
bebarinogitster
authored andcommitted
pretty.c: add %f format specifier to format_commit_message()
This specifier represents the sanitized and filename friendly subject line of a commit. No checks are made against the length of the string, so users may need to trim the result to the desired length if using as a filename. This is commonly used by format-patch to massage commit subjects into filenames and output patches to files. Signed-off-by: Stephen Boyd <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 636991b commit 46d164b

File tree

2 files changed

+36
-0
lines changed

2 files changed

+36
-0
lines changed

Documentation/pretty-formats.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ The placeholders are:
121121
- '%d': ref names, like the --decorate option of linkgit:git-log[1]
122122
- '%e': encoding
123123
- '%s': subject
124+
- '%f': sanitized subject line, suitable for a filename
124125
- '%b': body
125126
- '%Cred': switch color to red
126127
- '%Cgreen': switch color to green

pretty.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,38 @@ static void parse_commit_header(struct format_commit_context *context)
493493
context->commit_header_parsed = 1;
494494
}
495495

496+
static int istitlechar(char c)
497+
{
498+
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
499+
(c >= '0' && c <= '9') || c == '.' || c == '_';
500+
}
501+
502+
static void format_sanitized_subject(struct strbuf *sb, const char *msg)
503+
{
504+
size_t trimlen;
505+
int space = 2;
506+
507+
for (; *msg && *msg != '\n'; msg++) {
508+
if (istitlechar(*msg)) {
509+
if (space == 1)
510+
strbuf_addch(sb, '-');
511+
space = 0;
512+
strbuf_addch(sb, *msg);
513+
if (*msg == '.')
514+
while (*(msg+1) == '.')
515+
msg++;
516+
} else
517+
space |= 1;
518+
}
519+
520+
/* trim any trailing '.' or '-' characters */
521+
trimlen = 0;
522+
while (sb->buf[sb->len - 1 - trimlen] == '.'
523+
|| sb->buf[sb->len - 1 - trimlen] == '-')
524+
trimlen++;
525+
strbuf_remove(sb, sb->len - trimlen, trimlen);
526+
}
527+
496528
const char *format_subject(struct strbuf *sb, const char *msg,
497529
const char *line_separator)
498530
{
@@ -683,6 +715,9 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
683715
case 's': /* subject */
684716
format_subject(sb, msg + c->subject_off, " ");
685717
return 1;
718+
case 'f': /* sanitized subject */
719+
format_sanitized_subject(sb, msg + c->subject_off);
720+
return 1;
686721
case 'b': /* body */
687722
strbuf_addstr(sb, msg + c->body_off);
688723
return 1;

0 commit comments

Comments
 (0)