summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/Makefile1
-rw-r--r--Documentation/git-blame.txt2
-rw-r--r--Documentation/git-check-mailmap.txt9
-rw-r--r--Documentation/git-shortlog.txt6
-rw-r--r--Documentation/gitmailmap.txt123
-rw-r--r--Documentation/mailmap.txt75
-rw-r--r--builtin/blame.c2
-rw-r--r--builtin/check-mailmap.c2
-rw-r--r--builtin/commit.c2
-rw-r--r--builtin/log.c2
-rw-r--r--builtin/shortlog.c16
-rw-r--r--command-list.txt1
-rw-r--r--mailmap.c48
-rw-r--r--mailmap.h2
-rw-r--r--pretty.c2
-rw-r--r--shortlog.h1
-rwxr-xr-xt/t1412-reflog-loop.sh7
-rwxr-xr-xt/t2012-checkout-last.sh12
-rwxr-xr-xt/t4203-mailmap.sh825
-rwxr-xr-xt/t7509-commit-authorship.sh7
-rwxr-xr-xt/t7810-grep.sh18
-rw-r--r--t/test-lib-functions.sh37
22 files changed, 771 insertions, 429 deletions
diff --git a/Documentation/Makefile b/Documentation/Makefile
index b980407059..81d1bf7a04 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -21,6 +21,7 @@ MAN1_TXT += gitweb.txt
MAN5_TXT += gitattributes.txt
MAN5_TXT += githooks.txt
MAN5_TXT += gitignore.txt
+MAN5_TXT += gitmailmap.txt
MAN5_TXT += gitmodules.txt
MAN5_TXT += gitrepository-layout.txt
MAN5_TXT += gitweb.conf.txt
diff --git a/Documentation/git-blame.txt b/Documentation/git-blame.txt
index 34b496d485..3bf5d5d8b4 100644
--- a/Documentation/git-blame.txt
+++ b/Documentation/git-blame.txt
@@ -226,7 +226,7 @@ commit commentary), a blame viewer will not care.
MAPPING AUTHORS
---------------
-include::mailmap.txt[]
+See linkgit:gitmailmap[5].
SEE ALSO
diff --git a/Documentation/git-check-mailmap.txt b/Documentation/git-check-mailmap.txt
index aa2055dbeb..02f4418323 100644
--- a/Documentation/git-check-mailmap.txt
+++ b/Documentation/git-check-mailmap.txt
@@ -36,10 +36,17 @@ name is provided or known to the 'mailmap', ``Name $$<user@host>$$'' is
printed; otherwise only ``$$<user@host>$$'' is printed.
+CONFIGURATION
+-------------
+
+See `mailmap.file` and `mailmap.blob` in linkgit:git-config[1] for how
+to specify a custom `.mailmap` target file or object.
+
+
MAPPING AUTHORS
---------------
-include::mailmap.txt[]
+See linkgit:gitmailmap[5].
GIT
diff --git a/Documentation/git-shortlog.txt b/Documentation/git-shortlog.txt
index fd93cd41e9..c16cc3b608 100644
--- a/Documentation/git-shortlog.txt
+++ b/Documentation/git-shortlog.txt
@@ -111,11 +111,7 @@ include::rev-list-options.txt[]
MAPPING AUTHORS
---------------
-The `.mailmap` feature is used to coalesce together commits by the same
-person in the shortlog, where their name and/or email address was
-spelled differently.
-
-include::mailmap.txt[]
+See linkgit:gitmailmap[5].
GIT
---
diff --git a/Documentation/gitmailmap.txt b/Documentation/gitmailmap.txt
new file mode 100644
index 0000000000..7f1089786d
--- /dev/null
+++ b/Documentation/gitmailmap.txt
@@ -0,0 +1,123 @@
+gitmailmap(5)
+=============
+
+NAME
+----
+gitmailmap - Map author/committer names and/or E-Mail addresses
+
+SYNOPSIS
+--------
+$GIT_WORK_DIR/.mailmap
+
+
+DESCRIPTION
+-----------
+
+If the file `.mailmap` exists at the toplevel of the repository, or at
+the location pointed to by the `mailmap.file` or `mailmap.blob`
+configuration options (see linkgit:git-config[1]), it
+is used to map author and committer names and email addresses to
+canonical real names and email addresses.
+
+
+SYNTAX
+------
+
+The '#' character begins a comment to the end of line, blank lines
+are ignored.
+
+In the simple form, each line in the file consists of the canonical
+real name of an author, whitespace, and an email address used in the
+commit (enclosed by '<' and '>') to map to the name. For example:
+--
+ Proper Name <commit@email.xx>
+--
+
+The more complex forms are:
+--
+ <proper@email.xx> <commit@email.xx>
+--
+which allows mailmap to replace only the email part of a commit, and:
+--
+ Proper Name <proper@email.xx> <commit@email.xx>
+--
+which allows mailmap to replace both the name and the email of a
+commit matching the specified commit email address, and:
+--
+ Proper Name <proper@email.xx> Commit Name <commit@email.xx>
+--
+which allows mailmap to replace both the name and the email of a
+commit matching both the specified commit name and email address.
+
+Both E-Mails and names are matched case-insensitively. For example
+this would also match the 'Commit Name <commit@email.xx>' above:
+--
+Proper Name <proper@email.xx> CoMmIt NaMe <CoMmIt@EmAiL.xX>
+--
+
+EXAMPLES
+--------
+
+Your history contains commits by two authors, Jane
+and Joe, whose names appear in the repository under several forms:
+
+------------
+Joe Developer <joe@example.com>
+Joe R. Developer <joe@example.com>
+Jane Doe <jane@example.com>
+Jane Doe <jane@laptop.(none)>
+Jane D. <jane@desktop.(none)>
+------------
+
+Now suppose that Joe wants his middle name initial used, and Jane
+prefers her family name fully spelled out. A `.mailmap` file to
+correct the names would look like:
+
+------------
+Joe R. Developer <joe@example.com>
+Jane Doe <jane@example.com>
+Jane Doe <jane@desktop.(none)>
+------------
+
+Note that there's no need to map the name for 'jane@laptop.(none)' to
+only correct the names. However, leaving the obviously broken
+`<jane@laptop.(none)>' and '<jane@desktop.(none)>' E-Mails as-is is
+usually not what you want. A `.mailmap` file which also corrects those
+is:
+
+------------
+Joe R. Developer <joe@example.com>
+Jane Doe <jane@example.com> <jane@laptop.(none)>
+Jane Doe <jane@example.com> <jane@desktop.(none)>
+------------
+
+Finally, let's say that Joe and Jane shared an E-Mail address, but not
+a name, e.g. by having these two commits in the history generated by a
+bug reporting system. I.e. names appearing in history as:
+
+------------
+Joe <bugs@example.com>
+Jane <bugs@example.com>
+------------
+
+A full `.mailmap` file which also handles those cases (an addition of
+two lines to the above example) would be:
+
+------------
+Joe R. Developer <joe@example.com>
+Jane Doe <jane@example.com> <jane@laptop.(none)>
+Jane Doe <jane@example.com> <jane@desktop.(none)>
+Joe R. Developer <joe@example.com> Joe <bugs@example.com>
+Jane Doe <jane@example.com> Jane <bugs@example.com>
+------------
+
+
+
+SEE ALSO
+--------
+linkgit:git-check-mailmap[1]
+
+
+GIT
+---
+Part of the linkgit:git[1] suite
diff --git a/Documentation/mailmap.txt b/Documentation/mailmap.txt
deleted file mode 100644
index 4a8c276529..0000000000
--- a/Documentation/mailmap.txt
+++ /dev/null
@@ -1,75 +0,0 @@
-If the file `.mailmap` exists at the toplevel of the repository, or at
-the location pointed to by the mailmap.file or mailmap.blob
-configuration options, it
-is used to map author and committer names and email addresses to
-canonical real names and email addresses.
-
-In the simple form, each line in the file consists of the canonical
-real name of an author, whitespace, and an email address used in the
-commit (enclosed by '<' and '>') to map to the name. For example:
---
- Proper Name <commit@email.xx>
---
-
-The more complex forms are:
---
- <proper@email.xx> <commit@email.xx>
---
-which allows mailmap to replace only the email part of a commit, and:
---
- Proper Name <proper@email.xx> <commit@email.xx>
---
-which allows mailmap to replace both the name and the email of a
-commit matching the specified commit email address, and:
---
- Proper Name <proper@email.xx> Commit Name <commit@email.xx>
---
-which allows mailmap to replace both the name and the email of a
-commit matching both the specified commit name and email address.
-
-Example 1: Your history contains commits by two authors, Jane
-and Joe, whose names appear in the repository under several forms:
-
-------------
-Joe Developer <joe@example.com>
-Joe R. Developer <joe@example.com>
-Jane Doe <jane@example.com>
-Jane Doe <jane@laptop.(none)>
-Jane D. <jane@desktop.(none)>
-------------
-
-Now suppose that Joe wants his middle name initial used, and Jane
-prefers her family name fully spelled out. A proper `.mailmap` file
-would look like:
-
-------------
-Jane Doe <jane@desktop.(none)>
-Joe R. Developer <joe@example.com>
-------------
-
-Note how there is no need for an entry for `<jane@laptop.(none)>`, because the
-real name of that author is already correct.
-
-Example 2: Your repository contains commits from the following
-authors:
-
-------------
-nick1 <bugs@company.xx>
-nick2 <bugs@company.xx>
-nick2 <nick2@company.xx>
-santa <me@company.xx>
-claus <me@company.xx>
-CTO <cto@coompany.xx>
-------------
-
-Then you might want a `.mailmap` file that looks like:
-------------
-<cto@company.xx> <cto@coompany.xx>
-Some Dude <some@dude.xx> nick1 <bugs@company.xx>
-Other Author <other@author.xx> nick2 <bugs@company.xx>
-Other Author <other@author.xx> <nick2@company.xx>
-Santa Claus <santa.claus@northpole.xx> <me@company.xx>
-------------
-
-Use hash '#' for comments that are either on their own line, or after
-the email address.
diff --git a/builtin/blame.c b/builtin/blame.c
index 2c1c02c455..b66e938022 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -1151,7 +1151,7 @@ parse_done:
sb.xdl_opts = xdl_opts;
sb.no_whole_file_rename = no_whole_file_rename;
- read_mailmap(&mailmap, NULL);
+ read_mailmap(&mailmap);
sb.found_guilty_entry = &found_guilty_entry;
sb.found_guilty_entry_data = &pi;
diff --git a/builtin/check-mailmap.c b/builtin/check-mailmap.c
index cdce144f3b..7dc47e4793 100644
--- a/builtin/check-mailmap.c
+++ b/builtin/check-mailmap.c
@@ -47,7 +47,7 @@ int cmd_check_mailmap(int argc, const char **argv, const char *prefix)
if (argc == 0 && !use_stdin)
die(_("no contacts specified"));
- read_mailmap(&mailmap, NULL);
+ read_mailmap(&mailmap);
for (i = 0; i < argc; ++i)
check_mailmap(&mailmap, argv[i]);
diff --git a/builtin/commit.c b/builtin/commit.c
index 505fe60956..739110c5a7 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -1039,7 +1039,7 @@ static const char *find_author_by_nickname(const char *name)
av[++ac] = NULL;
setup_revisions(ac, av, &revs, NULL);
revs.mailmap = &mailmap;
- read_mailmap(revs.mailmap, NULL);
+ read_mailmap(revs.mailmap);
if (prepare_revision_walk(&revs))
die(_("revision walk setup failed"));
diff --git a/builtin/log.c b/builtin/log.c
index f23ccdbec3..fd282def43 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -230,7 +230,7 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix,
if (mailmap) {
rev->mailmap = xcalloc(1, sizeof(struct string_list));
- read_mailmap(rev->mailmap, NULL);
+ read_mailmap(rev->mailmap);
}
if (rev->pretty_given && rev->commit_format == CMIT_FMT_RAW) {
diff --git a/builtin/shortlog.c b/builtin/shortlog.c
index 1c0b3a9b05..3e7ab1ca82 100644
--- a/builtin/shortlog.c
+++ b/builtin/shortlog.c
@@ -61,8 +61,7 @@ static void insert_one_record(struct shortlog *log,
if (log->summary)
item->util = (void *)(UTIL_TO_INT(item) + 1);
else {
- const char *dot3 = log->common_repo_prefix;
- char *buffer, *p;
+ char *buffer;
struct strbuf subject = STRBUF_INIT;
const char *eol;
@@ -82,17 +81,6 @@ static void insert_one_record(struct shortlog *log,
format_subject(&subject, oneline, " ");
buffer = strbuf_detach(&subject, NULL);
- if (dot3) {
- int dot3len = strlen(dot3);
- if (dot3len > 5) {
- while ((p = strstr(buffer, dot3)) != NULL) {
- int taillen = strlen(p) - dot3len;
- memcpy(p, "/.../", 5);
- memmove(p + 5, p + dot3len, taillen + 1);
- }
- }
- }
-
if (item->util == NULL)
item->util = xcalloc(1, sizeof(struct string_list));
string_list_append(item->util, buffer);
@@ -342,7 +330,7 @@ void shortlog_init(struct shortlog *log)
{
memset(log, 0, sizeof(*log));
- read_mailmap(&log->mailmap, &log->common_repo_prefix);
+ read_mailmap(&log->mailmap);
log->list.strdup_strings = 1;
log->wrap = DEFAULT_WRAPLEN;
diff --git a/command-list.txt b/command-list.txt
index 9379b02e5e..a289f09ed6 100644
--- a/command-list.txt
+++ b/command-list.txt
@@ -204,6 +204,7 @@ gitfaq guide
gitglossary guide
githooks guide
gitignore guide
+gitmailmap guide
gitmodules guide
gitnamespaces guide
gitremote-helpers guide
diff --git a/mailmap.c b/mailmap.c
index 962fd86d6d..eb77c6e77c 100644
--- a/mailmap.c
+++ b/mailmap.c
@@ -143,31 +143,13 @@ static char *parse_name_and_email(char *buffer, char **name,
return (*right == '\0' ? NULL : right);
}
-static void read_mailmap_line(struct string_list *map, char *buffer,
- char **repo_abbrev)
+static void read_mailmap_line(struct string_list *map, char *buffer)
{
char *name1 = NULL, *email1 = NULL, *name2 = NULL, *email2 = NULL;
- if (buffer[0] == '#') {
- static const char abbrev[] = "# repo-abbrev:";
- int abblen = sizeof(abbrev) - 1;
- int len = strlen(buffer);
- if (!repo_abbrev)
- return;
-
- if (len && buffer[len - 1] == '\n')
- buffer[--len] = 0;
- if (!strncmp(buffer, abbrev, abblen)) {
- char *cp;
-
- free(*repo_abbrev);
-
- for (cp = buffer + abblen; isspace(*cp); cp++)
- ; /* nothing */
- *repo_abbrev = xstrdup(cp);
- }
+ if (buffer[0] == '#')
return;
- }
+
if ((name2 = parse_name_and_email(buffer, &name1, &email1, 0)) != NULL)
parse_name_and_email(name2, &name2, &email2, 1);
@@ -175,8 +157,7 @@ static void read_mailmap_line(struct string_list *map, char *buffer,
add_mapping(map, name1, email1, name2, email2);
}
-static int read_mailmap_file(struct string_list *map, const char *filename,
- char **repo_abbrev)
+static int read_mailmap_file(struct string_list *map, const char *filename)
{
char buffer[1024];
FILE *f;
@@ -192,13 +173,12 @@ static int read_mailmap_file(struct string_list *map, const char *filename,
}
while (fgets(buffer, sizeof(buffer), f) != NULL)
- read_mailmap_line(map, buffer, repo_abbrev);
+ read_mailmap_line(map, buffer);
fclose(f);
return 0;
}
-static void read_mailmap_string(struct string_list *map, char *buf,
- char **repo_abbrev)
+static void read_mailmap_string(struct string_list *map, char *buf)
{
while (*buf) {
char *end = strchrnul(buf, '\n');
@@ -206,14 +186,12 @@ static void read_mailmap_string(struct string_list *map, char *buf,
if (*end)
*end++ = '\0';
- read_mailmap_line(map, buf, repo_abbrev);
+ read_mailmap_line(map, buf);
buf = end;
}
}
-static int read_mailmap_blob(struct string_list *map,
- const char *name,
- char **repo_abbrev)
+static int read_mailmap_blob(struct string_list *map, const char *name)
{
struct object_id oid;
char *buf;
@@ -231,13 +209,13 @@ static int read_mailmap_blob(struct string_list *map,
if (type != OBJ_BLOB)
return error("mailmap is not a blob: %s", name);
- read_mailmap_string(map, buf, repo_abbrev);
+ read_mailmap_string(map, buf);
free(buf);
return 0;
}
-int read_mailmap(struct string_list *map, char **repo_abbrev)
+int read_mailmap(struct string_list *map)
{
int err = 0;
@@ -247,10 +225,10 @@ int read_mailmap(struct string_list *map, char **repo_abbrev)
if (!git_mailmap_blob && is_bare_repository())
git_mailmap_blob = "HEAD:.mailmap";
- err |= read_mailmap_file(map, ".mailmap", repo_abbrev);
+ err |= read_mailmap_file(map, ".mailmap");
if (startup_info->have_repository)
- err |= read_mailmap_blob(map, git_mailmap_blob, repo_abbrev);
- err |= read_mailmap_file(map, git_mailmap_file, repo_abbrev);
+ err |= read_mailmap_blob(map, git_mailmap_blob);
+ err |= read_mailmap_file(map, git_mailmap_file);
return err;
}
diff --git a/mailmap.h b/mailmap.h
index d0e65646cb..7e99fccb46 100644
--- a/mailmap.h
+++ b/mailmap.h
@@ -3,7 +3,7 @@
struct string_list;
-int read_mailmap(struct string_list *map, char **repo_abbrev);
+int read_mailmap(struct string_list *map);
void clear_mailmap(struct string_list *map);
int map_user(struct string_list *map,
diff --git a/pretty.c b/pretty.c
index 05eef7fda0..3922f6f9f2 100644
--- a/pretty.c
+++ b/pretty.c
@@ -679,7 +679,7 @@ static int mailmap_name(const char **email, size_t *email_len,
static struct string_list *mail_map;
if (!mail_map) {
mail_map = xcalloc(1, sizeof(*mail_map));
- read_mailmap(mail_map, NULL);
+ read_mailmap(mail_map);
}
return mail_map->nr && map_user(mail_map, email, email_len, name, name_len);
}
diff --git a/shortlog.h b/shortlog.h
index 64be879b24..3f7e9aabca 100644
--- a/shortlog.h
+++ b/shortlog.h
@@ -23,7 +23,6 @@ struct shortlog {
} groups;
struct string_list trailers;
- char *common_repo_prefix;
int email;
struct string_list mailmap;
FILE *file;
diff --git a/t/t1412-reflog-loop.sh b/t/t1412-reflog-loop.sh
index 3acd895afb..977603f7f1 100755
--- a/t/t1412-reflog-loop.sh
+++ b/t/t1412-reflog-loop.sh
@@ -4,11 +4,8 @@ test_description='reflog walk shows repeated commits again'
. ./test-lib.sh
test_expect_success 'setup commits' '
- test_tick &&
- echo content >file && git add file && git commit -m one &&
- git tag one &&
- echo content >>file && git add file && git commit -m two &&
- git tag two
+ test_commit one file content &&
+ test_commit --append two file content
'
test_expect_success 'setup reflog with alternating commits' '
diff --git a/t/t2012-checkout-last.sh b/t/t2012-checkout-last.sh
index 028a00d6ba..0e7d47ab31 100755
--- a/t/t2012-checkout-last.sh
+++ b/t/t2012-checkout-last.sh
@@ -8,13 +8,9 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
. ./test-lib.sh
test_expect_success 'setup' '
- echo hello >world &&
- git add world &&
- git commit -m initial &&
+ test_commit initial world hello &&
git branch other &&
- echo "hello again" >>world &&
- git add world &&
- git commit -m second
+ test_commit --append second world "hello again"
'
test_expect_success '"checkout -" does not work initially' '
@@ -96,9 +92,7 @@ test_expect_success 'switch to twelfth from the last' '
test_expect_success 'merge base test setup' '
git checkout -b another other &&
- echo "hello again" >>world &&
- git add world &&
- git commit -m third
+ test_commit --append third world "hello again"
'
test_expect_success 'another...main' '
diff --git a/t/t4203-mailmap.sh b/t/t4203-mailmap.sh
index 3f82c651b4..6fb18a34b0 100755
--- a/t/t4203-mailmap.sh
+++ b/t/t4203-mailmap.sh
@@ -7,28 +7,9 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
. ./test-lib.sh
-fuzz_blame () {
- sed "
- s/$_x05[0-9a-f][0-9a-f][0-9a-f]/OBJID/g
- s/$_x05[0-9a-f][0-9a-f]/OBJI/g
- s/[-0-9]\{10\} [:0-9]\{8\} [-+][0-9]\{4\}/DATE/g
- " "$@"
-}
-
-test_expect_success setup '
- cat >contacts <<- EOF &&
- $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>
- nick1 <bugs@company.xx>
- EOF
-
- echo one >one &&
- git add one &&
- test_tick &&
- git commit -m initial &&
- echo two >>one &&
- git add one &&
- test_tick &&
- git commit --author "nick1 <bugs@company.xx>" -m second
+test_expect_success 'setup commits and contacts file' '
+ test_commit initial one one &&
+ test_commit --author "nick1 <bugs@company.xx>" --append second one two
'
test_expect_success 'check-mailmap no arguments' '
@@ -36,7 +17,7 @@ test_expect_success 'check-mailmap no arguments' '
'
test_expect_success 'check-mailmap arguments' '
- cat >expect <<- EOF &&
+ cat >expect <<-EOF &&
$GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>
nick1 <bugs@company.xx>
EOF
@@ -47,150 +28,229 @@ test_expect_success 'check-mailmap arguments' '
'
test_expect_success 'check-mailmap --stdin' '
- cat >expect <<- EOF &&
+ cat >expect <<-EOF &&
$GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>
nick1 <bugs@company.xx>
EOF
- git check-mailmap --stdin <contacts >actual &&
+ git check-mailmap --stdin <expect >actual &&
test_cmp expect actual
'
-test_expect_success 'check-mailmap --stdin arguments' '
+test_expect_success 'check-mailmap --stdin arguments: no mapping' '
+ test_when_finished "rm contacts" &&
+ cat >contacts <<-EOF &&
+ $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>
+ nick1 <bugs@company.xx>
+ EOF
cat >expect <<-\EOF &&
Internal Guy <bugs@company.xy>
EOF
- cat <contacts >>expect &&
+ cat contacts >>expect &&
+
git check-mailmap --stdin "Internal Guy <bugs@company.xy>" \
<contacts >actual &&
test_cmp expect actual
'
+test_expect_success 'check-mailmap --stdin arguments: mapping' '
+ test_when_finished "rm .mailmap" &&
+ cat >.mailmap <<-EOF &&
+ New Name <$GIT_AUTHOR_EMAIL>
+ EOF
+ cat >stdin <<-EOF &&
+ Old Name <$GIT_AUTHOR_EMAIL>
+ EOF
+
+ cp .mailmap expect &&
+ git check-mailmap --stdin <stdin >actual &&
+ test_cmp expect actual &&
+
+ cat .mailmap >>expect &&
+ git check-mailmap --stdin "Another Old Name <$GIT_AUTHOR_EMAIL>" \
+ <stdin >actual &&
+ test_cmp expect actual
+'
+
test_expect_success 'check-mailmap bogus contact' '
test_must_fail git check-mailmap bogus
'
-cat >expect << EOF
-$GIT_AUTHOR_NAME (1):
- initial
+test_expect_success 'check-mailmap bogus contact --stdin' '
+ test_must_fail git check-mailmap --stdin bogus </dev/null
+'
-nick1 (1):
- second
+test_expect_success 'No mailmap' '
+ cat >expect <<-EOF &&
+ $GIT_AUTHOR_NAME (1):
+ initial
-EOF
+ nick1 (1):
+ second
-test_expect_success 'No mailmap' '
+ EOF
git shortlog HEAD >actual &&
test_cmp expect actual
'
-cat >expect <<\EOF
-Repo Guy (1):
- initial
+test_expect_success 'setup default .mailmap' '
+ cat >default.map <<-EOF
+ Repo Guy <$GIT_AUTHOR_EMAIL>
+ EOF
+'
-nick1 (1):
- second
+test_expect_success 'test default .mailmap' '
+ test_when_finished "rm .mailmap" &&
+ cp default.map .mailmap &&
-EOF
+ cat >expect <<-\EOF &&
+ Repo Guy (1):
+ initial
+
+ nick1 (1):
+ second
-test_expect_success 'default .mailmap' '
- echo "Repo Guy <$GIT_AUTHOR_EMAIL>" > .mailmap &&
+ EOF
git shortlog HEAD >actual &&
test_cmp expect actual
'
-# Using a mailmap file in a subdirectory of the repo here, but
-# could just as well have been a file outside of the repository
-cat >expect <<\EOF
-Internal Guy (1):
- second
+test_expect_success 'mailmap.file set' '
+ test_when_finished "rm .mailmap" &&
+ cp default.map .mailmap &&
-Repo Guy (1):
- initial
+ test_config mailmap.file internal.map &&
+ cat >internal.map <<-\EOF &&
+ Internal Guy <bugs@company.xx>
+ EOF
-EOF
-test_expect_success 'mailmap.file set' '
- mkdir -p internal_mailmap &&
- echo "Internal Guy <bugs@company.xx>" > internal_mailmap/.mailmap &&
- git config mailmap.file internal_mailmap/.mailmap &&
+ cat >expect <<-\EOF &&
+ Internal Guy (1):
+ second
+
+ Repo Guy (1):
+ initial
+
+ EOF
git shortlog HEAD >actual &&
- test_cmp expect actual
+ test_cmp expect actual &&
+
+ # The internal_mailmap/.mailmap file is an a subdirectory, but
+ # as shown here it can also be outside the repository
+ test_when_finished "rm -rf sub-repo" &&
+ git clone . sub-repo &&
+ (
+ cd sub-repo &&
+ cp ../.mailmap . &&
+ git config mailmap.file ../internal.map &&
+ git shortlog HEAD >actual &&
+ test_cmp ../expect actual
+ )
'
-cat >expect <<\EOF
-External Guy (1):
- initial
+test_expect_success 'mailmap.file override' '
+ test_config mailmap.file internal.map &&
+ cat >internal.map <<-EOF &&
+ Internal Guy <bugs@company.xx>
+ External Guy <$GIT_AUTHOR_EMAIL>
+ EOF
-Internal Guy (1):
- second
+ cat >expect <<-\EOF &&
+ External Guy (1):
+ initial
-EOF
-test_expect_success 'mailmap.file override' '
- echo "External Guy <$GIT_AUTHOR_EMAIL>" >> internal_mailmap/.mailmap &&
- git config mailmap.file internal_mailmap/.mailmap &&
+ Internal Guy (1):
+ second
+
+ EOF
git shortlog HEAD >actual &&
test_cmp expect actual
'
-cat >expect <<\EOF
-Repo Guy (1):
- initial
+test_expect_success 'mailmap.file non-existent' '
+ test_when_finished "rm .mailmap" &&
+ cp default.map .mailmap &&
-nick1 (1):
- second
+ cat >expect <<-\EOF &&
+ Repo Guy (1):
+ initial
-EOF
+ nick1 (1):
+ second
-test_expect_success 'mailmap.file non-existent' '
- rm internal_mailmap/.mailmap &&
- rmdir internal_mailmap &&
+ EOF
git shortlog HEAD >actual &&
test_cmp expect actual
'
-cat >expect <<\EOF
-Internal Guy (1):
- second
+test_expect_success 'name entry after email entry' '
+ test_when_finished "rm .mailmap" &&
+ cp default.map .mailmap &&
+
+ test_config mailmap.file internal.map &&
+ cat >internal.map <<-\EOF &&
+ <bugs@company.xy> <bugs@company.xx>
+ Internal Guy <bugs@company.xx>
+ EOF
-Repo Guy (1):
- initial
+ cat >expect <<-\EOF &&
+ Internal Guy (1):
+ second
-EOF
+ Repo Guy (1):
+ initial
+
+ EOF
-test_expect_success 'name entry after email entry' '
- mkdir -p internal_mailmap &&
- echo "<bugs@company.xy> <bugs@company.xx>" >internal_mailmap/.mailmap &&
- echo "Internal Guy <bugs@company.xx>" >>internal_mailmap/.mailmap &&
git shortlog HEAD >actual &&
test_cmp expect actual
'
-cat >expect <<\EOF
-Internal Guy (1):
- second
+test_expect_success 'name entry after email entry, case-insensitive' '
+ test_when_finished "rm .mailmap" &&
+ cp default.map .mailmap &&
-Repo Guy (1):
- initial
+ test_config mailmap.file internal.map &&
+ cat >internal.map <<-\EOF &&
+ <bugs@company.xy> <bugs@company.xx>
+ Internal Guy <BUGS@Company.xx>
+ EOF
-EOF
+ cat >expect <<-\EOF &&
+ Internal Guy (1):
+ second
-test_expect_success 'name entry after email entry, case-insensitive' '
- mkdir -p internal_mailmap &&
- echo "<bugs@company.xy> <bugs@company.xx>" >internal_mailmap/.mailmap &&
- echo "Internal Guy <BUGS@Company.xx>" >>internal_mailmap/.mailmap &&
+ Repo Guy (1):
+ initial
+
+ EOF
+ git shortlog HEAD >actual &&
+ test_cmp expect actual &&
+
+ cat >internal.map <<-\EOF &&
+ NiCk <BuGs@CoMpAnY.Xy> NICK1 <BUGS@COMPANY.XX>
+ EOF
+
+ cat >expect <<-\EOF &&
+ NiCk (1):
+ second
+
+ Repo Guy (1):
+ initial
+
+ EOF
git shortlog HEAD >actual &&
test_cmp expect actual
'
-cat >expect << EOF
-$GIT_AUTHOR_NAME (1):
- initial
+test_expect_success 'No mailmap files, but configured' '
+ cat >expect <<-EOF &&
+ $GIT_AUTHOR_NAME (1):
+ initial
-nick1 (1):
- second
+ nick1 (1):
+ second
-EOF
-test_expect_success 'No mailmap files, but configured' '
- rm -f .mailmap internal_mailmap/.mailmap &&
+ EOF
git shortlog HEAD >actual &&
test_cmp expect actual
'
@@ -198,21 +258,26 @@ test_expect_success 'No mailmap files, but configured' '
test_expect_success 'setup mailmap blob tests' '
git checkout -b map &&
test_when_finished "git checkout main" &&
- cat >just-bugs <<- EOF &&
+ cat >just-bugs <<-\EOF &&
Blob Guy <bugs@company.xx>
EOF
- cat >both <<- EOF &&
+ cat >both <<-EOF &&
Blob Guy <$GIT_AUTHOR_EMAIL>
Blob Guy <bugs@company.xx>
EOF
printf "Tricky Guy <$GIT_AUTHOR_EMAIL>" >no-newline &&
git add just-bugs both no-newline &&
git commit -m "my mailmaps" &&
- echo "Repo Guy <$GIT_AUTHOR_EMAIL>" >.mailmap &&
- echo "Internal Guy <$GIT_AUTHOR_EMAIL>" >internal.map
+
+ cat >internal.map <<-EOF
+ Internal Guy <$GIT_AUTHOR_EMAIL>
+ EOF
'
test_expect_success 'mailmap.blob set' '
+ test_when_finished "rm .mailmap" &&
+ cp default.map .mailmap &&
+
cat >expect <<-\EOF &&
Blob Guy (1):
second
@@ -226,6 +291,9 @@ test_expect_success 'mailmap.blob set' '
'
test_expect_success 'mailmap.blob overrides .mailmap' '
+ test_when_finished "rm .mailmap" &&
+ cp default.map .mailmap &&
+
cat >expect <<-\EOF &&
Blob Guy (2):
initial
@@ -252,7 +320,28 @@ test_expect_success 'mailmap.file overrides mailmap.blob' '
test_cmp expect actual
'
+test_expect_success 'mailmap.file can be missing' '
+ test_when_finished "rm .mailmap" &&
+ cp default.map .mailmap &&
+
+ test_config mailmap.file nonexistent &&
+ cat >expect <<-\EOF &&
+ Repo Guy (1):
+ initial
+
+ nick1 (1):
+ second
+
+ EOF
+ git shortlog HEAD >actual 2>err &&
+ test_must_be_empty err &&
+ test_cmp expect actual
+'
+
test_expect_success 'mailmap.blob can be missing' '
+ test_when_finished "rm .mailmap" &&
+ cp default.map .mailmap &&
+
cat >expect <<-\EOF &&
Repo Guy (1):
initial
@@ -261,7 +350,17 @@ test_expect_success 'mailmap.blob can be missing' '
second
EOF
- git -c mailmap.blob=map:nonexistent shortlog HEAD >actual &&
+ git -c mailmap.blob=map:nonexistent shortlog HEAD >actual 2>err &&
+ test_must_be_empty err &&
+ test_cmp expect actual
+'
+
+test_expect_success 'mailmap.blob might be the wrong type' '
+ test_when_finished "rm .mailmap" &&
+ cp default.map .mailmap &&
+
+ git -c mailmap.blob=HEAD: shortlog HEAD >actual 2>err &&
+ test_i18ngrep "mailmap is not a blob" err &&
test_cmp expect actual
'
@@ -270,11 +369,15 @@ test_expect_success 'mailmap.blob defaults to off in non-bare repo' '
(
cd non-bare &&
test_commit one .mailmap "Fake Name <$GIT_AUTHOR_EMAIL>" &&
- echo " 1 Fake Name" >expect &&
+ cat >expect <<-\EOF &&
+ 1 Fake Name
+ EOF
git shortlog -ns HEAD >actual &&
test_cmp expect actual &&
rm .mailmap &&
- echo " 1 $GIT_AUTHOR_NAME" >expect &&
+ cat >expect <<-EOF &&
+ 1 $GIT_AUTHOR_NAME
+ EOF
git shortlog -ns HEAD >actual &&
test_cmp expect actual
)
@@ -284,7 +387,9 @@ test_expect_success 'mailmap.blob defaults to HEAD:.mailmap in bare repo' '
git clone --bare non-bare bare &&
(
cd bare &&
- echo " 1 Fake Name" >expect &&
+ cat >expect <<-\EOF &&
+ 1 Fake Name
+ EOF
git shortlog -ns HEAD >actual &&
test_cmp expect actual
)
@@ -303,178 +408,258 @@ test_expect_success 'mailmap.blob can handle blobs without trailing newline' '
test_cmp expect actual
'
-test_expect_success 'cleanup after mailmap.blob tests' '
- rm -f .mailmap
-'
-
test_expect_success 'single-character name' '
- echo " 1 A <$GIT_AUTHOR_EMAIL>" >expect &&
- echo " 1 nick1 <bugs@company.xx>" >>expect &&
- echo "A <$GIT_AUTHOR_EMAIL>" >.mailmap &&
test_when_finished "rm .mailmap" &&
+ cat >.mailmap <<-EOF &&
+ A <$GIT_AUTHOR_EMAIL>
+ EOF
+
+ cat >expect <<-EOF &&
+ 1 A <$GIT_AUTHOR_EMAIL>
+ 1 nick1 <bugs@company.xx>
+ EOF
git shortlog -es HEAD >actual &&
test_cmp expect actual
'
test_expect_success 'preserve canonical email case' '
- echo " 1 $GIT_AUTHOR_NAME <AUTHOR@example.com>" >expect &&
- echo " 1 nick1 <bugs@company.xx>" >>expect &&
- echo "<AUTHOR@example.com> <$GIT_AUTHOR_EMAIL>" >.mailmap &&
test_when_finished "rm .mailmap" &&
+ cat >.mailmap <<-EOF &&
+ <AUTHOR@example.com> <$GIT_AUTHOR_EMAIL>
+ EOF
+
+ cat >expect <<-EOF &&
+ 1 $GIT_AUTHOR_NAME <AUTHOR@example.com>
+ 1 nick1 <bugs@company.xx>
+ EOF
git shortlog -es HEAD >actual &&
test_cmp expect actual
'
-# Extended mailmap configurations should give us the following output for shortlog
-cat >expect << EOF
-$GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL> (1):
- initial
+test_expect_success 'gitmailmap(5) example output: setup' '
+ test_create_repo doc &&
+ test_commit -C doc --author "Joe Developer <joe@example.com>" A &&
+ test_commit -C doc --author "Joe R. Developer <joe@example.com>" B &&
+ test_commit -C doc --author "Jane Doe <jane@example.com>" C &&
+ test_commit -C doc --author "Jane Doe <jane@laptop.(none)>" D &&
+ test_commit -C doc --author "Jane D. <jane@desktop.(none)>" E
+'
+
+test_expect_success 'gitmailmap(5) example output: example #1' '
+ test_config -C doc mailmap.file ../doc.map &&
+ cat >doc.map <<-\EOF &&
+ Joe R. Developer <joe@example.com>
+ Jane Doe <jane@example.com>
+ Jane Doe <jane@desktop.(none)>
+ EOF
+
+ cat >expect <<-\EOF &&
+ Author Joe Developer <joe@example.com> maps to Joe R. Developer <joe@example.com>
+ Committer C O Mitter <committer@example.com> maps to C O Mitter <committer@example.com>
+
+ Author Joe R. Developer <joe@example.com> maps to Joe R. Developer <joe@example.com>
+ Committer C O Mitter <committer@example.com> maps to C O Mitter <committer@example.com>
+
+ Author Jane Doe <jane@example.com> maps to Jane Doe <jane@example.com>
+ Committer C O Mitter <committer@example.com> maps to C O Mitter <committer@example.com>
+
+ Author Jane Doe <jane@laptop.(none)> maps to Jane Doe <jane@laptop.(none)>
+ Committer C O Mitter <committer@example.com> maps to C O Mitter <committer@example.com>
+
+ Author Jane D <jane@desktop.(none)> maps to Jane Doe <jane@desktop.(none)>
+ Committer C O Mitter <committer@example.com> maps to C O Mitter <committer@example.com>
+ EOF
+ git -C doc log --reverse --pretty=format:"Author %an <%ae> maps to %aN <%aE>%nCommitter %cn <%ce> maps to %cN <%cE>%n" >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'gitmailmap(5) example output: example #2' '
+ test_config -C doc mailmap.file ../doc.map &&
+ cat >doc.map <<-\EOF &&
+ Joe R. Developer <joe@example.com>
+ Jane Doe <jane@example.com> <jane@laptop.(none)>
+ Jane Doe <jane@example.com> <jane@desktop.(none)>
+ EOF
+
+ cat >expect <<-\EOF &&
+ Author Joe Developer <joe@example.com> maps to Joe R. Developer <joe@example.com>
+ Committer C O Mitter <committer@example.com> maps to C O Mitter <committer@example.com>
+
+ Author Joe R. Developer <joe@example.com> maps to Joe R. Developer <joe@example.com>
+ Committer C O Mitter <committer@example.com> maps to C O Mitter <committer@example.com>
+
+ Author Jane Doe <jane@example.com> maps to Jane Doe <jane@example.com>
+ Committer C O Mitter <committer@example.com> maps to C O Mitter <committer@example.com>
+
+ Author Jane Doe <jane@laptop.(none)> maps to Jane Doe <jane@example.com>
+ Committer C O Mitter <committer@example.com> maps to C O Mitter <committer@example.com>
+
+ Author Jane D <jane@desktop.(none)> maps to Jane Doe <jane@example.com>
+ Committer C O Mitter <committer@example.com> maps to C O Mitter <committer@example.com>
+ EOF
+ git -C doc log --reverse --pretty=format:"Author %an <%ae> maps to %aN <%aE>%nCommitter %cn <%ce> maps to %cN <%cE>%n" >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'gitmailmap(5) example output: example #3' '
+ test_config -C doc mailmap.file ../doc.map &&
+ cat >>doc.map <<-\EOF &&
+ Joe R. Developer <joe@example.com> Joe <bugs@example.com>
+ Jane Doe <jane@example.com> Jane <bugs@example.com>
+ EOF
-CTO <cto@company.xx> (1):
- seventh
+ test_commit -C doc --author "Joe <bugs@example.com>" F &&
+ test_commit -C doc --author "Jane <bugs@example.com>" G &&
-Other Author <other@author.xx> (2):
- third
- fourth
+ cat >>expect <<-\EOF &&
-Santa Claus <santa.claus@northpole.xx> (2):
- fifth
- sixth
+ Author Joe <bugs@example.com> maps to Joe R. Developer <joe@example.com>
+ Committer C O Mitter <committer@example.com> maps to C O Mitter <committer@example.com>
-Some Dude <some@dude.xx> (1):
- second
+ Author Jane <bugs@example.com> maps to Jane Doe <jane@example.com>
+ Committer C O Mitter <committer@example.com> maps to C O Mitter <committer@example.com>
+ EOF
+ git -C doc log --reverse --pretty=format:"Author %an <%ae> maps to %aN <%aE>%nCommitter %cn <%ce> maps to %cN <%cE>%n" >actual &&
+ test_cmp expect actual
+'
-EOF
test_expect_success 'Shortlog output (complex mapping)' '
- echo three >>one &&
- git add one &&
- test_tick &&
- git commit --author "nick2 <bugs@company.xx>" -m third &&
-
- echo four >>one &&
- git add one &&
- test_tick &&
- git commit --author "nick2 <nick2@company.xx>" -m fourth &&
-
- echo five >>one &&
- git add one &&
- test_tick &&
- git commit --author "santa <me@company.xx>" -m fifth &&
-
- echo six >>one &&
- git add one &&
- test_tick &&
- git commit --author "claus <me@company.xx>" -m sixth &&
-
- echo seven >>one &&
- git add one &&
- test_tick &&
- git commit --author "CTO <cto@coompany.xx>" -m seventh &&
-
- mkdir -p internal_mailmap &&
- echo "Committed <$GIT_COMMITTER_EMAIL>" > internal_mailmap/.mailmap &&
- echo "<cto@company.xx> <cto@coompany.xx>" >> internal_mailmap/.mailmap &&
- echo "Some Dude <some@dude.xx> nick1 <bugs@company.xx>" >> internal_mailmap/.mailmap &&
- echo "Other Author <other@author.xx> nick2 <bugs@company.xx>" >> internal_mailmap/.mailmap &&
- echo "Other Author <other@author.xx> <nick2@company.xx>" >> internal_mailmap/.mailmap &&
- echo "Santa Claus <santa.claus@northpole.xx> <me@company.xx>" >> internal_mailmap/.mailmap &&
- echo "Santa Claus <santa.claus@northpole.xx> <me@company.xx>" >> internal_mailmap/.mailmap &&
+ test_config mailmap.file complex.map &&
+ cat >complex.map <<-EOF &&
+ Committed <$GIT_COMMITTER_EMAIL>
+ <cto@company.xx> <cto@coompany.xx>
+ Some Dude <some@dude.xx> nick1 <bugs@company.xx>
+ Other Author <other@author.xx> nick2 <bugs@company.xx>
+ Other Author <other@author.xx> <nick2@company.xx>
+ Santa Claus <santa.claus@northpole.xx> <me@company.xx>
+ EOF
+
+ test_commit --author "nick2 <bugs@company.xx>" --append third one three &&
+ test_commit --author "nick2 <nick2@company.xx>" --append fourth one four &&
+ test_commit --author "santa <me@company.xx>" --append fifth one five &&
+ test_commit --author "claus <me@company.xx>" --append sixth one six &&
+ test_commit --author "CTO <cto@coompany.xx>" --append seventh one seven &&
+
+ cat >expect <<-EOF &&
+ $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL> (1):
+ initial
+
+ CTO <cto@company.xx> (1):
+ seventh
+
+ Other Author <other@author.xx> (2):
+ third
+ fourth
+
+ Santa Claus <santa.claus@northpole.xx> (2):
+ fifth
+ sixth
+
+ Some Dude <some@dude.xx> (1):
+ second
+
+ EOF
git shortlog -e HEAD >actual &&
test_cmp expect actual
'
-# git log with --pretty format which uses the name and email mailmap placemarkers
-cat >expect << EOF
-Author CTO <cto@coompany.xx> maps to CTO <cto@company.xx>
-Committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> maps to Committed <$GIT_COMMITTER_EMAIL>
+test_expect_success 'Log output (complex mapping)' '
+ test_config mailmap.file complex.map &&
-Author claus <me@company.xx> maps to Santa Claus <santa.claus@northpole.xx>
-Committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> maps to Committed <$GIT_COMMITTER_EMAIL>
+ cat >expect <<-EOF &&
+ Author CTO <cto@coompany.xx> maps to CTO <cto@company.xx>
+ Committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> maps to Committed <$GIT_COMMITTER_EMAIL>
-Author santa <me@company.xx> maps to Santa Claus <santa.claus@northpole.xx>
-Committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> maps to Committed <$GIT_COMMITTER_EMAIL>
+ Author claus <me@company.xx> maps to Santa Claus <santa.claus@northpole.xx>
+ Committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> maps to Committed <$GIT_COMMITTER_EMAIL>
-Author nick2 <nick2@company.xx> maps to Other Author <other@author.xx>
-Committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> maps to Committed <$GIT_COMMITTER_EMAIL>
+ Author santa <me@company.xx> maps to Santa Claus <santa.claus@northpole.xx>
+ Committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> maps to Committed <$GIT_COMMITTER_EMAIL>
-Author nick2 <bugs@company.xx> maps to Other Author <other@author.xx>
-Committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> maps to Committed <$GIT_COMMITTER_EMAIL>
+ Author nick2 <nick2@company.xx> maps to Other Author <other@author.xx>
+ Committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> maps to Committed <$GIT_COMMITTER_EMAIL>
-Author nick1 <bugs@company.xx> maps to Some Dude <some@dude.xx>
-Committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> maps to Committed <$GIT_COMMITTER_EMAIL>
+ Author nick2 <bugs@company.xx> maps to Other Author <other@author.xx>
+ Committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> maps to Committed <$GIT_COMMITTER_EMAIL>
-Author $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL> maps to $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>
-Committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> maps to Committed <$GIT_COMMITTER_EMAIL>
-EOF
+ Author nick1 <bugs@company.xx> maps to Some Dude <some@dude.xx>
+ Committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> maps to Committed <$GIT_COMMITTER_EMAIL>
+
+ Author $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL> maps to $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>
+ Committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> maps to Committed <$GIT_COMMITTER_EMAIL>
+ EOF
-test_expect_success 'Log output (complex mapping)' '
git log --pretty=format:"Author %an <%ae> maps to %aN <%aE>%nCommitter %cn <%ce> maps to %cN <%cE>%n" >actual &&
test_cmp expect actual
'
-cat >expect << EOF
-Author email cto@coompany.xx has local-part cto
-Committer email $GIT_COMMITTER_EMAIL has local-part $TEST_COMMITTER_LOCALNAME
+test_expect_success 'Log output (local-part email address)' '
+ cat >expect <<-EOF &&
+ Author email cto@coompany.xx has local-part cto
+ Committer email $GIT_COMMITTER_EMAIL has local-part $TEST_COMMITTER_LOCALNAME
-Author email me@company.xx has local-part me
-Committer email $GIT_COMMITTER_EMAIL has local-part $TEST_COMMITTER_LOCALNAME
+ Author email me@company.xx has local-part me
+ Committer email $GIT_COMMITTER_EMAIL has local-part $TEST_COMMITTER_LOCALNAME
-Author email me@company.xx has local-part me
-Committer email $GIT_COMMITTER_EMAIL has local-part $TEST_COMMITTER_LOCALNAME
+ Author email me@company.xx has local-part me
+ Committer email $GIT_COMMITTER_EMAIL has local-part $TEST_COMMITTER_LOCALNAME
-Author email nick2@company.xx has local-part nick2
-Committer email $GIT_COMMITTER_EMAIL has local-part $TEST_COMMITTER_LOCALNAME
+ Author email nick2@company.xx has local-part nick2
+ Committer email $GIT_COMMITTER_EMAIL has local-part $TEST_COMMITTER_LOCALNAME
-Author email bugs@company.xx has local-part bugs
-Committer email $GIT_COMMITTER_EMAIL has local-part $TEST_COMMITTER_LOCALNAME
+ Author email bugs@company.xx has local-part bugs
+ Committer email $GIT_COMMITTER_EMAIL has local-part $TEST_COMMITTER_LOCALNAME
-Author email bugs@company.xx has local-part bugs
-Committer email $GIT_COMMITTER_EMAIL has local-part $TEST_COMMITTER_LOCALNAME
+ Author email bugs@company.xx has local-part bugs
+ Committer email $GIT_COMMITTER_EMAIL has local-part $TEST_COMMITTER_LOCALNAME
-Author email author@example.com has local-part author
-Committer email $GIT_COMMITTER_EMAIL has local-part $TEST_COMMITTER_LOCALNAME
-EOF
+ Author email author@example.com has local-part author
+ Committer email $GIT_COMMITTER_EMAIL has local-part $TEST_COMMITTER_LOCALNAME
+ EOF
-test_expect_success 'Log output (local-part email address)' '
git log --pretty=format:"Author email %ae has local-part %al%nCommitter email %ce has local-part %cl%n" >actual &&
test_cmp expect actual
'
-cat >expect << EOF
-Author: CTO <cto@company.xx>
-Author: Santa Claus <santa.claus@northpole.xx>
-Author: Santa Claus <santa.claus@northpole.xx>
-Author: Other Author <other@author.xx>
-Author: Other Author <other@author.xx>
-Author: Some Dude <some@dude.xx>
-Author: $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>
-EOF
-
test_expect_success 'Log output with --use-mailmap' '
+ test_config mailmap.file complex.map &&
+
+ cat >expect <<-EOF &&
+ Author: CTO <cto@company.xx>
+ Author: Santa Claus <santa.claus@northpole.xx>
+ Author: Santa Claus <santa.claus@northpole.xx>
+ Author: Other Author <other@author.xx>
+ Author: Other Author <other@author.xx>
+ Author: Some Dude <some@dude.xx>
+ Author: $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>
+ EOF
+
git log --use-mailmap | grep Author >actual &&
test_cmp expect actual
'
-cat >expect << EOF
-Author: CTO <cto@company.xx>
-Author: Santa Claus <santa.claus@northpole.xx>
-Author: Santa Claus <santa.claus@northpole.xx>
-Author: Other Author <other@author.xx>
-Author: Other Author <other@author.xx>
-Author: Some Dude <some@dude.xx>
-Author: $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>
-EOF
-
test_expect_success 'Log output with log.mailmap' '
+ test_config mailmap.file complex.map &&
+
+ cat >expect <<-EOF &&
+ Author: CTO <cto@company.xx>
+ Author: Santa Claus <santa.claus@northpole.xx>
+ Author: Santa Claus <santa.claus@northpole.xx>
+ Author: Other Author <other@author.xx>
+ Author: Other Author <other@author.xx>
+ Author: Some Dude <some@dude.xx>
+ Author: $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>
+ EOF
+
git -c log.mailmap=True log | grep Author >actual &&
test_cmp expect actual
'
test_expect_success 'log.mailmap=false disables mailmap' '
- cat >expect <<- EOF &&
+ cat >expect <<-EOF &&
Author: CTO <cto@coompany.xx>
Author: claus <me@company.xx>
Author: santa <me@company.xx>
@@ -483,12 +668,12 @@ test_expect_success 'log.mailmap=false disables mailmap' '
Author: nick1 <bugs@company.xx>
Author: $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>
EOF
- git -c log.mailmap=False log | grep Author > actual &&
+ git -c log.mailmap=false log | grep Author >actual &&
test_cmp expect actual
'
test_expect_success '--no-use-mailmap disables mailmap' '
- cat >expect <<- EOF &&
+ cat >expect <<-EOF &&
Author: CTO <cto@coompany.xx>
Author: claus <me@company.xx>
Author: santa <me@company.xx>
@@ -501,60 +686,200 @@ test_expect_success '--no-use-mailmap disables mailmap' '
test_cmp expect actual
'
-cat >expect <<\EOF
-Author: Santa Claus <santa.claus@northpole.xx>
-Author: Santa Claus <santa.claus@northpole.xx>
-EOF
-
test_expect_success 'Grep author with --use-mailmap' '
+ test_config mailmap.file complex.map &&
+
+ cat >expect <<-\EOF &&
+ Author: Santa Claus <santa.claus@northpole.xx>
+ Author: Santa Claus <santa.claus@northpole.xx>
+ EOF
git log --use-mailmap --author Santa | grep Author >actual &&
test_cmp expect actual
'
-cat >expect <<\EOF
-Author: Santa Claus <santa.claus@northpole.xx>
-Author: Santa Claus <santa.claus@northpole.xx>
-EOF
test_expect_success 'Grep author with log.mailmap' '
+ test_config mailmap.file complex.map &&
+
+ cat >expect <<-\EOF &&
+ Author: Santa Claus <santa.claus@northpole.xx>
+ Author: Santa Claus <santa.claus@northpole.xx>
+ EOF
+
git -c log.mailmap=True log --author Santa | grep Author >actual &&
test_cmp expect actual
'
test_expect_success 'log.mailmap is true by default these days' '
+ test_config mailmap.file complex.map &&
git log --author Santa | grep Author >actual &&
test_cmp expect actual
'
test_expect_success 'Only grep replaced author with --use-mailmap' '
+ test_config mailmap.file complex.map &&
git log --use-mailmap --author "<cto@coompany.xx>" >actual &&
test_must_be_empty actual
'
-# git blame
-cat >expect <<EOF
-^OBJI ($GIT_AUTHOR_NAME DATE 1) one
-OBJID (Some Dude DATE 2) two
-OBJID (Other Author DATE 3) three
-OBJID (Other Author DATE 4) four
-OBJID (Santa Claus DATE 5) five
-OBJID (Santa Claus DATE 6) six
-OBJID (CTO DATE 7) seven
-EOF
-test_expect_success 'Blame output (complex mapping)' '
- git blame one >actual &&
- fuzz_blame actual >actual.fuzz &&
+test_expect_success 'Blame --porcelain output (complex mapping)' '
+ test_config mailmap.file complex.map &&
+
+ cat >expect <<-EOF &&
+ 1 1 1
+ A U Thor
+ 2 2 1
+ Some Dude
+ 3 3 1
+ Other Author
+ 4 4 1
+ Other Author
+ 5 5 1
+ Santa Claus
+ 6 6 1
+ Santa Claus
+ 7 7 1
+ CTO
+ EOF
+
+ git blame --porcelain one >actual.blame &&
+ grep -E \
+ -e "[0-9]+ [0-9]+ [0-9]+$" \
+ -e "^author .*$" \
+ actual.blame >actual.grep &&
+ cut -d " " -f2-4 <actual.grep >actual.fuzz &&
test_cmp expect actual.fuzz
'
-cat >expect <<\EOF
-Some Dude <some@dude.xx>
-EOF
+test_expect_success 'Blame output (complex mapping)' '
+ git -c mailmap.file=complex.map blame one >a &&
+ git blame one >b &&
+ test_file_not_empty a &&
+ ! cmp a b
+'
test_expect_success 'commit --author honors mailmap' '
+ test_config mailmap.file complex.map &&
+
+ cat >expect <<-\EOF &&
+ Some Dude <some@dude.xx>
+ EOF
+
test_must_fail git commit --author "nick" --allow-empty -meight &&
git commit --author "Some Dude" --allow-empty -meight &&
git show --pretty=format:"%an <%ae>%n" >actual &&
test_cmp expect actual
'
+test_expect_success 'comment syntax: setup' '
+ test_create_repo comm &&
+ test_commit -C comm --author "A <a@example.com>" A &&
+ test_commit -C comm --author "B <b@example.com>" B &&
+ test_commit -C comm --author "C <#@example.com>" C &&
+ test_commit -C comm --author "D <d@e#ample.com>" D &&
+
+ test_config -C comm mailmap.file ../doc.map &&
+ cat >>doc.map <<-\EOF &&
+ # Ah <a@example.com>
+
+ ; Bee <b@example.com>
+ Cee <cee@example.com> <#@example.com>
+ Dee <dee@example.com> <d@e#ample.com>
+ EOF
+
+ cat >expect <<-\EOF &&
+ Author A <a@example.com> maps to A <a@example.com>
+ Committer C O Mitter <committer@example.com> maps to C O Mitter <committer@example.com>
+
+ Author B <b@example.com> maps to ; Bee <b@example.com>
+ Committer C O Mitter <committer@example.com> maps to C O Mitter <committer@example.com>
+
+ Author C <#@example.com> maps to Cee <cee@example.com>
+ Committer C O Mitter <committer@example.com> maps to C O Mitter <committer@example.com>
+
+ Author D <d@e#ample.com> maps to Dee <dee@example.com>
+ Committer C O Mitter <committer@example.com> maps to C O Mitter <committer@example.com>
+ EOF
+ git -C comm log --reverse --pretty=format:"Author %an <%ae> maps to %aN <%aE>%nCommitter %cn <%ce> maps to %cN <%cE>%n" >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'whitespace syntax: setup' '
+ test_create_repo space &&
+ test_commit -C space --author "A <a@example.com>" A &&
+ test_commit -C space --author "B <b@example.com>" B &&
+ test_commit -C space --author " C <c@example.com>" C &&
+ test_commit -C space --author " D <d@example.com>" D &&
+ test_commit -C space --author "E E <e@example.com>" E &&
+ test_commit -C space --author "F F <f@example.com>" F &&
+ test_commit -C space --author "G G <g@example.com>" G &&
+ test_commit -C space --author "H H <h@example.com>" H &&
+
+ test_config -C space mailmap.file ../space.map &&
+ cat >>space.map <<-\EOF &&
+ Ah <ah@example.com> < a@example.com >
+ Bee <bee@example.com > < b@example.com >
+ Cee <cee@example.com> C <c@example.com>
+ dee <dee@example.com> D <d@example.com>
+ eee <eee@example.com> E E <e@example.com>
+ eff <eff@example.com> F F <f@example.com>
+ gee <gee@example.com> G G <g@example.com>
+ aitch <aitch@example.com> H H <h@example.com>
+ EOF
+
+ cat >expect <<-\EOF &&
+ Author A <a@example.com> maps to A <a@example.com>
+ Committer C O Mitter <committer@example.com> maps to C O Mitter <committer@example.com>
+
+ Author B <b@example.com> maps to B <b@example.com>
+ Committer C O Mitter <committer@example.com> maps to C O Mitter <committer@example.com>
+
+ Author C <c@example.com> maps to Cee <cee@example.com>
+ Committer C O Mitter <committer@example.com> maps to C O Mitter <committer@example.com>
+
+ Author D <d@example.com> maps to dee <dee@example.com>
+ Committer C O Mitter <committer@example.com> maps to C O Mitter <committer@example.com>
+
+ Author E E <e@example.com> maps to eee <eee@example.com>
+ Committer C O Mitter <committer@example.com> maps to C O Mitter <committer@example.com>
+
+ Author F F <f@example.com> maps to eff <eff@example.com>
+ Committer C O Mitter <committer@example.com> maps to C O Mitter <committer@example.com>
+
+ Author G G <g@example.com> maps to gee <gee@example.com>
+ Committer C O Mitter <committer@example.com> maps to C O Mitter <committer@example.com>
+
+ Author H H <h@example.com> maps to H H <h@example.com>
+ Committer C O Mitter <committer@example.com> maps to C O Mitter <committer@example.com>
+ EOF
+ git -C space log --reverse --pretty=format:"Author %an <%ae> maps to %aN <%aE>%nCommitter %cn <%ce> maps to %cN <%cE>%n" >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'empty syntax: setup' '
+ test_create_repo empty &&
+ test_commit -C empty --author "A <>" A &&
+ test_commit -C empty --author "B <b@example.com>" B &&
+ test_commit -C empty --author "C <c@example.com>" C &&
+
+ test_config -C empty mailmap.file ../empty.map &&
+ cat >>empty.map <<-\EOF &&
+ Ah <ah@example.com> <>
+ Bee <bee@example.com> <>
+ Cee <> <c@example.com>
+ EOF
+
+ cat >expect <<-\EOF &&
+ Author A <> maps to Bee <bee@example.com>
+ Committer C O Mitter <committer@example.com> maps to C O Mitter <committer@example.com>
+
+ Author B <b@example.com> maps to B <b@example.com>
+ Committer C O Mitter <committer@example.com> maps to C O Mitter <committer@example.com>
+
+ Author C <c@example.com> maps to C <c@example.com>
+ Committer C O Mitter <committer@example.com> maps to C O Mitter <committer@example.com>
+ EOF
+ git -C empty log --reverse --pretty=format:"Author %an <%ae> maps to %aN <%aE>%nCommitter %cn <%ce> maps to %cN <%cE>%n" >actual &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t7509-commit-authorship.sh b/t/t7509-commit-authorship.sh
index 500ab2fe72..ee6c47416e 100755
--- a/t/t7509-commit-authorship.sh
+++ b/t/t7509-commit-authorship.sh
@@ -18,11 +18,8 @@ message_body () {
}
test_expect_success '-C option copies authorship and message' '
- echo "Initial" >foo &&
- git add foo &&
- test_tick &&
- git commit -m "Initial Commit" --author Frigate\ \<flying@over.world\> &&
- git tag Initial &&
+ test_commit --author Frigate\ \<flying@over.world\> \
+ "Initial Commit" foo Initial Initial &&
echo "Test 1" >>foo &&
test_tick &&
git commit -a -C Initial &&
diff --git a/t/t7810-grep.sh b/t/t7810-grep.sh
index 9f1aa9ef25..8f7591c9cc 100755
--- a/t/t7810-grep.sh
+++ b/t/t7810-grep.sh
@@ -690,21 +690,9 @@ test_expect_success 'grep -C1 hunk mark between files' '
'
test_expect_success 'log grep setup' '
- echo a >>file &&
- test_tick &&
- GIT_AUTHOR_NAME="With * Asterisk" \
- GIT_AUTHOR_EMAIL="xyzzy@frotz.com" \
- git commit -a -m "second" &&
-
- echo a >>file &&
- test_tick &&
- git commit -a -m "third" &&
-
- echo a >>file &&
- test_tick &&
- GIT_AUTHOR_NAME="Night Fall" \
- GIT_AUTHOR_EMAIL="nitfol@frobozz.com" \
- git commit -a -m "fourth"
+ test_commit --append --author "With * Asterisk <xyzzy@frotz.com>" second file a &&
+ test_commit --append third file a &&
+ test_commit --append --author "Night Fall <nitfol@frobozz.com>" fourth file a
'
test_expect_success 'log grep (1)' '
diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
index 2f08ce7cba..c31a411372 100644
--- a/t/test-lib-functions.sh
+++ b/t/test-lib-functions.sh
@@ -178,19 +178,28 @@ debug () {
GIT_DEBUGGER="${GIT_DEBUGGER}" "$@" <&6 >&5 2>&7
}
-# Call test_commit with the arguments
-# [-C <directory>] <message> [<file> [<contents> [<tag>]]]"
+# Usage: test_commit [options] <message> [<file> [<contents> [<tag>]]]
+# -C <dir>:
+# Run all git commands in directory <dir>
+# --notick
+# Do not call test_tick before making a commit
+# --append
+# Use "echo >>" instead of "echo >" when writing "<contents>" to
+# "<file>"
+# --signoff
+# Invoke "git commit" with --signoff
+# --author=<author>
+# Invoke "git commit" with --author=<author>
#
# This will commit a file with the given contents and the given commit
# message, and tag the resulting commit with the given tag name.
#
# <file>, <contents>, and <tag> all default to <message>.
-#
-# If the first argument is "-C", the second argument is used as a path for
-# the git invocations.
test_commit () {
notick= &&
+ append= &&
+ author= &&
signoff= &&
indir= &&
while test $# != 0
@@ -199,6 +208,13 @@ test_commit () {
--notick)
notick=yes
;;
+ --append)
+ append=yes
+ ;;
+ --author)
+ author="$2"
+ shift
+ ;;
--signoff)
signoff="$1"
;;
@@ -214,13 +230,20 @@ test_commit () {
done &&
indir=${indir:+"$indir"/} &&
file=${2:-"$1.t"} &&
- echo "${3-$1}" > "$indir$file" &&
+ if test -n "$append"
+ then
+ echo "${3-$1}" >>"$indir$file"
+ else
+ echo "${3-$1}" >"$indir$file"
+ fi &&
git ${indir:+ -C "$indir"} add "$file" &&
if test -z "$notick"
then
test_tick
fi &&
- git ${indir:+ -C "$indir"} commit $signoff -m "$1" &&
+ git ${indir:+ -C "$indir"} commit \
+ ${author:+ --author "$author"} \
+ $signoff -m "$1" &&
git ${indir:+ -C "$indir"} tag "${4:-$1}"
}