7a5434c7ab8580d93816cf531c4ea16f0da96c64
   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 'with succeeding hook' '
  88        test_when_finished "rm -f \"$PRECOMMIT\" expected_hooks actual_hooks" &&
  89        cp "$HOOKDIR/success.sample" "$PRECOMMIT" &&
  90        echo "$PRECOMMIT" >expected_hooks &&
  91        echo "more" >>file &&
  92        git add file &&
  93        git commit -m "more" &&
  94        test_cmp expected_hooks actual_hooks
  95'
  96
  97test_expect_success 'with succeeding hook (merge)' '
  98        test_when_finished "rm -f \"$PREMERGE\" expected_hooks actual_hooks" &&
  99        cp "$HOOKDIR/success.sample" "$PREMERGE" &&
 100        echo "$PREMERGE" >expected_hooks &&
 101        git checkout side &&
 102        git merge -m "merge master" master &&
 103        git checkout master &&
 104        test_cmp expected_hooks actual_hooks
 105'
 106
 107test_expect_success 'automatic merge fails; both hooks are available' '
 108        test_when_finished "rm -f \"$PREMERGE\" \"$PRECOMMIT\"" &&
 109        test_when_finished "rm -f expected_hooks actual_hooks" &&
 110        test_when_finished "git checkout master" &&
 111        cp "$HOOKDIR/success.sample" "$PREMERGE" &&
 112        cp "$HOOKDIR/success.sample" "$PRECOMMIT" &&
 113
 114        git checkout conflicting-a &&
 115        test_must_fail git merge -m "merge conflicting-b" conflicting-b &&
 116        test_path_is_missing actual_hooks &&
 117
 118        echo "$PRECOMMIT" >expected_hooks &&
 119        echo a+b >conflicting &&
 120        git add conflicting &&
 121        git commit -m "resolve conflict" &&
 122        test_cmp expected_hooks actual_hooks
 123'
 124
 125test_expect_success '--no-verify with succeeding hook' '
 126        test_when_finished "rm -f \"$PRECOMMIT\" actual_hooks" &&
 127        cp "$HOOKDIR/success.sample" "$PRECOMMIT" &&
 128        echo "even more" >>file &&
 129        git add file &&
 130        git commit --no-verify -m "even more" &&
 131        test_path_is_missing actual_hooks
 132'
 133
 134test_expect_success 'with failing hook' '
 135        test_when_finished "rm -f \"$PRECOMMIT\" expected_hooks actual_hooks" &&
 136        cp "$HOOKDIR/fail.sample" "$PRECOMMIT" &&
 137        echo "$PRECOMMIT" >expected_hooks &&
 138        echo "another" >>file &&
 139        git add file &&
 140        test_must_fail git commit -m "another" &&
 141        test_cmp expected_hooks actual_hooks
 142'
 143
 144test_expect_success '--no-verify with failing hook' '
 145        test_when_finished "rm -f \"$PRECOMMIT\" actual_hooks" &&
 146        cp "$HOOKDIR/fail.sample" "$PRECOMMIT" &&
 147        echo "stuff" >>file &&
 148        git add file &&
 149        git commit --no-verify -m "stuff" &&
 150        test_path_is_missing actual_hooks
 151'
 152
 153test_expect_success 'with failing hook (merge)' '
 154        test_when_finished "rm -f \"$PREMERGE\" expected_hooks actual_hooks" &&
 155        cp "$HOOKDIR/fail.sample" "$PREMERGE" &&
 156        echo "$PREMERGE" >expected_hooks &&
 157        git checkout side &&
 158        test_must_fail git merge -m "merge master" master &&
 159        git checkout master &&
 160        test_cmp expected_hooks actual_hooks
 161'
 162
 163test_expect_success POSIXPERM 'with non-executable hook' '
 164        test_when_finished "rm -f \"$PRECOMMIT\" actual_hooks" &&
 165        cp "$HOOKDIR/non-exec.sample" "$PRECOMMIT" &&
 166        echo "content" >>file &&
 167        git add file &&
 168        git commit -m "content" &&
 169        test_path_is_missing actual_hooks
 170'
 171
 172test_expect_success POSIXPERM '--no-verify with non-executable hook' '
 173        test_when_finished "rm -f \"$PRECOMMIT\" actual_hooks" &&
 174        cp "$HOOKDIR/non-exec.sample" "$PRECOMMIT" &&
 175        echo "more content" >>file &&
 176        git add file &&
 177        git commit --no-verify -m "more content" &&
 178        test_path_is_missing actual_hooks
 179'
 180
 181test_expect_success POSIXPERM 'with non-executable hook (merge)' '
 182        test_when_finished "rm -f \"$PREMERGE\" actual_hooks" &&
 183        cp "$HOOKDIR/non-exec.sample" "$PREMERGE" &&
 184        git branch -f side side-orig &&
 185        git checkout side &&
 186        git merge -m "merge master" master &&
 187        git checkout master &&
 188        test_path_is_missing actual_hooks
 189'
 190
 191test_expect_success 'with hook requiring GIT_PREFIX' '
 192        test_when_finished "rm -rf \"$PRECOMMIT\" expected_hooks actual_hooks success" &&
 193        cp "$HOOKDIR/require-prefix.sample" "$PRECOMMIT" &&
 194        echo "$PRECOMMIT" >expected_hooks &&
 195        echo "more content" >>file &&
 196        git add file &&
 197        mkdir success &&
 198        (
 199                cd success &&
 200                git commit -m "hook requires GIT_PREFIX = success/"
 201        ) &&
 202        test_cmp expected_hooks actual_hooks
 203'
 204
 205test_expect_success 'with failing hook requiring GIT_PREFIX' '
 206        test_when_finished "rm -rf \"$PRECOMMIT\" expected_hooks actual_hooks fail" &&
 207        cp "$HOOKDIR/require-prefix.sample" "$PRECOMMIT" &&
 208        echo "$PRECOMMIT" >expected_hooks &&
 209        echo "more content" >>file &&
 210        git add file &&
 211        mkdir fail &&
 212        (
 213                cd fail &&
 214                test_must_fail git commit -m "hook must fail"
 215        ) &&
 216        git checkout -- file &&
 217        test_cmp expected_hooks actual_hooks
 218'
 219
 220test_expect_success 'check the author in hook' '
 221        test_when_finished "rm -f \"$PRECOMMIT\" expected_hooks actual_hooks" &&
 222        cp "$HOOKDIR/check-author.sample" "$PRECOMMIT" &&
 223        cat >expected_hooks <<-EOF &&
 224        $PRECOMMIT
 225        $PRECOMMIT
 226        $PRECOMMIT
 227        EOF
 228        test_must_fail git commit --allow-empty -m "by a.u.thor" &&
 229        (
 230                GIT_AUTHOR_NAME="New Author" &&
 231                GIT_AUTHOR_EMAIL="newauthor@example.com" &&
 232                export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL &&
 233                git commit --allow-empty -m "by new.author via env" &&
 234                git show -s
 235        ) &&
 236        git commit --author="New Author <newauthor@example.com>" \
 237                --allow-empty -m "by new.author via command line" &&
 238        git show -s &&
 239        test_cmp expected_hooks actual_hooks
 240'
 241
 242test_done