Skip to content
This repository was archived by the owner on Nov 9, 2017. It is now read-only.

Commit fbf59cd

Browse files
committed
Merge branch 'jc/mailmap-case-insensitivity'
The mailmap mechanism unnecessarily downcased the e-mail addresses in the output, and also ignored the human name when it is a single character name. This now has become Eric Sunshine's series, even though it still is under jc/ hierarchy. * jc/mailmap-case-insensitivity: mailmap: style fixes mailmap: debug: avoid passing NULL to fprintf() '%s' conversion specification mailmap: debug: eliminate -Wformat field precision type warning mailmap: debug: fix malformed fprintf() format conversion specification mailmap: debug: fix out-of-order fprintf() arguments mailmap: do not downcase mailmap entries t4203: demonstrate loss of uppercase characters in canonical email mailmap: do not lose single-letter names t4203: demonstrate loss of single-character name in mailmap entry
2 parents 1d1934c + bd23794 commit fbf59cd

File tree

2 files changed

+57
-28
lines changed

2 files changed

+57
-28
lines changed

mailmap.c

Lines changed: 39 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
#define DEBUG_MAILMAP 0
66
#if DEBUG_MAILMAP
77
#define debug_mm(...) fprintf(stderr, __VA_ARGS__)
8+
#define debug_str(X) ((X) ? (X) : "(none)")
89
#else
910
static inline void debug_mm(const char *format, ...) {}
11+
static inline const char *debug_str(const char *s) { return s; }
1012
#endif
1113

1214
const char *git_mailmap_file;
@@ -29,16 +31,20 @@ struct mailmap_entry {
2931
static void free_mailmap_info(void *p, const char *s)
3032
{
3133
struct mailmap_info *mi = (struct mailmap_info *)p;
32-
debug_mm("mailmap: -- complex: '%s' -> '%s' <%s>\n", s, mi->name, mi->email);
34+
debug_mm("mailmap: -- complex: '%s' -> '%s' <%s>\n",
35+
s, debug_str(mi->name), debug_str(mi->email));
3336
free(mi->name);
3437
free(mi->email);
3538
}
3639

3740
static void free_mailmap_entry(void *p, const char *s)
3841
{
3942
struct mailmap_entry *me = (struct mailmap_entry *)p;
40-
debug_mm("mailmap: removing entries for <%s>, with %d sub-entries\n", s, me->namemap.nr);
41-
debug_mm("mailmap: - simple: '%s' <%s>\n", me->name, me->email);
43+
debug_mm("mailmap: removing entries for <%s>, with %d sub-entries\n",
44+
s, me->namemap.nr);
45+
debug_mm("mailmap: - simple: '%s' <%s>\n",
46+
debug_str(me->name), debug_str(me->email));
47+
4248
free(me->name);
4349
free(me->email);
4450

@@ -47,18 +53,11 @@ static void free_mailmap_entry(void *p, const char *s)
4753
}
4854

4955
static void add_mapping(struct string_list *map,
50-
char *new_name, char *new_email, char *old_name, char *old_email)
56+
char *new_name, char *new_email,
57+
char *old_name, char *old_email)
5158
{
5259
struct mailmap_entry *me;
5360
int index;
54-
char *p;
55-
56-
if (old_email)
57-
for (p = old_email; *p; p++)
58-
*p = tolower(*p);
59-
if (new_email)
60-
for (p = new_email; *p; p++)
61-
*p = tolower(*p);
6261

6362
if (old_email == NULL) {
6463
old_email = new_email;
@@ -68,16 +67,21 @@ static void add_mapping(struct string_list *map,
6867
if ((index = string_list_find_insert_index(map, old_email, 1)) < 0) {
6968
/* mailmap entry exists, invert index value */
7069
index = -1 - index;
70+
me = (struct mailmap_entry *)map->items[index].util;
7171
} else {
7272
/* create mailmap entry */
73-
struct string_list_item *item = string_list_insert_at_index(map, index, old_email);
74-
item->util = xcalloc(1, sizeof(struct mailmap_entry));
75-
((struct mailmap_entry *)item->util)->namemap.strdup_strings = 1;
73+
struct string_list_item *item;
74+
75+
item = string_list_insert_at_index(map, index, old_email);
76+
me = xcalloc(1, sizeof(struct mailmap_entry));
77+
me->namemap.strdup_strings = 1;
78+
me->namemap.cmp = strcasecmp;
79+
item->util = me;
7680
}
77-
me = (struct mailmap_entry *)map->items[index].util;
7881

7982
if (old_name == NULL) {
80-
debug_mm("mailmap: adding (simple) entry for %s at index %d\n", old_email, index);
83+
debug_mm("mailmap: adding (simple) entry for %s at index %d\n",
84+
old_email, index);
8185
/* Replace current name and new email for simple entry */
8286
if (new_name) {
8387
free(me->name);
@@ -89,7 +93,8 @@ static void add_mapping(struct string_list *map,
8993
}
9094
} else {
9195
struct mailmap_info *mi = xcalloc(1, sizeof(struct mailmap_info));
92-
debug_mm("mailmap: adding (complex) entry for %s at index %d\n", old_email, index);
96+
debug_mm("mailmap: adding (complex) entry for %s at index %d\n",
97+
old_email, index);
9398
if (new_name)
9499
mi->name = xstrdup(new_name);
95100
if (new_email)
@@ -98,11 +103,12 @@ static void add_mapping(struct string_list *map,
98103
}
99104

100105
debug_mm("mailmap: '%s' <%s> -> '%s' <%s>\n",
101-
old_name, old_email, new_name, new_email);
106+
debug_str(old_name), old_email,
107+
debug_str(new_name), debug_str(new_email));
102108
}
103109

104110
static char *parse_name_and_email(char *buffer, char **name,
105-
char **email, int allow_empty_email)
111+
char **email, int allow_empty_email)
106112
{
107113
char *left, *right, *nstart, *nend;
108114
*name = *email = NULL;
@@ -122,7 +128,7 @@ static char *parse_name_and_email(char *buffer, char **name,
122128
while (nend > nstart && isspace(*nend))
123129
--nend;
124130

125-
*name = (nstart < nend ? nstart : NULL);
131+
*name = (nstart <= nend ? nstart : NULL);
126132
*email = left+1;
127133
*(nend+1) = '\0';
128134
*right++ = '\0';
@@ -306,21 +312,25 @@ static struct string_list_item *lookup_prefix(struct string_list *map,
306312
}
307313

308314
int map_user(struct string_list *map,
309-
const char **email, size_t *emaillen,
310-
const char **name, size_t *namelen)
315+
const char **email, size_t *emaillen,
316+
const char **name, size_t *namelen)
311317
{
312318
struct string_list_item *item;
313319
struct mailmap_entry *me;
314320

315321
debug_mm("map_user: map '%.*s' <%.*s>\n",
316-
*name, *namelen, *emaillen, *email);
322+
(int)*namelen, debug_str(*name),
323+
(int)*emaillen, debug_str(*email));
317324

318325
item = lookup_prefix(map, *email, *emaillen);
319326
if (item != NULL) {
320327
me = (struct mailmap_entry *)item->util;
321328
if (me->namemap.nr) {
322-
/* The item has multiple items, so we'll look up on name too */
323-
/* If the name is not found, we choose the simple entry */
329+
/*
330+
* The item has multiple items, so we'll look up on
331+
* name too. If the name is not found, we choose the
332+
* simple entry.
333+
*/
324334
struct string_list_item *subitem;
325335
subitem = lookup_prefix(&me->namemap, *name, *namelen);
326336
if (subitem)
@@ -341,8 +351,9 @@ int map_user(struct string_list *map,
341351
*name = mi->name;
342352
*namelen = strlen(*name);
343353
}
344-
debug_mm("map_user: to '%.*s' <.*%s>\n", *namelen, *name,
345-
*emaillen, *email);
354+
debug_mm("map_user: to '%.*s' <%.*s>\n",
355+
(int)*namelen, debug_str(*name),
356+
(int)*emaillen, debug_str(*email));
346357
return 1;
347358
}
348359
debug_mm("map_user: --\n");

t/t4203-mailmap.sh

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,24 @@ test_expect_success 'cleanup after mailmap.blob tests' '
247247
rm -f .mailmap
248248
'
249249

250+
test_expect_success 'single-character name' '
251+
echo " 1 A <[email protected]>" >expect &&
252+
echo " 1 nick1 <[email protected]>" >>expect &&
253+
echo "A <[email protected]>" >.mailmap &&
254+
test_when_finished "rm .mailmap" &&
255+
git shortlog -es HEAD >actual &&
256+
test_cmp expect actual
257+
'
258+
259+
test_expect_success 'preserve canonical email case' '
260+
echo " 1 A U Thor <[email protected]>" >expect &&
261+
echo " 1 nick1 <[email protected]>" >>expect &&
262+
echo "<[email protected]> <[email protected]>" >.mailmap &&
263+
test_when_finished "rm .mailmap" &&
264+
git shortlog -es HEAD >actual &&
265+
test_cmp expect actual
266+
'
267+
250268
# Extended mailmap configurations should give us the following output for shortlog
251269
cat >expect <<\EOF
252270
A U Thor <[email protected]> (1):

0 commit comments

Comments
 (0)