#!/bin/sh test_description='.mailmap configurations' . ./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 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 " -m second ' test_expect_success 'check-mailmap no arguments' ' test_must_fail git check-mailmap ' test_expect_success 'check-mailmap arguments' ' cat >expect <<- EOF && $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL> nick1 EOF git check-mailmap \ "$GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>" \ "nick1 " >actual && test_cmp expect actual ' test_expect_success 'check-mailmap --stdin' ' cat >expect <<- EOF && $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL> nick1 EOF git check-mailmap --stdin actual && test_cmp expect actual ' test_expect_success 'check-mailmap --stdin arguments' ' cat >expect <<-\EOF && Internal Guy EOF cat >expect && git check-mailmap --stdin "Internal Guy " \ 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 nick1 (1): second EOF test_expect_success 'No mailmap' ' git shortlog HEAD >actual && test_cmp expect actual ' cat >expect <<\EOF Repo Guy (1): initial nick1 (1): second EOF test_expect_success 'default .mailmap' ' echo "Repo Guy <$GIT_AUTHOR_EMAIL>" > .mailmap && 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 Repo Guy (1): initial EOF test_expect_success 'mailmap.file set' ' mkdir -p internal_mailmap && echo "Internal Guy " > internal_mailmap/.mailmap && git config mailmap.file internal_mailmap/.mailmap && git shortlog HEAD >actual && test_cmp expect actual ' cat >expect <<\EOF External Guy (1): initial Internal Guy (1): second EOF test_expect_success 'mailmap.file override' ' echo "External Guy <$GIT_AUTHOR_EMAIL>" >> internal_mailmap/.mailmap && git config mailmap.file internal_mailmap/.mailmap && git shortlog HEAD >actual && test_cmp expect actual ' cat >expect <<\EOF Repo Guy (1): initial nick1 (1): second EOF test_expect_success 'mailmap.file non-existent' ' rm internal_mailmap/.mailmap && rmdir internal_mailmap && git shortlog HEAD >actual && test_cmp expect actual ' cat >expect <<\EOF Internal Guy (1): second Repo Guy (1): initial EOF test_expect_success 'name entry after email entry' ' mkdir -p internal_mailmap && echo " " >internal_mailmap/.mailmap && echo "Internal Guy " >>internal_mailmap/.mailmap && git shortlog HEAD >actual && test_cmp expect actual ' cat >expect <<\EOF Internal Guy (1): second Repo Guy (1): initial EOF test_expect_success 'name entry after email entry, case-insensitive' ' mkdir -p internal_mailmap && echo " " >internal_mailmap/.mailmap && echo "Internal Guy " >>internal_mailmap/.mailmap && git shortlog HEAD >actual && test_cmp expect actual ' cat >expect << EOF $GIT_AUTHOR_NAME (1): initial nick1 (1): second EOF test_expect_success 'No mailmap files, but configured' ' rm -f .mailmap internal_mailmap/.mailmap && git shortlog HEAD >actual && test_cmp expect actual ' test_expect_success 'setup mailmap blob tests' ' git checkout -b map && test_when_finished "git checkout master" && cat >just-bugs <<- EOF && Blob Guy EOF cat >both <<- EOF && Blob Guy <$GIT_AUTHOR_EMAIL> Blob Guy 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 ' test_expect_success 'mailmap.blob set' ' cat >expect <<-\EOF && Blob Guy (1): second Repo Guy (1): initial EOF git -c mailmap.blob=map:just-bugs shortlog HEAD >actual && test_cmp expect actual ' test_expect_success 'mailmap.blob overrides .mailmap' ' cat >expect <<-\EOF && Blob Guy (2): initial second EOF git -c mailmap.blob=map:both shortlog HEAD >actual && test_cmp expect actual ' test_expect_success 'mailmap.file overrides mailmap.blob' ' cat >expect <<-\EOF && Blob Guy (1): second Internal Guy (1): initial EOF git \ -c mailmap.blob=map:both \ -c mailmap.file=internal.map \ shortlog HEAD >actual && test_cmp expect actual ' test_expect_success 'mailmap.blob can be missing' ' cat >expect <<-\EOF && Repo Guy (1): initial nick1 (1): second EOF git -c mailmap.blob=map:nonexistent shortlog HEAD >actual && test_cmp expect actual ' test_expect_success 'mailmap.blob defaults to off in non-bare repo' ' git init non-bare && ( cd non-bare && test_commit one .mailmap "Fake Name <$GIT_AUTHOR_EMAIL>" && echo " 1 Fake Name" >expect && git shortlog -ns HEAD >actual && test_cmp expect actual && rm .mailmap && echo " 1 $GIT_AUTHOR_NAME" >expect && git shortlog -ns HEAD >actual && test_cmp expect actual ) ' 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 && git shortlog -ns HEAD >actual && test_cmp expect actual ) ' test_expect_success 'mailmap.blob can handle blobs without trailing newline' ' cat >expect <<-\EOF && Tricky Guy (1): initial nick1 (1): second EOF git -c mailmap.blob=map:no-newline shortlog HEAD >actual && 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 " >>expect && echo "A <$GIT_AUTHOR_EMAIL>" >.mailmap && test_when_finished "rm .mailmap" && git shortlog -es HEAD >actual && test_cmp expect actual ' test_expect_success 'preserve canonical email case' ' echo " 1 $GIT_AUTHOR_NAME " >expect && echo " 1 nick1 " >>expect && echo " <$GIT_AUTHOR_EMAIL>" >.mailmap && test_when_finished "rm .mailmap" && 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 CTO (1): seventh Other Author (2): third fourth Santa Claus (2): fifth sixth Some Dude (1): second EOF test_expect_success 'Shortlog output (complex mapping)' ' echo three >>one && git add one && test_tick && git commit --author "nick2 " -m third && echo four >>one && git add one && test_tick && git commit --author "nick2 " -m fourth && echo five >>one && git add one && test_tick && git commit --author "santa " -m fifth && echo six >>one && git add one && test_tick && git commit --author "claus " -m sixth && echo seven >>one && git add one && test_tick && git commit --author "CTO " -m seventh && mkdir -p internal_mailmap && echo "Committed <$GIT_COMMITTER_EMAIL>" > internal_mailmap/.mailmap && echo " " >> internal_mailmap/.mailmap && echo "Some Dude nick1 " >> internal_mailmap/.mailmap && echo "Other Author nick2 " >> internal_mailmap/.mailmap && echo "Other Author " >> internal_mailmap/.mailmap && echo "Santa Claus " >> internal_mailmap/.mailmap && echo "Santa Claus " >> internal_mailmap/.mailmap && 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 maps to CTO Committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> maps to Committed <$GIT_COMMITTER_EMAIL> Author claus maps to Santa Claus Committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> maps to Committed <$GIT_COMMITTER_EMAIL> Author santa maps to Santa Claus Committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> maps to Committed <$GIT_COMMITTER_EMAIL> Author nick2 maps to Other Author Committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> maps to Committed <$GIT_COMMITTER_EMAIL> Author nick2 maps to Other Author Committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> maps to Committed <$GIT_COMMITTER_EMAIL> Author nick1 maps to Some Dude 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 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 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 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 Author: Santa Claus Author: Santa Claus Author: Other Author Author: Other Author Author: Some Dude Author: $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL> EOF test_expect_success 'Log output with --use-mailmap' ' git log --use-mailmap | grep Author >actual && test_cmp expect actual ' cat >expect << EOF Author: CTO Author: Santa Claus Author: Santa Claus Author: Other Author Author: Other Author Author: Some Dude Author: $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL> EOF test_expect_success 'Log output with log.mailmap' ' git -c log.mailmap=True log | grep Author >actual && test_cmp expect actual ' test_expect_success 'log.mailmap=false disables mailmap' ' cat >expect <<- EOF && Author: CTO Author: claus Author: santa Author: nick2 Author: nick2 Author: nick1 Author: $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL> EOF git -c log.mailmap=False log | grep Author > actual && test_cmp expect actual ' test_expect_success '--no-use-mailmap disables mailmap' ' cat >expect <<- EOF && Author: CTO Author: claus Author: santa Author: nick2 Author: nick2 Author: nick1 Author: $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL> EOF git log --no-use-mailmap | grep Author > actual && test_cmp expect actual ' cat >expect <<\EOF Author: Santa Claus Author: Santa Claus EOF test_expect_success 'Grep author with --use-mailmap' ' git log --use-mailmap --author Santa | grep Author >actual && test_cmp expect actual ' cat >expect <<\EOF Author: Santa Claus Author: Santa Claus EOF test_expect_success 'Grep author with log.mailmap' ' 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' ' git log --author Santa | grep Author >actual && test_cmp expect actual ' test_expect_success 'Only grep replaced author with --use-mailmap' ' git log --use-mailmap --author "" >actual && test_must_be_empty actual ' # git blame cat >expect <actual && fuzz_blame actual >actual.fuzz && test_cmp expect actual.fuzz ' cat >expect <<\EOF Some Dude EOF test_expect_success 'commit --author honors mailmap' ' 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_done