Merge branch 'ab/mailmap'
Clean-up docs, codepaths and tests around mailmap. * ab/mailmap: (22 commits) shortlog: remove unused(?) "repo-abbrev" feature mailmap doc + tests: document and test for case-insensitivity mailmap tests: add tests for empty "<>" syntax mailmap tests: add tests for whitespace syntax mailmap tests: add a test for comment syntax mailmap doc + tests: add better examples & test them tests: refactor a few tests to use "test_commit --append" test-lib functions: add an --append option to test_commit test-lib functions: add --author support to test_commit test-lib functions: document arguments to test_commit test-lib functions: expand "test_commit" comment template mailmap: test for silent exiting on missing file/blob mailmap tests: get rid of overly complex blame fuzzing mailmap tests: add a test for "not a blob" error mailmap tests: remove redundant entry in test mailmap tests: improve --stdin tests mailmap tests: modernize syntax & test idioms mailmap tests: use our preferred whitespace syntax mailmap doc: start by mentioning the comment syntax check-mailmap doc: note config options ...maint
						commit
						42342b3ee6
					
				|  | @ -21,6 +21,7 @@ MAN1_TXT += gitweb.txt | ||||||
| MAN5_TXT += gitattributes.txt | MAN5_TXT += gitattributes.txt | ||||||
| MAN5_TXT += githooks.txt | MAN5_TXT += githooks.txt | ||||||
| MAN5_TXT += gitignore.txt | MAN5_TXT += gitignore.txt | ||||||
|  | MAN5_TXT += gitmailmap.txt | ||||||
| MAN5_TXT += gitmodules.txt | MAN5_TXT += gitmodules.txt | ||||||
| MAN5_TXT += gitrepository-layout.txt | MAN5_TXT += gitrepository-layout.txt | ||||||
| MAN5_TXT += gitweb.conf.txt | MAN5_TXT += gitweb.conf.txt | ||||||
|  |  | ||||||
|  | @ -226,7 +226,7 @@ commit commentary), a blame viewer will not care. | ||||||
| MAPPING AUTHORS | MAPPING AUTHORS | ||||||
| --------------- | --------------- | ||||||
|  |  | ||||||
| include::mailmap.txt[] | See linkgit:gitmailmap[5]. | ||||||
|  |  | ||||||
|  |  | ||||||
| SEE ALSO | SEE ALSO | ||||||
|  |  | ||||||
|  | @ -36,10 +36,17 @@ name is provided or known to the 'mailmap', ``Name $$<user@host>$$'' is | ||||||
| printed; otherwise only ``$$<user@host>$$'' is printed. | 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 | MAPPING AUTHORS | ||||||
| --------------- | --------------- | ||||||
|  |  | ||||||
| include::mailmap.txt[] | See linkgit:gitmailmap[5]. | ||||||
|  |  | ||||||
|  |  | ||||||
| GIT | GIT | ||||||
|  |  | ||||||
|  | @ -111,11 +111,7 @@ include::rev-list-options.txt[] | ||||||
| MAPPING AUTHORS | MAPPING AUTHORS | ||||||
| --------------- | --------------- | ||||||
|  |  | ||||||
| The `.mailmap` feature is used to coalesce together commits by the same | See linkgit:gitmailmap[5]. | ||||||
| person in the shortlog, where their name and/or email address was |  | ||||||
| spelled differently. |  | ||||||
|  |  | ||||||
| include::mailmap.txt[] |  | ||||||
|  |  | ||||||
| GIT | GIT | ||||||
| --- | --- | ||||||
|  |  | ||||||
|  | @ -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 | ||||||
|  | @ -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. |  | ||||||
|  | @ -1151,7 +1151,7 @@ parse_done: | ||||||
| 	sb.xdl_opts = xdl_opts; | 	sb.xdl_opts = xdl_opts; | ||||||
| 	sb.no_whole_file_rename = no_whole_file_rename; | 	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 = &found_guilty_entry; | ||||||
| 	sb.found_guilty_entry_data = π | 	sb.found_guilty_entry_data = π | ||||||
|  |  | ||||||
|  | @ -47,7 +47,7 @@ int cmd_check_mailmap(int argc, const char **argv, const char *prefix) | ||||||
| 	if (argc == 0 && !use_stdin) | 	if (argc == 0 && !use_stdin) | ||||||
| 		die(_("no contacts specified")); | 		die(_("no contacts specified")); | ||||||
|  |  | ||||||
| 	read_mailmap(&mailmap, NULL); | 	read_mailmap(&mailmap); | ||||||
|  |  | ||||||
| 	for (i = 0; i < argc; ++i) | 	for (i = 0; i < argc; ++i) | ||||||
| 		check_mailmap(&mailmap, argv[i]); | 		check_mailmap(&mailmap, argv[i]); | ||||||
|  |  | ||||||
|  | @ -1039,7 +1039,7 @@ static const char *find_author_by_nickname(const char *name) | ||||||
| 	av[++ac] = NULL; | 	av[++ac] = NULL; | ||||||
| 	setup_revisions(ac, av, &revs, NULL); | 	setup_revisions(ac, av, &revs, NULL); | ||||||
| 	revs.mailmap = &mailmap; | 	revs.mailmap = &mailmap; | ||||||
| 	read_mailmap(revs.mailmap, NULL); | 	read_mailmap(revs.mailmap); | ||||||
|  |  | ||||||
| 	if (prepare_revision_walk(&revs)) | 	if (prepare_revision_walk(&revs)) | ||||||
| 		die(_("revision walk setup failed")); | 		die(_("revision walk setup failed")); | ||||||
|  |  | ||||||
|  | @ -230,7 +230,7 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix, | ||||||
|  |  | ||||||
| 	if (mailmap) { | 	if (mailmap) { | ||||||
| 		rev->mailmap = xcalloc(1, sizeof(struct string_list)); | 		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) { | 	if (rev->pretty_given && rev->commit_format == CMIT_FMT_RAW) { | ||||||
|  |  | ||||||
|  | @ -61,8 +61,7 @@ static void insert_one_record(struct shortlog *log, | ||||||
| 	if (log->summary) | 	if (log->summary) | ||||||
| 		item->util = (void *)(UTIL_TO_INT(item) + 1); | 		item->util = (void *)(UTIL_TO_INT(item) + 1); | ||||||
| 	else { | 	else { | ||||||
| 		const char *dot3 = log->common_repo_prefix; | 		char *buffer; | ||||||
| 		char *buffer, *p; |  | ||||||
| 		struct strbuf subject = STRBUF_INIT; | 		struct strbuf subject = STRBUF_INIT; | ||||||
| 		const char *eol; | 		const char *eol; | ||||||
|  |  | ||||||
|  | @ -82,17 +81,6 @@ static void insert_one_record(struct shortlog *log, | ||||||
| 		format_subject(&subject, oneline, " "); | 		format_subject(&subject, oneline, " "); | ||||||
| 		buffer = strbuf_detach(&subject, NULL); | 		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) | 		if (item->util == NULL) | ||||||
| 			item->util = xcalloc(1, sizeof(struct string_list)); | 			item->util = xcalloc(1, sizeof(struct string_list)); | ||||||
| 		string_list_append(item->util, buffer); | 		string_list_append(item->util, buffer); | ||||||
|  | @ -342,7 +330,7 @@ void shortlog_init(struct shortlog *log) | ||||||
| { | { | ||||||
| 	memset(log, 0, sizeof(*log)); | 	memset(log, 0, sizeof(*log)); | ||||||
|  |  | ||||||
| 	read_mailmap(&log->mailmap, &log->common_repo_prefix); | 	read_mailmap(&log->mailmap); | ||||||
|  |  | ||||||
| 	log->list.strdup_strings = 1; | 	log->list.strdup_strings = 1; | ||||||
| 	log->wrap = DEFAULT_WRAPLEN; | 	log->wrap = DEFAULT_WRAPLEN; | ||||||
|  |  | ||||||
|  | @ -204,6 +204,7 @@ gitfaq                                  guide | ||||||
| gitglossary                             guide | gitglossary                             guide | ||||||
| githooks                                guide | githooks                                guide | ||||||
| gitignore                               guide | gitignore                               guide | ||||||
|  | gitmailmap                              guide | ||||||
| gitmodules                              guide | gitmodules                              guide | ||||||
| gitnamespaces                           guide | gitnamespaces                           guide | ||||||
| gitremote-helpers                       guide | gitremote-helpers                       guide | ||||||
|  |  | ||||||
							
								
								
									
										48
									
								
								mailmap.c
								
								
								
								
							
							
						
						
									
										48
									
								
								mailmap.c
								
								
								
								
							|  | @ -143,31 +143,13 @@ static char *parse_name_and_email(char *buffer, char **name, | ||||||
| 	return (*right == '\0' ? NULL : right); | 	return (*right == '\0' ? NULL : right); | ||||||
| } | } | ||||||
|  |  | ||||||
| static void read_mailmap_line(struct string_list *map, char *buffer, | static void read_mailmap_line(struct string_list *map, char *buffer) | ||||||
| 			      char **repo_abbrev) |  | ||||||
| { | { | ||||||
| 	char *name1 = NULL, *email1 = NULL, *name2 = NULL, *email2 = NULL; | 	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) | 	if (buffer[0] == '#') | ||||||
| 			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); |  | ||||||
| 		} |  | ||||||
| 		return; | 		return; | ||||||
| 	} |  | ||||||
| 	if ((name2 = parse_name_and_email(buffer, &name1, &email1, 0)) != NULL) | 	if ((name2 = parse_name_and_email(buffer, &name1, &email1, 0)) != NULL) | ||||||
| 		parse_name_and_email(name2, &name2, &email2, 1); | 		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); | 		add_mapping(map, name1, email1, name2, email2); | ||||||
| } | } | ||||||
|  |  | ||||||
| static int read_mailmap_file(struct string_list *map, const char *filename, | static int read_mailmap_file(struct string_list *map, const char *filename) | ||||||
| 			     char **repo_abbrev) |  | ||||||
| { | { | ||||||
| 	char buffer[1024]; | 	char buffer[1024]; | ||||||
| 	FILE *f; | 	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) | 	while (fgets(buffer, sizeof(buffer), f) != NULL) | ||||||
| 		read_mailmap_line(map, buffer, repo_abbrev); | 		read_mailmap_line(map, buffer); | ||||||
| 	fclose(f); | 	fclose(f); | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| static void read_mailmap_string(struct string_list *map, char *buf, | static void read_mailmap_string(struct string_list *map, char *buf) | ||||||
| 				char **repo_abbrev) |  | ||||||
| { | { | ||||||
| 	while (*buf) { | 	while (*buf) { | ||||||
| 		char *end = strchrnul(buf, '\n'); | 		char *end = strchrnul(buf, '\n'); | ||||||
|  | @ -206,14 +186,12 @@ static void read_mailmap_string(struct string_list *map, char *buf, | ||||||
| 		if (*end) | 		if (*end) | ||||||
| 			*end++ = '\0'; | 			*end++ = '\0'; | ||||||
|  |  | ||||||
| 		read_mailmap_line(map, buf, repo_abbrev); | 		read_mailmap_line(map, buf); | ||||||
| 		buf = end; | 		buf = end; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| static int read_mailmap_blob(struct string_list *map, | static int read_mailmap_blob(struct string_list *map, const char *name) | ||||||
| 			     const char *name, |  | ||||||
| 			     char **repo_abbrev) |  | ||||||
| { | { | ||||||
| 	struct object_id oid; | 	struct object_id oid; | ||||||
| 	char *buf; | 	char *buf; | ||||||
|  | @ -231,13 +209,13 @@ static int read_mailmap_blob(struct string_list *map, | ||||||
| 	if (type != OBJ_BLOB) | 	if (type != OBJ_BLOB) | ||||||
| 		return error("mailmap is not a blob: %s", name); | 		return error("mailmap is not a blob: %s", name); | ||||||
|  |  | ||||||
| 	read_mailmap_string(map, buf, repo_abbrev); | 	read_mailmap_string(map, buf); | ||||||
|  |  | ||||||
| 	free(buf); | 	free(buf); | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| int read_mailmap(struct string_list *map, char **repo_abbrev) | int read_mailmap(struct string_list *map) | ||||||
| { | { | ||||||
| 	int err = 0; | 	int err = 0; | ||||||
|  |  | ||||||
|  | @ -247,10 +225,10 @@ int read_mailmap(struct string_list *map, char **repo_abbrev) | ||||||
| 	if (!git_mailmap_blob && is_bare_repository()) | 	if (!git_mailmap_blob && is_bare_repository()) | ||||||
| 		git_mailmap_blob = "HEAD:.mailmap"; | 		git_mailmap_blob = "HEAD:.mailmap"; | ||||||
|  |  | ||||||
| 	err |= read_mailmap_file(map, ".mailmap", repo_abbrev); | 	err |= read_mailmap_file(map, ".mailmap"); | ||||||
| 	if (startup_info->have_repository) | 	if (startup_info->have_repository) | ||||||
| 		err |= read_mailmap_blob(map, git_mailmap_blob, repo_abbrev); | 		err |= read_mailmap_blob(map, git_mailmap_blob); | ||||||
| 	err |= read_mailmap_file(map, git_mailmap_file, repo_abbrev); | 	err |= read_mailmap_file(map, git_mailmap_file); | ||||||
| 	return err; | 	return err; | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @ -3,7 +3,7 @@ | ||||||
|  |  | ||||||
| struct string_list; | 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); | void clear_mailmap(struct string_list *map); | ||||||
|  |  | ||||||
| int map_user(struct string_list *map, | int map_user(struct string_list *map, | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								pretty.c
								
								
								
								
							
							
						
						
									
										2
									
								
								pretty.c
								
								
								
								
							|  | @ -679,7 +679,7 @@ static int mailmap_name(const char **email, size_t *email_len, | ||||||
| 	static struct string_list *mail_map; | 	static struct string_list *mail_map; | ||||||
| 	if (!mail_map) { | 	if (!mail_map) { | ||||||
| 		mail_map = xcalloc(1, sizeof(*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); | 	return mail_map->nr && map_user(mail_map, email, email_len, name, name_len); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -23,7 +23,6 @@ struct shortlog { | ||||||
| 	} groups; | 	} groups; | ||||||
| 	struct string_list trailers; | 	struct string_list trailers; | ||||||
|  |  | ||||||
| 	char *common_repo_prefix; |  | ||||||
| 	int email; | 	int email; | ||||||
| 	struct string_list mailmap; | 	struct string_list mailmap; | ||||||
| 	FILE *file; | 	FILE *file; | ||||||
|  |  | ||||||
|  | @ -4,11 +4,8 @@ test_description='reflog walk shows repeated commits again' | ||||||
| . ./test-lib.sh | . ./test-lib.sh | ||||||
|  |  | ||||||
| test_expect_success 'setup commits' ' | test_expect_success 'setup commits' ' | ||||||
| 	test_tick && | 	test_commit one file content && | ||||||
| 	echo content >file && git add file && git commit -m one && | 	test_commit --append two file content | ||||||
| 	git tag one && |  | ||||||
| 	echo content >>file && git add file && git commit -m two && |  | ||||||
| 	git tag two |  | ||||||
| ' | ' | ||||||
|  |  | ||||||
| test_expect_success 'setup reflog with alternating commits' ' | test_expect_success 'setup reflog with alternating commits' ' | ||||||
|  |  | ||||||
|  | @ -8,13 +8,9 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME | ||||||
| . ./test-lib.sh | . ./test-lib.sh | ||||||
|  |  | ||||||
| test_expect_success 'setup' ' | test_expect_success 'setup' ' | ||||||
| 	echo hello >world && | 	test_commit initial world hello && | ||||||
| 	git add world && |  | ||||||
| 	git commit -m initial && |  | ||||||
| 	git branch other && | 	git branch other && | ||||||
| 	echo "hello again" >>world && | 	test_commit --append second world "hello again" | ||||||
| 	git add world && |  | ||||||
| 	git commit -m second |  | ||||||
| ' | ' | ||||||
|  |  | ||||||
| test_expect_success '"checkout -" does not work initially' ' | 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' ' | test_expect_success 'merge base test setup' ' | ||||||
| 	git checkout -b another other && | 	git checkout -b another other && | ||||||
| 	echo "hello again" >>world && | 	test_commit --append third world "hello again" | ||||||
| 	git add world && |  | ||||||
| 	git commit -m third |  | ||||||
| ' | ' | ||||||
|  |  | ||||||
| test_expect_success 'another...main' ' | test_expect_success 'another...main' ' | ||||||
|  |  | ||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							|  | @ -18,11 +18,8 @@ message_body () { | ||||||
| } | } | ||||||
|  |  | ||||||
| test_expect_success '-C option copies authorship and message' ' | test_expect_success '-C option copies authorship and message' ' | ||||||
| 	echo "Initial" >foo && | 	test_commit --author Frigate\ \<flying@over.world\> \ | ||||||
| 	git add foo && | 		"Initial Commit" foo Initial Initial && | ||||||
| 	test_tick && |  | ||||||
| 	git commit -m "Initial Commit" --author Frigate\ \<flying@over.world\> && |  | ||||||
| 	git tag Initial && |  | ||||||
| 	echo "Test 1" >>foo && | 	echo "Test 1" >>foo && | ||||||
| 	test_tick && | 	test_tick && | ||||||
| 	git commit -a -C Initial && | 	git commit -a -C Initial && | ||||||
|  |  | ||||||
|  | @ -690,21 +690,9 @@ test_expect_success 'grep -C1 hunk mark between files' ' | ||||||
| ' | ' | ||||||
|  |  | ||||||
| test_expect_success 'log grep setup' ' | test_expect_success 'log grep setup' ' | ||||||
| 	echo a >>file && | 	test_commit --append --author "With * Asterisk <xyzzy@frotz.com>" second file a && | ||||||
| 	test_tick && | 	test_commit --append third file a && | ||||||
| 	GIT_AUTHOR_NAME="With * Asterisk" \ | 	test_commit --append --author "Night Fall <nitfol@frobozz.com>" fourth file a | ||||||
| 	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_expect_success 'log grep (1)' ' | test_expect_success 'log grep (1)' ' | ||||||
|  |  | ||||||
|  | @ -178,19 +178,28 @@ debug () { | ||||||
| 	GIT_DEBUGGER="${GIT_DEBUGGER}" "$@" <&6 >&5 2>&7 | 	GIT_DEBUGGER="${GIT_DEBUGGER}" "$@" <&6 >&5 2>&7 | ||||||
| } | } | ||||||
|  |  | ||||||
| # Call test_commit with the arguments | # Usage: test_commit [options] <message> [<file> [<contents> [<tag>]]] | ||||||
| # [-C <directory>] <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 | # This will commit a file with the given contents and the given commit | ||||||
| # message, and tag the resulting commit with the given tag name. | # message, and tag the resulting commit with the given tag name. | ||||||
| # | # | ||||||
| # <file>, <contents>, and <tag> all default to <message>. | # <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 () { | test_commit () { | ||||||
| 	notick= && | 	notick= && | ||||||
|  | 	append= && | ||||||
|  | 	author= && | ||||||
| 	signoff= && | 	signoff= && | ||||||
| 	indir= && | 	indir= && | ||||||
| 	while test $# != 0 | 	while test $# != 0 | ||||||
|  | @ -199,6 +208,13 @@ test_commit () { | ||||||
| 		--notick) | 		--notick) | ||||||
| 			notick=yes | 			notick=yes | ||||||
| 			;; | 			;; | ||||||
|  | 		--append) | ||||||
|  | 			append=yes | ||||||
|  | 			;; | ||||||
|  | 		--author) | ||||||
|  | 			author="$2" | ||||||
|  | 			shift | ||||||
|  | 			;; | ||||||
| 		--signoff) | 		--signoff) | ||||||
| 			signoff="$1" | 			signoff="$1" | ||||||
| 			;; | 			;; | ||||||
|  | @ -214,13 +230,20 @@ test_commit () { | ||||||
| 	done && | 	done && | ||||||
| 	indir=${indir:+"$indir"/} && | 	indir=${indir:+"$indir"/} && | ||||||
| 	file=${2:-"$1.t"} && | 	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" && | 	git ${indir:+ -C "$indir"} add "$file" && | ||||||
| 	if test -z "$notick" | 	if test -z "$notick" | ||||||
| 	then | 	then | ||||||
| 		test_tick | 		test_tick | ||||||
| 	fi && | 	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}" | 	git ${indir:+ -C "$indir"} tag "${4:-$1}" | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Junio C Hamano
						Junio C Hamano