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
This commit is contained in:
commit
fbf59cdb4f
67
mailmap.c
67
mailmap.c
@ -5,8 +5,10 @@
|
||||
#define DEBUG_MAILMAP 0
|
||||
#if DEBUG_MAILMAP
|
||||
#define debug_mm(...) fprintf(stderr, __VA_ARGS__)
|
||||
#define debug_str(X) ((X) ? (X) : "(none)")
|
||||
#else
|
||||
static inline void debug_mm(const char *format, ...) {}
|
||||
static inline const char *debug_str(const char *s) { return s; }
|
||||
#endif
|
||||
|
||||
const char *git_mailmap_file;
|
||||
@ -29,7 +31,8 @@ struct mailmap_entry {
|
||||
static void free_mailmap_info(void *p, const char *s)
|
||||
{
|
||||
struct mailmap_info *mi = (struct mailmap_info *)p;
|
||||
debug_mm("mailmap: -- complex: '%s' -> '%s' <%s>\n", s, mi->name, mi->email);
|
||||
debug_mm("mailmap: -- complex: '%s' -> '%s' <%s>\n",
|
||||
s, debug_str(mi->name), debug_str(mi->email));
|
||||
free(mi->name);
|
||||
free(mi->email);
|
||||
}
|
||||
@ -37,8 +40,11 @@ static void free_mailmap_info(void *p, const char *s)
|
||||
static void free_mailmap_entry(void *p, const char *s)
|
||||
{
|
||||
struct mailmap_entry *me = (struct mailmap_entry *)p;
|
||||
debug_mm("mailmap: removing entries for <%s>, with %d sub-entries\n", s, me->namemap.nr);
|
||||
debug_mm("mailmap: - simple: '%s' <%s>\n", me->name, me->email);
|
||||
debug_mm("mailmap: removing entries for <%s>, with %d sub-entries\n",
|
||||
s, me->namemap.nr);
|
||||
debug_mm("mailmap: - simple: '%s' <%s>\n",
|
||||
debug_str(me->name), debug_str(me->email));
|
||||
|
||||
free(me->name);
|
||||
free(me->email);
|
||||
|
||||
@ -47,18 +53,11 @@ static void free_mailmap_entry(void *p, const char *s)
|
||||
}
|
||||
|
||||
static void add_mapping(struct string_list *map,
|
||||
char *new_name, char *new_email, char *old_name, char *old_email)
|
||||
char *new_name, char *new_email,
|
||||
char *old_name, char *old_email)
|
||||
{
|
||||
struct mailmap_entry *me;
|
||||
int index;
|
||||
char *p;
|
||||
|
||||
if (old_email)
|
||||
for (p = old_email; *p; p++)
|
||||
*p = tolower(*p);
|
||||
if (new_email)
|
||||
for (p = new_email; *p; p++)
|
||||
*p = tolower(*p);
|
||||
|
||||
if (old_email == NULL) {
|
||||
old_email = new_email;
|
||||
@ -68,16 +67,21 @@ static void add_mapping(struct string_list *map,
|
||||
if ((index = string_list_find_insert_index(map, old_email, 1)) < 0) {
|
||||
/* mailmap entry exists, invert index value */
|
||||
index = -1 - index;
|
||||
me = (struct mailmap_entry *)map->items[index].util;
|
||||
} else {
|
||||
/* create mailmap entry */
|
||||
struct string_list_item *item = string_list_insert_at_index(map, index, old_email);
|
||||
item->util = xcalloc(1, sizeof(struct mailmap_entry));
|
||||
((struct mailmap_entry *)item->util)->namemap.strdup_strings = 1;
|
||||
struct string_list_item *item;
|
||||
|
||||
item = string_list_insert_at_index(map, index, old_email);
|
||||
me = xcalloc(1, sizeof(struct mailmap_entry));
|
||||
me->namemap.strdup_strings = 1;
|
||||
me->namemap.cmp = strcasecmp;
|
||||
item->util = me;
|
||||
}
|
||||
me = (struct mailmap_entry *)map->items[index].util;
|
||||
|
||||
if (old_name == NULL) {
|
||||
debug_mm("mailmap: adding (simple) entry for %s at index %d\n", old_email, index);
|
||||
debug_mm("mailmap: adding (simple) entry for %s at index %d\n",
|
||||
old_email, index);
|
||||
/* Replace current name and new email for simple entry */
|
||||
if (new_name) {
|
||||
free(me->name);
|
||||
@ -89,7 +93,8 @@ static void add_mapping(struct string_list *map,
|
||||
}
|
||||
} else {
|
||||
struct mailmap_info *mi = xcalloc(1, sizeof(struct mailmap_info));
|
||||
debug_mm("mailmap: adding (complex) entry for %s at index %d\n", old_email, index);
|
||||
debug_mm("mailmap: adding (complex) entry for %s at index %d\n",
|
||||
old_email, index);
|
||||
if (new_name)
|
||||
mi->name = xstrdup(new_name);
|
||||
if (new_email)
|
||||
@ -98,11 +103,12 @@ static void add_mapping(struct string_list *map,
|
||||
}
|
||||
|
||||
debug_mm("mailmap: '%s' <%s> -> '%s' <%s>\n",
|
||||
old_name, old_email, new_name, new_email);
|
||||
debug_str(old_name), old_email,
|
||||
debug_str(new_name), debug_str(new_email));
|
||||
}
|
||||
|
||||
static char *parse_name_and_email(char *buffer, char **name,
|
||||
char **email, int allow_empty_email)
|
||||
char **email, int allow_empty_email)
|
||||
{
|
||||
char *left, *right, *nstart, *nend;
|
||||
*name = *email = NULL;
|
||||
@ -122,7 +128,7 @@ static char *parse_name_and_email(char *buffer, char **name,
|
||||
while (nend > nstart && isspace(*nend))
|
||||
--nend;
|
||||
|
||||
*name = (nstart < nend ? nstart : NULL);
|
||||
*name = (nstart <= nend ? nstart : NULL);
|
||||
*email = left+1;
|
||||
*(nend+1) = '\0';
|
||||
*right++ = '\0';
|
||||
@ -306,21 +312,25 @@ static struct string_list_item *lookup_prefix(struct string_list *map,
|
||||
}
|
||||
|
||||
int map_user(struct string_list *map,
|
||||
const char **email, size_t *emaillen,
|
||||
const char **name, size_t *namelen)
|
||||
const char **email, size_t *emaillen,
|
||||
const char **name, size_t *namelen)
|
||||
{
|
||||
struct string_list_item *item;
|
||||
struct mailmap_entry *me;
|
||||
|
||||
debug_mm("map_user: map '%.*s' <%.*s>\n",
|
||||
*name, *namelen, *emaillen, *email);
|
||||
(int)*namelen, debug_str(*name),
|
||||
(int)*emaillen, debug_str(*email));
|
||||
|
||||
item = lookup_prefix(map, *email, *emaillen);
|
||||
if (item != NULL) {
|
||||
me = (struct mailmap_entry *)item->util;
|
||||
if (me->namemap.nr) {
|
||||
/* The item has multiple items, so we'll look up on name too */
|
||||
/* If the name is not found, we choose the simple entry */
|
||||
/*
|
||||
* The item has multiple items, so we'll look up on
|
||||
* name too. If the name is not found, we choose the
|
||||
* simple entry.
|
||||
*/
|
||||
struct string_list_item *subitem;
|
||||
subitem = lookup_prefix(&me->namemap, *name, *namelen);
|
||||
if (subitem)
|
||||
@ -341,8 +351,9 @@ int map_user(struct string_list *map,
|
||||
*name = mi->name;
|
||||
*namelen = strlen(*name);
|
||||
}
|
||||
debug_mm("map_user: to '%.*s' <.*%s>\n", *namelen, *name,
|
||||
*emaillen, *email);
|
||||
debug_mm("map_user: to '%.*s' <%.*s>\n",
|
||||
(int)*namelen, debug_str(*name),
|
||||
(int)*emaillen, debug_str(*email));
|
||||
return 1;
|
||||
}
|
||||
debug_mm("map_user: --\n");
|
||||
|
@ -247,6 +247,24 @@ test_expect_success 'cleanup after mailmap.blob tests' '
|
||||
rm -f .mailmap
|
||||
'
|
||||
|
||||
test_expect_success 'single-character name' '
|
||||
echo " 1 A <author@example.com>" >expect &&
|
||||
echo " 1 nick1 <bugs@company.xx>" >>expect &&
|
||||
echo "A <author@example.com>" >.mailmap &&
|
||||
test_when_finished "rm .mailmap" &&
|
||||
git shortlog -es HEAD >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'preserve canonical email case' '
|
||||
echo " 1 A U Thor <AUTHOR@example.com>" >expect &&
|
||||
echo " 1 nick1 <bugs@company.xx>" >>expect &&
|
||||
echo "<AUTHOR@example.com> <author@example.com>" >.mailmap &&
|
||||
test_when_finished "rm .mailmap" &&
|
||||
git shortlog -es HEAD >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
# Extended mailmap configurations should give us the following output for shortlog
|
||||
cat >expect <<\EOF
|
||||
A U Thor <author@example.com> (1):
|
||||
|
Loading…
Reference in New Issue
Block a user