Merge branch 'sb/doc-config-submodule-update'
[git] / t / t4203-mailmap.sh
1 #!/bin/sh
2
3 test_description='.mailmap configurations'
4
5 . ./test-lib.sh
6
7 fuzz_blame () {
8         sed "
9                 s/$_x05[0-9a-f][0-9a-f][0-9a-f]/OBJID/g
10                 s/$_x05[0-9a-f][0-9a-f]/OBJI/g
11                 s/[-0-9]\{10\} [:0-9]\{8\} [-+][0-9]\{4\}/DATE/g
12         " "$@"
13 }
14
15 test_expect_success setup '
16         cat >contacts <<-\EOF &&
17         A U Thor <author@example.com>
18         nick1 <bugs@company.xx>
19         EOF
20
21         echo one >one &&
22         git add one &&
23         test_tick &&
24         git commit -m initial &&
25         echo two >>one &&
26         git add one &&
27         test_tick &&
28         git commit --author "nick1 <bugs@company.xx>" -m second
29 '
30
31 test_expect_success 'check-mailmap no arguments' '
32         test_must_fail git check-mailmap
33 '
34
35 test_expect_success 'check-mailmap arguments' '
36         cat >expect <<-\EOF &&
37         A U Thor <author@example.com>
38         nick1 <bugs@company.xx>
39         EOF
40         git check-mailmap \
41                 "A U Thor <author@example.com>" \
42                 "nick1 <bugs@company.xx>" >actual &&
43         test_cmp expect actual
44 '
45
46 test_expect_success 'check-mailmap --stdin' '
47         cat >expect <<-\EOF &&
48         A U Thor <author@example.com>
49         nick1 <bugs@company.xx>
50         EOF
51         git check-mailmap --stdin <contacts >actual &&
52         test_cmp expect actual
53 '
54
55 test_expect_success 'check-mailmap --stdin arguments' '
56         cat >expect <<-\EOF &&
57         Internal Guy <bugs@company.xy>
58         EOF
59         cat <contacts >>expect &&
60         git check-mailmap --stdin "Internal Guy <bugs@company.xy>" \
61                 <contacts >actual &&
62         test_cmp expect actual
63 '
64
65 test_expect_success 'check-mailmap bogus contact' '
66         test_must_fail git check-mailmap bogus
67 '
68
69 cat >expect <<\EOF
70 A U Thor (1):
71       initial
72
73 nick1 (1):
74       second
75
76 EOF
77
78 test_expect_success 'No mailmap' '
79         git shortlog HEAD >actual &&
80         test_cmp expect actual
81 '
82
83 cat >expect <<\EOF
84 Repo Guy (1):
85       initial
86
87 nick1 (1):
88       second
89
90 EOF
91
92 test_expect_success 'default .mailmap' '
93         echo "Repo Guy <author@example.com>" > .mailmap &&
94         git shortlog HEAD >actual &&
95         test_cmp expect actual
96 '
97
98 # Using a mailmap file in a subdirectory of the repo here, but
99 # could just as well have been a file outside of the repository
100 cat >expect <<\EOF
101 Internal Guy (1):
102       second
103
104 Repo Guy (1):
105       initial
106
107 EOF
108 test_expect_success 'mailmap.file set' '
109         mkdir -p internal_mailmap &&
110         echo "Internal Guy <bugs@company.xx>" > internal_mailmap/.mailmap &&
111         git config mailmap.file internal_mailmap/.mailmap &&
112         git shortlog HEAD >actual &&
113         test_cmp expect actual
114 '
115
116 cat >expect <<\EOF
117 External Guy (1):
118       initial
119
120 Internal Guy (1):
121       second
122
123 EOF
124 test_expect_success 'mailmap.file override' '
125         echo "External Guy <author@example.com>" >> internal_mailmap/.mailmap &&
126         git config mailmap.file internal_mailmap/.mailmap &&
127         git shortlog HEAD >actual &&
128         test_cmp expect actual
129 '
130
131 cat >expect <<\EOF
132 Repo Guy (1):
133       initial
134
135 nick1 (1):
136       second
137
138 EOF
139
140 test_expect_success 'mailmap.file non-existent' '
141         rm internal_mailmap/.mailmap &&
142         rmdir internal_mailmap &&
143         git shortlog HEAD >actual &&
144         test_cmp expect actual
145 '
146
147 cat >expect <<\EOF
148 Internal Guy (1):
149       second
150
151 Repo Guy (1):
152       initial
153
154 EOF
155
156 test_expect_success 'name entry after email entry' '
157         mkdir -p internal_mailmap &&
158         echo "<bugs@company.xy> <bugs@company.xx>" >internal_mailmap/.mailmap &&
159         echo "Internal Guy <bugs@company.xx>" >>internal_mailmap/.mailmap &&
160         git shortlog HEAD >actual &&
161         test_cmp expect actual
162 '
163
164 cat >expect <<\EOF
165 Internal Guy (1):
166       second
167
168 Repo Guy (1):
169       initial
170
171 EOF
172
173 test_expect_success 'name entry after email entry, case-insensitive' '
174         mkdir -p internal_mailmap &&
175         echo "<bugs@company.xy> <bugs@company.xx>" >internal_mailmap/.mailmap &&
176         echo "Internal Guy <BUGS@Company.xx>" >>internal_mailmap/.mailmap &&
177         git shortlog HEAD >actual &&
178         test_cmp expect actual
179 '
180
181 cat >expect <<\EOF
182 A U Thor (1):
183       initial
184
185 nick1 (1):
186       second
187
188 EOF
189 test_expect_success 'No mailmap files, but configured' '
190         rm -f .mailmap internal_mailmap/.mailmap &&
191         git shortlog HEAD >actual &&
192         test_cmp expect actual
193 '
194
195 test_expect_success 'setup mailmap blob tests' '
196         git checkout -b map &&
197         test_when_finished "git checkout master" &&
198         cat >just-bugs <<-\EOF &&
199         Blob Guy <bugs@company.xx>
200         EOF
201         cat >both <<-\EOF &&
202         Blob Guy <author@example.com>
203         Blob Guy <bugs@company.xx>
204         EOF
205         printf "Tricky Guy <author@example.com>" >no-newline &&
206         git add just-bugs both no-newline &&
207         git commit -m "my mailmaps" &&
208         echo "Repo Guy <author@example.com>" >.mailmap &&
209         echo "Internal Guy <author@example.com>" >internal.map
210 '
211
212 test_expect_success 'mailmap.blob set' '
213         cat >expect <<-\EOF &&
214         Blob Guy (1):
215               second
216
217         Repo Guy (1):
218               initial
219
220         EOF
221         git -c mailmap.blob=map:just-bugs shortlog HEAD >actual &&
222         test_cmp expect actual
223 '
224
225 test_expect_success 'mailmap.blob overrides .mailmap' '
226         cat >expect <<-\EOF &&
227         Blob Guy (2):
228               initial
229               second
230
231         EOF
232         git -c mailmap.blob=map:both shortlog HEAD >actual &&
233         test_cmp expect actual
234 '
235
236 test_expect_success 'mailmap.file overrides mailmap.blob' '
237         cat >expect <<-\EOF &&
238         Blob Guy (1):
239               second
240
241         Internal Guy (1):
242               initial
243
244         EOF
245         git \
246           -c mailmap.blob=map:both \
247           -c mailmap.file=internal.map \
248           shortlog HEAD >actual &&
249         test_cmp expect actual
250 '
251
252 test_expect_success 'mailmap.blob can be missing' '
253         cat >expect <<-\EOF &&
254         Repo Guy (1):
255               initial
256
257         nick1 (1):
258               second
259
260         EOF
261         git -c mailmap.blob=map:nonexistent shortlog HEAD >actual &&
262         test_cmp expect actual
263 '
264
265 test_expect_success 'mailmap.blob defaults to off in non-bare repo' '
266         git init non-bare &&
267         (
268                 cd non-bare &&
269                 test_commit one .mailmap "Fake Name <author@example.com>" &&
270                 echo "     1    Fake Name" >expect &&
271                 git shortlog -ns HEAD >actual &&
272                 test_cmp expect actual &&
273                 rm .mailmap &&
274                 echo "     1    A U Thor" >expect &&
275                 git shortlog -ns HEAD >actual &&
276                 test_cmp expect actual
277         )
278 '
279
280 test_expect_success 'mailmap.blob defaults to HEAD:.mailmap in bare repo' '
281         git clone --bare non-bare bare &&
282         (
283                 cd bare &&
284                 echo "     1    Fake Name" >expect &&
285                 git shortlog -ns HEAD >actual &&
286                 test_cmp expect actual
287         )
288 '
289
290 test_expect_success 'mailmap.blob can handle blobs without trailing newline' '
291         cat >expect <<-\EOF &&
292         Tricky Guy (1):
293               initial
294
295         nick1 (1):
296               second
297
298         EOF
299         git -c mailmap.blob=map:no-newline shortlog HEAD >actual &&
300         test_cmp expect actual
301 '
302
303 test_expect_success 'cleanup after mailmap.blob tests' '
304         rm -f .mailmap
305 '
306
307 test_expect_success 'single-character name' '
308         echo "     1    A <author@example.com>" >expect &&
309         echo "     1    nick1 <bugs@company.xx>" >>expect &&
310         echo "A <author@example.com>" >.mailmap &&
311         test_when_finished "rm .mailmap" &&
312         git shortlog -es HEAD >actual &&
313         test_cmp expect actual
314 '
315
316 test_expect_success 'preserve canonical email case' '
317         echo "     1    A U Thor <AUTHOR@example.com>" >expect &&
318         echo "     1    nick1 <bugs@company.xx>" >>expect &&
319         echo "<AUTHOR@example.com> <author@example.com>" >.mailmap &&
320         test_when_finished "rm .mailmap" &&
321         git shortlog -es HEAD >actual &&
322         test_cmp expect actual
323 '
324
325 # Extended mailmap configurations should give us the following output for shortlog
326 cat >expect <<\EOF
327 A U Thor <author@example.com> (1):
328       initial
329
330 CTO <cto@company.xx> (1):
331       seventh
332
333 Other Author <other@author.xx> (2):
334       third
335       fourth
336
337 Santa Claus <santa.claus@northpole.xx> (2):
338       fifth
339       sixth
340
341 Some Dude <some@dude.xx> (1):
342       second
343
344 EOF
345
346 test_expect_success 'Shortlog output (complex mapping)' '
347         echo three >>one &&
348         git add one &&
349         test_tick &&
350         git commit --author "nick2 <bugs@company.xx>" -m third &&
351
352         echo four >>one &&
353         git add one &&
354         test_tick &&
355         git commit --author "nick2 <nick2@company.xx>" -m fourth &&
356
357         echo five >>one &&
358         git add one &&
359         test_tick &&
360         git commit --author "santa <me@company.xx>" -m fifth &&
361
362         echo six >>one &&
363         git add one &&
364         test_tick &&
365         git commit --author "claus <me@company.xx>" -m sixth &&
366
367         echo seven >>one &&
368         git add one &&
369         test_tick &&
370         git commit --author "CTO <cto@coompany.xx>" -m seventh &&
371
372         mkdir -p internal_mailmap &&
373         echo "Committed <committer@example.com>" > internal_mailmap/.mailmap &&
374         echo "<cto@company.xx>                       <cto@coompany.xx>" >> internal_mailmap/.mailmap &&
375         echo "Some Dude <some@dude.xx>         nick1 <bugs@company.xx>" >> internal_mailmap/.mailmap &&
376         echo "Other Author <other@author.xx>   nick2 <bugs@company.xx>" >> internal_mailmap/.mailmap &&
377         echo "Other Author <other@author.xx>         <nick2@company.xx>" >> internal_mailmap/.mailmap &&
378         echo "Santa Claus <santa.claus@northpole.xx> <me@company.xx>" >> internal_mailmap/.mailmap &&
379         echo "Santa Claus <santa.claus@northpole.xx> <me@company.xx>" >> internal_mailmap/.mailmap &&
380
381         git shortlog -e HEAD >actual &&
382         test_cmp expect actual
383
384 '
385
386 # git log with --pretty format which uses the name and email mailmap placemarkers
387 cat >expect <<\EOF
388 Author CTO <cto@coompany.xx> maps to CTO <cto@company.xx>
389 Committer C O Mitter <committer@example.com> maps to Committed <committer@example.com>
390
391 Author claus <me@company.xx> maps to Santa Claus <santa.claus@northpole.xx>
392 Committer C O Mitter <committer@example.com> maps to Committed <committer@example.com>
393
394 Author santa <me@company.xx> maps to Santa Claus <santa.claus@northpole.xx>
395 Committer C O Mitter <committer@example.com> maps to Committed <committer@example.com>
396
397 Author nick2 <nick2@company.xx> maps to Other Author <other@author.xx>
398 Committer C O Mitter <committer@example.com> maps to Committed <committer@example.com>
399
400 Author nick2 <bugs@company.xx> maps to Other Author <other@author.xx>
401 Committer C O Mitter <committer@example.com> maps to Committed <committer@example.com>
402
403 Author nick1 <bugs@company.xx> maps to Some Dude <some@dude.xx>
404 Committer C O Mitter <committer@example.com> maps to Committed <committer@example.com>
405
406 Author A U Thor <author@example.com> maps to A U Thor <author@example.com>
407 Committer C O Mitter <committer@example.com> maps to Committed <committer@example.com>
408 EOF
409
410 test_expect_success 'Log output (complex mapping)' '
411         git log --pretty=format:"Author %an <%ae> maps to %aN <%aE>%nCommitter %cn <%ce> maps to %cN <%cE>%n" >actual &&
412         test_cmp expect actual
413 '
414
415 cat >expect <<\EOF
416 Author: CTO <cto@company.xx>
417 Author: Santa Claus <santa.claus@northpole.xx>
418 Author: Santa Claus <santa.claus@northpole.xx>
419 Author: Other Author <other@author.xx>
420 Author: Other Author <other@author.xx>
421 Author: Some Dude <some@dude.xx>
422 Author: A U Thor <author@example.com>
423 EOF
424
425 test_expect_success 'Log output with --use-mailmap' '
426         git log --use-mailmap | grep Author >actual &&
427         test_cmp expect actual
428 '
429
430 cat >expect <<\EOF
431 Author: CTO <cto@company.xx>
432 Author: Santa Claus <santa.claus@northpole.xx>
433 Author: Santa Claus <santa.claus@northpole.xx>
434 Author: Other Author <other@author.xx>
435 Author: Other Author <other@author.xx>
436 Author: Some Dude <some@dude.xx>
437 Author: A U Thor <author@example.com>
438 EOF
439
440 test_expect_success 'Log output with log.mailmap' '
441         git -c log.mailmap=True log | grep Author >actual &&
442         test_cmp expect actual
443 '
444
445 cat >expect <<\EOF
446 Author: Santa Claus <santa.claus@northpole.xx>
447 Author: Santa Claus <santa.claus@northpole.xx>
448 EOF
449
450 test_expect_success 'Grep author with --use-mailmap' '
451         git log --use-mailmap --author Santa | grep Author >actual &&
452         test_cmp expect actual
453 '
454 cat >expect <<\EOF
455 Author: Santa Claus <santa.claus@northpole.xx>
456 Author: Santa Claus <santa.claus@northpole.xx>
457 EOF
458
459 test_expect_success 'Grep author with log.mailmap' '
460         git -c log.mailmap=True log --author Santa | grep Author >actual &&
461         test_cmp expect actual
462 '
463
464 >expect
465
466 test_expect_success 'Only grep replaced author with --use-mailmap' '
467         git log --use-mailmap --author "<cto@coompany.xx>" >actual &&
468         test_cmp expect actual
469 '
470
471 # git blame
472 cat >expect <<\EOF
473 ^OBJI (A U Thor     DATE 1) one
474 OBJID (Some Dude    DATE 2) two
475 OBJID (Other Author DATE 3) three
476 OBJID (Other Author DATE 4) four
477 OBJID (Santa Claus  DATE 5) five
478 OBJID (Santa Claus  DATE 6) six
479 OBJID (CTO          DATE 7) seven
480 EOF
481 test_expect_success 'Blame output (complex mapping)' '
482         git blame one >actual &&
483         fuzz_blame actual >actual.fuzz &&
484         test_cmp expect actual.fuzz
485 '
486
487 cat >expect <<\EOF
488 Some Dude <some@dude.xx>
489 EOF
490
491 test_expect_success 'commit --author honors mailmap' '
492         test_must_fail git commit --author "nick" --allow-empty -meight &&
493         git commit --author "Some Dude" --allow-empty -meight &&
494         git show --pretty=format:"%an <%ae>%n" >actual &&
495         test_cmp expect actual
496 '
497
498 test_done