t / t7504-commit-msg-hook.shon commit t4205: sort log output in a hash-independent way (2a73022)
   1#!/bin/sh
   2
   3test_description='commit-msg hook'
   4
   5. ./test-lib.sh
   6
   7test_expect_success 'with no hook' '
   8
   9        echo "foo" > file &&
  10        git add file &&
  11        git commit -m "first"
  12
  13'
  14
  15# set up fake editor for interactive editing
  16cat > fake-editor <<'EOF'
  17#!/bin/sh
  18cp FAKE_MSG "$1"
  19exit 0
  20EOF
  21chmod +x fake-editor
  22
  23## Not using test_set_editor here so we can easily ensure the editor variable
  24## is only set for the editor tests
  25FAKE_EDITOR="$(pwd)/fake-editor"
  26export FAKE_EDITOR
  27
  28test_expect_success 'with no hook (editor)' '
  29
  30        echo "more foo" >> file &&
  31        git add file &&
  32        echo "more foo" > FAKE_MSG &&
  33        GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit
  34
  35'
  36
  37test_expect_success '--no-verify with no hook' '
  38
  39        echo "bar" > file &&
  40        git add file &&
  41        git commit --no-verify -m "bar"
  42
  43'
  44
  45test_expect_success '--no-verify with no hook (editor)' '
  46
  47        echo "more bar" > file &&
  48        git add file &&
  49        echo "more bar" > FAKE_MSG &&
  50        GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit --no-verify
  51
  52'
  53
  54# now install hook that always succeeds
  55HOOKDIR="$(git rev-parse --git-dir)/hooks"
  56HOOK="$HOOKDIR/commit-msg"
  57mkdir -p "$HOOKDIR"
  58cat > "$HOOK" <<EOF
  59#!/bin/sh
  60exit 0
  61EOF
  62chmod +x "$HOOK"
  63
  64test_expect_success 'with succeeding hook' '
  65
  66        echo "more" >> file &&
  67        git add file &&
  68        git commit -m "more"
  69
  70'
  71
  72test_expect_success 'with succeeding hook (editor)' '
  73
  74        echo "more more" >> file &&
  75        git add file &&
  76        echo "more more" > FAKE_MSG &&
  77        GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit
  78
  79'
  80
  81test_expect_success '--no-verify with succeeding hook' '
  82
  83        echo "even more" >> file &&
  84        git add file &&
  85        git commit --no-verify -m "even more"
  86
  87'
  88
  89test_expect_success '--no-verify with succeeding hook (editor)' '
  90
  91        echo "even more more" >> file &&
  92        git add file &&
  93        echo "even more more" > FAKE_MSG &&
  94        GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit --no-verify
  95
  96'
  97
  98# now a hook that fails
  99cat > "$HOOK" <<EOF
 100#!/bin/sh
 101exit 1
 102EOF
 103
 104commit_msg_is () {
 105        test "$(git log --pretty=format:%s%b -1)" = "$1"
 106}
 107
 108test_expect_success 'with failing hook' '
 109
 110        echo "another" >> file &&
 111        git add file &&
 112        test_must_fail git commit -m "another"
 113
 114'
 115
 116test_expect_success 'with failing hook (editor)' '
 117
 118        echo "more another" >> file &&
 119        git add file &&
 120        echo "more another" > FAKE_MSG &&
 121        ! (GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit)
 122
 123'
 124
 125test_expect_success '--no-verify with failing hook' '
 126
 127        echo "stuff" >> file &&
 128        git add file &&
 129        git commit --no-verify -m "stuff"
 130
 131'
 132
 133test_expect_success '--no-verify with failing hook (editor)' '
 134
 135        echo "more stuff" >> file &&
 136        git add file &&
 137        echo "more stuff" > FAKE_MSG &&
 138        GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit --no-verify
 139
 140'
 141
 142test_expect_success 'merge fails with failing hook' '
 143
 144        test_when_finished "git branch -D newbranch" &&
 145        test_when_finished "git checkout -f master" &&
 146        git checkout --orphan newbranch &&
 147        : >file2 &&
 148        git add file2 &&
 149        git commit --no-verify file2 -m in-side-branch &&
 150        test_must_fail git merge --allow-unrelated-histories master &&
 151        commit_msg_is "in-side-branch" # HEAD before merge
 152
 153'
 154
 155test_expect_success 'merge bypasses failing hook with --no-verify' '
 156
 157        test_when_finished "git branch -D newbranch" &&
 158        test_when_finished "git checkout -f master" &&
 159        git checkout --orphan newbranch &&
 160        : >file2 &&
 161        git add file2 &&
 162        git commit --no-verify file2 -m in-side-branch &&
 163        git merge --no-verify --allow-unrelated-histories master &&
 164        commit_msg_is "Merge branch '\''master'\'' into newbranch"
 165'
 166
 167
 168chmod -x "$HOOK"
 169test_expect_success POSIXPERM 'with non-executable hook' '
 170
 171        echo "content" >> file &&
 172        git add file &&
 173        git commit -m "content"
 174
 175'
 176
 177test_expect_success POSIXPERM 'with non-executable hook (editor)' '
 178
 179        echo "content again" >> file &&
 180        git add file &&
 181        echo "content again" > FAKE_MSG &&
 182        GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit -m "content again"
 183
 184'
 185
 186test_expect_success POSIXPERM '--no-verify with non-executable hook' '
 187
 188        echo "more content" >> file &&
 189        git add file &&
 190        git commit --no-verify -m "more content"
 191
 192'
 193
 194test_expect_success POSIXPERM '--no-verify with non-executable hook (editor)' '
 195
 196        echo "even more content" >> file &&
 197        git add file &&
 198        echo "even more content" > FAKE_MSG &&
 199        GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit --no-verify
 200
 201'
 202
 203# now a hook that edits the commit message
 204cat > "$HOOK" <<'EOF'
 205#!/bin/sh
 206echo "new message" > "$1"
 207exit 0
 208EOF
 209chmod +x "$HOOK"
 210
 211test_expect_success 'hook edits commit message' '
 212
 213        echo "additional" >> file &&
 214        git add file &&
 215        git commit -m "additional" &&
 216        commit_msg_is "new message"
 217
 218'
 219
 220test_expect_success 'hook edits commit message (editor)' '
 221
 222        echo "additional content" >> file &&
 223        git add file &&
 224        echo "additional content" > FAKE_MSG &&
 225        GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit &&
 226        commit_msg_is "new message"
 227
 228'
 229
 230test_expect_success "hook doesn't edit commit message" '
 231
 232        echo "plus" >> file &&
 233        git add file &&
 234        git commit --no-verify -m "plus" &&
 235        commit_msg_is "plus"
 236
 237'
 238
 239test_expect_success "hook doesn't edit commit message (editor)" '
 240
 241        echo "more plus" >> file &&
 242        git add file &&
 243        echo "more plus" > FAKE_MSG &&
 244        GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit --no-verify &&
 245        commit_msg_is "more plus"
 246'
 247
 248test_expect_success 'hook called in git-merge picks up commit message' '
 249        test_when_finished "git branch -D newbranch" &&
 250        test_when_finished "git checkout -f master" &&
 251        git checkout --orphan newbranch &&
 252        : >file2 &&
 253        git add file2 &&
 254        git commit --no-verify file2 -m in-side-branch &&
 255        git merge --allow-unrelated-histories master &&
 256        commit_msg_is "new message"
 257'
 258
 259test_expect_failure 'merge --continue remembers --no-verify' '
 260        test_when_finished "git branch -D newbranch" &&
 261        test_when_finished "git checkout -f master" &&
 262        git checkout master &&
 263        echo a >file2 &&
 264        git add file2 &&
 265        git commit --no-verify -m "add file2 to master" &&
 266        git checkout -b newbranch master^ &&
 267        echo b >file2 &&
 268        git add file2 &&
 269        git commit --no-verify file2 -m in-side-branch &&
 270        git merge --no-verify -m not-rewritten-by-hook master &&
 271        # resolve conflict:
 272        echo c >file2 &&
 273        git add file2 &&
 274        git merge --continue &&
 275        commit_msg_is not-rewritten-by-hook
 276'
 277
 278# set up fake editor to replace `pick` by `reword`
 279cat > reword-editor <<'EOF'
 280#!/bin/sh
 281mv "$1" "$1".bup &&
 282sed 's/^pick/reword/' <"$1".bup >"$1"
 283EOF
 284chmod +x reword-editor
 285REWORD_EDITOR="$(pwd)/reword-editor"
 286export REWORD_EDITOR
 287
 288test_expect_success 'hook is called for reword during `rebase -i`' '
 289
 290        GIT_SEQUENCE_EDITOR="\"$REWORD_EDITOR\"" git rebase -i HEAD^ &&
 291        commit_msg_is "new message"
 292
 293'
 294
 295
 296test_done