Browse Source

Merge branch 'jc/prettier-pretty-note'

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()
maint
Junio C Hamano 12 years ago
parent
commit
4ad4fce63a
  1. 3
      Documentation/SubmittingPatches
  2. 14
      Documentation/git-format-patch.txt
  3. 4
      Documentation/git-notes.txt
  4. 7
      Documentation/user-manual.txt
  5. 5
      builtin/blame.c
  6. 4
      commit.h
  7. 51
      log-tree.c
  8. 13
      notes.c
  9. 6
      notes.h
  10. 22
      pretty.c
  11. 2
      revision.c
  12. 1
      revision.h
  13. 15
      t/t4014-format-patch.sh

3
Documentation/SubmittingPatches

@ -179,7 +179,8 @@ message starts, you can put a "From: " line to name that person. @@ -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

14
Documentation/git-format-patch.txt

@ -20,7 +20,7 @@ SYNOPSIS @@ -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> ]

@ -191,6 +191,18 @@ will want to ensure that threading is disabled for `git send-email`. @@ -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

4
Documentation/git-notes.txt

@ -39,6 +39,10 @@ message stored in the commit object, the notes are indented like the @@ -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].


7
Documentation/user-manual.txt

@ -1787,6 +1787,13 @@ $ git format-patch origin @@ -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.

5
builtin/blame.c

@ -1425,7 +1425,7 @@ static void get_commit_info(struct commit *commit, @@ -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];
@ -1446,7 +1446,8 @@ static void get_commit_info(struct commit *commit, @@ -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;

4
commit.h

@ -86,7 +86,7 @@ struct pretty_print_context { @@ -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;
};
@ -99,8 +99,6 @@ extern int has_non_ascii(const char *text); @@ -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);

51
log-tree.c

@ -540,7 +540,6 @@ void show_log(struct rev_info *opt) @@ -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);

@ -648,6 +647,18 @@ void show_log(struct rev_info *opt) @@ -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
*/
@ -664,6 +675,16 @@ void show_log(struct rev_info *opt) @@ -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);
@ -689,10 +710,12 @@ void show_log(struct rev_info *opt) @@ -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()) {
@ -704,15 +727,16 @@ int log_tree_diff_flush(struct rev_info *opt) @@ -704,15 +727,16 @@ 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;
@ -720,9 +744,20 @@ int log_tree_diff_flush(struct rev_info *opt) @@ -720,9 +744,20 @@ int log_tree_diff_flush(struct rev_info *opt)
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');
}
}

13
notes.c

@ -1193,10 +1193,11 @@ void free_notes(struct notes_tree *t) @@ -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;
@ -1233,7 +1234,7 @@ static void format_note(struct notes_tree *t, const unsigned char *object_sha1, @@ -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");
@ -1249,7 +1250,7 @@ static void format_note(struct notes_tree *t, const unsigned char *object_sha1, @@ -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');
@ -1259,13 +1260,13 @@ static void format_note(struct notes_tree *t, const unsigned char *object_sha1, @@ -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,

6
notes.h

@ -237,10 +237,6 @@ void prune_notes(struct notes_tree *t, int flags); @@ -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 {
@ -274,7 +270,7 @@ void init_display_notes(struct display_notes_opt *opt); @@ -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

22
pretty.c

@ -1100,9 +1100,8 @@ static size_t format_commit_one(struct strbuf *sb, const char *placeholder, @@ -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;
@ -1414,16 +1413,6 @@ void pp_remainder(const struct pretty_print_context *pp, @@ -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)
@ -1440,7 +1429,8 @@ void pretty_print_commit(const struct pretty_print_context *pp, @@ -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;
}
@ -1500,10 +1490,6 @@ void pretty_print_commit(const struct pretty_print_context *pp, @@ -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);
}


2
revision.c

@ -2242,7 +2242,7 @@ static int commit_match(struct commit *commit, struct rev_info *opt) @@ -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 */

1
revision.h

@ -111,6 +111,7 @@ struct rev_info { @@ -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,

15
t/t4014-format-patch.sh

@ -650,8 +650,19 @@ test_expect_success 'format-patch --in-reply-to' ' @@ -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

Loading…
Cancel
Save