git/mailmap.c

355 lines
8.6 KiB
C
Raw Normal View History

#include "cache.h"
#include "string-list.h"
#include "mailmap.h"
#include "object-store.h"
#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;
const char *git_mailmap_blob;
struct mailmap_info {
char *name;
char *email;
};
struct mailmap_entry {
/* name and email for the simple mail-only case */
char *name;
char *email;
/* name and email for the complex mail and name matching case */
struct string_list namemap;
};
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, debug_str(mi->name), debug_str(mi->email));
free(mi->name);
free(mi->email);
}
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",
debug_str(me->name), debug_str(me->email));
free(me->name);
free(me->email);
me->namemap.strdup_strings = 1;
string_list_clear_func(&me->namemap, free_mailmap_info);
}
/*
* On some systems (e.g. MinGW 4.0), string.h has _only_ inline
* definition of strcasecmp and no non-inline implementation is
* supplied anywhere, which is, eh, "unusual"; we cannot take an
* address of such a function to store it in namemap.cmp. This is
* here as a workaround---do not assign strcasecmp directly to
* namemap.cmp until we know no systems that matter have such an
* "unusual" string.h.
*/
static int namemap_cmp(const char *a, const char *b)
{
return strcasecmp(a, b);
}
static void add_mapping(struct string_list *map,
char *new_name, char *new_email,
char *old_name, char *old_email)
{
struct mailmap_entry *me;
struct string_list_item *item;
if (old_email == NULL) {
old_email = new_email;
new_email = NULL;
}
item = string_list_insert(map, old_email);
if (item->util) {
me = (struct mailmap_entry *)item->util;
} else {
CALLOC_ARRAY(me, 1);
me->namemap.strdup_strings = 1;
me->namemap.cmp = namemap_cmp;
item->util = me;
}
if (old_name == NULL) {
debug_mm("mailmap: adding (simple) entry for '%s'\n", old_email);
/* Replace current name and new email for simple entry */
if (new_name) {
free(me->name);
me->name = xstrdup(new_name);
}
if (new_email) {
free(me->email);
me->email = xstrdup(new_email);
}
} else {
struct mailmap_info *mi = xcalloc(1, sizeof(struct mailmap_info));
debug_mm("mailmap: adding (complex) entry for '%s'\n", old_email);
mi->name = xstrdup_or_null(new_name);
mi->email = xstrdup_or_null(new_email);
string_list_insert(&me->namemap, old_name)->util = mi;
}
debug_mm("mailmap: '%s' <%s> -> '%s' <%s>\n",
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 *left, *right, *nstart, *nend;
*name = *email = NULL;
if ((left = strchr(buffer, '<')) == NULL)
return NULL;
if ((right = strchr(left+1, '>')) == NULL)
return NULL;
if (!allow_empty_email && (left+1 == right))
return NULL;
/* remove whitespace from beginning and end of name */
nstart = buffer;
while (isspace(*nstart) && nstart < left)
++nstart;
nend = left-1;
while (nend > nstart && isspace(*nend))
--nend;
*name = (nstart <= nend ? nstart : NULL);
*email = left+1;
*(nend+1) = '\0';
*right++ = '\0';
return (*right == '\0' ? NULL : right);
}
shortlog: remove unused(?) "repo-abbrev" feature Remove support for the magical "repo-abbrev" comment in .mailmap files. This was added to .mailmap parsing in [1], as a generalized feature of the git-shortlog Perl script added earlier in [2]. There was no documentation or tests for this feature, and I don't think it's used in practice anymore. What it did was to allow you to specify a single string to be search-replaced with "/.../" in the .mailmap file. E.g. for linux.git's current .mailmap: git archive --remote=git@gitlab.com:linux-kernel/linux.git \ HEAD -- .mailmap | grep -a repo-abbrev # repo-abbrev: /pub/scm/linux/kernel/git/ Then when running e.g.: git shortlog --merges --author=Linus -1 v5.10-rc7..v5.10 | grep Merge We'd emit (the [...] is mine): Merge tag [...]git://git.kernel.org/.../tip/tip But will now emit: Merge tag [...]git.kernel.org/pub/scm/linux/kernel/git/tip/tip I think at this point this is just a historical artifact we can get rid of. It was initially meant for Linus's own use when we integrated the Perl script[2], but since then it seems he's stopped using it. Digging through Linus's release announcements on the LKML[3] the last release I can find that made use of this output is Linux 2.6.25-rc6 back in March 2008[4]. Later on Linus started using --no-merges[5], and nowadays seems to prefer some custom not-quite-shortlog format of merges from lieutenants[6]. You will still see it on linux.git if you run "git shortlog" manually yourself with --merges, with this removed you can still get the same output with: git log --pretty=fuller v5.10-rc7..v5.10 | sed 's!/pub/scm/linux/kernel/git/!/.../!g' | git shortlog Arguably we should do the same for the search-replacing of "[PATCH]" at the beginning with "". That seems to be another relic of a bygone era when linux.git patches would have their E-Mail subject lines applied as-is by "git am" or whatever. But we documented that feature in "git-shortlog(1)", and it seems more widely applicable than something purely kernel-specific. 1. 7595e2ee6ef (git-shortlog: make common repository prefix configurable with .mailmap, 2006-11-25) 2. fa375c7f1b6 (Add git-shortlog perl script, 2005-06-04) 3. https://lore.kernel.org/lkml/ 4. https://lore.kernel.org/lkml/alpine.LFD.1.00.0803161651350.3020@woody.linux-foundation.org/ 5. https://lore.kernel.org/lkml/BANLkTinrbh7Xi27an3uY7pDWrNKhJRYmEA@mail.gmail.com/ 6. https://lore.kernel.org/lkml/CAHk-=wg1+kf1AVzXA-RQX0zjM6t9J2Kay9xyuNqcFHWV-y5ZYw@mail.gmail.com/ Acked-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-01-13 04:18:06 +08:00
static void read_mailmap_line(struct string_list *map, char *buffer)
{
char *name1 = NULL, *email1 = NULL, *name2 = NULL, *email2 = NULL;
shortlog: remove unused(?) "repo-abbrev" feature Remove support for the magical "repo-abbrev" comment in .mailmap files. This was added to .mailmap parsing in [1], as a generalized feature of the git-shortlog Perl script added earlier in [2]. There was no documentation or tests for this feature, and I don't think it's used in practice anymore. What it did was to allow you to specify a single string to be search-replaced with "/.../" in the .mailmap file. E.g. for linux.git's current .mailmap: git archive --remote=git@gitlab.com:linux-kernel/linux.git \ HEAD -- .mailmap | grep -a repo-abbrev # repo-abbrev: /pub/scm/linux/kernel/git/ Then when running e.g.: git shortlog --merges --author=Linus -1 v5.10-rc7..v5.10 | grep Merge We'd emit (the [...] is mine): Merge tag [...]git://git.kernel.org/.../tip/tip But will now emit: Merge tag [...]git.kernel.org/pub/scm/linux/kernel/git/tip/tip I think at this point this is just a historical artifact we can get rid of. It was initially meant for Linus's own use when we integrated the Perl script[2], but since then it seems he's stopped using it. Digging through Linus's release announcements on the LKML[3] the last release I can find that made use of this output is Linux 2.6.25-rc6 back in March 2008[4]. Later on Linus started using --no-merges[5], and nowadays seems to prefer some custom not-quite-shortlog format of merges from lieutenants[6]. You will still see it on linux.git if you run "git shortlog" manually yourself with --merges, with this removed you can still get the same output with: git log --pretty=fuller v5.10-rc7..v5.10 | sed 's!/pub/scm/linux/kernel/git/!/.../!g' | git shortlog Arguably we should do the same for the search-replacing of "[PATCH]" at the beginning with "". That seems to be another relic of a bygone era when linux.git patches would have their E-Mail subject lines applied as-is by "git am" or whatever. But we documented that feature in "git-shortlog(1)", and it seems more widely applicable than something purely kernel-specific. 1. 7595e2ee6ef (git-shortlog: make common repository prefix configurable with .mailmap, 2006-11-25) 2. fa375c7f1b6 (Add git-shortlog perl script, 2005-06-04) 3. https://lore.kernel.org/lkml/ 4. https://lore.kernel.org/lkml/alpine.LFD.1.00.0803161651350.3020@woody.linux-foundation.org/ 5. https://lore.kernel.org/lkml/BANLkTinrbh7Xi27an3uY7pDWrNKhJRYmEA@mail.gmail.com/ 6. https://lore.kernel.org/lkml/CAHk-=wg1+kf1AVzXA-RQX0zjM6t9J2Kay9xyuNqcFHWV-y5ZYw@mail.gmail.com/ Acked-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-01-13 04:18:06 +08:00
if (buffer[0] == '#')
return;
shortlog: remove unused(?) "repo-abbrev" feature Remove support for the magical "repo-abbrev" comment in .mailmap files. This was added to .mailmap parsing in [1], as a generalized feature of the git-shortlog Perl script added earlier in [2]. There was no documentation or tests for this feature, and I don't think it's used in practice anymore. What it did was to allow you to specify a single string to be search-replaced with "/.../" in the .mailmap file. E.g. for linux.git's current .mailmap: git archive --remote=git@gitlab.com:linux-kernel/linux.git \ HEAD -- .mailmap | grep -a repo-abbrev # repo-abbrev: /pub/scm/linux/kernel/git/ Then when running e.g.: git shortlog --merges --author=Linus -1 v5.10-rc7..v5.10 | grep Merge We'd emit (the [...] is mine): Merge tag [...]git://git.kernel.org/.../tip/tip But will now emit: Merge tag [...]git.kernel.org/pub/scm/linux/kernel/git/tip/tip I think at this point this is just a historical artifact we can get rid of. It was initially meant for Linus's own use when we integrated the Perl script[2], but since then it seems he's stopped using it. Digging through Linus's release announcements on the LKML[3] the last release I can find that made use of this output is Linux 2.6.25-rc6 back in March 2008[4]. Later on Linus started using --no-merges[5], and nowadays seems to prefer some custom not-quite-shortlog format of merges from lieutenants[6]. You will still see it on linux.git if you run "git shortlog" manually yourself with --merges, with this removed you can still get the same output with: git log --pretty=fuller v5.10-rc7..v5.10 | sed 's!/pub/scm/linux/kernel/git/!/.../!g' | git shortlog Arguably we should do the same for the search-replacing of "[PATCH]" at the beginning with "". That seems to be another relic of a bygone era when linux.git patches would have their E-Mail subject lines applied as-is by "git am" or whatever. But we documented that feature in "git-shortlog(1)", and it seems more widely applicable than something purely kernel-specific. 1. 7595e2ee6ef (git-shortlog: make common repository prefix configurable with .mailmap, 2006-11-25) 2. fa375c7f1b6 (Add git-shortlog perl script, 2005-06-04) 3. https://lore.kernel.org/lkml/ 4. https://lore.kernel.org/lkml/alpine.LFD.1.00.0803161651350.3020@woody.linux-foundation.org/ 5. https://lore.kernel.org/lkml/BANLkTinrbh7Xi27an3uY7pDWrNKhJRYmEA@mail.gmail.com/ 6. https://lore.kernel.org/lkml/CAHk-=wg1+kf1AVzXA-RQX0zjM6t9J2Kay9xyuNqcFHWV-y5ZYw@mail.gmail.com/ Acked-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-01-13 04:18:06 +08:00
if ((name2 = parse_name_and_email(buffer, &name1, &email1, 0)) != NULL)
parse_name_and_email(name2, &name2, &email2, 1);
if (email1)
add_mapping(map, name1, email1, name2, email2);
}
/* Flags for read_mailmap_file() */
#define MAILMAP_NOFOLLOW (1<<0)
static int read_mailmap_file(struct string_list *map, const char *filename,
unsigned flags)
{
char buffer[1024];
FILE *f;
int fd;
if (!filename)
return 0;
if (flags & MAILMAP_NOFOLLOW)
fd = open_nofollow(filename, O_RDONLY);
else
fd = open(filename, O_RDONLY);
if (fd < 0) {
if (errno == ENOENT)
return 0;
return error_errno("unable to open mailmap at %s", filename);
}
f = xfdopen(fd, "r");
while (fgets(buffer, sizeof(buffer), f) != NULL)
shortlog: remove unused(?) "repo-abbrev" feature Remove support for the magical "repo-abbrev" comment in .mailmap files. This was added to .mailmap parsing in [1], as a generalized feature of the git-shortlog Perl script added earlier in [2]. There was no documentation or tests for this feature, and I don't think it's used in practice anymore. What it did was to allow you to specify a single string to be search-replaced with "/.../" in the .mailmap file. E.g. for linux.git's current .mailmap: git archive --remote=git@gitlab.com:linux-kernel/linux.git \ HEAD -- .mailmap | grep -a repo-abbrev # repo-abbrev: /pub/scm/linux/kernel/git/ Then when running e.g.: git shortlog --merges --author=Linus -1 v5.10-rc7..v5.10 | grep Merge We'd emit (the [...] is mine): Merge tag [...]git://git.kernel.org/.../tip/tip But will now emit: Merge tag [...]git.kernel.org/pub/scm/linux/kernel/git/tip/tip I think at this point this is just a historical artifact we can get rid of. It was initially meant for Linus's own use when we integrated the Perl script[2], but since then it seems he's stopped using it. Digging through Linus's release announcements on the LKML[3] the last release I can find that made use of this output is Linux 2.6.25-rc6 back in March 2008[4]. Later on Linus started using --no-merges[5], and nowadays seems to prefer some custom not-quite-shortlog format of merges from lieutenants[6]. You will still see it on linux.git if you run "git shortlog" manually yourself with --merges, with this removed you can still get the same output with: git log --pretty=fuller v5.10-rc7..v5.10 | sed 's!/pub/scm/linux/kernel/git/!/.../!g' | git shortlog Arguably we should do the same for the search-replacing of "[PATCH]" at the beginning with "". That seems to be another relic of a bygone era when linux.git patches would have their E-Mail subject lines applied as-is by "git am" or whatever. But we documented that feature in "git-shortlog(1)", and it seems more widely applicable than something purely kernel-specific. 1. 7595e2ee6ef (git-shortlog: make common repository prefix configurable with .mailmap, 2006-11-25) 2. fa375c7f1b6 (Add git-shortlog perl script, 2005-06-04) 3. https://lore.kernel.org/lkml/ 4. https://lore.kernel.org/lkml/alpine.LFD.1.00.0803161651350.3020@woody.linux-foundation.org/ 5. https://lore.kernel.org/lkml/BANLkTinrbh7Xi27an3uY7pDWrNKhJRYmEA@mail.gmail.com/ 6. https://lore.kernel.org/lkml/CAHk-=wg1+kf1AVzXA-RQX0zjM6t9J2Kay9xyuNqcFHWV-y5ZYw@mail.gmail.com/ Acked-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-01-13 04:18:06 +08:00
read_mailmap_line(map, buffer);
fclose(f);
return 0;
}
shortlog: remove unused(?) "repo-abbrev" feature Remove support for the magical "repo-abbrev" comment in .mailmap files. This was added to .mailmap parsing in [1], as a generalized feature of the git-shortlog Perl script added earlier in [2]. There was no documentation or tests for this feature, and I don't think it's used in practice anymore. What it did was to allow you to specify a single string to be search-replaced with "/.../" in the .mailmap file. E.g. for linux.git's current .mailmap: git archive --remote=git@gitlab.com:linux-kernel/linux.git \ HEAD -- .mailmap | grep -a repo-abbrev # repo-abbrev: /pub/scm/linux/kernel/git/ Then when running e.g.: git shortlog --merges --author=Linus -1 v5.10-rc7..v5.10 | grep Merge We'd emit (the [...] is mine): Merge tag [...]git://git.kernel.org/.../tip/tip But will now emit: Merge tag [...]git.kernel.org/pub/scm/linux/kernel/git/tip/tip I think at this point this is just a historical artifact we can get rid of. It was initially meant for Linus's own use when we integrated the Perl script[2], but since then it seems he's stopped using it. Digging through Linus's release announcements on the LKML[3] the last release I can find that made use of this output is Linux 2.6.25-rc6 back in March 2008[4]. Later on Linus started using --no-merges[5], and nowadays seems to prefer some custom not-quite-shortlog format of merges from lieutenants[6]. You will still see it on linux.git if you run "git shortlog" manually yourself with --merges, with this removed you can still get the same output with: git log --pretty=fuller v5.10-rc7..v5.10 | sed 's!/pub/scm/linux/kernel/git/!/.../!g' | git shortlog Arguably we should do the same for the search-replacing of "[PATCH]" at the beginning with "". That seems to be another relic of a bygone era when linux.git patches would have their E-Mail subject lines applied as-is by "git am" or whatever. But we documented that feature in "git-shortlog(1)", and it seems more widely applicable than something purely kernel-specific. 1. 7595e2ee6ef (git-shortlog: make common repository prefix configurable with .mailmap, 2006-11-25) 2. fa375c7f1b6 (Add git-shortlog perl script, 2005-06-04) 3. https://lore.kernel.org/lkml/ 4. https://lore.kernel.org/lkml/alpine.LFD.1.00.0803161651350.3020@woody.linux-foundation.org/ 5. https://lore.kernel.org/lkml/BANLkTinrbh7Xi27an3uY7pDWrNKhJRYmEA@mail.gmail.com/ 6. https://lore.kernel.org/lkml/CAHk-=wg1+kf1AVzXA-RQX0zjM6t9J2Kay9xyuNqcFHWV-y5ZYw@mail.gmail.com/ Acked-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-01-13 04:18:06 +08:00
static void read_mailmap_string(struct string_list *map, char *buf)
{
mailmap: handle mailmap blobs without trailing newlines The read_mailmap_buf function reads each line of the mailmap using strchrnul, like: const char *end = strchrnul(buf, '\n'); unsigned long linelen = end - buf + 1; But that's off-by-one when we actually hit the NUL byte; our line does not have a terminator, and so is only "end - buf" bytes long. As a result, when we subtract the linelen from the total len, we end up with (unsigned long)-1 bytes left in the buffer, and we start reading random junk from memory. We could fix it with: unsigned long linelen = end - buf + !!*end; but let's take a step back for a moment. It's questionable in the first place for a function that takes a buffer and length to be using strchrnul. But it works because we only have one caller (and are only likely to ever have this one), which is handing us data from read_sha1_file. Which means that it's always NUL-terminated. Instead of tightening the assumptions to make the buffer/length pair work for a caller that doesn't actually exist, let's let loosen the assumptions to what the real caller has: a modifiable, NUL-terminated string. This makes the code simpler and shorter (because we don't have to correlate strchrnul with the length calculation), correct (because the code with the off-by-one just goes away), and more efficient (we can drop the extra allocation we needed to create NUL-terminated strings for each line, and just terminate in place). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-08-28 09:41:39 +08:00
while (*buf) {
char *end = strchrnul(buf, '\n');
mailmap: handle mailmap blobs without trailing newlines The read_mailmap_buf function reads each line of the mailmap using strchrnul, like: const char *end = strchrnul(buf, '\n'); unsigned long linelen = end - buf + 1; But that's off-by-one when we actually hit the NUL byte; our line does not have a terminator, and so is only "end - buf" bytes long. As a result, when we subtract the linelen from the total len, we end up with (unsigned long)-1 bytes left in the buffer, and we start reading random junk from memory. We could fix it with: unsigned long linelen = end - buf + !!*end; but let's take a step back for a moment. It's questionable in the first place for a function that takes a buffer and length to be using strchrnul. But it works because we only have one caller (and are only likely to ever have this one), which is handing us data from read_sha1_file. Which means that it's always NUL-terminated. Instead of tightening the assumptions to make the buffer/length pair work for a caller that doesn't actually exist, let's let loosen the assumptions to what the real caller has: a modifiable, NUL-terminated string. This makes the code simpler and shorter (because we don't have to correlate strchrnul with the length calculation), correct (because the code with the off-by-one just goes away), and more efficient (we can drop the extra allocation we needed to create NUL-terminated strings for each line, and just terminate in place). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-08-28 09:41:39 +08:00
if (*end)
*end++ = '\0';
shortlog: remove unused(?) "repo-abbrev" feature Remove support for the magical "repo-abbrev" comment in .mailmap files. This was added to .mailmap parsing in [1], as a generalized feature of the git-shortlog Perl script added earlier in [2]. There was no documentation or tests for this feature, and I don't think it's used in practice anymore. What it did was to allow you to specify a single string to be search-replaced with "/.../" in the .mailmap file. E.g. for linux.git's current .mailmap: git archive --remote=git@gitlab.com:linux-kernel/linux.git \ HEAD -- .mailmap | grep -a repo-abbrev # repo-abbrev: /pub/scm/linux/kernel/git/ Then when running e.g.: git shortlog --merges --author=Linus -1 v5.10-rc7..v5.10 | grep Merge We'd emit (the [...] is mine): Merge tag [...]git://git.kernel.org/.../tip/tip But will now emit: Merge tag [...]git.kernel.org/pub/scm/linux/kernel/git/tip/tip I think at this point this is just a historical artifact we can get rid of. It was initially meant for Linus's own use when we integrated the Perl script[2], but since then it seems he's stopped using it. Digging through Linus's release announcements on the LKML[3] the last release I can find that made use of this output is Linux 2.6.25-rc6 back in March 2008[4]. Later on Linus started using --no-merges[5], and nowadays seems to prefer some custom not-quite-shortlog format of merges from lieutenants[6]. You will still see it on linux.git if you run "git shortlog" manually yourself with --merges, with this removed you can still get the same output with: git log --pretty=fuller v5.10-rc7..v5.10 | sed 's!/pub/scm/linux/kernel/git/!/.../!g' | git shortlog Arguably we should do the same for the search-replacing of "[PATCH]" at the beginning with "". That seems to be another relic of a bygone era when linux.git patches would have their E-Mail subject lines applied as-is by "git am" or whatever. But we documented that feature in "git-shortlog(1)", and it seems more widely applicable than something purely kernel-specific. 1. 7595e2ee6ef (git-shortlog: make common repository prefix configurable with .mailmap, 2006-11-25) 2. fa375c7f1b6 (Add git-shortlog perl script, 2005-06-04) 3. https://lore.kernel.org/lkml/ 4. https://lore.kernel.org/lkml/alpine.LFD.1.00.0803161651350.3020@woody.linux-foundation.org/ 5. https://lore.kernel.org/lkml/BANLkTinrbh7Xi27an3uY7pDWrNKhJRYmEA@mail.gmail.com/ 6. https://lore.kernel.org/lkml/CAHk-=wg1+kf1AVzXA-RQX0zjM6t9J2Kay9xyuNqcFHWV-y5ZYw@mail.gmail.com/ Acked-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-01-13 04:18:06 +08:00
read_mailmap_line(map, buf);
mailmap: handle mailmap blobs without trailing newlines The read_mailmap_buf function reads each line of the mailmap using strchrnul, like: const char *end = strchrnul(buf, '\n'); unsigned long linelen = end - buf + 1; But that's off-by-one when we actually hit the NUL byte; our line does not have a terminator, and so is only "end - buf" bytes long. As a result, when we subtract the linelen from the total len, we end up with (unsigned long)-1 bytes left in the buffer, and we start reading random junk from memory. We could fix it with: unsigned long linelen = end - buf + !!*end; but let's take a step back for a moment. It's questionable in the first place for a function that takes a buffer and length to be using strchrnul. But it works because we only have one caller (and are only likely to ever have this one), which is handing us data from read_sha1_file. Which means that it's always NUL-terminated. Instead of tightening the assumptions to make the buffer/length pair work for a caller that doesn't actually exist, let's let loosen the assumptions to what the real caller has: a modifiable, NUL-terminated string. This makes the code simpler and shorter (because we don't have to correlate strchrnul with the length calculation), correct (because the code with the off-by-one just goes away), and more efficient (we can drop the extra allocation we needed to create NUL-terminated strings for each line, and just terminate in place). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-08-28 09:41:39 +08:00
buf = end;
}
}
shortlog: remove unused(?) "repo-abbrev" feature Remove support for the magical "repo-abbrev" comment in .mailmap files. This was added to .mailmap parsing in [1], as a generalized feature of the git-shortlog Perl script added earlier in [2]. There was no documentation or tests for this feature, and I don't think it's used in practice anymore. What it did was to allow you to specify a single string to be search-replaced with "/.../" in the .mailmap file. E.g. for linux.git's current .mailmap: git archive --remote=git@gitlab.com:linux-kernel/linux.git \ HEAD -- .mailmap | grep -a repo-abbrev # repo-abbrev: /pub/scm/linux/kernel/git/ Then when running e.g.: git shortlog --merges --author=Linus -1 v5.10-rc7..v5.10 | grep Merge We'd emit (the [...] is mine): Merge tag [...]git://git.kernel.org/.../tip/tip But will now emit: Merge tag [...]git.kernel.org/pub/scm/linux/kernel/git/tip/tip I think at this point this is just a historical artifact we can get rid of. It was initially meant for Linus's own use when we integrated the Perl script[2], but since then it seems he's stopped using it. Digging through Linus's release announcements on the LKML[3] the last release I can find that made use of this output is Linux 2.6.25-rc6 back in March 2008[4]. Later on Linus started using --no-merges[5], and nowadays seems to prefer some custom not-quite-shortlog format of merges from lieutenants[6]. You will still see it on linux.git if you run "git shortlog" manually yourself with --merges, with this removed you can still get the same output with: git log --pretty=fuller v5.10-rc7..v5.10 | sed 's!/pub/scm/linux/kernel/git/!/.../!g' | git shortlog Arguably we should do the same for the search-replacing of "[PATCH]" at the beginning with "". That seems to be another relic of a bygone era when linux.git patches would have their E-Mail subject lines applied as-is by "git am" or whatever. But we documented that feature in "git-shortlog(1)", and it seems more widely applicable than something purely kernel-specific. 1. 7595e2ee6ef (git-shortlog: make common repository prefix configurable with .mailmap, 2006-11-25) 2. fa375c7f1b6 (Add git-shortlog perl script, 2005-06-04) 3. https://lore.kernel.org/lkml/ 4. https://lore.kernel.org/lkml/alpine.LFD.1.00.0803161651350.3020@woody.linux-foundation.org/ 5. https://lore.kernel.org/lkml/BANLkTinrbh7Xi27an3uY7pDWrNKhJRYmEA@mail.gmail.com/ 6. https://lore.kernel.org/lkml/CAHk-=wg1+kf1AVzXA-RQX0zjM6t9J2Kay9xyuNqcFHWV-y5ZYw@mail.gmail.com/ Acked-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-01-13 04:18:06 +08:00
static int read_mailmap_blob(struct string_list *map, const char *name)
{
struct object_id oid;
char *buf;
unsigned long size;
enum object_type type;
if (!name)
return 0;
if (get_oid(name, &oid) < 0)
return 0;
buf = read_object_file(&oid, &type, &size);
if (!buf)
return error("unable to read mailmap object at %s", name);
if (type != OBJ_BLOB)
return error("mailmap is not a blob: %s", name);
shortlog: remove unused(?) "repo-abbrev" feature Remove support for the magical "repo-abbrev" comment in .mailmap files. This was added to .mailmap parsing in [1], as a generalized feature of the git-shortlog Perl script added earlier in [2]. There was no documentation or tests for this feature, and I don't think it's used in practice anymore. What it did was to allow you to specify a single string to be search-replaced with "/.../" in the .mailmap file. E.g. for linux.git's current .mailmap: git archive --remote=git@gitlab.com:linux-kernel/linux.git \ HEAD -- .mailmap | grep -a repo-abbrev # repo-abbrev: /pub/scm/linux/kernel/git/ Then when running e.g.: git shortlog --merges --author=Linus -1 v5.10-rc7..v5.10 | grep Merge We'd emit (the [...] is mine): Merge tag [...]git://git.kernel.org/.../tip/tip But will now emit: Merge tag [...]git.kernel.org/pub/scm/linux/kernel/git/tip/tip I think at this point this is just a historical artifact we can get rid of. It was initially meant for Linus's own use when we integrated the Perl script[2], but since then it seems he's stopped using it. Digging through Linus's release announcements on the LKML[3] the last release I can find that made use of this output is Linux 2.6.25-rc6 back in March 2008[4]. Later on Linus started using --no-merges[5], and nowadays seems to prefer some custom not-quite-shortlog format of merges from lieutenants[6]. You will still see it on linux.git if you run "git shortlog" manually yourself with --merges, with this removed you can still get the same output with: git log --pretty=fuller v5.10-rc7..v5.10 | sed 's!/pub/scm/linux/kernel/git/!/.../!g' | git shortlog Arguably we should do the same for the search-replacing of "[PATCH]" at the beginning with "". That seems to be another relic of a bygone era when linux.git patches would have their E-Mail subject lines applied as-is by "git am" or whatever. But we documented that feature in "git-shortlog(1)", and it seems more widely applicable than something purely kernel-specific. 1. 7595e2ee6ef (git-shortlog: make common repository prefix configurable with .mailmap, 2006-11-25) 2. fa375c7f1b6 (Add git-shortlog perl script, 2005-06-04) 3. https://lore.kernel.org/lkml/ 4. https://lore.kernel.org/lkml/alpine.LFD.1.00.0803161651350.3020@woody.linux-foundation.org/ 5. https://lore.kernel.org/lkml/BANLkTinrbh7Xi27an3uY7pDWrNKhJRYmEA@mail.gmail.com/ 6. https://lore.kernel.org/lkml/CAHk-=wg1+kf1AVzXA-RQX0zjM6t9J2Kay9xyuNqcFHWV-y5ZYw@mail.gmail.com/ Acked-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-01-13 04:18:06 +08:00
read_mailmap_string(map, buf);
free(buf);
return 0;
}
shortlog: remove unused(?) "repo-abbrev" feature Remove support for the magical "repo-abbrev" comment in .mailmap files. This was added to .mailmap parsing in [1], as a generalized feature of the git-shortlog Perl script added earlier in [2]. There was no documentation or tests for this feature, and I don't think it's used in practice anymore. What it did was to allow you to specify a single string to be search-replaced with "/.../" in the .mailmap file. E.g. for linux.git's current .mailmap: git archive --remote=git@gitlab.com:linux-kernel/linux.git \ HEAD -- .mailmap | grep -a repo-abbrev # repo-abbrev: /pub/scm/linux/kernel/git/ Then when running e.g.: git shortlog --merges --author=Linus -1 v5.10-rc7..v5.10 | grep Merge We'd emit (the [...] is mine): Merge tag [...]git://git.kernel.org/.../tip/tip But will now emit: Merge tag [...]git.kernel.org/pub/scm/linux/kernel/git/tip/tip I think at this point this is just a historical artifact we can get rid of. It was initially meant for Linus's own use when we integrated the Perl script[2], but since then it seems he's stopped using it. Digging through Linus's release announcements on the LKML[3] the last release I can find that made use of this output is Linux 2.6.25-rc6 back in March 2008[4]. Later on Linus started using --no-merges[5], and nowadays seems to prefer some custom not-quite-shortlog format of merges from lieutenants[6]. You will still see it on linux.git if you run "git shortlog" manually yourself with --merges, with this removed you can still get the same output with: git log --pretty=fuller v5.10-rc7..v5.10 | sed 's!/pub/scm/linux/kernel/git/!/.../!g' | git shortlog Arguably we should do the same for the search-replacing of "[PATCH]" at the beginning with "". That seems to be another relic of a bygone era when linux.git patches would have their E-Mail subject lines applied as-is by "git am" or whatever. But we documented that feature in "git-shortlog(1)", and it seems more widely applicable than something purely kernel-specific. 1. 7595e2ee6ef (git-shortlog: make common repository prefix configurable with .mailmap, 2006-11-25) 2. fa375c7f1b6 (Add git-shortlog perl script, 2005-06-04) 3. https://lore.kernel.org/lkml/ 4. https://lore.kernel.org/lkml/alpine.LFD.1.00.0803161651350.3020@woody.linux-foundation.org/ 5. https://lore.kernel.org/lkml/BANLkTinrbh7Xi27an3uY7pDWrNKhJRYmEA@mail.gmail.com/ 6. https://lore.kernel.org/lkml/CAHk-=wg1+kf1AVzXA-RQX0zjM6t9J2Kay9xyuNqcFHWV-y5ZYw@mail.gmail.com/ Acked-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-01-13 04:18:06 +08:00
int read_mailmap(struct string_list *map)
{
int err = 0;
map->strdup_strings = 1;
map->cmp = namemap_cmp;
if (!git_mailmap_blob && is_bare_repository())
git_mailmap_blob = "HEAD:.mailmap";
mailmap: only look for .mailmap in work tree When trying to find a .mailmap file, we will always look for it in the current directory. This makes sense in a repository with a working tree, since we'd always go to the toplevel directory at startup. But for a bare repository, it can be confusing. With an option like --git-dir (or $GIT_DIR in the environment), we don't chdir at all, and we'd read .mailmap from whatever directory you happened to be in before starting Git. (Note that --git-dir without specifying a working tree historically means "the current directory is the root of the working tree", but most bare repositories will have core.bare set these days, meaning they will realize there is no working tree at all). The documentation for gitmailmap(5) says: If the file `.mailmap` exists at the toplevel of the repository[...] which likewise reinforces the notion that we are looking in the working tree. This patch prevents us from looking for such a file when we're in a bare repository. This does break something that used to work: cd bare.git git cat-file blob HEAD:.mailmap >.mailmap git shortlog But that was never advertised in the documentation. And these days we have mailmap.blob (which defaults to HEAD:.mailmap) to do the same thing in a much cleaner way. However, there's one more interesting case: we might not have a repository at all! The git-shortlog command can be run with git-log output fed on its stdin, and it will apply the mailmap. In that case, it probably does make sense to read .mailmap from the current directory. This patch will continue to do so. That leads to one even weirder case: if you run git-shortlog to process stdin, the input _could_ be from a different repository entirely. Should we respect the in-tree .mailmap then? Probably yes. Whatever the source of the input, if shortlog is running in a repository, the documentation claims that we'd read the .mailmap from its top-level (and of course it's reasonably likely that it _is_ from the same repo, and the user just preferred to run git-log and git-shortlog separately for whatever reason). The included test covers these cases, and we now document the "no repo" case explicitly. We also add a test that confirms we find a top-level ".mailmap" even when we start in a subdirectory of the working tree. This worked both before and after this commit, but we never tested it explicitly (it works because we always chdir to the top-level of the working tree if there is one). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-02-11 04:34:33 +08:00
if (!startup_info->have_repository || !is_bare_repository())
err |= read_mailmap_file(map, ".mailmap",
startup_info->have_repository ?
MAILMAP_NOFOLLOW : 0);
if (startup_info->have_repository)
shortlog: remove unused(?) "repo-abbrev" feature Remove support for the magical "repo-abbrev" comment in .mailmap files. This was added to .mailmap parsing in [1], as a generalized feature of the git-shortlog Perl script added earlier in [2]. There was no documentation or tests for this feature, and I don't think it's used in practice anymore. What it did was to allow you to specify a single string to be search-replaced with "/.../" in the .mailmap file. E.g. for linux.git's current .mailmap: git archive --remote=git@gitlab.com:linux-kernel/linux.git \ HEAD -- .mailmap | grep -a repo-abbrev # repo-abbrev: /pub/scm/linux/kernel/git/ Then when running e.g.: git shortlog --merges --author=Linus -1 v5.10-rc7..v5.10 | grep Merge We'd emit (the [...] is mine): Merge tag [...]git://git.kernel.org/.../tip/tip But will now emit: Merge tag [...]git.kernel.org/pub/scm/linux/kernel/git/tip/tip I think at this point this is just a historical artifact we can get rid of. It was initially meant for Linus's own use when we integrated the Perl script[2], but since then it seems he's stopped using it. Digging through Linus's release announcements on the LKML[3] the last release I can find that made use of this output is Linux 2.6.25-rc6 back in March 2008[4]. Later on Linus started using --no-merges[5], and nowadays seems to prefer some custom not-quite-shortlog format of merges from lieutenants[6]. You will still see it on linux.git if you run "git shortlog" manually yourself with --merges, with this removed you can still get the same output with: git log --pretty=fuller v5.10-rc7..v5.10 | sed 's!/pub/scm/linux/kernel/git/!/.../!g' | git shortlog Arguably we should do the same for the search-replacing of "[PATCH]" at the beginning with "". That seems to be another relic of a bygone era when linux.git patches would have their E-Mail subject lines applied as-is by "git am" or whatever. But we documented that feature in "git-shortlog(1)", and it seems more widely applicable than something purely kernel-specific. 1. 7595e2ee6ef (git-shortlog: make common repository prefix configurable with .mailmap, 2006-11-25) 2. fa375c7f1b6 (Add git-shortlog perl script, 2005-06-04) 3. https://lore.kernel.org/lkml/ 4. https://lore.kernel.org/lkml/alpine.LFD.1.00.0803161651350.3020@woody.linux-foundation.org/ 5. https://lore.kernel.org/lkml/BANLkTinrbh7Xi27an3uY7pDWrNKhJRYmEA@mail.gmail.com/ 6. https://lore.kernel.org/lkml/CAHk-=wg1+kf1AVzXA-RQX0zjM6t9J2Kay9xyuNqcFHWV-y5ZYw@mail.gmail.com/ Acked-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-01-13 04:18:06 +08:00
err |= read_mailmap_blob(map, git_mailmap_blob);
err |= read_mailmap_file(map, git_mailmap_file, 0);
return err;
}
void clear_mailmap(struct string_list *map)
{
debug_mm("mailmap: clearing %d entries...\n", map->nr);
map->strdup_strings = 1;
string_list_clear_func(map, free_mailmap_entry);
debug_mm("mailmap: cleared\n");
}
mailmap: remove email copy and length limitation In map_user(), we have email pointer that points at the beginning of an e-mail address, but the buffer is not terminated with a NUL after the e-mail address. It typically has ">" after the address, and it could have even more if it comes from author/committer line in a commit object. Or it may not have ">" after it. We used to copy the e-mail address proper into a temporary buffer before asking the string-list API to find the e-mail address in the mailmap, because string_list_lookup() function only takes a NUL terminated full string. Introduce a helper function lookup_prefix that takes the email pointer and the length, and finds a matching entry in the string list used for the mailmap, by doing the following: - First ask string_list_find_insert_index() where in its sorted list the e-mail address we have (including the possible trailing junk ">...") would be inserted. - It could find an exact match (e.g. we had a clean e-mail address without any trailing junk). We can return the item in that case. - Or it could return the index of an item that sorts after the e-mail address we have. - If we did not find an exact match against a clean e-mail address, then the record we are looking for in the mailmap has to exist before the index returned by the function (i.e. "email>junk" always sorts later than "email"). Iterate, starting from that index, down the map->items[] array until we find the exact record we are looking for, or we see a record with a key that definitely sorts earlier than the e-mail we are looking for (i.e. when we are looking for "email" in "email>junk", a record in the mailmap that begins with "emaik" strictly sorts before "email", if such a key existed in the mailmap). This, together with the earlier enhancement to support case-insensitive sorting, allow us to remove an extra copy of email buffer to downcase it. A part of this is based on Antoine Pelisse's previous work. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-01-06 05:26:39 +08:00
/*
* Look for an entry in map that match string[0:len]; string[len]
* does not have to be NUL (but it could be).
*/
static struct string_list_item *lookup_prefix(struct string_list *map,
const char *string, size_t len)
{
int i = string_list_find_insert_index(map, string, 1);
if (i < 0) {
/* exact match */
i = -1 - i;
if (!string[len])
return &map->items[i];
/*
* that map entry matches exactly to the string, including
* the cruft at the end beyond "len". That is not a match
* with string[0:len] that we are looking for.
*/
} else if (!string[len]) {
/*
* asked with the whole string, and got nothing. No
* matching entry can exist in the map.
*/
return NULL;
}
/*
* i is at the exact match to an overlong key, or location the
* overlong key would be inserted, which must come after the
* real location of the key if one exists.
*/
while (0 <= --i && i < map->nr) {
int cmp = strncasecmp(map->items[i].string, string, len);
if (cmp < 0)
/*
* "i" points at a key definitely below the prefix;
* the map does not have string[0:len] in it.
*/
break;
else if (!cmp && !map->items[i].string[len])
/* found it */
return &map->items[i];
/*
* otherwise, the string at "i" may be string[0:len]
* followed by a string that sorts later than string[len:];
* keep trying.
*/
}
return NULL;
}
int map_user(struct string_list *map,
const char **email, size_t *emaillen,
const char **name, size_t *namelen)
{
struct string_list_item *item;
struct mailmap_entry *me;
mailmap: remove email copy and length limitation In map_user(), we have email pointer that points at the beginning of an e-mail address, but the buffer is not terminated with a NUL after the e-mail address. It typically has ">" after the address, and it could have even more if it comes from author/committer line in a commit object. Or it may not have ">" after it. We used to copy the e-mail address proper into a temporary buffer before asking the string-list API to find the e-mail address in the mailmap, because string_list_lookup() function only takes a NUL terminated full string. Introduce a helper function lookup_prefix that takes the email pointer and the length, and finds a matching entry in the string list used for the mailmap, by doing the following: - First ask string_list_find_insert_index() where in its sorted list the e-mail address we have (including the possible trailing junk ">...") would be inserted. - It could find an exact match (e.g. we had a clean e-mail address without any trailing junk). We can return the item in that case. - Or it could return the index of an item that sorts after the e-mail address we have. - If we did not find an exact match against a clean e-mail address, then the record we are looking for in the mailmap has to exist before the index returned by the function (i.e. "email>junk" always sorts later than "email"). Iterate, starting from that index, down the map->items[] array until we find the exact record we are looking for, or we see a record with a key that definitely sorts earlier than the e-mail we are looking for (i.e. when we are looking for "email" in "email>junk", a record in the mailmap that begins with "emaik" strictly sorts before "email", if such a key existed in the mailmap). This, together with the earlier enhancement to support case-insensitive sorting, allow us to remove an extra copy of email buffer to downcase it. A part of this is based on Antoine Pelisse's previous work. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-01-06 05:26:39 +08:00
debug_mm("map_user: map '%.*s' <%.*s>\n",
(int)*namelen, debug_str(*name),
(int)*emaillen, debug_str(*email));
mailmap: remove email copy and length limitation In map_user(), we have email pointer that points at the beginning of an e-mail address, but the buffer is not terminated with a NUL after the e-mail address. It typically has ">" after the address, and it could have even more if it comes from author/committer line in a commit object. Or it may not have ">" after it. We used to copy the e-mail address proper into a temporary buffer before asking the string-list API to find the e-mail address in the mailmap, because string_list_lookup() function only takes a NUL terminated full string. Introduce a helper function lookup_prefix that takes the email pointer and the length, and finds a matching entry in the string list used for the mailmap, by doing the following: - First ask string_list_find_insert_index() where in its sorted list the e-mail address we have (including the possible trailing junk ">...") would be inserted. - It could find an exact match (e.g. we had a clean e-mail address without any trailing junk). We can return the item in that case. - Or it could return the index of an item that sorts after the e-mail address we have. - If we did not find an exact match against a clean e-mail address, then the record we are looking for in the mailmap has to exist before the index returned by the function (i.e. "email>junk" always sorts later than "email"). Iterate, starting from that index, down the map->items[] array until we find the exact record we are looking for, or we see a record with a key that definitely sorts earlier than the e-mail we are looking for (i.e. when we are looking for "email" in "email>junk", a record in the mailmap that begins with "emaik" strictly sorts before "email", if such a key existed in the mailmap). This, together with the earlier enhancement to support case-insensitive sorting, allow us to remove an extra copy of email buffer to downcase it. A part of this is based on Antoine Pelisse's previous work. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-01-06 05:26:39 +08:00
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.
*/
struct string_list_item *subitem;
subitem = lookup_prefix(&me->namemap, *name, *namelen);
if (subitem)
item = subitem;
}
}
if (item != NULL) {
struct mailmap_info *mi = (struct mailmap_info *)item->util;
if (mi->name == NULL && mi->email == NULL) {
debug_mm("map_user: -- (no simple mapping)\n");
return 0;
}
if (mi->email) {
*email = mi->email;
*emaillen = strlen(*email);
}
if (mi->name) {
*name = mi->name;
*namelen = strlen(*name);
}
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");
return 0;
}