t / t7503-pre-commit-and-pre-merge-commit-hooks.shon commit general improvements (43abf13)
   1#!/bin/sh
   2
   3test_description='pre-commit and pre-merge-commit hooks'
   4
   5. ./test-lib.sh
   6
   7HOOKDIR="$(git rev-parse --git-dir)/hooks"
   8PRECOMMIT="$HOOKDIR/pre-commit"
   9PREMERGE="$HOOKDIR/pre-merge-commit"
  10
  11# Prepare sample scripts that write their $0 to actual_hooks
  12test_expect_success 'sample script setup' '
  13        mkdir -p "$HOOKDIR" &&
  14        write_script "$HOOKDIR/success.sample" <<-\EOF &&
  15        echo $0 >>actual_hooks
  16        exit 0
  17        EOF
  18        write_script "$HOOKDIR/fail.sample" <<-\EOF &&
  19        echo $0 >>actual_hooks
  20        exit 1
  21        EOF
  22        write_script "$HOOKDIR/non-exec.sample" <<-\EOF &&
  23        echo $0 >>actual_hooks
  24        exit 1
  25        EOF
  26        chmod -x "$HOOKDIR/non-exec.sample" &&
  27        write_script "$HOOKDIR/require-prefix.sample" <<-\EOF &&
  28        echo $0 >>actual_hooks
  29        test $GIT_PREFIX = "success/"
  30        EOF
  31        write_script "$HOOKDIR/check-author.sample" <<-\EOF
  32        echo $0 >>actual_hooks
  33        test "$GIT_AUTHOR_NAME" = "New Author" &&
  34        test "$GIT_AUTHOR_EMAIL" = "newauthor@example.com"
  35        EOF
  36'
  37
  38test_expect_success 'root commit' '
  39        echo "root" >file &&
  40        git add file &&
  41        git commit -m "zeroth" &&
  42        git checkout -b side &&
  43        echo "foo" >foo &&
  44        git add foo &&
  45        git commit -m "make it non-ff" &&
  46        git branch side-orig side &&
  47        git checkout master
  48'
  49
  50test_expect_success 'setup conflicting branches' '
  51        test_when_finished "git checkout master" &&
  52        git checkout -b conflicting-a master &&
  53        echo a >conflicting &&
  54        git add conflicting &&
  55        git commit -m conflicting-a &&
  56        git checkout -b conflicting-b master &&
  57        echo b >conflicting &&
  58        git add conflicting &&
  59        git commit -m conflicting-b
  60'
  61
  62test_expect_success 'with no hook' '
  63        test_when_finished "rm -f actual_hooks" &&
  64        echo "foo" >file &&
  65        git add file &&
  66        git commit -m "first" &&
  67        test_path_is_missing actual_hooks
  68'
  69
  70test_expect_success 'with no hook (merge)' '
  71        test_when_finished "rm -f actual_hooks" &&
  72        git branch -f side side-orig &&
  73        git checkout side &&
  74        git merge -m "merge master" master &&
  75        git checkout master &&
  76        test_path_is_missing actual_hooks
  77'
  78
  79test_expect_success '--no-verify with no hook' '
  80        test_when_finished "rm -f actual_hooks" &&
  81        echo "bar" >file &&
  82        git add file &&
  83        git commit --no-verify -m "bar" &&
  84        test_path_is_missing actual_hooks
  85'
  86
  87test_expect_success '--no-verify with no hook (merge)' '
  88        test_when_finished "rm -f actual_hooks" &&
  89        git branch -f side side-orig &&
  90        git checkout side &&
  91        git merge --no-verify -m "merge master" master &&
  92        git checkout master &&
  93        test_path_is_missing actual_hooks
  94'
  95
  96test_expect_success 'with succeeding hook' '
  97        test_when_finished "rm -f \"$PRECOMMIT\" expected_hooks actual_hooks" &&
  98        cp "$HOOKDIR/success.sample" "$PRECOMMIT" &&
  99        echo "$PRECOMMIT" >expected_hooks &&
 100        echo "more" >>file &&
 101        git add file &&
 102        git commit -m "more" &&
 103        test_cmp expected_hooks actual_hooks
 104'
 105
 106test_expect_success 'with succeeding hook (merge)' '
 107        test_when_finished "rm -f \"$PREMERGE\" expected_hooks actual_hooks" &&
 108        cp "$HOOKDIR/success.sample" "$PREMERGE" &&
 109        echo "$PREMERGE" >expected_hooks &&
 110        git checkout side &&
 111        git merge -m "merge master" master &&
 112        git checkout master &&
 113        test_cmp expected_hooks actual_hooks
 114'
 115
 116test_expect_success 'automatic merge fails; both hooks are available' '
 117        test_when_finished "rm -f \"$PREMERGE\" \"$PRECOMMIT\"" &&
 118        test_when_finished "rm -f expected_hooks actual_hooks" &&
 119        test_when_finished "git checkout master" &&
 120        cp "$HOOKDIR/success.sample" "$PREMERGE" &&
 121        cp "$HOOKDIR/success.sample" "$PRECOMMIT" &&
 122
 123        git checkout conflicting-a &&
 124        test_must_fail git merge -m "merge conflicting-b" conflicting-b &&
 125        test_path_is_missing actual_hooks &&
 126
 127        echo "$PRECOMMIT" >expected_hooks &&
 128        echo a+b >conflicting &&
 129        git add conflicting &&
 130        git commit -m "resolve conflict" &&
 131        test_cmp expected_hooks actual_hooks
 132'
 133
 134test_expect_success '--no-verify with succeeding hook' '
 135        test_when_finished "rm -f \"$PRECOMMIT\" actual_hooks" &&
 136        cp "$HOOKDIR/success.sample" "$PRECOMMIT" &&
 137        echo "even more" >>file &&
 138        git add file &&
 139        git commit --no-verify -m "even more" &&
 140        test_path_is_missing actual_hooks
 141'
 142
 143test_expect_success '--no-verify with succeeding hook (merge)' '
 144        test_when_finished "rm -f \"$PREMERGE\" actual_hooks" &&
 145        cp "$HOOKDIR/success.sample" "$PREMERGE" &&
 146        git branch -f side side-orig &&
 147        git checkout side &&
 148        git merge --no-verify -m "merge master" master &&
 149        git checkout master &&
 150        test_path_is_missing actual_hooks
 151'
 152
 153test_expect_success 'with failing hook' '
 154        test_when_finished "rm -f \"$PRECOMMIT\" expected_hooks actual_hooks" &&
 155        cp "$HOOKDIR/fail.sample" "$PRECOMMIT" &&
 156        echo "$PRECOMMIT" >expected_hooks &&
 157        echo "another" >>file &&
 158        git add file &&
 159        test_must_fail git commit -m "another" &&
 160        test_cmp expected_hooks actual_hooks
 161'
 162
 163test_expect_success '--no-verify with failing hook' '
 164        test_when_finished "rm -f \"$PRECOMMIT\" actual_hooks" &&
 165        cp "$HOOKDIR/fail.sample" "$PRECOMMIT" &&
 166        echo "stuff" >>file &&
 167        git add file &&
 168        git commit --no-verify -m "stuff" &&
 169        test_path_is_missing actual_hooks
 170'
 171
 172test_expect_success 'with failing hook (merge)' '
 173        test_when_finished "rm -f \"$PREMERGE\" expected_hooks actual_hooks" &&
 174        cp "$HOOKDIR/fail.sample" "$PREMERGE" &&
 175        echo "$PREMERGE" >expected_hooks &&
 176        git checkout side &&
 177        test_must_fail git merge -m "merge master" master &&
 178        git checkout master &&
 179        test_cmp expected_hooks actual_hooks
 180'
 181
 182test_expect_success '--no-verify with failing hook (merge)' '
 183        test_when_finished "rm -f \"$PREMERGE\" actual_hooks" &&
 184        cp "$HOOKDIR/fail.sample" "$PREMERGE" &&
 185        git branch -f side side-orig &&
 186        git checkout side &&
 187        git merge --no-verify -m "merge master" master &&
 188        git checkout master &&
 189        test_path_is_missing actual_hooks
 190'
 191
 192test_expect_success POSIXPERM 'with non-executable hook' '
 193        test_when_finished "rm -f \"$PRECOMMIT\" actual_hooks" &&
 194        cp "$HOOKDIR/non-exec.sample" "$PRECOMMIT" &&
 195        echo "content" >>file &&
 196        git add file &&
 197        git commit -m "content" &&
 198        test_path_is_missing actual_hooks
 199'
 200
 201test_expect_success POSIXPERM '--no-verify with non-executable hook' '
 202        test_when_finished "rm -f \"$PRECOMMIT\" actual_hooks" &&
 203        cp "$HOOKDIR/non-exec.sample" "$PRECOMMIT" &&
 204        echo "more content" >>file &&
 205        git add file &&
 206        git commit --no-verify -m "more content" &&
 207        test_path_is_missing actual_hooks
 208'
 209
 210test_expect_success POSIXPERM 'with non-executable hook (merge)' '
 211        test_when_finished "rm -f \"$PREMERGE\" actual_hooks" &&
 212        cp "$HOOKDIR/non-exec.sample" "$PREMERGE" &&
 213        git branch -f side side-orig &&
 214        git checkout side &&
 215        git merge -m "merge master" master &&
 216        git checkout master &&
 217        test_path_is_missing actual_hooks
 218'
 219
 220test_expect_success POSIXPERM '--no-verify with non-executable hook (merge)' '
 221        test_when_finished "rm -f \"$PREMERGE\" actual_hooks" &&
 222        cp "$HOOKDIR/non-exec.sample" "$PREMERGE" &&
 223        git branch -f side side-orig &&
 224        git checkout side &&
 225        git merge --no-verify -m "merge master" master &&
 226        git checkout master &&
 227        test_path_is_missing actual_hooks
 228'
 229
 230test_expect_success 'with hook requiring GIT_PREFIX' '
 231        test_when_finished "rm -rf \"$PRECOMMIT\" expected_hooks actual_hooks success" &&
 232        cp "$HOOKDIR/require-prefix.sample" "$PRECOMMIT" &&
 233        echo "$PRECOMMIT" >expected_hooks &&
 234        echo "more content" >>file &&
 235        git add file &&
 236        mkdir success &&
 237        (
 238                cd success &&
 239                git commit -m "hook requires GIT_PREFIX = success/"
 240        ) &&
 241        test_cmp expected_hooks actual_hooks
 242'
 243
 244test_expect_success 'with failing hook requiring GIT_PREFIX' '
 245        test_when_finished "rm -rf \"$PRECOMMIT\" expected_hooks actual_hooks fail" &&
 246        cp "$HOOKDIR/require-prefix.sample" "$PRECOMMIT" &&
 247        echo "$PRECOMMIT" >expected_hooks &&
 248        echo "more content" >>file &&
 249        git add file &&
 250        mkdir fail &&
 251        (
 252                cd fail &&
 253                test_must_fail git commit -m "hook must fail"
 254        ) &&
 255        git checkout -- file &&
 256        test_cmp expected_hooks actual_hooks
 257'
 258
 259test_expect_success 'check the author in hook' '
 260        test_when_finished "rm -f \"$PRECOMMIT\" expected_hooks actual_hooks" &&
 261        cp "$HOOKDIR/check-author.sample" "$PRECOMMIT" &&
 262        cat >expected_hooks <<-EOF &&
 263        $PRECOMMIT
 264        $PRECOMMIT
 265        $PRECOMMIT
 266        EOF
 267        test_must_fail git commit --allow-empty -m "by a.u.thor" &&
 268        (
 269                GIT_AUTHOR_NAME="New Author" &&
 270                GIT_AUTHOR_EMAIL="newauthor@example.com" &&
 271                export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL &&
 272                git commit --allow-empty -m "by new.author via env" &&
 273                git show -s
 274        ) &&
 275        git commit --author="New Author <newauthor@example.com>" \
 276                --allow-empty -m "by new.author via command line" &&
 277        git show -s &&
 278        test_cmp expected_hooks actual_hooks
 279'
 280
 281test_done