#!/bin/sh global test_description := ''pulling from symlinked subdir'' source ./test-lib.sh # The scenario we are building: # # trash\ directory/ # clone-repo/ # subdir/ # bar # subdir-link -> clone-repo/subdir/ # # The working directory is subdir-link. test_expect_success SYMLINKS setup ' mkdir subdir && echo file >subdir/file && git add subdir/file && git commit -q -m file && git clone -q . clone-repo && ln -s clone-repo/subdir/ subdir-link && ( cd clone-repo && git config receive.denyCurrentBranch warn ) && git config receive.denyCurrentBranch warn ' # Demonstrate that things work if we just avoid the symlink # test_expect_success SYMLINKS 'pulling from real subdir' ' ( echo real >subdir/file && git commit -m real subdir/file && cd clone-repo/subdir/ && git pull && test real = $(cat file) ) ' # From subdir-link, pulling should work as it does from # clone-repo/subdir/. # # Instead, the error pull gave was: # # fatal: 'origin': unable to chdir or not a git archive # fatal: The remote end hung up unexpectedly # # because git would find the .git/config for the "trash directory" # repo, not for the clone-repo repo. The "trash directory" repo # had no entry for origin. Git found the wrong .git because # git rev-parse --show-cdup printed a path relative to # clone-repo/subdir/, not subdir-link/. Git rev-parse --show-cdup # used the correct .git, but when the git pull shell script did # "cd $(git rev-parse --show-cdup)", it ended up in the wrong # directory. A POSIX shell's "cd" works a little differently # than chdir() in C; "cd -P" is much closer to chdir(). # test_expect_success SYMLINKS 'pulling from symlinked subdir' ' ( echo link >subdir/file && git commit -m link subdir/file && cd subdir-link/ && git pull && test link = $(cat file) ) ' # Prove that the remote end really is a repo, and other commands # work fine in this context. It's just that "git pull" breaks. # test_expect_success SYMLINKS 'pushing from symlinked subdir' ' ( cd subdir-link/ && echo push >file && git commit -m push ./file && git push ) && test push = $(git show HEAD:subdir/file) ' test_done (CommandList children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:test_description) op: Equal rhs: {(SQ <"pulling from symlinked subdir">)} spids: [4] ) ] spids: [4] ) (C {(.)} {(./test-lib.sh)}) (C {(test_expect_success)} {(SYMLINKS)} {(setup)} { (SQ <"\n"> <"\tmkdir subdir &&\n"> <"\techo file >subdir/file &&\n"> <"\tgit add subdir/file &&\n"> <"\tgit commit -q -m file &&\n"> <"\tgit clone -q . clone-repo &&\n"> <"\tln -s clone-repo/subdir/ subdir-link &&\n"> <"\t(\n"> <"\t\tcd clone-repo &&\n"> <"\t\tgit config receive.denyCurrentBranch warn\n"> <"\t) &&\n"> <"\tgit config receive.denyCurrentBranch warn\n"> ) } ) (C {(test_expect_success)} {(SYMLINKS)} {(SQ <"pulling from real subdir">)} { (SQ <"\n"> <"\t(\n"> <"\t\techo real >subdir/file &&\n"> <"\t\tgit commit -m real subdir/file &&\n"> <"\t\tcd clone-repo/subdir/ &&\n"> <"\t\tgit pull &&\n"> <"\t\ttest real = $(cat file)\n"> <"\t)\n"> ) } ) (C {(test_expect_success)} {(SYMLINKS)} {(SQ <"pulling from symlinked subdir">)} { (SQ <"\n"> <"\t(\n"> <"\t\techo link >subdir/file &&\n"> <"\t\tgit commit -m link subdir/file &&\n"> <"\t\tcd subdir-link/ &&\n"> <"\t\tgit pull &&\n"> <"\t\ttest link = $(cat file)\n"> <"\t)\n"> ) } ) (C {(test_expect_success)} {(SYMLINKS)} {(SQ <"pushing from symlinked subdir">)} { (SQ <"\n"> <"\t(\n"> <"\t\tcd subdir-link/ &&\n"> <"\t\techo push >file &&\n"> <"\t\tgit commit -m push ./file &&\n"> <"\t\tgit push\n"> <"\t) &&\n"> <"\ttest push = $(git show HEAD:subdir/file)\n"> ) } ) (C {(test_done)}) ] )