t / t0001-init.shon commit clean: show an error message when the path is too long (b09364c)
   1#!/bin/sh
   2
   3test_description='git init'
   4
   5. ./test-lib.sh
   6
   7check_config () {
   8        if test -d "$1" && test -f "$1/config" && test -d "$1/refs"
   9        then
  10                : happy
  11        else
  12                echo "expected a directory $1, a file $1/config and $1/refs"
  13                return 1
  14        fi
  15
  16        if test_have_prereq POSIXPERM && test -x "$1/config"
  17        then
  18                echo "$1/config is executable?"
  19                return 1
  20        fi
  21
  22        bare=$(cd "$1" && git config --bool core.bare)
  23        worktree=$(cd "$1" && git config core.worktree) ||
  24        worktree=unset
  25
  26        test "$bare" = "$2" && test "$worktree" = "$3" || {
  27                echo "expected bare=$2 worktree=$3"
  28                echo "     got bare=$bare worktree=$worktree"
  29                return 1
  30        }
  31}
  32
  33test_expect_success 'plain' '
  34        git init plain &&
  35        check_config plain/.git false unset
  36'
  37
  38test_expect_success 'plain nested in bare' '
  39        (
  40                git init --bare bare-ancestor.git &&
  41                cd bare-ancestor.git &&
  42                mkdir plain-nested &&
  43                cd plain-nested &&
  44                git init
  45        ) &&
  46        check_config bare-ancestor.git/plain-nested/.git false unset
  47'
  48
  49test_expect_success 'plain through aliased command, outside any git repo' '
  50        (
  51                HOME=$(pwd)/alias-config &&
  52                export HOME &&
  53                mkdir alias-config &&
  54                echo "[alias] aliasedinit = init" >alias-config/.gitconfig &&
  55
  56                GIT_CEILING_DIRECTORIES=$(pwd) &&
  57                export GIT_CEILING_DIRECTORIES &&
  58
  59                mkdir plain-aliased &&
  60                cd plain-aliased &&
  61                git aliasedinit
  62        ) &&
  63        check_config plain-aliased/.git false unset
  64'
  65
  66test_expect_success 'plain nested through aliased command' '
  67        (
  68                git init plain-ancestor-aliased &&
  69                cd plain-ancestor-aliased &&
  70                echo "[alias] aliasedinit = init" >>.git/config &&
  71                mkdir plain-nested &&
  72                cd plain-nested &&
  73                git aliasedinit
  74        ) &&
  75        check_config plain-ancestor-aliased/plain-nested/.git false unset
  76'
  77
  78test_expect_success 'plain nested in bare through aliased command' '
  79        (
  80                git init --bare bare-ancestor-aliased.git &&
  81                cd bare-ancestor-aliased.git &&
  82                echo "[alias] aliasedinit = init" >>config &&
  83                mkdir plain-nested &&
  84                cd plain-nested &&
  85                git aliasedinit
  86        ) &&
  87        check_config bare-ancestor-aliased.git/plain-nested/.git false unset
  88'
  89
  90test_expect_success 'No extra GIT_* on alias scripts' '
  91        write_script script <<-\EOF &&
  92        env |
  93                sed -n \
  94                        -e "/^GIT_PREFIX=/d" \
  95                        -e "/^GIT_TEXTDOMAINDIR=/d" \
  96                        -e "/^GIT_TRACE2_PARENT/d" \
  97                        -e "/^GIT_/s/=.*//p" |
  98                sort
  99        EOF
 100        ./script >expected &&
 101        git config alias.script \!./script &&
 102        ( mkdir sub && cd sub && git script >../actual ) &&
 103        test_cmp expected actual
 104'
 105
 106test_expect_success 'plain with GIT_WORK_TREE' '
 107        mkdir plain-wt &&
 108        test_must_fail env GIT_WORK_TREE="$(pwd)/plain-wt" git init plain-wt
 109'
 110
 111test_expect_success 'plain bare' '
 112        git --bare init plain-bare-1 &&
 113        check_config plain-bare-1 true unset
 114'
 115
 116test_expect_success 'plain bare with GIT_WORK_TREE' '
 117        mkdir plain-bare-2 &&
 118        test_must_fail \
 119                env GIT_WORK_TREE="$(pwd)/plain-bare-2" \
 120                git --bare init plain-bare-2
 121'
 122
 123test_expect_success 'GIT_DIR bare' '
 124        mkdir git-dir-bare.git &&
 125        GIT_DIR=git-dir-bare.git git init &&
 126        check_config git-dir-bare.git true unset
 127'
 128
 129test_expect_success 'init --bare' '
 130        git init --bare init-bare.git &&
 131        check_config init-bare.git true unset
 132'
 133
 134test_expect_success 'GIT_DIR non-bare' '
 135
 136        (
 137                mkdir non-bare &&
 138                cd non-bare &&
 139                GIT_DIR=.git git init
 140        ) &&
 141        check_config non-bare/.git false unset
 142'
 143
 144test_expect_success 'GIT_DIR & GIT_WORK_TREE (1)' '
 145
 146        (
 147                mkdir git-dir-wt-1.git &&
 148                GIT_WORK_TREE=$(pwd) GIT_DIR=git-dir-wt-1.git git init
 149        ) &&
 150        check_config git-dir-wt-1.git false "$(pwd)"
 151'
 152
 153test_expect_success 'GIT_DIR & GIT_WORK_TREE (2)' '
 154        mkdir git-dir-wt-2.git &&
 155        test_must_fail env \
 156                GIT_WORK_TREE="$(pwd)" \
 157                GIT_DIR=git-dir-wt-2.git \
 158                git --bare init
 159'
 160
 161test_expect_success 'reinit' '
 162
 163        (
 164                mkdir again &&
 165                cd again &&
 166                git init >out1 2>err1 &&
 167                git init >out2 2>err2
 168        ) &&
 169        test_i18ngrep "Initialized empty" again/out1 &&
 170        test_i18ngrep "Reinitialized existing" again/out2 &&
 171        test_must_be_empty again/err1 &&
 172        test_must_be_empty again/err2
 173'
 174
 175test_expect_success 'init with --template' '
 176        mkdir template-source &&
 177        echo content >template-source/file &&
 178        git init --template=../template-source template-custom &&
 179        test_cmp template-source/file template-custom/.git/file
 180'
 181
 182test_expect_success 'init with --template (blank)' '
 183        git init template-plain &&
 184        test_path_is_file template-plain/.git/info/exclude &&
 185        git init --template= template-blank &&
 186        test_path_is_missing template-blank/.git/info/exclude
 187'
 188
 189test_expect_success 'init with init.templatedir set' '
 190        mkdir templatedir-source &&
 191        echo Content >templatedir-source/file &&
 192        test_config_global init.templatedir "${HOME}/templatedir-source" &&
 193        (
 194                mkdir templatedir-set &&
 195                cd templatedir-set &&
 196                sane_unset GIT_TEMPLATE_DIR &&
 197                NO_SET_GIT_TEMPLATE_DIR=t &&
 198                export NO_SET_GIT_TEMPLATE_DIR &&
 199                git init
 200        ) &&
 201        test_cmp templatedir-source/file templatedir-set/.git/file
 202'
 203
 204test_expect_success 'init --bare/--shared overrides system/global config' '
 205        test_config_global core.bare false &&
 206        test_config_global core.sharedRepository 0640 &&
 207        git init --bare --shared=0666 init-bare-shared-override &&
 208        check_config init-bare-shared-override true unset &&
 209        test x0666 = \
 210        x$(git config -f init-bare-shared-override/config core.sharedRepository)
 211'
 212
 213test_expect_success 'init honors global core.sharedRepository' '
 214        test_config_global core.sharedRepository 0666 &&
 215        git init shared-honor-global &&
 216        test x0666 = \
 217        x$(git config -f shared-honor-global/.git/config core.sharedRepository)
 218'
 219
 220test_expect_success 'init allows insanely long --template' '
 221        git init --template=$(printf "x%09999dx" 1) test
 222'
 223
 224test_expect_success 'init creates a new directory' '
 225        rm -fr newdir &&
 226        git init newdir &&
 227        test_path_is_dir newdir/.git/refs
 228'
 229
 230test_expect_success 'init creates a new bare directory' '
 231        rm -fr newdir &&
 232        git init --bare newdir &&
 233        test_path_is_dir newdir/refs
 234'
 235
 236test_expect_success 'init recreates a directory' '
 237        rm -fr newdir &&
 238        mkdir newdir &&
 239        git init newdir &&
 240        test_path_is_dir newdir/.git/refs
 241'
 242
 243test_expect_success 'init recreates a new bare directory' '
 244        rm -fr newdir &&
 245        mkdir newdir &&
 246        git init --bare newdir &&
 247        test_path_is_dir newdir/refs
 248'
 249
 250test_expect_success 'init creates a new deep directory' '
 251        rm -fr newdir &&
 252        git init newdir/a/b/c &&
 253        test_path_is_dir newdir/a/b/c/.git/refs
 254'
 255
 256test_expect_success POSIXPERM 'init creates a new deep directory (umask vs. shared)' '
 257        rm -fr newdir &&
 258        (
 259                # Leading directories should honor umask while
 260                # the repository itself should follow "shared"
 261                mkdir newdir &&
 262                # Remove a default ACL if possible.
 263                (setfacl -k newdir 2>/dev/null || true) &&
 264                umask 002 &&
 265                git init --bare --shared=0660 newdir/a/b/c &&
 266                test_path_is_dir newdir/a/b/c/refs &&
 267                ls -ld newdir/a newdir/a/b > lsab.out &&
 268                ! grep -v "^drwxrw[sx]r-x" lsab.out &&
 269                ls -ld newdir/a/b/c > lsc.out &&
 270                ! grep -v "^drwxrw[sx]---" lsc.out
 271        )
 272'
 273
 274test_expect_success 'init notices EEXIST (1)' '
 275        rm -fr newdir &&
 276        >newdir &&
 277        test_must_fail git init newdir &&
 278        test_path_is_file newdir
 279'
 280
 281test_expect_success 'init notices EEXIST (2)' '
 282        rm -fr newdir &&
 283        mkdir newdir &&
 284        >newdir/a &&
 285        test_must_fail git init newdir/a/b &&
 286        test_path_is_file newdir/a
 287'
 288
 289test_expect_success POSIXPERM,SANITY 'init notices EPERM' '
 290        test_when_finished "chmod +w newdir" &&
 291        rm -fr newdir &&
 292        mkdir newdir &&
 293        chmod -w newdir &&
 294        test_must_fail git init newdir/a/b
 295'
 296
 297test_expect_success 'init creates a new bare directory with global --bare' '
 298        rm -rf newdir &&
 299        git --bare init newdir &&
 300        test_path_is_dir newdir/refs
 301'
 302
 303test_expect_success 'init prefers command line to GIT_DIR' '
 304        rm -rf newdir &&
 305        mkdir otherdir &&
 306        GIT_DIR=otherdir git --bare init newdir &&
 307        test_path_is_dir newdir/refs &&
 308        test_path_is_missing otherdir/refs
 309'
 310
 311test_expect_success 'init with separate gitdir' '
 312        rm -rf newdir &&
 313        git init --separate-git-dir realgitdir newdir &&
 314        echo "gitdir: $(pwd)/realgitdir" >expected &&
 315        test_cmp expected newdir/.git &&
 316        test_path_is_dir realgitdir/refs
 317'
 318
 319test_lazy_prereq GETCWD_IGNORES_PERMS '
 320        base=GETCWD_TEST_BASE_DIR &&
 321        mkdir -p $base/dir &&
 322        chmod 100 $base ||
 323        BUG "cannot prepare $base"
 324
 325        (cd $base/dir && /bin/pwd -P)
 326        status=$?
 327
 328        chmod 700 $base &&
 329        rm -rf $base ||
 330        BUG "cannot clean $base"
 331        return $status
 332'
 333
 334check_long_base_path () {
 335        # exceed initial buffer size of strbuf_getcwd()
 336        component=123456789abcdef &&
 337        test_when_finished "chmod 0700 $component; rm -rf $component" &&
 338        p31=$component/$component &&
 339        p127=$p31/$p31/$p31/$p31 &&
 340        mkdir -p $p127 &&
 341        if test $# = 1
 342        then
 343                chmod $1 $component
 344        fi &&
 345        (
 346                cd $p127 &&
 347                git init newdir
 348        )
 349}
 350
 351test_expect_success 'init in long base path' '
 352        check_long_base_path
 353'
 354
 355test_expect_success GETCWD_IGNORES_PERMS 'init in long restricted base path' '
 356        check_long_base_path 0111
 357'
 358
 359test_expect_success 're-init on .git file' '
 360        ( cd newdir && git init )
 361'
 362
 363test_expect_success 're-init to update git link' '
 364        (
 365        cd newdir &&
 366        git init --separate-git-dir ../surrealgitdir
 367        ) &&
 368        echo "gitdir: $(pwd)/surrealgitdir" >expected &&
 369        test_cmp expected newdir/.git &&
 370        test_path_is_dir surrealgitdir/refs &&
 371        test_path_is_missing realgitdir/refs
 372'
 373
 374test_expect_success 're-init to move gitdir' '
 375        rm -rf newdir realgitdir surrealgitdir &&
 376        git init newdir &&
 377        (
 378        cd newdir &&
 379        git init --separate-git-dir ../realgitdir
 380        ) &&
 381        echo "gitdir: $(pwd)/realgitdir" >expected &&
 382        test_cmp expected newdir/.git &&
 383        test_path_is_dir realgitdir/refs
 384'
 385
 386test_expect_success SYMLINKS 're-init to move gitdir symlink' '
 387        rm -rf newdir realgitdir &&
 388        git init newdir &&
 389        (
 390        cd newdir &&
 391        mv .git here &&
 392        ln -s here .git &&
 393        git init --separate-git-dir ../realgitdir
 394        ) &&
 395        echo "gitdir: $(pwd)/realgitdir" >expected &&
 396        test_cmp expected newdir/.git &&
 397        test_cmp expected newdir/here &&
 398        test_path_is_dir realgitdir/refs
 399'
 400
 401# Tests for the hidden file attribute on windows
 402is_hidden () {
 403        # Use the output of `attrib`, ignore the absolute path
 404        case "$(attrib "$1")" in *H*?:*) return 0;; esac
 405        return 1
 406}
 407
 408test_expect_success MINGW '.git hidden' '
 409        rm -rf newdir &&
 410        (
 411                sane_unset GIT_DIR GIT_WORK_TREE &&
 412                mkdir newdir &&
 413                cd newdir &&
 414                git init &&
 415                is_hidden .git
 416        ) &&
 417        check_config newdir/.git false unset
 418'
 419
 420test_expect_success MINGW 'bare git dir not hidden' '
 421        rm -rf newdir &&
 422        (
 423                sane_unset GIT_DIR GIT_WORK_TREE GIT_CONFIG &&
 424                mkdir newdir &&
 425                cd newdir &&
 426                git --bare init
 427        ) &&
 428        ! is_hidden newdir
 429'
 430
 431test_expect_success 'remote init from does not use config from cwd' '
 432        rm -rf newdir &&
 433        test_config core.logallrefupdates true &&
 434        git init newdir &&
 435        echo true >expect &&
 436        git -C newdir config --bool core.logallrefupdates >actual &&
 437        test_cmp expect actual
 438'
 439
 440test_expect_success 're-init from a linked worktree' '
 441        git init main-worktree &&
 442        (
 443                cd main-worktree &&
 444                test_commit first &&
 445                git worktree add ../linked-worktree &&
 446                mv .git/info/exclude expected-exclude &&
 447                cp .git/config expected-config &&
 448                find .git/worktrees -print | sort >expected &&
 449                git -C ../linked-worktree init &&
 450                test_cmp expected-exclude .git/info/exclude &&
 451                test_cmp expected-config .git/config &&
 452                find .git/worktrees -print | sort >actual &&
 453                test_cmp expected actual
 454        )
 455'
 456
 457test_expect_success MINGW 'core.hidedotfiles = false' '
 458        git config --global core.hidedotfiles false &&
 459        rm -rf newdir &&
 460        mkdir newdir &&
 461        (
 462                sane_unset GIT_DIR GIT_WORK_TREE GIT_CONFIG &&
 463                git -C newdir init
 464        ) &&
 465        ! is_hidden newdir/.git
 466'
 467
 468test_expect_success MINGW 'redirect std handles' '
 469        GIT_REDIRECT_STDOUT=output.txt git rev-parse --git-dir &&
 470        test .git = "$(cat output.txt)" &&
 471        test -z "$(GIT_REDIRECT_STDOUT=off git rev-parse --git-dir)" &&
 472        test_must_fail env \
 473                GIT_REDIRECT_STDOUT=output.txt \
 474                GIT_REDIRECT_STDERR="2>&1" \
 475                git rev-parse --git-dir --verify refs/invalid &&
 476        printf ".git\nfatal: Needed a single revision\n" >expect &&
 477        test_cmp expect output.txt
 478'
 479
 480test_done