format-patch: track several references

Currently, format-patch can only track a single reference (the
In-Reply-To:) for each mail.  To ensure proper threading, we should
list all known references for every mail.

Change the rev_info.ref_message_id field to a string_list, so that we
can append references at will, and change the output formatting
routines to print all of them in the References: header.  The last
entry in the list is implicitly assumed to be the In-Reply-To:, which
gives output consistent with RFC 2822:

   The "References:" field will contain the contents of the parent's
   "References:" field (if any) followed by the contents of the
   parent's "Message-ID:" field (if any).

Note that this is just preparatory work; nothing uses it yet, so all
"References:" fields in the output are still only one deep.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Thomas Rast 2009-02-19 22:26:31 +01:00 committed by Junio C Hamano
parent 484cf6c3f1
commit b079c50e03
3 changed files with 19 additions and 8 deletions

View File

@ -17,6 +17,7 @@
#include "run-command.h" #include "run-command.h"
#include "shortlog.h" #include "shortlog.h"
#include "remote.h" #include "remote.h"
#include "string-list.h"
/* Set a default date-time format for git log ("log.date" config variable) */ /* Set a default date-time format for git log ("log.date" config variable) */
static const char *default_date_mode = NULL; static const char *default_date_mode = NULL;
@ -1011,8 +1012,12 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
numbered = 1; numbered = 1;
if (numbered) if (numbered)
rev.total = total + start_number - 1; rev.total = total + start_number - 1;
if (in_reply_to) if (in_reply_to || thread || cover_letter)
rev.ref_message_id = clean_message_id(in_reply_to); rev.ref_message_ids = xcalloc(1, sizeof(struct string_list));
if (in_reply_to) {
const char *msgid = clean_message_id(in_reply_to);
string_list_append(msgid, rev.ref_message_ids);
}
if (cover_letter) { if (cover_letter) {
if (thread) if (thread)
gen_message_id(&rev, "cover"); gen_message_id(&rev, "cover");
@ -1036,10 +1041,11 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
* otherwise, make everything a reply * otherwise, make everything a reply
* to that. * to that.
*/ */
if (rev.ref_message_id) if (rev.ref_message_ids->nr > 0)
free(rev.message_id); free(rev.message_id);
else else
rev.ref_message_id = rev.message_id; string_list_append(rev.message_id,
rev.ref_message_ids);
} }
gen_message_id(&rev, sha1_to_hex(commit->object.sha1)); gen_message_id(&rev, sha1_to_hex(commit->object.sha1));
} }

View File

@ -6,6 +6,7 @@
#include "log-tree.h" #include "log-tree.h"
#include "reflog-walk.h" #include "reflog-walk.h"
#include "refs.h" #include "refs.h"
#include "string-list.h"
struct decoration name_decoration = { "object names" }; struct decoration name_decoration = { "object names" };
@ -211,9 +212,13 @@ void log_write_email_headers(struct rev_info *opt, const char *name,
printf("Message-Id: <%s>\n", opt->message_id); printf("Message-Id: <%s>\n", opt->message_id);
graph_show_oneline(opt->graph); graph_show_oneline(opt->graph);
} }
if (opt->ref_message_id) { if (opt->ref_message_ids && opt->ref_message_ids->nr > 0) {
printf("In-Reply-To: <%s>\nReferences: <%s>\n", int i, n;
opt->ref_message_id, opt->ref_message_id); n = opt->ref_message_ids->nr;
printf("In-Reply-To: <%s>\n", opt->ref_message_ids->items[n-1].string);
for (i = 0; i < n; i++)
printf("%s<%s>\n", (i > 0 ? "\t" : "References: "),
opt->ref_message_ids->items[i].string);
graph_show_oneline(opt->graph); graph_show_oneline(opt->graph);
} }
if (opt->mime_boundary) { if (opt->mime_boundary) {

View File

@ -89,7 +89,7 @@ struct rev_info {
int nr, total; int nr, total;
const char *mime_boundary; const char *mime_boundary;
char *message_id; char *message_id;
const char *ref_message_id; struct string_list *ref_message_ids;
const char *add_signoff; const char *add_signoff;
const char *extra_headers; const char *extra_headers;
const char *log_reencode; const char *log_reencode;