1#!/bin/sh 2 3test_description='pulling from symlinked subdir' 4 5. ./test-lib.sh 6 7# The scenario we are building: 8# 9# trash\ directory/ 10# clone-repo/ 11# subdir/ 12# bar 13# subdir-link -> clone-repo/subdir/ 14# 15# The working directory is subdir-link. 16 17mkdir subdir 18echofile>subdir/file 19git add subdir/file 20git commit -q -mfile 21git clone -q . clone-repo 22ln-s clone-repo/subdir/ subdir-link 23 24 25# Demonstrate that things work if we just avoid the symlink 26# 27test_expect_success 'pulling from real subdir'' 28 ( 29 echo real >subdir/file && 30 git commit -m real subdir/file && 31 cd clone-repo/subdir/ && 32 git pull && 33 test real =$(cat file) 34 ) 35' 36 37# From subdir-link, pulling should work as it does from 38# clone-repo/subdir/. 39# 40# Instead, the error pull gave was: 41# 42# fatal: 'origin': unable to chdir or not a git archive 43# fatal: The remote end hung up unexpectedly 44# 45# because git would find the .git/config for the "trash directory" 46# repo, not for the clone-repo repo. The "trash directory" repo 47# had no entry for origin. Git found the wrong .git because 48# git rev-parse --show-cdup printed a path relative to 49# clone-repo/subdir/, not subdir-link/. Git rev-parse --show-cdup 50# used the correct .git, but when the git pull shell script did 51# "cd `git rev-parse --show-cdup`", it ended up in the wrong 52# directory. A POSIX shell's "cd" works a little differently 53# than chdir() in C; "cd -P" is much closer to chdir(). 54# 55test_expect_success 'pulling from symlinked subdir'' 56 ( 57 echo link >subdir/file && 58 git commit -m link subdir/file && 59 cd subdir-link/ && 60 git pull && 61 test link =$(cat file) 62 ) 63' 64 65# Prove that the remote end really is a repo, and other commands 66# work fine in this context. It's just that "git pull" breaks. 67# 68test_expect_success 'pushing from symlinked subdir'' 69 ( 70 cd subdir-link/ && 71 echo push >file && 72 git commit -m push ./file && 73 git push 74 ) && 75 test push =$(git show HEAD:subdir/file) 76' 77 78test_done