format-patch: use branch description in cover letter
Use the description for the branch when preparing the cover letter when available. While at it, mark a loosely written codepath that would do a random and useless thing given an unusual input (e.g. "^master HEAD HEAD^"), which we may want to fix someday. Signed-off-by: Junio C Hamano <gitster@pobox.com>
Junio C Hamano committed
Sep 21, 2011 at 20:32 UTC
739453a3fb74ade725243ac972f02ba1aedabdf6
1 file changed
+68
-3
builtin/log.c
+68
-3
@@ -19,6 +19,7 @@
19
#include "remote.h"
20
#include "string-list.h"
21
#include "parse-options.h"
22
+#include "branch.h"
23
24
/* Set a default date-time format for git log ("log.date" config variable) */
25
static const char *default_date_mode = NULL;
@@ -746,10 +747,24 @@ static void print_signature(void)
747
printf("-- \n%s\n\n", signature);
748
}
749
750
+static void add_branch_description(struct strbuf *buf, const char *branch_name)
751
+{
752
+ struct strbuf desc = STRBUF_INIT;
753
+ if (!branch_name || !*branch_name)
754
+ return;
755
+ read_branch_desc(&desc, branch_name);
756
+ if (desc.len) {
757
+ strbuf_addch(buf, '\n');
758
+ strbuf_add(buf, desc.buf, desc.len);
759
+ strbuf_addch(buf, '\n');
760
+ }
761
+}
762
+
763
static void make_cover_letter(struct rev_info *rev, int use_stdout,
764
int numbered, int numbered_files,
765
struct commit *origin,
766
int nr, struct commit **list, struct commit *head,
767
+ const char *branch_name,
768
int quiet)
769
{
770
const char *committer;
@@ -807,6 +822,7 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
822
pp_user_info(&pp, NULL, &sb, committer, encoding);
823
pp_title_line(&pp, &msg, &sb, encoding, need_8bit_cte);
824
pp_remainder(&pp, &msg, &sb, 0);
825
+ add_branch_description(&sb, branch_name);
826
printf("%s\n", sb.buf);
827
828
strbuf_release(&sb);
@@ -1006,6 +1022,35 @@ static int cc_callback(const struct option *opt, const char *arg, int unset)
1022
return 0;
1023
}
1024
1025
+static char *find_branch_name(struct rev_info *rev)
1026
+{
1027
+ int i, positive = -1;
1028
+ unsigned char branch_sha1[20];
1029
+ struct strbuf buf = STRBUF_INIT;
1030
+ const char *branch;
1031
+
1032
+ for (i = 0; i < rev->cmdline.nr; i++) {
1033
+ if (rev->cmdline.rev[i].flags & UNINTERESTING)
1034
+ continue;
1035
+ if (positive < 0)
1036
+ positive = i;
1037
+ else
1038
+ return NULL;
1039
+ }
1040
+ if (positive < 0)
1041
+ return NULL;
1042
+ strbuf_addf(&buf, "refs/heads/%s", rev->cmdline.rev[positive].name);
1043
+ branch = resolve_ref(buf.buf, branch_sha1, 1, 0);
1044
+ if (!branch ||
1045
+ prefixcmp(branch, "refs/heads/") ||
1046
+ hashcmp(rev->cmdline.rev[positive].item->sha1, branch_sha1))
1047
+ branch = NULL;
1048
+ strbuf_release(&buf);
1049
+ if (branch)
1050
+ return xstrdup(rev->cmdline.rev[positive].name);
1051
+ return NULL;
1052
+}
1053
+
1054
int cmd_format_patch(int argc, const char **argv, const char *prefix)
1055
{
1056
struct commit *commit;
@@ -1027,6 +1072,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
1072
struct strbuf buf = STRBUF_INIT;
1073
int use_patch_format = 0;
1074
int quiet = 0;
1075
+ char *branch_name = NULL;
1076
const struct option builtin_format_patch_options[] = {
1077
{ OPTION_CALLBACK, 'n', "numbered", &numbered, NULL,
1078
"use [PATCH n/m] even with a single patch",
@@ -1217,8 +1263,16 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
1263
* origin" that prepares what the origin side still
1264
* does not have.
1265
*/
1266
+ unsigned char sha1[20];
1267
+ const char *ref;
1268
+
1269
rev.pending.objects[0].item->flags |= UNINTERESTING;
1270
add_head_to_pending(&rev);
1271
+ ref = resolve_ref("HEAD", sha1, 1, NULL);
1272
+ if (ref && !prefixcmp(ref, "refs/heads/"))
1273
+ branch_name = xstrdup(ref + strlen("refs/heads/"));
1274
+ else
1275
+ branch_name = xstrdup(""); /* no branch */
1276
}
1277
/*
1278
* Otherwise, it is "format-patch -22 HEAD", and/or
@@ -1234,16 +1288,26 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
1288
rev.show_root_diff = 1;
1289
1290
if (cover_letter) {
1237
- /* remember the range */
1291
+ /*
1292
+ * NEEDSWORK:randomly pick one positive commit to show
1293
+ * diffstat; this is often the tip and the command
1294
+ * happens to do the right thing in most cases, but a
1295
+ * complex command like "--cover-letter a b c ^bottom"
1296
+ * picks "c" and shows diffstat between bottom..c
1297
+ * which may not match what the series represents at
1298
+ * all and totally broken.
1299
+ */
1300
int i;
1301
for (i = 0; i < rev.pending.nr; i++) {
1302
struct object *o = rev.pending.objects[i].item;
1303
if (!(o->flags & UNINTERESTING))
1304
head = (struct commit *)o;
1305
}
1244
- /* We can't generate a cover letter without any patches */
1306
+ /* There is nothing to show; it is not an error, though. */
1307
if (!head)
1308
return 0;
1309
+ if (!branch_name)
1310
+ branch_name = find_branch_name(&rev);
1311
}
1312
1313
if (ignore_if_in_upstream) {
@@ -1294,7 +1358,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
1358
if (thread)
1359
gen_message_id(&rev, "cover");
1360
make_cover_letter(&rev, use_stdout, numbered, numbered_files,
1297
- origin, nr, list, head, quiet);
1361
+ origin, nr, list, head, branch_name, quiet);
1362
total++;
1363
start_number--;
1364
}
@@ -1366,6 +1430,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
1430
fclose(stdout);
1431
}
1432
free(list);
1433
+ free(branch_name);
1434
string_list_clear(&extra_to, 0);
1435
string_list_clear(&extra_cc, 0);
1436
string_list_clear(&extra_hdr, 0);