1#!/bin/sh
   2test_description='.mailmap configurations'
   4. ./test-lib.sh
   6fuzz_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}
  14test_expect_success setup '
  16        cat >contacts <<-\EOF &&
  17        A U Thor <author@example.com>
  18        nick1 <bugs@company.xx>
  19        EOF
  20        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'
  30test_expect_success 'check-mailmap no arguments' '
  32        test_must_fail git check-mailmap
  33'
  34test_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'
  45test_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'
  54test_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'
  64test_expect_success 'check-mailmap bogus contact' '
  66        test_must_fail git check-mailmap bogus
  67'
  68cat >expect <<\EOF
  70A U Thor (1):
  71      initial
  72nick1 (1):
  74      second
  75EOF
  77test_expect_success 'No mailmap' '
  79        git shortlog HEAD >actual &&
  80        test_cmp expect actual
  81'
  82cat >expect <<\EOF
  84Repo Guy (1):
  85      initial
  86nick1 (1):
  88      second
  89EOF
  91test_expect_success 'default .mailmap' '
  93        echo "Repo Guy <author@example.com>" > .mailmap &&
  94        git shortlog HEAD >actual &&
  95        test_cmp expect actual
  96'
  97# 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
 100cat >expect <<\EOF
 101Internal Guy (1):
 102      second
 103Repo Guy (1):
 105      initial
 106EOF
 108test_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'
 115cat >expect <<\EOF
 117External Guy (1):
 118      initial
 119Internal Guy (1):
 121      second
 122EOF
 124test_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'
 130cat >expect <<\EOF
 132Repo Guy (1):
 133      initial
 134nick1 (1):
 136      second
 137EOF
 139test_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'
 146cat >expect <<\EOF
 148Internal Guy (1):
 149      second
 150Repo Guy (1):
 152      initial
 153EOF
 155test_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'
 163cat >expect <<\EOF
 165Internal Guy (1):
 166      second
 167Repo Guy (1):
 169      initial
 170EOF
 172test_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'
 180cat >expect <<\EOF
 182A U Thor (1):
 183      initial
 184nick1 (1):
 186      second
 187EOF
 189test_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'
 194test_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'
 211test_expect_success 'mailmap.blob set' '
 213        cat >expect <<-\EOF &&
 214        Blob Guy (1):
 215              second
 216        Repo Guy (1):
 218              initial
 219        EOF
 221        git -c mailmap.blob=map:just-bugs shortlog HEAD >actual &&
 222        test_cmp expect actual
 223'
 224test_expect_success 'mailmap.blob overrides .mailmap' '
 226        cat >expect <<-\EOF &&
 227        Blob Guy (2):
 228              initial
 229              second
 230        EOF
 232        git -c mailmap.blob=map:both shortlog HEAD >actual &&
 233        test_cmp expect actual
 234'
 235test_expect_success 'mailmap.file overrides mailmap.blob' '
 237        cat >expect <<-\EOF &&
 238        Blob Guy (1):
 239              second
 240        Internal Guy (1):
 242              initial
 243        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'
 251test_expect_success 'mailmap.blob can be missing' '
 253        cat >expect <<-\EOF &&
 254        Repo Guy (1):
 255              initial
 256        nick1 (1):
 258              second
 259        EOF
 261        git -c mailmap.blob=map:nonexistent shortlog HEAD >actual &&
 262        test_cmp expect actual
 263'
 264test_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'
 279test_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'
 289test_expect_success 'mailmap.blob can handle blobs without trailing newline' '
 291        cat >expect <<-\EOF &&
 292        Tricky Guy (1):
 293              initial
 294        nick1 (1):
 296              second
 297        EOF
 299        git -c mailmap.blob=map:no-newline shortlog HEAD >actual &&
 300        test_cmp expect actual
 301'
 302test_expect_success 'cleanup after mailmap.blob tests' '
 304        rm -f .mailmap
 305'
 306test_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'
 315test_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# Extended mailmap configurations should give us the following output for shortlog
 326cat >expect <<\EOF
 327A U Thor <author@example.com> (1):
 328      initial
 329CTO <cto@company.xx> (1):
 331      seventh
 332Other Author <other@author.xx> (2):
 334      third
 335      fourth
 336Santa Claus <santa.claus@northpole.xx> (2):
 338      fifth
 339      sixth
 340Some Dude <some@dude.xx> (1):
 342      second
 343EOF
 345test_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        echo four >>one &&
 353        git add one &&
 354        test_tick &&
 355        git commit --author "nick2 <nick2@company.xx>" -m fourth &&
 356        echo five >>one &&
 358        git add one &&
 359        test_tick &&
 360        git commit --author "santa <me@company.xx>" -m fifth &&
 361        echo six >>one &&
 363        git add one &&
 364        test_tick &&
 365        git commit --author "claus <me@company.xx>" -m sixth &&
 366        echo seven >>one &&
 368        git add one &&
 369        test_tick &&
 370        git commit --author "CTO <cto@coompany.xx>" -m seventh &&
 371        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        git shortlog -e HEAD >actual &&
 382        test_cmp expect actual
 383'
 385# git log with --pretty format which uses the name and email mailmap placemarkers
 387cat >expect <<\EOF
 388Author CTO <cto@coompany.xx> maps to CTO <cto@company.xx>
 389Committer C O Mitter <committer@example.com> maps to Committed <committer@example.com>
 390Author claus <me@company.xx> maps to Santa Claus <santa.claus@northpole.xx>
 392Committer C O Mitter <committer@example.com> maps to Committed <committer@example.com>
 393Author santa <me@company.xx> maps to Santa Claus <santa.claus@northpole.xx>
 395Committer C O Mitter <committer@example.com> maps to Committed <committer@example.com>
 396Author nick2 <nick2@company.xx> maps to Other Author <other@author.xx>
 398Committer C O Mitter <committer@example.com> maps to Committed <committer@example.com>
 399Author nick2 <bugs@company.xx> maps to Other Author <other@author.xx>
 401Committer C O Mitter <committer@example.com> maps to Committed <committer@example.com>
 402Author nick1 <bugs@company.xx> maps to Some Dude <some@dude.xx>
 404Committer C O Mitter <committer@example.com> maps to Committed <committer@example.com>
 405Author A U Thor <author@example.com> maps to A U Thor <author@example.com>
 407Committer C O Mitter <committer@example.com> maps to Committed <committer@example.com>
 408EOF
 409test_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'
 414cat >expect <<\EOF
 416Author: CTO <cto@company.xx>
 417Author: Santa Claus <santa.claus@northpole.xx>
 418Author: Santa Claus <santa.claus@northpole.xx>
 419Author: Other Author <other@author.xx>
 420Author: Other Author <other@author.xx>
 421Author: Some Dude <some@dude.xx>
 422Author: A U Thor <author@example.com>
 423EOF
 424test_expect_success 'Log output with --use-mailmap' '
 426        git log --use-mailmap | grep Author >actual &&
 427        test_cmp expect actual
 428'
 429cat >expect <<\EOF
 431Author: CTO <cto@company.xx>
 432Author: Santa Claus <santa.claus@northpole.xx>
 433Author: Santa Claus <santa.claus@northpole.xx>
 434Author: Other Author <other@author.xx>
 435Author: Other Author <other@author.xx>
 436Author: Some Dude <some@dude.xx>
 437Author: A U Thor <author@example.com>
 438EOF
 439test_expect_success 'Log output with log.mailmap' '
 441        git -c log.mailmap=True log | grep Author >actual &&
 442        test_cmp expect actual
 443'
 444cat >expect <<\EOF
 446Author: Santa Claus <santa.claus@northpole.xx>
 447Author: Santa Claus <santa.claus@northpole.xx>
 448EOF
 449test_expect_success 'Grep author with --use-mailmap' '
 451        git log --use-mailmap --author Santa | grep Author >actual &&
 452        test_cmp expect actual
 453'
 454cat >expect <<\EOF
 455Author: Santa Claus <santa.claus@northpole.xx>
 456Author: Santa Claus <santa.claus@northpole.xx>
 457EOF
 458test_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'
 463test_expect_success 'Only grep replaced author with --use-mailmap' '
 465        git log --use-mailmap --author "<cto@coompany.xx>" >actual &&
 466        test_must_be_empty actual
 467'
 468# git blame
 470cat >expect <<\EOF
 471^OBJI (A U Thor     DATE 1) one
 472OBJID (Some Dude    DATE 2) two
 473OBJID (Other Author DATE 3) three
 474OBJID (Other Author DATE 4) four
 475OBJID (Santa Claus  DATE 5) five
 476OBJID (Santa Claus  DATE 6) six
 477OBJID (CTO          DATE 7) seven
 478EOF
 479test_expect_success 'Blame output (complex mapping)' '
 480        git blame one >actual &&
 481        fuzz_blame actual >actual.fuzz &&
 482        test_cmp expect actual.fuzz
 483'
 484cat >expect <<\EOF
 486Some Dude <some@dude.xx>
 487EOF
 488test_expect_success 'commit --author honors mailmap' '
 490        test_must_fail git commit --author "nick" --allow-empty -meight &&
 491        git commit --author "Some Dude" --allow-empty -meight &&
 492        git show --pretty=format:"%an <%ae>%n" >actual &&
 493        test_cmp expect actual
 494'
 495test_done