Skip to content

Commit

Permalink
Merge branch 'jc/prettier-pretty-note'
Browse files Browse the repository at this point in the history
Emit the notes attached to the commit in "format-patch --notes"
output after three-dashes.

* jc/prettier-pretty-note:
  format-patch: add a blank line between notes and diffstat
  Doc User-Manual: Patch cover letter, three dashes, and --notes
  Doc format-patch: clarify --notes use case
  Doc notes: Include the format-patch --notes option
  Doc SubmittingPatches: Mention --notes option after "cover letter"
  Documentation: decribe format-patch --notes
  format-patch --notes: show notes after three-dashes
  format-patch: append --signature after notes
  pretty_print_commit(): do not append notes message
  pretty: prepare notes message at a centralized place
  format_note(): simplify API
  pretty: remove reencode_commit_message()
  • Loading branch information
Junio C Hamano committed Nov 15, 2012
2 parents 159a5a2 + 1d34c50 commit 4ad4fce
Show file tree
Hide file tree
Showing 13 changed files with 100 additions and 47 deletions.
3 changes: 2 additions & 1 deletion Documentation/SubmittingPatches
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,8 @@ message starts, you can put a "From: " line to name that person.

You often want to add additional explanation about the patch,
other than the commit message itself. Place such "cover letter"
material between the three dash lines and the diffstat.
material between the three dash lines and the diffstat. Git-notes
can also be inserted using the `--notes` option.

Do not attach the patch as a MIME attachment, compressed or not.
Do not let your e-mail client send quoted-printable. Do not let
Expand Down
14 changes: 13 additions & 1 deletion Documentation/git-format-patch.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ SYNOPSIS
[--ignore-if-in-upstream]
[--subject-prefix=Subject-Prefix]
[--to=<email>] [--cc=<email>]
[--cover-letter] [--quiet]
[--cover-letter] [--quiet] [--notes[=<ref>]]
[<common diff options>]
[ <since> | <revision range> ]

Expand Down Expand Up @@ -191,6 +191,18 @@ will want to ensure that threading is disabled for `git send-email`.
containing the shortlog and the overall diffstat. You can
fill in a description in the file before sending it out.

--notes[=<ref>]::
Append the notes (see linkgit:git-notes[1]) for the commit
after the three-dash line.
+
The expected use case of this is to write supporting explanation for
the commit that does not belong to the commit log message proper,
and include it with the patch submission. While one can simply write
these explanations after `format-patch` has run but before sending,
keeping them as git notes allows them to be maintained between versions
of the patch series (but see the discussion of the `notes.rewrite`
configuration options in linkgit:git-notes[1] to use this workflow).

--[no]-signature=<signature>::
Add a signature to each message produced. Per RFC 3676 the signature
is separated from the body by a line with '-- ' on it. If the
Expand Down
4 changes: 4 additions & 0 deletions Documentation/git-notes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ message stored in the commit object, the notes are indented like the
message, after an unindented line saying "Notes (<refname>):" (or
"Notes:" for `refs/notes/commits`).

Notes can also be added to patches prepared with `git format-patch` by
using the `--notes` option. Such notes are added as a patch commentary
after a three dash separator line.

To change which notes are shown by 'git log', see the
"notes.displayRef" configuration in linkgit:git-log[1].

Expand Down
7 changes: 7 additions & 0 deletions Documentation/user-manual.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1787,6 +1787,13 @@ $ git format-patch origin
will produce a numbered series of files in the current directory, one
for each patch in the current branch but not in origin/HEAD.

`git format-patch` can include an initial "cover letter". You can insert
commentary on individual patches after the three dash line which
`format-patch` places after the commit message but before the patch
itself. If you use `git notes` to track your cover letter material,
`git format-patch --notes` will include the commit's notes in a similar
manner.

You can then import these into your mail client and send them by
hand. However, if you have a lot to send at once, you may prefer to
use the linkgit:git-send-email[1] script to automate the process.
Expand Down
5 changes: 3 additions & 2 deletions builtin/blame.c
Original file line number Diff line number Diff line change
Expand Up @@ -1425,7 +1425,7 @@ static void get_commit_info(struct commit *commit,
int detailed)
{
int len;
const char *subject;
const char *subject, *encoding;
char *reencoded, *message;
static char author_name[1024];
static char author_mail[1024];
Expand All @@ -1446,7 +1446,8 @@ static void get_commit_info(struct commit *commit,
die("Cannot read commit %s",
sha1_to_hex(commit->object.sha1));
}
reencoded = reencode_commit_message(commit, NULL);
encoding = get_log_output_encoding();
reencoded = logmsg_reencode(commit, encoding);
message = reencoded ? reencoded : commit->buffer;
ret->author = author_name;
ret->author_mail = author_mail;
Expand Down
4 changes: 1 addition & 3 deletions commit.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ struct pretty_print_context {
enum date_mode date_mode;
unsigned date_mode_explicit:1;
int need_8bit_cte;
int show_notes;
char *notes_message;
struct reflog_walk_info *reflog_info;
const char *output_encoding;
};
Expand All @@ -99,8 +99,6 @@ extern int has_non_ascii(const char *text);
struct rev_info; /* in revision.h, it circularly uses enum cmit_fmt */
extern char *logmsg_reencode(const struct commit *commit,
const char *output_encoding);
extern char *reencode_commit_message(const struct commit *commit,
const char **encoding_p);
extern void get_commit_format(const char *arg, struct rev_info *);
extern const char *format_subject(struct strbuf *sb, const char *msg,
const char *line_separator);
Expand Down
51 changes: 43 additions & 8 deletions log-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -540,7 +540,6 @@ void show_log(struct rev_info *opt)
struct pretty_print_context ctx = {0};

opt->loginfo = NULL;
ctx.show_notes = opt->show_notes;
if (!opt->verbose_header) {
graph_show_commit(opt->graph);

Expand Down Expand Up @@ -648,6 +647,18 @@ void show_log(struct rev_info *opt)
if (!commit->buffer)
return;

if (opt->show_notes) {
int raw;
struct strbuf notebuf = STRBUF_INIT;

raw = (opt->commit_format == CMIT_FMT_USERFORMAT);
format_display_notes(commit->object.sha1, &notebuf,
get_log_output_encoding(), raw);
ctx.notes_message = notebuf.len
? strbuf_detach(&notebuf, NULL)
: xcalloc(1, 1);
}

/*
* And then the pretty-printed message itself
*/
Expand All @@ -664,6 +675,16 @@ void show_log(struct rev_info *opt)

if (opt->add_signoff)
append_signoff(&msgbuf, opt->add_signoff);

if ((ctx.fmt != CMIT_FMT_USERFORMAT) &&
ctx.notes_message && *ctx.notes_message) {
if (ctx.fmt == CMIT_FMT_EMAIL) {
strbuf_addstr(&msgbuf, "---\n");
opt->shown_dashes = 1;
}
strbuf_addstr(&msgbuf, ctx.notes_message);
}

if (opt->show_log_size) {
printf("log size %i\n", (int)msgbuf.len);
graph_show_oneline(opt->graph);
Expand All @@ -689,10 +710,12 @@ void show_log(struct rev_info *opt)
}

strbuf_release(&msgbuf);
free(ctx.notes_message);
}

int log_tree_diff_flush(struct rev_info *opt)
{
opt->shown_dashes = 0;
diffcore_std(&opt->diffopt);

if (diff_queue_is_empty()) {
Expand All @@ -704,25 +727,37 @@ int log_tree_diff_flush(struct rev_info *opt)
}

if (opt->loginfo && !opt->no_commit_id) {
/* When showing a verbose header (i.e. log message),
* and not in --pretty=oneline format, we would want
* an extra newline between the end of log and the
* output for readability.
*/
show_log(opt);
if ((opt->diffopt.output_format & ~DIFF_FORMAT_NO_OUTPUT) &&
opt->verbose_header &&
opt->commit_format != CMIT_FMT_ONELINE) {
/*
* When showing a verbose header (i.e. log message),
* and not in --pretty=oneline format, we would want
* an extra newline between the end of log and the
* diff/diffstat output for readability.
*/
int pch = DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_PATCH;
if (opt->diffopt.output_prefix) {
struct strbuf *msg = NULL;
msg = opt->diffopt.output_prefix(&opt->diffopt,
opt->diffopt.output_prefix_data);
fwrite(msg->buf, msg->len, 1, stdout);
}
if ((pch & opt->diffopt.output_format) == pch) {

/*
* We may have shown three-dashes line early
* between notes and the log message, in which
* case we only want a blank line after the
* notes without (an extra) three-dashes line.
* Otherwise, we show the three-dashes line if
* we are showing the patch with diffstat, but
* in that case, there is no extra blank line
* after the three-dashes line.
*/
if (!opt->shown_dashes &&
(pch & opt->diffopt.output_format) == pch)
printf("---");
}
putchar('\n');
}
}
Expand Down
13 changes: 7 additions & 6 deletions notes.c
Original file line number Diff line number Diff line change
Expand Up @@ -1193,10 +1193,11 @@ void free_notes(struct notes_tree *t)
* If the given notes_tree is NULL, the internal/default notes_tree will be
* used instead.
*
* 'flags' is a bitwise combination of the flags for format_display_notes.
* (raw != 0) gives the %N userformat; otherwise, the note message is given
* for human consumption.
*/
static void format_note(struct notes_tree *t, const unsigned char *object_sha1,
struct strbuf *sb, const char *output_encoding, int flags)
struct strbuf *sb, const char *output_encoding, int raw)
{
static const char utf8[] = "utf-8";
const unsigned char *sha1;
Expand Down Expand Up @@ -1233,7 +1234,7 @@ static void format_note(struct notes_tree *t, const unsigned char *object_sha1,
if (msglen && msg[msglen - 1] == '\n')
msglen--;

if (flags & NOTES_SHOW_HEADER) {
if (!raw) {
const char *ref = t->ref;
if (!ref || !strcmp(ref, GIT_NOTES_DEFAULT_REF)) {
strbuf_addstr(sb, "\nNotes:\n");
Expand All @@ -1249,7 +1250,7 @@ static void format_note(struct notes_tree *t, const unsigned char *object_sha1,
for (msg_p = msg; msg_p < msg + msglen; msg_p += linelen + 1) {
linelen = strchrnul(msg_p, '\n') - msg_p;

if (flags & NOTES_INDENT)
if (!raw)
strbuf_addstr(sb, " ");
strbuf_add(sb, msg_p, linelen);
strbuf_addch(sb, '\n');
Expand All @@ -1259,13 +1260,13 @@ static void format_note(struct notes_tree *t, const unsigned char *object_sha1,
}

void format_display_notes(const unsigned char *object_sha1,
struct strbuf *sb, const char *output_encoding, int flags)
struct strbuf *sb, const char *output_encoding, int raw)
{
int i;
assert(display_notes_trees);
for (i = 0; display_notes_trees[i]; i++)
format_note(display_notes_trees[i], object_sha1, sb,
output_encoding, flags);
output_encoding, raw);
}

int copy_note(struct notes_tree *t,
Expand Down
6 changes: 1 addition & 5 deletions notes.h
Original file line number Diff line number Diff line change
Expand Up @@ -237,10 +237,6 @@ void prune_notes(struct notes_tree *t, int flags);
*/
void free_notes(struct notes_tree *t);

/* Flags controlling how notes are formatted */
#define NOTES_SHOW_HEADER 1
#define NOTES_INDENT 2

struct string_list;

struct display_notes_opt {
Expand Down Expand Up @@ -274,7 +270,7 @@ void init_display_notes(struct display_notes_opt *opt);
* You *must* call init_display_notes() before using this function.
*/
void format_display_notes(const unsigned char *object_sha1,
struct strbuf *sb, const char *output_encoding, int flags);
struct strbuf *sb, const char *output_encoding, int raw);

/*
* Load the notes tree from each ref listed in 'refs'. The output is
Expand Down
22 changes: 4 additions & 18 deletions pretty.c
Original file line number Diff line number Diff line change
Expand Up @@ -1100,9 +1100,8 @@ static size_t format_commit_one(struct strbuf *sb, const char *placeholder,
}
return 0; /* unknown %g placeholder */
case 'N':
if (c->pretty_ctx->show_notes) {
format_display_notes(commit->object.sha1, sb,
get_log_output_encoding(), 0);
if (c->pretty_ctx->notes_message) {
strbuf_addstr(sb, c->pretty_ctx->notes_message);
return 1;
}
return 0;
Expand Down Expand Up @@ -1414,16 +1413,6 @@ void pp_remainder(const struct pretty_print_context *pp,
}
}

char *reencode_commit_message(const struct commit *commit, const char **encoding_p)
{
const char *encoding;

encoding = get_log_output_encoding();
if (encoding_p)
*encoding_p = encoding;
return logmsg_reencode(commit, encoding);
}

void pretty_print_commit(const struct pretty_print_context *pp,
const struct commit *commit,
struct strbuf *sb)
Expand All @@ -1440,7 +1429,8 @@ void pretty_print_commit(const struct pretty_print_context *pp,
return;
}

reencoded = reencode_commit_message(commit, &encoding);
encoding = get_log_output_encoding();
reencoded = logmsg_reencode(commit, encoding);
if (reencoded) {
msg = reencoded;
}
Expand Down Expand Up @@ -1500,10 +1490,6 @@ void pretty_print_commit(const struct pretty_print_context *pp,
if (pp->fmt == CMIT_FMT_EMAIL && sb->len <= beginning_of_body)
strbuf_addch(sb, '\n');

if (pp->show_notes)
format_display_notes(commit->object.sha1, sb, encoding,
NOTES_SHOW_HEADER | NOTES_INDENT);

free(reencoded);
}

Expand Down
2 changes: 1 addition & 1 deletion revision.c
Original file line number Diff line number Diff line change
Expand Up @@ -2242,7 +2242,7 @@ static int commit_match(struct commit *commit, struct rev_info *opt)
if (!buf.len)
strbuf_addstr(&buf, commit->buffer);
format_display_notes(commit->object.sha1, &buf,
get_log_output_encoding(), 0);
get_log_output_encoding(), 1);
}

/* Find either in the commit object, or in the temporary */
Expand Down
1 change: 1 addition & 0 deletions revision.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ struct rev_info {

/* Format info */
unsigned int shown_one:1,
shown_dashes:1,
show_merge:1,
show_notes:1,
show_notes_given:1,
Expand Down
15 changes: 13 additions & 2 deletions t/t4014-format-patch.sh
Original file line number Diff line number Diff line change
Expand Up @@ -650,8 +650,19 @@ test_expect_success 'format-patch --in-reply-to' '
'

test_expect_success 'format-patch --signoff' '
git format-patch -1 --signoff --stdout |
grep "^Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
git format-patch -1 --signoff --stdout >out &&
grep "^Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" out
'

test_expect_success 'format-patch --notes --signoff' '
git notes --ref test add -m "test message" HEAD &&
git format-patch -1 --signoff --stdout --notes=test >out &&
# Three dashes must come after S-o-b
! sed "/^Signed-off-by: /q" out | grep "test message" &&
sed "1,/^Signed-off-by: /d" out | grep "test message" &&
# Notes message must come after three dashes
! sed "/^---$/q" out | grep "test message" &&
sed "1,/^---$/d" out | grep "test message"
'

echo "fatal: --name-only does not make sense" > expect.name-only
Expand Down

0 comments on commit 4ad4fce

Please sign in to comment.