1#!/bin/sh
   2test_description='Test cherry-pick -x and -s'
   4. ./test-lib.sh
   6pristine_detach () {
   8        git cherry-pick --quit &&
   9        git checkout -f "$1^0" &&
  10        git read-tree -u --reset HEAD &&
  11        git clean -d -f -f -q -x
  12}
  13mesg_one_line='base: commit message'
  15mesg_no_footer="$mesg_one_line
  17OneWordBodyThatsNotA-S-o-B"
  19mesg_with_footer="$mesg_no_footer
  21Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
  23Signed-off-by: A.U. Thor <author@example.com>
  24Signed-off-by: B.U. Thor <buthor@example.com>"
  25mesg_broken_footer="$mesg_no_footer
  27The signed-off-by string should begin with the words Signed-off-by followed
  29by a colon and space, and then the signers name and email address. e.g.
  30Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
  31mesg_with_footer_sob="$mesg_with_footer
  33Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
  34mesg_with_cherry_footer="$mesg_with_footer_sob
  36(cherry picked from commit da39a3ee5e6b4b0d3255bfef95601890afd80709)
  37Tested-by: C.U. Thor <cuthor@example.com>"
  38mesg_unclean="$mesg_one_line
  40leading empty lines
  43consecutive empty lines
  46# hash tag comment
  48trailing empty lines
  50"
  53test_expect_success setup '
  55        git config advice.detachedhead false &&
  56        echo unrelated >unrelated &&
  57        git add unrelated &&
  58        test_commit initial foo a &&
  59        test_commit "$mesg_one_line" foo b mesg-one-line &&
  60        git reset --hard initial &&
  61        test_commit "$mesg_no_footer" foo b mesg-no-footer &&
  62        git reset --hard initial &&
  63        test_commit "$mesg_broken_footer" foo b mesg-broken-footer &&
  64        git reset --hard initial &&
  65        test_commit "$mesg_with_footer" foo b mesg-with-footer &&
  66        git reset --hard initial &&
  67        test_commit "$mesg_with_footer_sob" foo b mesg-with-footer-sob &&
  68        git reset --hard initial &&
  69        test_commit "$mesg_with_cherry_footer" foo b mesg-with-cherry-footer &&
  70        git reset --hard initial &&
  71        test_config commit.cleanup verbatim &&
  72        test_commit "$mesg_unclean" foo b mesg-unclean &&
  73        test_unconfig commit.cleanup &&
  74        pristine_detach initial &&
  75        test_commit conflicting unrelated
  76'
  77test_expect_success 'cherry-pick -x inserts blank line after one line subject' '
  79        pristine_detach initial &&
  80        sha1=`git rev-parse mesg-one-line^0` &&
  81        git cherry-pick -x mesg-one-line &&
  82        cat <<-EOF >expect &&
  83                $mesg_one_line
  84                (cherry picked from commit $sha1)
  86        EOF
  87        git log -1 --pretty=format:%B >actual &&
  88        test_cmp expect actual
  89'
  90test_expect_success 'cherry-pick -s inserts blank line after one line subject' '
  92        pristine_detach initial &&
  93        git cherry-pick -s mesg-one-line &&
  94        cat <<-EOF >expect &&
  95                $mesg_one_line
  96                Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
  98        EOF
  99        git log -1 --pretty=format:%B >actual &&
 100        test_cmp expect actual
 101'
 102test_expect_success 'cherry-pick -s inserts blank line after non-conforming footer' '
 104        pristine_detach initial &&
 105        git cherry-pick -s mesg-broken-footer &&
 106        cat <<-EOF >expect &&
 107                $mesg_broken_footer
 108                Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
 110        EOF
 111        git log -1 --pretty=format:%B >actual &&
 112        test_cmp expect actual
 113'
 114test_expect_success 'cherry-pick -x inserts blank line when conforming footer not found' '
 116        pristine_detach initial &&
 117        sha1=`git rev-parse mesg-no-footer^0` &&
 118        git cherry-pick -x mesg-no-footer &&
 119        cat <<-EOF >expect &&
 120                $mesg_no_footer
 121                (cherry picked from commit $sha1)
 123        EOF
 124        git log -1 --pretty=format:%B >actual &&
 125        test_cmp expect actual
 126'
 127test_expect_success 'cherry-pick -s inserts blank line when conforming footer not found' '
 129        pristine_detach initial &&
 130        git cherry-pick -s mesg-no-footer &&
 131        cat <<-EOF >expect &&
 132                $mesg_no_footer
 133                Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
 135        EOF
 136        git log -1 --pretty=format:%B >actual &&
 137        test_cmp expect actual
 138'
 139test_expect_success 'cherry-pick -x -s inserts blank line when conforming footer not found' '
 141        pristine_detach initial &&
 142        sha1=`git rev-parse mesg-no-footer^0` &&
 143        git cherry-pick -x -s mesg-no-footer &&
 144        cat <<-EOF >expect &&
 145                $mesg_no_footer
 146                (cherry picked from commit $sha1)
 148                Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
 149        EOF
 150        git log -1 --pretty=format:%B >actual &&
 151        test_cmp expect actual
 152'
 153test_expect_success 'cherry-pick -s adds sob when last sob doesnt match committer' '
 155        pristine_detach initial &&
 156        git cherry-pick -s mesg-with-footer &&
 157        cat <<-EOF >expect &&
 158                $mesg_with_footer
 159                Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
 160        EOF
 161        git log -1 --pretty=format:%B >actual &&
 162        test_cmp expect actual
 163'
 164test_expect_success 'cherry-pick -x -s adds sob when last sob doesnt match committer' '
 166        pristine_detach initial &&
 167        sha1=`git rev-parse mesg-with-footer^0` &&
 168        git cherry-pick -x -s mesg-with-footer &&
 169        cat <<-EOF >expect &&
 170                $mesg_with_footer
 171                (cherry picked from commit $sha1)
 172                Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
 173        EOF
 174        git log -1 --pretty=format:%B >actual &&
 175        test_cmp expect actual
 176'
 177test_expect_success 'cherry-pick -s refrains from adding duplicate trailing sob' '
 179        pristine_detach initial &&
 180        git cherry-pick -s mesg-with-footer-sob &&
 181        cat <<-EOF >expect &&
 182                $mesg_with_footer_sob
 183        EOF
 184        git log -1 --pretty=format:%B >actual &&
 185        test_cmp expect actual
 186'
 187test_expect_success 'cherry-pick -x -s adds sob even when trailing sob exists for committer' '
 189        pristine_detach initial &&
 190        sha1=`git rev-parse mesg-with-footer-sob^0` &&
 191        git cherry-pick -x -s mesg-with-footer-sob &&
 192        cat <<-EOF >expect &&
 193                $mesg_with_footer_sob
 194                (cherry picked from commit $sha1)
 195                Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
 196        EOF
 197        git log -1 --pretty=format:%B >actual &&
 198        test_cmp expect actual
 199'
 200test_expect_success 'cherry-pick -x treats "(cherry picked from..." line as part of footer' '
 202        pristine_detach initial &&
 203        sha1=`git rev-parse mesg-with-cherry-footer^0` &&
 204        git cherry-pick -x mesg-with-cherry-footer &&
 205        cat <<-EOF >expect &&
 206                $mesg_with_cherry_footer
 207                (cherry picked from commit $sha1)
 208        EOF
 209        git log -1 --pretty=format:%B >actual &&
 210        test_cmp expect actual
 211'
 212test_expect_success 'cherry-pick -s treats "(cherry picked from..." line as part of footer' '
 214        pristine_detach initial &&
 215        git cherry-pick -s mesg-with-cherry-footer &&
 216        cat <<-EOF >expect &&
 217                $mesg_with_cherry_footer
 218                Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
 219        EOF
 220        git log -1 --pretty=format:%B >actual &&
 221        test_cmp expect actual
 222'
 223test_expect_success 'cherry-pick -x -s treats "(cherry picked from..." line as part of footer' '
 225        pristine_detach initial &&
 226        sha1=`git rev-parse mesg-with-cherry-footer^0` &&
 227        git cherry-pick -x -s mesg-with-cherry-footer &&
 228        cat <<-EOF >expect &&
 229                $mesg_with_cherry_footer
 230                (cherry picked from commit $sha1)
 231                Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
 232        EOF
 233        git log -1 --pretty=format:%B >actual &&
 234        test_cmp expect actual
 235'
 236test_expect_success 'cherry-pick preserves commit message' '
 238        pristine_detach initial &&
 239        printf "$mesg_unclean" >expect &&
 240        git log -1 --pretty=format:%B mesg-unclean >actual &&
 241        test_cmp expect actual &&
 242        git cherry-pick mesg-unclean &&
 243        git log -1 --pretty=format:%B >actual &&
 244        test_cmp expect actual
 245'
 246test_done