Merge branch 'jc/missing-ref-store-fix'
[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         $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>
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         $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>
38         nick1 <bugs@company.xx>
39         EOF
40         git check-mailmap \
41                 "$GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>" \
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         $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>
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 $GIT_AUTHOR_NAME (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 <$GIT_AUTHOR_EMAIL>" > .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 <$GIT_AUTHOR_EMAIL>" >> 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 $GIT_AUTHOR_NAME (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 <$GIT_AUTHOR_EMAIL>
203         Blob Guy <bugs@company.xx>
204         EOF
205         printf "Tricky Guy <$GIT_AUTHOR_EMAIL>" >no-newline &&
206         git add just-bugs both no-newline &&
207         git commit -m "my mailmaps" &&
208         echo "Repo Guy <$GIT_AUTHOR_EMAIL>" >.mailmap &&
209         echo "Internal Guy <$GIT_AUTHOR_EMAIL>" >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 <$GIT_AUTHOR_EMAIL>" &&
270                 echo "     1    Fake Name" >expect &&
271                 git shortlog -ns HEAD >actual &&
272                 test_cmp expect actual &&
273                 rm .mailmap &&
274                 echo "     1    $GIT_AUTHOR_NAME" >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 <$GIT_AUTHOR_EMAIL>" >expect &&
309         echo "     1    nick1 <bugs@company.xx>" >>expect &&
310         echo "A <$GIT_AUTHOR_EMAIL>" >.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    $GIT_AUTHOR_NAME <AUTHOR@example.com>" >expect &&
318         echo "     1    nick1 <bugs@company.xx>" >>expect &&
319         echo "<AUTHOR@example.com> <$GIT_AUTHOR_EMAIL>" >.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 $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL> (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 <$GIT_COMMITTER_EMAIL>" > 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 $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> maps to Committed <$GIT_COMMITTER_EMAIL>
390
391 Author claus <me@company.xx> maps to Santa Claus <santa.claus@northpole.xx>
392 Committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> maps to Committed <$GIT_COMMITTER_EMAIL>
393
394 Author santa <me@company.xx> maps to Santa Claus <santa.claus@northpole.xx>
395 Committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> maps to Committed <$GIT_COMMITTER_EMAIL>
396
397 Author nick2 <nick2@company.xx> maps to Other Author <other@author.xx>
398 Committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> maps to Committed <$GIT_COMMITTER_EMAIL>
399
400 Author nick2 <bugs@company.xx> maps to Other Author <other@author.xx>
401 Committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> maps to Committed <$GIT_COMMITTER_EMAIL>
402
403 Author nick1 <bugs@company.xx> maps to Some Dude <some@dude.xx>
404 Committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> maps to Committed <$GIT_COMMITTER_EMAIL>
405
406 Author $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL> maps to $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>
407 Committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> maps to Committed <$GIT_COMMITTER_EMAIL>
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 email cto@coompany.xx has local-part cto
417 Committer email $GIT_COMMITTER_EMAIL has local-part $TEST_COMMITTER_LOCALNAME
418
419 Author email me@company.xx has local-part me
420 Committer email $GIT_COMMITTER_EMAIL has local-part $TEST_COMMITTER_LOCALNAME
421
422 Author email me@company.xx has local-part me
423 Committer email $GIT_COMMITTER_EMAIL has local-part $TEST_COMMITTER_LOCALNAME
424
425 Author email nick2@company.xx has local-part nick2
426 Committer email $GIT_COMMITTER_EMAIL has local-part $TEST_COMMITTER_LOCALNAME
427
428 Author email bugs@company.xx has local-part bugs
429 Committer email $GIT_COMMITTER_EMAIL has local-part $TEST_COMMITTER_LOCALNAME
430
431 Author email bugs@company.xx has local-part bugs
432 Committer email $GIT_COMMITTER_EMAIL has local-part $TEST_COMMITTER_LOCALNAME
433
434 Author email author@example.com has local-part author
435 Committer email $GIT_COMMITTER_EMAIL has local-part $TEST_COMMITTER_LOCALNAME
436 EOF
437
438 test_expect_success 'Log output (local-part email address)' '
439         git log --pretty=format:"Author email %ae has local-part %al%nCommitter email %ce has local-part %cl%n" >actual &&
440         test_cmp expect actual
441 '
442
443 cat >expect << EOF
444 Author: CTO <cto@company.xx>
445 Author: Santa Claus <santa.claus@northpole.xx>
446 Author: Santa Claus <santa.claus@northpole.xx>
447 Author: Other Author <other@author.xx>
448 Author: Other Author <other@author.xx>
449 Author: Some Dude <some@dude.xx>
450 Author: $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>
451 EOF
452
453 test_expect_success 'Log output with --use-mailmap' '
454         git log --use-mailmap | grep Author >actual &&
455         test_cmp expect actual
456 '
457
458 cat >expect << EOF
459 Author: CTO <cto@company.xx>
460 Author: Santa Claus <santa.claus@northpole.xx>
461 Author: Santa Claus <santa.claus@northpole.xx>
462 Author: Other Author <other@author.xx>
463 Author: Other Author <other@author.xx>
464 Author: Some Dude <some@dude.xx>
465 Author: $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>
466 EOF
467
468 test_expect_success 'Log output with log.mailmap' '
469         git -c log.mailmap=True log | grep Author >actual &&
470         test_cmp expect actual
471 '
472
473 test_expect_success 'log.mailmap=false disables mailmap' '
474         cat >expect <<- EOF &&
475         Author: CTO <cto@coompany.xx>
476         Author: claus <me@company.xx>
477         Author: santa <me@company.xx>
478         Author: nick2 <nick2@company.xx>
479         Author: nick2 <bugs@company.xx>
480         Author: nick1 <bugs@company.xx>
481         Author: $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>
482         EOF
483         git -c log.mailmap=False log | grep Author > actual &&
484         test_cmp expect actual
485 '
486
487 test_expect_success '--no-use-mailmap disables mailmap' '
488         cat >expect <<- EOF &&
489         Author: CTO <cto@coompany.xx>
490         Author: claus <me@company.xx>
491         Author: santa <me@company.xx>
492         Author: nick2 <nick2@company.xx>
493         Author: nick2 <bugs@company.xx>
494         Author: nick1 <bugs@company.xx>
495         Author: $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>
496         EOF
497         git log --no-use-mailmap | grep Author > actual &&
498         test_cmp expect actual
499 '
500
501 cat >expect <<\EOF
502 Author: Santa Claus <santa.claus@northpole.xx>
503 Author: Santa Claus <santa.claus@northpole.xx>
504 EOF
505
506 test_expect_success 'Grep author with --use-mailmap' '
507         git log --use-mailmap --author Santa | grep Author >actual &&
508         test_cmp expect actual
509 '
510 cat >expect <<\EOF
511 Author: Santa Claus <santa.claus@northpole.xx>
512 Author: Santa Claus <santa.claus@northpole.xx>
513 EOF
514
515 test_expect_success 'Grep author with log.mailmap' '
516         git -c log.mailmap=True log --author Santa | grep Author >actual &&
517         test_cmp expect actual
518 '
519
520 test_expect_success 'log.mailmap is true by default these days' '
521         git log --author Santa | grep Author >actual &&
522         test_cmp expect actual
523 '
524
525 test_expect_success 'Only grep replaced author with --use-mailmap' '
526         git log --use-mailmap --author "<cto@coompany.xx>" >actual &&
527         test_must_be_empty actual
528 '
529
530 # git blame
531 cat >expect <<EOF
532 ^OBJI ($GIT_AUTHOR_NAME     DATE 1) one
533 OBJID (Some Dude    DATE 2) two
534 OBJID (Other Author DATE 3) three
535 OBJID (Other Author DATE 4) four
536 OBJID (Santa Claus  DATE 5) five
537 OBJID (Santa Claus  DATE 6) six
538 OBJID (CTO          DATE 7) seven
539 EOF
540 test_expect_success 'Blame output (complex mapping)' '
541         git blame one >actual &&
542         fuzz_blame actual >actual.fuzz &&
543         test_cmp expect actual.fuzz
544 '
545
546 cat >expect <<\EOF
547 Some Dude <some@dude.xx>
548 EOF
549
550 test_expect_success 'commit --author honors mailmap' '
551         test_must_fail git commit --author "nick" --allow-empty -meight &&
552         git commit --author "Some Dude" --allow-empty -meight &&
553         git show --pretty=format:"%an <%ae>%n" >actual &&
554         test_cmp expect actual
555 '
556
557 test_done