Skip to content

Commit 898eacd

Browse files
committed
fmt-merge-msg: use branch.$name.description
This teaches "merge --log" and fmt-merge-msg to use branch description information when merging a local topic branch into the mainline. The description goes between the branch name label and the list of commit titles. The refactoring to share the common configuration parsing between merge and fmt-merge-msg needs to be made into a separate patch. Signed-off-by: Junio C Hamano <[email protected]>
1 parent c016814 commit 898eacd

File tree

5 files changed

+78
-26
lines changed

5 files changed

+78
-26
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,7 @@ LIB_H += diffcore.h
527527
LIB_H += diff.h
528528
LIB_H += dir.h
529529
LIB_H += exec_cmd.h
530+
LIB_H += fmt-merge-msg.h
530531
LIB_H += fsck.h
531532
LIB_H += gettext.h
532533
LIB_H += git-compat-util.h

builtin/fmt-merge-msg.c

Lines changed: 59 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,27 @@
55
#include "revision.h"
66
#include "tag.h"
77
#include "string-list.h"
8+
#include "branch.h"
9+
#include "fmt-merge-msg.h"
810

911
static const char * const fmt_merge_msg_usage[] = {
1012
"git fmt-merge-msg [-m <message>] [--log[=<n>]|--no-log] [--file <file>]",
1113
NULL
1214
};
1315

14-
static int shortlog_len;
16+
static int use_branch_desc;
1517

16-
static int fmt_merge_msg_config(const char *key, const char *value, void *cb)
18+
int fmt_merge_msg_config(const char *key, const char *value, void *cb)
1719
{
1820
if (!strcmp(key, "merge.log") || !strcmp(key, "merge.summary")) {
1921
int is_bool;
20-
shortlog_len = git_config_bool_or_int(key, value, &is_bool);
21-
if (!is_bool && shortlog_len < 0)
22+
merge_log_config = git_config_bool_or_int(key, value, &is_bool);
23+
if (!is_bool && merge_log_config < 0)
2224
return error("%s: negative length %s", key, value);
23-
if (is_bool && shortlog_len)
24-
shortlog_len = DEFAULT_MERGE_LOG_LEN;
25+
if (is_bool && merge_log_config)
26+
merge_log_config = DEFAULT_MERGE_LOG_LEN;
27+
} else if (!strcmp(key, "merge.branchdesc")) {
28+
use_branch_desc = git_config_bool(key, value);
2529
}
2630
return 0;
2731
}
@@ -31,6 +35,11 @@ struct src_data {
3135
int head_status;
3236
};
3337

38+
struct origin_data {
39+
unsigned char sha1[20];
40+
int is_local_branch:1;
41+
};
42+
3443
static void init_src_data(struct src_data *data)
3544
{
3645
data->branch.strdup_strings = 1;
@@ -45,7 +54,7 @@ static struct string_list origins = STRING_LIST_INIT_DUP;
4554
static int handle_line(char *line)
4655
{
4756
int i, len = strlen(line);
48-
unsigned char *sha1;
57+
struct origin_data *origin_data;
4958
char *src, *origin;
5059
struct src_data *src_data;
5160
struct string_list_item *item;
@@ -61,11 +70,13 @@ static int handle_line(char *line)
6170
return 2;
6271

6372
line[40] = 0;
64-
sha1 = xmalloc(20);
65-
i = get_sha1(line, sha1);
73+
origin_data = xcalloc(1, sizeof(struct origin_data));
74+
i = get_sha1(line, origin_data->sha1);
6675
line[40] = '\t';
67-
if (i)
76+
if (i) {
77+
free(origin_data);
6878
return 3;
79+
}
6980

7081
if (line[len - 1] == '\n')
7182
line[len - 1] = 0;
@@ -93,6 +104,7 @@ static int handle_line(char *line)
93104
origin = src;
94105
src_data->head_status |= 1;
95106
} else if (!prefixcmp(line, "branch ")) {
107+
origin_data->is_local_branch = 1;
96108
origin = line + 7;
97109
string_list_append(&src_data->branch, origin);
98110
src_data->head_status |= 2;
@@ -119,7 +131,9 @@ static int handle_line(char *line)
119131
sprintf(new_origin, "%s of %s", origin, src);
120132
origin = new_origin;
121133
}
122-
string_list_append(&origins, origin)->util = sha1;
134+
if (strcmp(".", src))
135+
origin_data->is_local_branch = 0;
136+
string_list_append(&origins, origin)->util = origin_data;
123137
return 0;
124138
}
125139

@@ -140,16 +154,38 @@ static void print_joined(const char *singular, const char *plural,
140154
}
141155
}
142156

143-
static void shortlog(const char *name, unsigned char *sha1,
144-
struct commit *head, struct rev_info *rev, int limit,
145-
struct strbuf *out)
157+
static void add_branch_desc(struct strbuf *out, const char *name)
158+
{
159+
struct strbuf desc = STRBUF_INIT;
160+
161+
if (!read_branch_desc(&desc, name)) {
162+
const char *bp = desc.buf;
163+
while (*bp) {
164+
const char *ep = strchrnul(bp, '\n');
165+
if (*ep)
166+
ep++;
167+
strbuf_addf(out, " : %.*s", (int)(ep - bp), bp);
168+
bp = ep;
169+
}
170+
if (out->buf[out->len - 1] != '\n')
171+
strbuf_addch(out, '\n');
172+
}
173+
strbuf_release(&desc);
174+
}
175+
176+
static void shortlog(const char *name,
177+
struct origin_data *origin_data,
178+
struct commit *head,
179+
struct rev_info *rev, int limit,
180+
struct strbuf *out)
146181
{
147182
int i, count = 0;
148183
struct commit *commit;
149184
struct object *branch;
150185
struct string_list subjects = STRING_LIST_INIT_DUP;
151186
int flags = UNINTERESTING | TREESAME | SEEN | SHOWN | ADDED;
152187
struct strbuf sb = STRBUF_INIT;
188+
const unsigned char *sha1 = origin_data->sha1;
153189

154190
branch = deref_tag(parse_object(sha1), sha1_to_hex(sha1), 40);
155191
if (!branch || branch->type != OBJ_COMMIT)
@@ -188,6 +224,9 @@ static void shortlog(const char *name, unsigned char *sha1,
188224
else
189225
strbuf_addf(out, "\n* %s:\n", name);
190226

227+
if (origin_data->is_local_branch && use_branch_desc)
228+
add_branch_desc(out, name);
229+
191230
for (i = 0; i < subjects.nr; i++)
192231
if (i >= limit)
193232
strbuf_addf(out, " ...\n");
@@ -303,8 +342,9 @@ static int do_fmt_merge_msg(int merge_title, struct strbuf *in,
303342
strbuf_addch(out, '\n');
304343

305344
for (i = 0; i < origins.nr; i++)
306-
shortlog(origins.items[i].string, origins.items[i].util,
307-
head, &rev, shortlog_len, out);
345+
shortlog(origins.items[i].string,
346+
origins.items[i].util,
347+
head, &rev, shortlog_len, out);
308348
}
309349
return 0;
310350
}
@@ -318,6 +358,7 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)
318358
{
319359
const char *inpath = NULL;
320360
const char *message = NULL;
361+
int shortlog_len = -1;
321362
struct option options[] = {
322363
{ OPTION_INTEGER, 0, "log", &shortlog_len, "n",
323364
"populate log with at most <n> entries from shortlog",
@@ -341,6 +382,8 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)
341382
0);
342383
if (argc > 0)
343384
usage_with_options(fmt_merge_msg_usage, options);
385+
if (shortlog_len < 0)
386+
shortlog_len = (merge_log_config > 0) ? merge_log_config : 0;
344387
if (message && !shortlog_len) {
345388
char nl = '\n';
346389
write_in_full(STDOUT_FILENO, message, strlen(message));

builtin/merge.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "merge-recursive.h"
2727
#include "resolve-undo.h"
2828
#include "remote.h"
29+
#include "fmt-merge-msg.h"
2930

3031
#define DEFAULT_TWOHEAD (1<<0)
3132
#define DEFAULT_OCTOPUS (1<<1)
@@ -44,7 +45,7 @@ static const char * const builtin_merge_usage[] = {
4445
NULL
4546
};
4647

47-
static int show_diffstat = 1, shortlog_len, squash;
48+
static int show_diffstat = 1, shortlog_len = -1, squash;
4849
static int option_commit = 1, allow_fast_forward = 1;
4950
static int fast_forward_only;
5051
static int allow_trivial = 1, have_message;
@@ -525,6 +526,8 @@ static void parse_branch_merge_options(char *bmo)
525526

526527
static int git_merge_config(const char *k, const char *v, void *cb)
527528
{
529+
int status;
530+
528531
if (branch && !prefixcmp(k, "branch.") &&
529532
!prefixcmp(k + 7, branch) &&
530533
!strcmp(k + 7 + strlen(branch), ".mergeoptions")) {
@@ -541,15 +544,7 @@ static int git_merge_config(const char *k, const char *v, void *cb)
541544
return git_config_string(&pull_octopus, k, v);
542545
else if (!strcmp(k, "merge.renormalize"))
543546
option_renormalize = git_config_bool(k, v);
544-
else if (!strcmp(k, "merge.log") || !strcmp(k, "merge.summary")) {
545-
int is_bool;
546-
shortlog_len = git_config_bool_or_int(k, v, &is_bool);
547-
if (!is_bool && shortlog_len < 0)
548-
return error(_("%s: negative length %s"), k, v);
549-
if (is_bool && shortlog_len)
550-
shortlog_len = DEFAULT_MERGE_LOG_LEN;
551-
return 0;
552-
} else if (!strcmp(k, "merge.ff")) {
547+
else if (!strcmp(k, "merge.ff")) {
553548
int boolval = git_config_maybe_bool(k, v);
554549
if (0 <= boolval) {
555550
allow_fast_forward = boolval;
@@ -562,6 +557,9 @@ static int git_merge_config(const char *k, const char *v, void *cb)
562557
default_to_upstream = git_config_bool(k, v);
563558
return 0;
564559
}
560+
status = fmt_merge_msg_config(k, v, cb);
561+
if (status)
562+
return status;
565563
return git_diff_ui_config(k, v, cb);
566564
}
567565

@@ -1035,6 +1033,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
10351033
parse_branch_merge_options(branch_mergeoptions);
10361034
argc = parse_options(argc, argv, prefix, builtin_merge_options,
10371035
builtin_merge_usage, 0);
1036+
if (shortlog_len < 0)
1037+
shortlog_len = (merge_log_config > 0) ? merge_log_config : 0;
10381038

10391039
if (verbosity < 0 && show_progress == -1)
10401040
show_progress = 0;

environment.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ enum object_creation_mode object_creation_mode = OBJECT_CREATION_MODE;
5858
char *notes_ref_name;
5959
int grafts_replace_parents = 1;
6060
int core_apply_sparse_checkout;
61+
int merge_log_config = -1;
6162
struct startup_info *startup_info;
6263

6364
/* Parallel index stat data preload? */

fmt-merge-msg.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#ifndef FMT_MERGE_MSG_H
2+
#define FMT_MERGE_MSG_H
3+
4+
extern int merge_log_config;
5+
extern int fmt_merge_msg_config(const char *key, const char *value, void *cb);
6+
7+
#endif /* FMT_MERGE_MSG_H */

0 commit comments

Comments
 (0)