t / t3511-cherry-pick-x.shon commit Merge branch 'bc/reread-attributes-during-rebase' (c8ada15)
   1#!/bin/sh
   2
   3test_description='Test cherry-pick -x and -s'
   4
   5. ./test-lib.sh
   6
   7pristine_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}
  13
  14mesg_one_line='base: commit message'
  15
  16mesg_no_footer="$mesg_one_line
  17
  18OneWordBodyThatsNotA-S-o-B"
  19
  20mesg_with_footer="$mesg_no_footer
  21
  22Signed-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>"
  25
  26mesg_broken_footer="$mesg_no_footer
  27
  28This is not recognized as a footer because Myfooter is not a recognized token.
  29Myfooter: A.U. Thor <author@example.com>"
  30
  31mesg_with_footer_sob="$mesg_with_footer
  32Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
  33
  34mesg_with_cherry_footer="$mesg_with_footer_sob
  35(cherry picked from commit da39a3ee5e6b4b0d3255bfef95601890afd80709)
  36Tested-by: C.U. Thor <cuthor@example.com>"
  37
  38mesg_unclean="$mesg_one_line
  39
  40
  41leading empty lines
  42
  43
  44consecutive empty lines
  45
  46# hash tag comment
  47
  48trailing empty lines
  49
  50
  51"
  52
  53test_expect_success setup '
  54        git config advice.detachedhead false &&
  55        echo unrelated >unrelated &&
  56        git add unrelated &&
  57        test_commit initial foo a &&
  58        test_commit "$mesg_one_line" foo b mesg-one-line &&
  59        git reset --hard initial &&
  60        test_commit "$mesg_no_footer" foo b mesg-no-footer &&
  61        git reset --hard initial &&
  62        test_commit "$mesg_broken_footer" foo b mesg-broken-footer &&
  63        git reset --hard initial &&
  64        test_commit "$mesg_with_footer" foo b mesg-with-footer &&
  65        git reset --hard initial &&
  66        test_commit "$mesg_with_footer_sob" foo b mesg-with-footer-sob &&
  67        git reset --hard initial &&
  68        test_commit "$mesg_with_cherry_footer" foo b mesg-with-cherry-footer &&
  69        git reset --hard initial &&
  70        test_config commit.cleanup verbatim &&
  71        test_commit "$mesg_unclean" foo b mesg-unclean &&
  72        test_unconfig commit.cleanup &&
  73        pristine_detach initial &&
  74        test_commit conflicting unrelated
  75'
  76
  77test_expect_success 'cherry-pick -x inserts blank line after one line subject' '
  78        pristine_detach initial &&
  79        sha1=$(git rev-parse mesg-one-line^0) &&
  80        git cherry-pick -x mesg-one-line &&
  81        cat <<-EOF >expect &&
  82                $mesg_one_line
  83
  84                (cherry picked from commit $sha1)
  85        EOF
  86        git log -1 --pretty=format:%B >actual &&
  87        test_cmp expect actual
  88'
  89
  90test_expect_success 'cherry-pick -s inserts blank line after one line subject' '
  91        pristine_detach initial &&
  92        git cherry-pick -s mesg-one-line &&
  93        cat <<-EOF >expect &&
  94                $mesg_one_line
  95
  96                Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
  97        EOF
  98        git log -1 --pretty=format:%B >actual &&
  99        test_cmp expect actual
 100'
 101
 102test_expect_success 'cherry-pick -s inserts blank line after non-conforming footer' '
 103        pristine_detach initial &&
 104        git cherry-pick -s mesg-broken-footer &&
 105        cat <<-EOF >expect &&
 106                $mesg_broken_footer
 107
 108                Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
 109        EOF
 110        git log -1 --pretty=format:%B >actual &&
 111        test_cmp expect actual
 112'
 113
 114test_expect_success 'cherry-pick -s recognizes trailer config' '
 115        pristine_detach initial &&
 116        git -c "trailer.Myfooter.ifexists=add" cherry-pick -s mesg-broken-footer &&
 117        cat <<-EOF >expect &&
 118                $mesg_broken_footer
 119                Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
 120        EOF
 121        git log -1 --pretty=format:%B >actual &&
 122        test_cmp expect actual
 123'
 124
 125test_expect_success 'cherry-pick -x inserts blank line when conforming footer not found' '
 126        pristine_detach initial &&
 127        sha1=$(git rev-parse mesg-no-footer^0) &&
 128        git cherry-pick -x mesg-no-footer &&
 129        cat <<-EOF >expect &&
 130                $mesg_no_footer
 131
 132                (cherry picked from commit $sha1)
 133        EOF
 134        git log -1 --pretty=format:%B >actual &&
 135        test_cmp expect actual
 136'
 137
 138test_expect_success 'cherry-pick -s inserts blank line when conforming footer not found' '
 139        pristine_detach initial &&
 140        git cherry-pick -s mesg-no-footer &&
 141        cat <<-EOF >expect &&
 142                $mesg_no_footer
 143
 144                Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
 145        EOF
 146        git log -1 --pretty=format:%B >actual &&
 147        test_cmp expect actual
 148'
 149
 150test_expect_success 'cherry-pick -x -s inserts blank line when conforming footer not found' '
 151        pristine_detach initial &&
 152        sha1=$(git rev-parse mesg-no-footer^0) &&
 153        git cherry-pick -x -s mesg-no-footer &&
 154        cat <<-EOF >expect &&
 155                $mesg_no_footer
 156
 157                (cherry picked from commit $sha1)
 158                Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
 159        EOF
 160        git log -1 --pretty=format:%B >actual &&
 161        test_cmp expect actual
 162'
 163
 164test_expect_success 'cherry-pick -s adds sob when last sob doesnt match committer' '
 165        pristine_detach initial &&
 166        git cherry-pick -s mesg-with-footer &&
 167        cat <<-EOF >expect &&
 168                $mesg_with_footer
 169                Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
 170        EOF
 171        git log -1 --pretty=format:%B >actual &&
 172        test_cmp expect actual
 173'
 174
 175test_expect_success 'cherry-pick -x -s adds sob when last sob doesnt match committer' '
 176        pristine_detach initial &&
 177        sha1=$(git rev-parse mesg-with-footer^0) &&
 178        git cherry-pick -x -s mesg-with-footer &&
 179        cat <<-EOF >expect &&
 180                $mesg_with_footer
 181                (cherry picked from commit $sha1)
 182                Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
 183        EOF
 184        git log -1 --pretty=format:%B >actual &&
 185        test_cmp expect actual
 186'
 187
 188test_expect_success 'cherry-pick -s refrains from adding duplicate trailing sob' '
 189        pristine_detach initial &&
 190        git cherry-pick -s mesg-with-footer-sob &&
 191        cat <<-EOF >expect &&
 192                $mesg_with_footer_sob
 193        EOF
 194        git log -1 --pretty=format:%B >actual &&
 195        test_cmp expect actual
 196'
 197
 198test_expect_success 'cherry-pick -x -s adds sob even when trailing sob exists for committer' '
 199        pristine_detach initial &&
 200        sha1=$(git rev-parse mesg-with-footer-sob^0) &&
 201        git cherry-pick -x -s mesg-with-footer-sob &&
 202        cat <<-EOF >expect &&
 203                $mesg_with_footer_sob
 204                (cherry picked from commit $sha1)
 205                Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
 206        EOF
 207        git log -1 --pretty=format:%B >actual &&
 208        test_cmp expect actual
 209'
 210
 211test_expect_success 'cherry-pick -x handles commits with no NL at end of message' '
 212        pristine_detach initial &&
 213        printf "title\n\nSigned-off-by: A <a@example.com>" >msg &&
 214        sha1=$(git commit-tree -p initial mesg-with-footer^{tree} <msg) &&
 215        git cherry-pick -x $sha1 &&
 216        git log -1 --pretty=format:%B >actual &&
 217
 218        printf "\n(cherry picked from commit %s)\n" $sha1 >>msg &&
 219        test_cmp msg actual
 220'
 221
 222test_expect_success 'cherry-pick -x handles commits with no footer and no NL at end of message' '
 223        pristine_detach initial &&
 224        printf "title\n\nnot a footer" >msg &&
 225        sha1=$(git commit-tree -p initial mesg-with-footer^{tree} <msg) &&
 226        git cherry-pick -x $sha1 &&
 227        git log -1 --pretty=format:%B >actual &&
 228
 229        printf "\n\n(cherry picked from commit %s)\n" $sha1 >>msg &&
 230        test_cmp msg actual
 231'
 232
 233test_expect_success 'cherry-pick -s handles commits with no NL at end of message' '
 234        pristine_detach initial &&
 235        printf "title\n\nSigned-off-by: A <a@example.com>" >msg &&
 236        sha1=$(git commit-tree -p initial mesg-with-footer^{tree} <msg) &&
 237        git cherry-pick -s $sha1 &&
 238        git log -1 --pretty=format:%B >actual &&
 239
 240        printf "\nSigned-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>\n" >>msg &&
 241        test_cmp msg actual
 242'
 243
 244test_expect_success 'cherry-pick -s handles commits with no footer and no NL at end of message' '
 245        pristine_detach initial &&
 246        printf "title\n\nnot a footer" >msg &&
 247        sha1=$(git commit-tree -p initial mesg-with-footer^{tree} <msg) &&
 248        git cherry-pick -s $sha1 &&
 249        git log -1 --pretty=format:%B >actual &&
 250
 251        printf "\n\nSigned-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>\n" >>msg &&
 252        test_cmp msg actual
 253'
 254
 255test_expect_success 'cherry-pick -x treats "(cherry picked from..." line as part of footer' '
 256        pristine_detach initial &&
 257        sha1=$(git rev-parse mesg-with-cherry-footer^0) &&
 258        git cherry-pick -x mesg-with-cherry-footer &&
 259        cat <<-EOF >expect &&
 260                $mesg_with_cherry_footer
 261                (cherry picked from commit $sha1)
 262        EOF
 263        git log -1 --pretty=format:%B >actual &&
 264        test_cmp expect actual
 265'
 266
 267test_expect_success 'cherry-pick -s treats "(cherry picked from..." line as part of footer' '
 268        pristine_detach initial &&
 269        git cherry-pick -s mesg-with-cherry-footer &&
 270        cat <<-EOF >expect &&
 271                $mesg_with_cherry_footer
 272                Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
 273        EOF
 274        git log -1 --pretty=format:%B >actual &&
 275        test_cmp expect actual
 276'
 277
 278test_expect_success 'cherry-pick -x -s treats "(cherry picked from..." line as part of footer' '
 279        pristine_detach initial &&
 280        sha1=$(git rev-parse mesg-with-cherry-footer^0) &&
 281        git cherry-pick -x -s mesg-with-cherry-footer &&
 282        cat <<-EOF >expect &&
 283                $mesg_with_cherry_footer
 284                (cherry picked from commit $sha1)
 285                Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
 286        EOF
 287        git log -1 --pretty=format:%B >actual &&
 288        test_cmp expect actual
 289'
 290
 291test_expect_success 'cherry-pick preserves commit message' '
 292        pristine_detach initial &&
 293        printf "$mesg_unclean" >expect &&
 294        git log -1 --pretty=format:%B mesg-unclean >actual &&
 295        test_cmp expect actual &&
 296        git cherry-pick mesg-unclean &&
 297        git log -1 --pretty=format:%B >actual &&
 298        test_cmp expect actual
 299'
 300
 301test_expect_success 'cherry-pick -x cleans commit message' '
 302        pristine_detach initial &&
 303        git cherry-pick -x mesg-unclean &&
 304        git log -1 --pretty=format:%B >actual &&
 305        printf "%s\n(cherry picked from commit %s)\n" \
 306                "$mesg_unclean" $(git rev-parse mesg-unclean) |
 307                        git stripspace >expect &&
 308        test_cmp expect actual
 309'
 310
 311test_expect_success 'cherry-pick -x respects commit.cleanup' '
 312        pristine_detach initial &&
 313        git -c commit.cleanup=strip cherry-pick -x mesg-unclean &&
 314        git log -1 --pretty=format:%B >actual &&
 315        printf "%s\n(cherry picked from commit %s)\n" \
 316                "$mesg_unclean" $(git rev-parse mesg-unclean) |
 317                        git stripspace -s >expect &&
 318        test_cmp expect actual
 319'
 320
 321test_done