t / t7505-prepare-commit-msg-hook.shon commit untracked-cache: be defensive about missing NULs in index (c6909f9)
   1#!/bin/sh
   2
   3test_description='prepare-commit-msg hook'
   4
   5. ./test-lib.sh
   6
   7test_expect_success 'set up commits for rebasing' '
   8        test_commit root &&
   9        test_commit a a a &&
  10        test_commit b b b &&
  11        git checkout -b rebase-me root &&
  12        test_commit rebase-a a aa &&
  13        test_commit rebase-b b bb &&
  14        for i in $(test_seq 1 13)
  15        do
  16                test_commit rebase-$i c $i
  17        done &&
  18        git checkout master &&
  19
  20        cat >rebase-todo <<-EOF
  21        pick $(git rev-parse rebase-a)
  22        pick $(git rev-parse rebase-b)
  23        fixup $(git rev-parse rebase-1)
  24        fixup $(git rev-parse rebase-2)
  25        pick $(git rev-parse rebase-3)
  26        fixup $(git rev-parse rebase-4)
  27        squash $(git rev-parse rebase-5)
  28        reword $(git rev-parse rebase-6)
  29        squash $(git rev-parse rebase-7)
  30        fixup $(git rev-parse rebase-8)
  31        fixup $(git rev-parse rebase-9)
  32        edit $(git rev-parse rebase-10)
  33        squash $(git rev-parse rebase-11)
  34        squash $(git rev-parse rebase-12)
  35        edit $(git rev-parse rebase-13)
  36        EOF
  37'
  38
  39test_expect_success 'with no hook' '
  40
  41        echo "foo" > file &&
  42        git add file &&
  43        git commit -m "first"
  44
  45'
  46
  47# set up fake editor for interactive editing
  48cat > fake-editor <<'EOF'
  49#!/bin/sh
  50exit 0
  51EOF
  52chmod +x fake-editor
  53
  54## Not using test_set_editor here so we can easily ensure the editor variable
  55## is only set for the editor tests
  56FAKE_EDITOR="$(pwd)/fake-editor"
  57export FAKE_EDITOR
  58
  59# now install hook that always succeeds and adds a message
  60HOOKDIR="$(git rev-parse --git-dir)/hooks"
  61HOOK="$HOOKDIR/prepare-commit-msg"
  62mkdir -p "$HOOKDIR"
  63echo "#!$SHELL_PATH" > "$HOOK"
  64cat >> "$HOOK" <<'EOF'
  65
  66GIT_DIR=$(git rev-parse --git-dir)
  67if test -d "$GIT_DIR/rebase-merge"
  68then
  69        rebasing=1
  70else
  71        rebasing=0
  72fi
  73
  74get_last_cmd () {
  75        tail -n1 "$GIT_DIR/rebase-merge/done" | {
  76                read cmd id _
  77                git log --pretty="[$cmd %s]" -n1 $id
  78        }
  79}
  80
  81if test "$2" = commit
  82then
  83        if test $rebasing = 1
  84        then
  85                source="$3"
  86        else
  87                source=$(git rev-parse "$3")
  88        fi
  89else
  90        source=${2-default}
  91fi
  92test "$GIT_EDITOR" = : && source="$source (no editor)"
  93
  94if test $rebasing = 1
  95then
  96        echo "$source $(get_last_cmd)" >"$1"
  97else
  98        sed -e "1s/.*/$source/" "$1" >msg.tmp
  99        mv msg.tmp "$1"
 100fi
 101exit 0
 102EOF
 103chmod +x "$HOOK"
 104
 105echo dummy template > "$(git rev-parse --git-dir)/template"
 106
 107test_expect_success 'with hook (-m)' '
 108
 109        echo "more" >> file &&
 110        git add file &&
 111        git commit -m "more" &&
 112        test "$(git log -1 --pretty=format:%s)" = "message (no editor)"
 113
 114'
 115
 116test_expect_success 'with hook (-m editor)' '
 117
 118        echo "more" >> file &&
 119        git add file &&
 120        GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit -e -m "more more" &&
 121        test "$(git log -1 --pretty=format:%s)" = message
 122
 123'
 124
 125test_expect_success 'with hook (-t)' '
 126
 127        echo "more" >> file &&
 128        git add file &&
 129        git commit -t "$(git rev-parse --git-dir)/template" &&
 130        test "$(git log -1 --pretty=format:%s)" = template
 131
 132'
 133
 134test_expect_success 'with hook (-F)' '
 135
 136        echo "more" >> file &&
 137        git add file &&
 138        (echo more | git commit -F -) &&
 139        test "$(git log -1 --pretty=format:%s)" = "message (no editor)"
 140
 141'
 142
 143test_expect_success 'with hook (-F editor)' '
 144
 145        echo "more" >> file &&
 146        git add file &&
 147        (echo more more | GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit -e -F -) &&
 148        test "$(git log -1 --pretty=format:%s)" = message
 149
 150'
 151
 152test_expect_success 'with hook (-C)' '
 153
 154        head=$(git rev-parse HEAD) &&
 155        echo "more" >> file &&
 156        git add file &&
 157        git commit -C $head &&
 158        test "$(git log -1 --pretty=format:%s)" = "$head (no editor)"
 159
 160'
 161
 162test_expect_success 'with hook (editor)' '
 163
 164        echo "more more" >> file &&
 165        git add file &&
 166        GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit &&
 167        test "$(git log -1 --pretty=format:%s)" = default
 168
 169'
 170
 171test_expect_success 'with hook (--amend)' '
 172
 173        head=$(git rev-parse HEAD) &&
 174        echo "more" >> file &&
 175        git add file &&
 176        GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit --amend &&
 177        test "$(git log -1 --pretty=format:%s)" = "$head"
 178
 179'
 180
 181test_expect_success 'with hook (-c)' '
 182
 183        head=$(git rev-parse HEAD) &&
 184        echo "more" >> file &&
 185        git add file &&
 186        GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit -c $head &&
 187        test "$(git log -1 --pretty=format:%s)" = "$head"
 188
 189'
 190
 191test_expect_success 'with hook (merge)' '
 192
 193        test_when_finished "git checkout -f master" &&
 194        git checkout -B other HEAD@{1} &&
 195        echo "more" >>file &&
 196        git add file &&
 197        git commit -m other &&
 198        git checkout - &&
 199        git merge --no-ff other &&
 200        test "$(git log -1 --pretty=format:%s)" = "merge (no editor)"
 201'
 202
 203test_expect_success 'with hook and editor (merge)' '
 204
 205        test_when_finished "git checkout -f master" &&
 206        git checkout -B other HEAD@{1} &&
 207        echo "more" >>file &&
 208        git add file &&
 209        git commit -m other &&
 210        git checkout - &&
 211        env GIT_EDITOR="\"\$FAKE_EDITOR\"" git merge --no-ff -e other &&
 212        test "$(git log -1 --pretty=format:%s)" = "merge"
 213'
 214
 215test_rebase () {
 216        expect=$1 &&
 217        mode=$2 &&
 218        test_expect_$expect C_LOCALE_OUTPUT "with hook (rebase ${mode:--i})" '
 219                test_when_finished "\
 220                        git rebase --abort
 221                        git checkout -f master
 222                        git branch -D tmp" &&
 223                git checkout -b tmp rebase-me &&
 224                GIT_SEQUENCE_EDITOR="cp rebase-todo" &&
 225                GIT_EDITOR="\"$FAKE_EDITOR\"" &&
 226                (
 227                        export GIT_SEQUENCE_EDITOR GIT_EDITOR &&
 228                        test_must_fail git rebase -i $mode b &&
 229                        echo x >a &&
 230                        git add a &&
 231                        test_must_fail git rebase --continue &&
 232                        echo x >b &&
 233                        git add b &&
 234                        git commit &&
 235                        git rebase --continue &&
 236                        echo y >a &&
 237                        git add a &&
 238                        git commit &&
 239                        git rebase --continue &&
 240                        echo y >b &&
 241                        git add b &&
 242                        git rebase --continue
 243                ) &&
 244                if test "$mode" = -p # reword amended after pick
 245                then
 246                        n=18
 247                else
 248                        n=17
 249                fi &&
 250                git log --pretty=%s -g -n$n HEAD@{1} >actual &&
 251                test_cmp "$TEST_DIRECTORY/t7505/expected-rebase${mode:--i}" actual
 252        '
 253}
 254
 255test_rebase success
 256test_have_prereq !REBASE_P || test_rebase success -p
 257
 258test_expect_success 'with hook (cherry-pick)' '
 259        test_when_finished "git checkout -f master" &&
 260        git checkout -B other b &&
 261        git cherry-pick rebase-1 &&
 262        test "$(git log -1 --pretty=format:%s)" = "message (no editor)"
 263'
 264
 265test_expect_success 'with hook and editor (cherry-pick)' '
 266        test_when_finished "git checkout -f master" &&
 267        git checkout -B other b &&
 268        git cherry-pick -e rebase-1 &&
 269        test "$(git log -1 --pretty=format:%s)" = merge
 270'
 271
 272cat > "$HOOK" <<'EOF'
 273#!/bin/sh
 274exit 1
 275EOF
 276
 277test_expect_success 'with failing hook' '
 278
 279        test_when_finished "git checkout -f master" &&
 280        head=$(git rev-parse HEAD) &&
 281        echo "more" >> file &&
 282        git add file &&
 283        test_must_fail env GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit -c $head
 284
 285'
 286
 287test_expect_success 'with failing hook (--no-verify)' '
 288
 289        test_when_finished "git checkout -f master" &&
 290        head=$(git rev-parse HEAD) &&
 291        echo "more" >> file &&
 292        git add file &&
 293        test_must_fail env GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit --no-verify -c $head
 294
 295'
 296
 297test_expect_success 'with failing hook (merge)' '
 298
 299        test_when_finished "git checkout -f master" &&
 300        git checkout -B other HEAD@{1} &&
 301        echo "more" >> file &&
 302        git add file &&
 303        rm -f "$HOOK" &&
 304        git commit -m other &&
 305        write_script "$HOOK" <<-EOF &&
 306        exit 1
 307        EOF
 308        git checkout - &&
 309        test_must_fail git merge --no-ff other
 310
 311'
 312
 313test_expect_success C_LOCALE_OUTPUT 'with failing hook (cherry-pick)' '
 314        test_when_finished "git checkout -f master" &&
 315        git checkout -B other b &&
 316        test_must_fail git cherry-pick rebase-1 2>actual &&
 317        test $(grep -c prepare-commit-msg actual) = 1
 318'
 319
 320test_done