Merge branch 'jl/fix-test'

* jl/fix-test:
  t1020: Get rid of 'cd "$HERE"' at the start of each test
  t2016 (checkout -p): add missing &&
  t1302 (core.repositoryversion): style tweaks
  t2105 (gitfile): add missing &&
  t1450 (fsck): remove dangling objects
  tests: subshell indentation stylefix
  Several tests: cd inside subshell instead of around
diff --git a/t/t1020-subdirectory.sh b/t/t1020-subdirectory.sh
index 5687499..a3ac338 100755
--- a/t/t1020-subdirectory.sh
+++ b/t/t1020-subdirectory.sh
@@ -16,24 +16,23 @@
 	cp one original.one &&
 	cp dir/two original.two
 '
-HERE=`pwd`
 LF='
 '
 
 test_expect_success 'update-index and ls-files' '
-	cd "$HERE" &&
 	git update-index --add one &&
 	case "`git ls-files`" in
 	one) echo pass one ;;
 	*) echo bad one; exit 1 ;;
 	esac &&
-	cd dir &&
-	git update-index --add two &&
-	case "`git ls-files`" in
-	two) echo pass two ;;
-	*) echo bad two; exit 1 ;;
-	esac &&
-	cd .. &&
+	(
+		cd dir &&
+		git update-index --add two &&
+		case "`git ls-files`" in
+		two) echo pass two ;;
+		*) echo bad two; exit 1 ;;
+		esac
+	) &&
 	case "`git ls-files`" in
 	dir/two"$LF"one) echo pass both ;;
 	*) echo bad; exit 1 ;;
@@ -41,20 +40,20 @@
 '
 
 test_expect_success 'cat-file' '
-	cd "$HERE" &&
 	two=`git ls-files -s dir/two` &&
 	two=`expr "$two" : "[0-7]* \\([0-9a-f]*\\)"` &&
 	echo "$two" &&
 	git cat-file -p "$two" >actual &&
 	cmp dir/two actual &&
-	cd dir &&
-	git cat-file -p "$two" >actual &&
-	cmp two actual
+	(
+		cd dir &&
+		git cat-file -p "$two" >actual &&
+		cmp two actual
+	)
 '
 rm -f actual dir/actual
 
 test_expect_success 'diff-files' '
-	cd "$HERE" &&
 	echo a >>one &&
 	echo d >>dir/two &&
 	case "`git diff-files --name-only`" in
@@ -62,77 +61,88 @@
 	*) echo bad top; exit 1 ;;
 	esac &&
 	# diff should not omit leading paths
-	cd dir &&
-	case "`git diff-files --name-only`" in
-	dir/two"$LF"one) echo pass subdir ;;
-	*) echo bad subdir; exit 1 ;;
-	esac &&
-	case "`git diff-files --name-only .`" in
-	dir/two) echo pass subdir limited ;;
-	*) echo bad subdir limited; exit 1 ;;
-	esac
+	(
+		cd dir &&
+		case "`git diff-files --name-only`" in
+		dir/two"$LF"one) echo pass subdir ;;
+		*) echo bad subdir; exit 1 ;;
+		esac &&
+		case "`git diff-files --name-only .`" in
+		dir/two) echo pass subdir limited ;;
+		*) echo bad subdir limited; exit 1 ;;
+		esac
+	)
 '
 
 test_expect_success 'write-tree' '
-	cd "$HERE" &&
 	top=`git write-tree` &&
 	echo $top &&
-	cd dir &&
-	sub=`git write-tree` &&
-	echo $sub &&
-	test "z$top" = "z$sub"
+	(
+		cd dir &&
+		sub=`git write-tree` &&
+		echo $sub &&
+		test "z$top" = "z$sub"
+	)
 '
 
 test_expect_success 'checkout-index' '
-	cd "$HERE" &&
 	git checkout-index -f -u one &&
 	cmp one original.one &&
-	cd dir &&
-	git checkout-index -f -u two &&
-	cmp two ../original.two
+	(
+		cd dir &&
+		git checkout-index -f -u two &&
+		cmp two ../original.two
+	)
 '
 
 test_expect_success 'read-tree' '
-	cd "$HERE" &&
 	rm -f one dir/two &&
 	tree=`git write-tree` &&
 	git read-tree --reset -u "$tree" &&
 	cmp one original.one &&
 	cmp dir/two original.two &&
-	cd dir &&
-	rm -f two &&
-	git read-tree --reset -u "$tree" &&
-	cmp two ../original.two &&
-	cmp ../one ../original.one
+	(
+		cd dir &&
+		rm -f two &&
+		git read-tree --reset -u "$tree" &&
+		cmp two ../original.two &&
+		cmp ../one ../original.one
+	)
 '
 
 test_expect_success 'no file/rev ambiguity check inside .git' '
-	cd "$HERE" &&
 	git commit -a -m 1 &&
-	cd "$HERE"/.git &&
-	git show -s HEAD
+	(
+		cd .git &&
+		git show -s HEAD
+	)
 '
 
 test_expect_success 'no file/rev ambiguity check inside a bare repo' '
-	cd "$HERE" &&
 	git clone -s --bare .git foo.git &&
-	cd foo.git && GIT_DIR=. git show -s HEAD
+	(
+		cd foo.git &&
+		GIT_DIR=. git show -s HEAD
+	)
 '
 
 # This still does not work as it should...
 : test_expect_success 'no file/rev ambiguity check inside a bare repo' '
-	cd "$HERE" &&
 	git clone -s --bare .git foo.git &&
-	cd foo.git && git show -s HEAD
+	(
+		cd foo.git &&
+		git show -s HEAD
+	)
 '
 
 test_expect_success SYMLINKS 'detection should not be fooled by a symlink' '
-	cd "$HERE" &&
 	rm -fr foo.git &&
 	git clone -s .git another &&
 	ln -s another yetanother &&
-	cd yetanother/.git &&
-	git show -s HEAD
+	(
+		cd yetanother/.git &&
+		git show -s HEAD
+	)
 '
 
 test_done
diff --git a/t/t1302-repo-version.sh b/t/t1302-repo-version.sh
index 8d305b4..a6bf1bf 100755
--- a/t/t1302-repo-version.sh
+++ b/t/t1302-repo-version.sh
@@ -7,41 +7,64 @@
 
 . ./test-lib.sh
 
-cat >test.patch <<EOF
-diff --git a/test.txt b/test.txt
-new file mode 100644
---- /dev/null
-+++ b/test.txt
-@@ -0,0 +1 @@
-+123
-EOF
+test_expect_success 'setup' '
+	cat >test.patch <<-\EOF &&
+	diff --git a/test.txt b/test.txt
+	new file mode 100644
+	--- /dev/null
+	+++ b/test.txt
+	@@ -0,0 +1 @@
+	+123
+	EOF
 
-test_create_repo "test"
-test_create_repo "test2"
-
-GIT_CONFIG=test2/.git/config git config core.repositoryformatversion 99 || exit 1
+	test_create_repo "test" &&
+	test_create_repo "test2" &&
+	GIT_CONFIG=test2/.git/config git config core.repositoryformatversion 99
+'
 
 test_expect_success 'gitdir selection on normal repos' '
-	(test "$(git config core.repositoryformatversion)" = 0 &&
-	cd test &&
-	test "$(git config core.repositoryformatversion)" = 0)'
+	echo 0 >expect &&
+	git config core.repositoryformatversion >actual &&
+	(
+		cd test &&
+		git config core.repositoryformatversion >../actual2
+	) &&
+	test_cmp expect actual &&
+	test_cmp expect actual2
+'
 
-# Make sure it would stop at test2, not trash
 test_expect_success 'gitdir selection on unsupported repo' '
-	(cd test2 &&
-	test "$(git config core.repositoryformatversion)" = 99)'
+	# Make sure it would stop at test2, not trash
+	echo 99 >expect &&
+	(
+		cd test2 &&
+		git config core.repositoryformatversion >../actual
+	)
+	test_cmp expect actual
+'
 
 test_expect_success 'gitdir not required mode' '
-	(git apply --stat test.patch &&
-	cd test && git apply --stat ../test.patch &&
-	cd ../test2 && git apply --stat ../test.patch)'
+	git apply --stat test.patch &&
+	(
+		cd test &&
+		git apply --stat ../test.patch
+	) &&
+	(
+		cd test2 &&
+		git apply --stat ../test.patch
+	)
+'
 
-test_expect_success 'gitdir required mode on normal repos' '
-	(git apply --check --index test.patch &&
-	cd test && git apply --check --index ../test.patch)'
-
-test_expect_success 'gitdir required mode on unsupported repo' '
-	(cd test2 && test_must_fail git apply --check --index ../test.patch)
+test_expect_success 'gitdir required mode' '
+	git apply --check --index test.patch &&
+	(
+		cd test &&
+		git apply --check --index ../test.patch
+	) &&
+	(
+		cd test2 &&
+		test_must_fail git apply --check --index ../test.patch
+	)
 '
 
 test_done
diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh
index 759cf12..1be415e 100755
--- a/t/t1450-fsck.sh
+++ b/t/t1450-fsck.sh
@@ -1,21 +1,23 @@
 #!/bin/sh
 
-test_description='git fsck random collection of tests'
+test_description='git fsck random collection of tests
+
+* (HEAD) B
+* (master) A
+'
 
 . ./test-lib.sh
 
 test_expect_success setup '
+	git config gc.auto 0 &&
 	git config i18n.commitencoding ISO-8859-1 &&
 	test_commit A fileA one &&
 	git config --unset i18n.commitencoding &&
 	git checkout HEAD^0 &&
 	test_commit B fileB two &&
 	git tag -d A B &&
-	git reflog expire --expire=now --all
-'
-
-test_expect_success 'HEAD is part of refs' '
-	test 0 = $(git fsck | wc -l)
+	git reflog expire --expire=now --all &&
+	>empty
 '
 
 test_expect_success 'loose objects borrowed from alternate are not missing' '
@@ -25,110 +27,132 @@
 		git init &&
 		echo ../../../.git/objects >.git/objects/info/alternates &&
 		test_commit C fileC one &&
-		git fsck >out &&
-		! grep "missing blob" out
-	)
+		git fsck >../out 2>&1
+	) &&
+	{
+		grep -v dangling out >actual ||
+		:
+	} &&
+	test_cmp empty actual
 '
 
-test_expect_success 'valid objects appear valid' '
-	{ git fsck 2>out; true; } &&
-	! grep error out &&
-	! grep fatal out
+test_expect_success 'HEAD is part of refs, valid objects appear valid' '
+	git fsck >actual 2>&1 &&
+	test_cmp empty actual
 '
 
 # Corruption tests follow.  Make sure to remove all traces of the
 # specific corruption you test afterwards, lest a later test trip over
 # it.
 
+test_expect_success 'setup: helpers for corruption tests' '
+	sha1_file() {
+		echo "$*" | sed "s#..#.git/objects/&/#"
+	} &&
+
+	remove_object() {
+		file=$(sha1_file "$*") &&
+		test -e "$file" &&
+		rm -f "$file"
+	}
+'
+
 test_expect_success 'object with bad sha1' '
 	sha=$(echo blob | git hash-object -w --stdin) &&
-	echo $sha &&
 	old=$(echo $sha | sed "s+^..+&/+") &&
 	new=$(dirname $old)/ffffffffffffffffffffffffffffffffffffff &&
 	sha="$(dirname $new)$(basename $new)"
 	mv .git/objects/$old .git/objects/$new &&
+	test_when_finished "remove_object $sha" &&
 	git update-index --add --cacheinfo 100644 $sha foo &&
+	test_when_finished "git read-tree -u --reset HEAD" &&
 	tree=$(git write-tree) &&
+	test_when_finished "remove_object $tree" &&
 	cmt=$(echo bogus | git commit-tree $tree) &&
+	test_when_finished "remove_object $cmt" &&
 	git update-ref refs/heads/bogus $cmt &&
-	(git fsck 2>out; true) &&
-	grep "$sha.*corrupt" out &&
-	rm -f .git/objects/$new &&
-	git update-ref -d refs/heads/bogus &&
-	git read-tree -u --reset HEAD
+	test_when_finished "git update-ref -d refs/heads/bogus" &&
+
+	test_might_fail git fsck 2>out &&
+	cat out &&
+	grep "$sha.*corrupt" out
 '
 
 test_expect_success 'branch pointing to non-commit' '
-	git rev-parse HEAD^{tree} > .git/refs/heads/invalid &&
+	git rev-parse HEAD^{tree} >.git/refs/heads/invalid &&
+	test_when_finished "git update-ref -d refs/heads/invalid" &&
 	git fsck 2>out &&
-	grep "not a commit" out &&
-	git update-ref -d refs/heads/invalid
+	cat out &&
+	grep "not a commit" out
 '
 
-new=nothing
 test_expect_success 'email without @ is okay' '
 	git cat-file commit HEAD >basis &&
 	sed "s/@/AT/" basis >okay &&
 	new=$(git hash-object -t commit -w --stdin <okay) &&
-	echo "$new" &&
+	test_when_finished "remove_object $new" &&
 	git update-ref refs/heads/bogus "$new" &&
+	test_when_finished "git update-ref -d refs/heads/bogus" &&
 	git fsck 2>out &&
 	cat out &&
-	! grep "error in commit $new" out
+	! grep "commit $new" out
 '
-git update-ref -d refs/heads/bogus
-rm -f ".git/objects/$new"
 
-new=nothing
 test_expect_success 'email with embedded > is not okay' '
 	git cat-file commit HEAD >basis &&
 	sed "s/@[a-z]/&>/" basis >bad-email &&
 	new=$(git hash-object -t commit -w --stdin <bad-email) &&
-	echo "$new" &&
+	test_when_finished "remove_object $new" &&
 	git update-ref refs/heads/bogus "$new" &&
+	test_when_finished "git update-ref -d refs/heads/bogus" &&
 	git fsck 2>out &&
 	cat out &&
 	grep "error in commit $new" out
 '
-git update-ref -d refs/heads/bogus
-rm -f ".git/objects/$new"
-
-cat > invalid-tag <<EOF
-object ffffffffffffffffffffffffffffffffffffffff
-type commit
-tag invalid
-tagger T A Gger <tagger@example.com> 1234567890 -0000
-
-This is an invalid tag.
-EOF
 
 test_expect_success 'tag pointing to nonexistent' '
-	tag=$(git hash-object -t tag -w --stdin < invalid-tag) &&
-	echo $tag > .git/refs/tags/invalid &&
+	cat >invalid-tag <<-\EOF
+	object ffffffffffffffffffffffffffffffffffffffff
+	type commit
+	tag invalid
+	tagger T A Gger <tagger@example.com> 1234567890 -0000
+
+	This is an invalid tag.
+	EOF
+
+	tag=$(git hash-object -t tag -w --stdin <invalid-tag) &&
+	test_when_finished "remove_object $tag" &&
+	echo $tag >.git/refs/tags/invalid &&
+	test_when_finished "git update-ref -d refs/tags/invalid" &&
 	test_must_fail git fsck --tags >out &&
 	cat out &&
-	grep "broken link" out &&
-	rm .git/refs/tags/invalid
+	grep "broken link" out
 '
 
-cat > wrong-tag <<EOF
-object $(echo blob | git hash-object -w --stdin)
-type commit
-tag wrong
-tagger T A Gger <tagger@example.com> 1234567890 -0000
-
-This is an invalid tag.
-EOF
-
 test_expect_success 'tag pointing to something else than its type' '
-	tag=$(git hash-object -t tag -w --stdin < wrong-tag) &&
-	echo $tag > .git/refs/tags/wrong &&
+	sha=$(echo blob | git hash-object -w --stdin) &&
+	test_when_finished "remove_object $sha" &&
+	cat >wrong-tag <<-EOF &&
+	object $sha
+	type commit
+	tag wrong
+	tagger T A Gger <tagger@example.com> 1234567890 -0000
+
+	This is an invalid tag.
+	EOF
+
+	tag=$(git hash-object -t tag -w --stdin <wrong-tag) &&
+	test_when_finished "remove_object $tag" &&
+	echo $tag >.git/refs/tags/wrong &&
+	test_when_finished "git update-ref -d refs/tags/wrong" &&
 	test_must_fail git fsck --tags 2>out &&
 	cat out &&
-	grep "error in tag.*broken links" out &&
-	rm .git/refs/tags/wrong
+	grep "error in tag.*broken links" out
 '
 
-
+test_expect_success 'cleaned up' '
+	git fsck >actual 2>&1 &&
+	test_cmp empty actual
+'
 
 test_done
diff --git a/t/t2016-checkout-patch.sh b/t/t2016-checkout-patch.sh
index 7657ec1..a463b13 100755
--- a/t/t2016-checkout-patch.sh
+++ b/t/t2016-checkout-patch.sh
@@ -52,7 +52,7 @@
 '
 
 test_expect_success PERL 'git checkout -p HEAD with change already staged' '
-	set_state dir/foo index index
+	set_state dir/foo index index &&
 	# the third n is to get out in case it mistakenly does not apply
 	(echo n; echo y; echo n) | git checkout -p HEAD &&
 	verify_saved_state bar &&
diff --git a/t/t2101-update-index-reupdate.sh b/t/t2101-update-index-reupdate.sh
index 648184f..76ad7c3 100755
--- a/t/t2101-update-index-reupdate.sh
+++ b/t/t2101-update-index-reupdate.sh
@@ -63,10 +63,10 @@
 EOF
 test_expect_success 'update-index --update from subdir' \
 	'echo not so happy >file2 &&
-	cd dir1 &&
+	(cd dir1 &&
 	cat ../file2 >file3 &&
-	git update-index --again &&
-	cd .. &&
+	git update-index --again
+	) &&
 	git ls-files -s >current &&
 	cmp current expected'
 
diff --git a/t/t2105-update-index-gitfile.sh b/t/t2105-update-index-gitfile.sh
index 641607d..a7f3d47 100755
--- a/t/t2105-update-index-gitfile.sh
+++ b/t/t2105-update-index-gitfile.sh
@@ -13,7 +13,7 @@
 	(cd sub1 &&
 	 git init &&
 	 REAL="$(pwd)/.real" &&
-	 mv .git "$REAL"
+	 mv .git "$REAL" &&
 	 echo "gitdir: $REAL" >.git &&
 	 test_commit first)
 '
diff --git a/t/t3060-ls-files-with-tree.sh b/t/t3060-ls-files-with-tree.sh
index 3ce501b..61c1f53 100755
--- a/t/t3060-ls-files-with-tree.sh
+++ b/t/t3060-ls-files-with-tree.sh
@@ -53,17 +53,15 @@
 	git add .
 '
 
-# We have to run from a sub-directory to trigger prune_path
-# Then we finally get to run our --with-tree test
-cd sub
-
 test_expect_success 'git -ls-files --with-tree should succeed from subdir' '
-
-	git ls-files --with-tree=HEAD~1 >../output
-
+	# We have to run from a sub-directory to trigger prune_path
+	# Then we finally get to run our --with-tree test
+	(
+		cd sub &&
+		git ls-files --with-tree=HEAD~1 >../output
+	)
 '
 
-cd ..
 test_expect_success \
     'git -ls-files --with-tree should add entries from named tree.' \
     'test_cmp expected output'
diff --git a/t/t3409-rebase-preserve-merges.sh b/t/t3409-rebase-preserve-merges.sh
index 8f785e7..74161a4 100755
--- a/t/t3409-rebase-preserve-merges.sh
+++ b/t/t3409-rebase-preserve-merges.sh
@@ -42,23 +42,24 @@
 	git commit -a -m "Modify A2" &&
 
 	git clone ./. clone1 &&
-	cd clone1 &&
+	(cd clone1 &&
 	git checkout -b topic origin/topic &&
-	git merge origin/master &&
-	cd .. &&
+	git merge origin/master
+	) &&
 
 	echo Fifth > B &&
 	git add B &&
 	git commit -m "Add different B" &&
 
 	git clone ./. clone2 &&
-	cd clone2 &&
-	git checkout -b topic origin/topic &&
-	test_must_fail git merge origin/master &&
-	echo Resolved > B &&
-	git add B &&
-	git commit -m "Merge origin/master into topic" &&
-	cd .. &&
+	(
+		cd clone2 &&
+		git checkout -b topic origin/topic &&
+		test_must_fail git merge origin/master &&
+		echo Resolved >B &&
+		git add B &&
+		git commit -m "Merge origin/master into topic"
+	) &&
 
 	git checkout topic &&
 	echo Fourth >> B &&
diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh
index d99f27a..a283dca 100755
--- a/t/t3903-stash.sh
+++ b/t/t3903-stash.sh
@@ -69,9 +69,10 @@
 test_expect_success 'unstashing in a subdirectory' '
 	git reset --hard HEAD &&
 	mkdir subdir &&
-	cd subdir &&
-	git stash apply &&
-	cd ..
+	(
+		cd subdir &&
+		git stash apply
+	)
 '
 
 test_expect_success 'drop top stash' '
diff --git a/t/t4041-diff-submodule-option.sh b/t/t4041-diff-submodule-option.sh
index 8e391cf..995bdfa 100755
--- a/t/t4041-diff-submodule-option.sh
+++ b/t/t4041-diff-submodule-option.sh
@@ -85,10 +85,11 @@
 "
 
 commit_file sm1 &&
-cd sm1 &&
-git reset --hard HEAD~2 >/dev/null &&
-head3=$(git rev-parse --verify HEAD | cut -c1-7) &&
-cd ..
+head3=$(
+	cd sm1 &&
+	git reset --hard HEAD~2 >/dev/null &&
+	git rev-parse --verify HEAD | cut -c1-7
+)
 
 test_expect_success 'modified submodule(backward)' "
 	git diff-index -p --submodule=log HEAD >actual &&
diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh
index efb42d1..9a88475 100755
--- a/t/t5510-fetch.sh
+++ b/t/t5510-fetch.sh
@@ -21,27 +21,30 @@
 
 test_expect_success "clone and setup child repos" '
 	git clone . one &&
-	cd one &&
-	echo >file updated by one &&
-	git commit -a -m "updated by one" &&
-	cd .. &&
+	(
+		cd one &&
+		echo >file updated by one &&
+		git commit -a -m "updated by one"
+	) &&
 	git clone . two &&
-	cd two &&
-	git config branch.master.remote one &&
-	git config remote.one.url ../one/.git/ &&
-	git config remote.one.fetch refs/heads/master:refs/heads/one &&
-	cd .. &&
+	(
+		cd two &&
+		git config branch.master.remote one &&
+		git config remote.one.url ../one/.git/ &&
+		git config remote.one.fetch refs/heads/master:refs/heads/one
+	) &&
 	git clone . three &&
-	cd three &&
-	git config branch.master.remote two &&
-	git config branch.master.merge refs/heads/one &&
-	mkdir -p .git/remotes &&
-	{
-		echo "URL: ../two/.git/"
-		echo "Pull: refs/heads/master:refs/heads/two"
-		echo "Pull: refs/heads/one:refs/heads/one"
-	} >.git/remotes/two &&
-	cd .. &&
+	(
+		cd three &&
+		git config branch.master.remote two &&
+		git config branch.master.merge refs/heads/one &&
+		mkdir -p .git/remotes &&
+		{
+			echo "URL: ../two/.git/"
+			echo "Pull: refs/heads/master:refs/heads/two"
+			echo "Pull: refs/heads/one:refs/heads/one"
+		} >.git/remotes/two
+	) &&
 	git clone . bundle &&
 	git clone . seven
 '
diff --git a/t/t6050-replace.sh b/t/t6050-replace.sh
index dd917d7..c907523 100755
--- a/t/t6050-replace.sh
+++ b/t/t6050-replace.sh
@@ -104,17 +104,18 @@
 test_expect_success 'repack, clone and fetch work' '
      git repack -a -d &&
      git clone --no-hardlinks . clone_dir &&
-     cd clone_dir &&
-     git show HEAD~5 | grep "A U Thor" &&
-     git show $HASH2 | grep "A U Thor" &&
-     git cat-file commit $R &&
-     git repack -a -d &&
-     test_must_fail git cat-file commit $R &&
-     git fetch ../ "refs/replace/*:refs/replace/*" &&
-     git show HEAD~5 | grep "O Thor" &&
-     git show $HASH2 | grep "O Thor" &&
-     git cat-file commit $R &&
-     cd ..
+     (
+	  cd clone_dir &&
+	  git show HEAD~5 | grep "A U Thor" &&
+	  git show $HASH2 | grep "A U Thor" &&
+	  git cat-file commit $R &&
+	  git repack -a -d &&
+	  test_must_fail git cat-file commit $R &&
+	  git fetch ../ "refs/replace/*:refs/replace/*" &&
+	  git show HEAD~5 | grep "O Thor" &&
+	  git show $HASH2 | grep "O Thor" &&
+	  git cat-file commit $R
+     )
 '
 
 test_expect_success '"git replace" listing and deleting' '
@@ -177,10 +178,11 @@
 
 test_expect_success 'push to cloned repo' '
      git push cloned $HASH6^:refs/heads/parallel &&
-     cd clone_dir &&
-     git checkout parallel &&
-     git log --pretty=oneline | grep $PARA2 &&
-     cd ..
+     (
+	  cd clone_dir &&
+	  git checkout parallel &&
+	  git log --pretty=oneline | grep $PARA2
+     )
 '
 
 test_expect_success 'push branch with replacement' '
@@ -191,20 +193,22 @@
      git show $HASH6~2 | grep "O Thor" &&
      git show $PARA3 | grep "O Thor" &&
      git push cloned $HASH6^:refs/heads/parallel2 &&
-     cd clone_dir &&
-     git checkout parallel2 &&
-     git log --pretty=oneline | grep $PARA3 &&
-     git show $PARA3 | grep "A U Thor" &&
-     cd ..
+     (
+	  cd clone_dir &&
+	  git checkout parallel2 &&
+	  git log --pretty=oneline | grep $PARA3 &&
+	  git show $PARA3 | grep "A U Thor"
+     )
 '
 
 test_expect_success 'fetch branch with replacement' '
      git branch tofetch $HASH6 &&
-     cd clone_dir &&
-     git fetch origin refs/heads/tofetch:refs/heads/parallel3
-     git log --pretty=oneline parallel3 | grep $PARA3
-     git show $PARA3 | grep "A U Thor"
-     cd ..
+     (
+	  cd clone_dir &&
+	  git fetch origin refs/heads/tofetch:refs/heads/parallel3
+	  git log --pretty=oneline parallel3 | grep $PARA3
+	  git show $PARA3 | grep "A U Thor"
+     )
 '
 
 test_expect_success 'bisect and replacements' '
diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh
index 9bda970..782b0a3 100755
--- a/t/t7400-submodule-basic.sh
+++ b/t/t7400-submodule-basic.sh
@@ -413,12 +413,13 @@
 
 test_expect_success 'add submodules without specifying an explicit path' '
 	mkdir repo &&
-	cd repo &&
-	git init &&
-	echo r >r &&
-	git add r &&
-	git commit -m "repo commit 1" &&
-	cd .. &&
+	(
+		cd repo &&
+		git init &&
+		echo r >r &&
+		git add r &&
+		git commit -m "repo commit 1"
+	) &&
 	git clone --bare repo/ bare.git &&
 	cd addtest &&
 	git submodule add "$submodurl/repo" &&
diff --git a/t/t7401-submodule-summary.sh b/t/t7401-submodule-summary.sh
index cee319d..2945844 100755
--- a/t/t7401-submodule-summary.sh
+++ b/t/t7401-submodule-summary.sh
@@ -66,10 +66,11 @@
 "
 
 commit_file sm1 &&
-cd sm1 &&
-git reset --hard HEAD~2 >/dev/null &&
-head3=$(git rev-parse --verify HEAD | cut -c1-7) &&
-cd ..
+head3=$(
+	cd sm1 &&
+	git reset --hard HEAD~2 >/dev/null &&
+	git rev-parse --verify HEAD | cut -c1-7
+)
 
 test_expect_success 'modified submodule(backward)' "
     git submodule summary >actual &&
diff --git a/t/t9100-git-svn-basic.sh b/t/t9100-git-svn-basic.sh
index d5adae6..2f458f7 100755
--- a/t/t9100-git-svn-basic.sh
+++ b/t/t9100-git-svn-basic.sh
@@ -22,17 +22,18 @@
 test_expect_success \
     'initialize git svn' '
 	mkdir import &&
-	cd import &&
-	echo foo > foo &&
-	ln -s foo foo.link
-	mkdir -p dir/a/b/c/d/e &&
-	echo "deep dir" > dir/a/b/c/d/e/file &&
-	mkdir bar &&
-	echo "zzz" > bar/zzz &&
-	echo "#!/bin/sh" > exec.sh &&
-	chmod +x exec.sh &&
-	svn_cmd import -m "import for git svn" . "$svnrepo" >/dev/null &&
-	cd .. &&
+	(
+		cd import &&
+		echo foo >foo &&
+		ln -s foo foo.link
+		mkdir -p dir/a/b/c/d/e &&
+		echo "deep dir" >dir/a/b/c/d/e/file &&
+		mkdir bar &&
+		echo "zzz" >bar/zzz &&
+		echo "#!/bin/sh" >exec.sh &&
+		chmod +x exec.sh &&
+		svn_cmd import -m "import for git svn" . "$svnrepo" >/dev/null
+	) &&
 	rm -rf import &&
 	git svn init "$svnrepo"'
 
diff --git a/t/t9101-git-svn-props.sh b/t/t9101-git-svn-props.sh
index 929499e..8869f50 100755
--- a/t/t9101-git-svn-props.sh
+++ b/t/t9101-git-svn-props.sh
@@ -53,8 +53,9 @@
 
 rm -rf import
 test_expect_success 'checkout working copy from svn' 'svn co "$svnrepo" test_wc'
-test_expect_success 'setup some commits to svn' \
-	'cd test_wc &&
+test_expect_success 'setup some commits to svn' '
+	(
+		cd test_wc &&
 		echo Greetings >> kw.c &&
 		poke kw.c &&
 		svn_cmd commit -m "Not yet an Id" &&
@@ -63,8 +64,9 @@
 		svn_cmd commit -m "Modified file, but still not yet an Id" &&
 		svn_cmd propset svn:keywords Id kw.c &&
 		poke kw.c &&
-		svn_cmd commit -m "Propset Id" &&
-	cd ..'
+		svn_cmd commit -m "Propset Id"
+	)
+'
 
 test_expect_success 'initialize git svn' 'git svn init "$svnrepo"'
 test_expect_success 'fetch revisions from svn' 'git svn fetch'
@@ -81,13 +83,15 @@
 got="`sed -ne 2p kw.c`"
 test_expect_success 'raw $Id$ found in kw.c' "test '$expect' = '$got'"
 
-test_expect_success "propset CR on crlf files" \
-	'cd test_wc &&
+test_expect_success "propset CR on crlf files" '
+	(
+		cd test_wc &&
 		svn_cmd propset svn:eol-style CR empty &&
 		svn_cmd propset svn:eol-style CR crlf &&
 		svn_cmd propset svn:eol-style CR ne_crlf &&
-		svn_cmd commit -m "propset CR on crlf files" &&
-	 cd ..'
+		svn_cmd commit -m "propset CR on crlf files"
+	 )
+'
 
 test_expect_success 'fetch and pull latest from svn and checkout a new wc' \
 	'git svn fetch &&
@@ -137,19 +141,20 @@
 EOF
 
 test_expect_success 'test show-ignore' "
-	cd test_wc &&
-	mkdir -p deeply/nested/directory &&
-	touch deeply/nested/directory/.keep &&
-	svn_cmd add deeply &&
-	svn_cmd up &&
-	svn_cmd propset -R svn:ignore '
+	(
+		cd test_wc &&
+		mkdir -p deeply/nested/directory &&
+		touch deeply/nested/directory/.keep &&
+		svn_cmd add deeply &&
+		svn_cmd up &&
+		svn_cmd propset -R svn:ignore '
 no-such-file*
 ' .
-	svn_cmd commit -m 'propset svn:ignore'
-	cd .. &&
+		svn_cmd commit -m 'propset svn:ignore'
+	) &&
 	git svn show-ignore > show-ignore.got &&
 	cmp show-ignore.expect show-ignore.got
-	"
+"
 
 cat >create-ignore.expect <<\EOF
 /no-such-file*
diff --git a/t/t9102-git-svn-deep-rmdir.sh b/t/t9102-git-svn-deep-rmdir.sh
index 028fb19..eb70f48 100755
--- a/t/t9102-git-svn-deep-rmdir.sh
+++ b/t/t9102-git-svn-deep-rmdir.sh
@@ -4,13 +4,14 @@
 
 test_expect_success 'initialize repo' '
 	mkdir import &&
-	cd import &&
-	mkdir -p deeply/nested/directory/number/1 &&
-	mkdir -p deeply/nested/directory/number/2 &&
-	echo foo > deeply/nested/directory/number/1/file &&
-	echo foo > deeply/nested/directory/number/2/another &&
-	svn_cmd import -m "import for git svn" . "$svnrepo" &&
-	cd ..
+	(
+		cd import &&
+		mkdir -p deeply/nested/directory/number/1 &&
+		mkdir -p deeply/nested/directory/number/2 &&
+		echo foo >deeply/nested/directory/number/1/file &&
+		echo foo >deeply/nested/directory/number/2/another &&
+		svn_cmd import -m "import for git svn" . "$svnrepo"
+	)
 	'
 
 test_expect_success 'mirror via git svn' '
diff --git a/t/t9104-git-svn-follow-parent.sh b/t/t9104-git-svn-follow-parent.sh
index bbfd7f4..f7f3c5a 100755
--- a/t/t9104-git-svn-follow-parent.sh
+++ b/t/t9104-git-svn-follow-parent.sh
@@ -8,22 +8,24 @@
 
 test_expect_success 'initialize repo' '
 	mkdir import &&
-	cd import &&
-	mkdir -p trunk &&
-	echo hello > trunk/readme &&
-	svn_cmd import -m "initial" . "$svnrepo" &&
-	cd .. &&
+	(
+		cd import &&
+		mkdir -p trunk &&
+		echo hello >trunk/readme &&
+		svn_cmd import -m "initial" . "$svnrepo"
+	) &&
 	svn_cmd co "$svnrepo" wc &&
-	cd wc &&
-	echo world >> trunk/readme &&
-	poke trunk/readme &&
-	svn_cmd commit -m "another commit" &&
-	svn_cmd up &&
-	svn_cmd mv trunk thunk &&
-	echo goodbye >> thunk/readme &&
-	poke thunk/readme &&
-	svn_cmd commit -m "bye now" &&
-	cd ..
+	(
+		cd wc &&
+		echo world >>trunk/readme &&
+		poke trunk/readme &&
+		svn_cmd commit -m "another commit" &&
+		svn_cmd up &&
+		svn_cmd mv trunk thunk &&
+		echo goodbye >>thunk/readme &&
+		poke thunk/readme &&
+		svn_cmd commit -m "bye now"
+	)
 	'
 
 test_expect_success 'init and fetch a moved directory' '
@@ -83,16 +85,17 @@
         '
 
 test_expect_success 'follow higher-level parent' '
-        svn mkdir -m "follow higher-level parent" "$svnrepo"/blob &&
-        svn co "$svnrepo"/blob blob &&
-        cd blob &&
-                echo hi > hi &&
-                svn add hi &&
-                svn commit -m "hihi" &&
-                cd ..
-        svn mkdir -m "new glob at top level" "$svnrepo"/glob &&
-        svn mv -m "move blob down a level" "$svnrepo"/blob "$svnrepo"/glob/blob &&
-        git svn init --minimize-url -i blob "$svnrepo"/glob/blob &&
+	svn mkdir -m "follow higher-level parent" "$svnrepo"/blob &&
+	svn co "$svnrepo"/blob blob &&
+	(
+		cd blob &&
+		echo hi > hi &&
+		svn add hi &&
+		svn commit -m "hihi"
+	) &&
+	svn mkdir -m "new glob at top level" "$svnrepo"/glob &&
+	svn mv -m "move blob down a level" "$svnrepo"/blob "$svnrepo"/glob/blob &&
+	git svn init --minimize-url -i blob "$svnrepo"/glob/blob &&
         git svn fetch -i blob
         '
 
@@ -117,18 +120,23 @@
 	   import/trunk/subversion/bindings/swig/perl/t/larger-parent &&
 	  echo "bad delete test 2" > \
 	   import/trunk/subversion/bindings/swig/perl/another-larger &&
-	cd import &&
-	  svn import -m "r9270 test" . "$svnrepo"/r9270 &&
-	cd .. &&
+	(
+		cd import &&
+		svn import -m "r9270 test" . "$svnrepo"/r9270
+	) &&
 	svn_cmd co "$svnrepo"/r9270/trunk/subversion/bindings/swig/perl r9270 &&
-	cd r9270 &&
-	  svn mkdir native &&
-	  svn mv t native/t &&
-	  for i in a b c; do svn mv $i.pm native/$i.pm; done &&
-	  echo z >> native/t/c.t &&
-	  poke native/t/c.t &&
-	  svn commit -m "reorg test" &&
-	cd .. &&
+	(
+		cd r9270 &&
+		svn mkdir native &&
+		svn mv t native/t &&
+		for i in a b c
+		do
+			svn mv $i.pm native/$i.pm
+		done &&
+		echo z >>native/t/c.t &&
+		poke native/t/c.t &&
+		svn commit -m "reorg test"
+	) &&
 	git svn init --minimize-url -i r9270-t \
 	  "$svnrepo"/r9270/trunk/subversion/bindings/swig/perl/native/t &&
 	git svn fetch -i r9270-t &&
diff --git a/t/t9105-git-svn-commit-diff.sh b/t/t9105-git-svn-commit-diff.sh
index dd48e9c..5d0afea 100755
--- a/t/t9105-git-svn-commit-diff.sh
+++ b/t/t9105-git-svn-commit-diff.sh
@@ -6,10 +6,11 @@
 
 test_expect_success 'initialize repo' '
 	mkdir import &&
-	cd import &&
-	echo hello > readme &&
-	svn_cmd import -m "initial" . "$svnrepo" &&
-	cd .. &&
+	(
+		cd import &&
+		echo hello >readme &&
+		svn_cmd import -m "initial" . "$svnrepo"
+	) &&
 	echo hello > readme &&
 	git update-index --add readme &&
 	git commit -a -m "initial" &&
diff --git a/t/t9106-git-svn-commit-diff-clobber.sh b/t/t9106-git-svn-commit-diff-clobber.sh
index 12f21b7..f6d7ac7 100755
--- a/t/t9106-git-svn-commit-diff-clobber.sh
+++ b/t/t9106-git-svn-commit-diff-clobber.sh
@@ -6,21 +6,23 @@
 
 test_expect_success 'initialize repo' '
 	mkdir import &&
-	cd import &&
-	echo initial > file &&
-	svn_cmd import -m "initial" . "$svnrepo" &&
-	cd .. &&
+	(
+		cd import &&
+		echo initial >file &&
+		svn_cmd import -m "initial" . "$svnrepo"
+	) &&
 	echo initial > file &&
 	git update-index --add file &&
 	git commit -a -m "initial"
 	'
 test_expect_success 'commit change from svn side' '
 	svn_cmd co "$svnrepo" t.svn &&
-	cd t.svn &&
-	echo second line from svn >> file &&
-	poke file &&
-	svn_cmd commit -m "second line from svn" &&
-	cd .. &&
+	(
+		cd t.svn &&
+		echo second line from svn >>file &&
+		poke file &&
+		svn_cmd commit -m "second line from svn"
+	) &&
 	rm -rf t.svn
 	'
 
@@ -44,11 +46,12 @@
 	git svn fetch &&
 	git reset --hard refs/${remotes_git_svn} &&
 	svn_cmd co "$svnrepo" t.svn &&
-	cd t.svn &&
-	echo fourth line from svn >> file &&
-	poke file &&
-	svn_cmd commit -m "fourth line from svn" &&
-	cd .. &&
+	(
+		cd t.svn &&
+		echo fourth line from svn >>file &&
+		poke file &&
+		svn_cmd commit -m "fourth line from svn"
+	) &&
 	rm -rf t.svn &&
 	echo "fourth line from git" >> file &&
 	git commit -a -m "fourth line from git" &&
@@ -68,11 +71,12 @@
 
 test_expect_success 'commit another change from svn side' '
 	svn_cmd co "$svnrepo" t.svn &&
-	cd t.svn &&
-		echo third line from svn >> file &&
+	(
+		cd t.svn &&
+		echo third line from svn >>file &&
 		poke file &&
-		svn_cmd commit -m "third line from svn" &&
-	cd .. &&
+		svn_cmd commit -m "third line from svn"
+	) &&
 	rm -rf t.svn
 	'
 
diff --git a/t/t9107-git-svn-migrate.sh b/t/t9107-git-svn-migrate.sh
index 901b8e0..289fc31 100755
--- a/t/t9107-git-svn-migrate.sh
+++ b/t/t9107-git-svn-migrate.sh
@@ -6,14 +6,16 @@
 test_expect_success 'setup old-looking metadata' '
 	cp "$GIT_DIR"/config "$GIT_DIR"/config-old-git-svn &&
 	mkdir import &&
-	cd import &&
-		for i in trunk branches/a branches/b \
-		         tags/0.1 tags/0.2 tags/0.3; do
-			mkdir -p $i && \
-			echo hello >> $i/README || exit 1
-		done && \
+	(
+		cd import &&
+		for i in trunk branches/a branches/b tags/0.1 tags/0.2 tags/0.3
+		do
+			mkdir -p $i &&
+			echo hello >>$i/README ||
+			exit 1
+		done &&
 		svn_cmd import -m test . "$svnrepo"
-		cd .. &&
+	) &&
 	git svn init "$svnrepo" &&
 	git svn fetch &&
 	rm -rf "$GIT_DIR"/svn &&
diff --git a/t/t9114-git-svn-dcommit-merge.sh b/t/t9114-git-svn-dcommit-merge.sh
index 84f7c9b..3077851 100755
--- a/t/t9114-git-svn-dcommit-merge.sh
+++ b/t/t9114-git-svn-dcommit-merge.sh
@@ -37,11 +37,12 @@
 test_expect_success 'setup svn repository' '
 	svn_cmd co "$svnrepo" mysvnwork &&
 	mkdir -p mysvnwork/trunk &&
-	cd mysvnwork &&
-		big_text_block >> trunk/README &&
+	(
+		cd mysvnwork &&
+		big_text_block >>trunk/README &&
 		svn_cmd add trunk &&
-		svn_cmd ci -m "first commit" trunk &&
-		cd ..
+		svn_cmd ci -m "first commit" trunk
+	)
 	'
 
 test_expect_success 'setup git mirror and merge' '
diff --git a/t/t9115-git-svn-dcommit-funky-renames.sh b/t/t9115-git-svn-dcommit-funky-renames.sh
index 767799e..6a48e40 100755
--- a/t/t9115-git-svn-dcommit-funky-renames.sh
+++ b/t/t9115-git-svn-dcommit-funky-renames.sh
@@ -61,11 +61,12 @@
 
 test_expect_success 'clone the repository to test rebase' '
 	git svn clone "$svnrepo" test-rebase &&
-	cd test-rebase &&
-		echo test-rebase > test-rebase &&
+	(
+		cd test-rebase &&
+		echo test-rebase >test-rebase &&
 		git add test-rebase &&
-		git commit -m test-rebase &&
-		cd ..
+		git commit -m test-rebase
+	)
 	'
 
 test_expect_success 'make a commit to test rebase' '
diff --git a/t/t9116-git-svn-log.sh b/t/t9116-git-svn-log.sh
index 0374a74..5d477e4 100755
--- a/t/t9116-git-svn-log.sh
+++ b/t/t9116-git-svn-log.sh
@@ -8,14 +8,16 @@
 
 test_expect_success 'setup repository and import' '
 	mkdir import &&
-	cd import &&
-		for i in trunk branches/a branches/b \
-		         tags/0.1 tags/0.2 tags/0.3; do
-			mkdir -p $i && \
-			echo hello >> $i/README || exit 1
-		done && \
+	(
+		cd import &&
+		for i in trunk branches/a branches/b tags/0.1 tags/0.2 tags/0.3
+		do
+			mkdir -p $i &&
+			echo hello >>$i/README ||
+			exit 1
+		done &&
 		svn_cmd import -m test . "$svnrepo"
-		cd .. &&
+	) &&
 	git svn init "$svnrepo" -T trunk -b branches -t tags &&
 	git svn fetch &&
 	git reset --hard trunk &&
diff --git a/t/t9119-git-svn-info.sh b/t/t9119-git-svn-info.sh
index 5fb94fb..f3f397c 100755
--- a/t/t9119-git-svn-info.sh
+++ b/t/t9119-git-svn-info.sh
@@ -39,27 +39,30 @@
 
 test_expect_success 'setup repository and import' '
 	mkdir info &&
-	cd info &&
-		echo FIRST > A &&
-		echo one > file &&
+	(
+		cd info &&
+		echo FIRST >A &&
+		echo one >file &&
 		ln -s file symlink-file &&
 		mkdir directory &&
 		touch directory/.placeholder &&
 		ln -s directory symlink-directory &&
-		svn_cmd import -m "initial" . "$svnrepo" &&
-	cd .. &&
+		svn_cmd import -m "initial" . "$svnrepo"
+	) &&
 	svn_cmd co "$svnrepo" svnwc &&
-	cd svnwc &&
-		echo foo > foo &&
+	(
+		cd svnwc &&
+		echo foo >foo &&
 		svn_cmd add foo &&
 		svn_cmd commit -m "change outside directory" &&
-		svn_cmd update &&
-	cd .. &&
+		svn_cmd update
+	) &&
 	mkdir gitwc &&
-	cd gitwc &&
+	(
+		cd gitwc &&
 		git svn init "$svnrepo" &&
-		git svn fetch &&
-	cd .. &&
+		git svn fetch
+	) &&
 	ptouch gitwc/file svnwc/file &&
 	ptouch gitwc/directory svnwc/directory &&
 	ptouch gitwc/symlink-file svnwc/symlink-file &&
@@ -138,14 +141,16 @@
 
 test_expect_success 'info added-file' "
 	echo two > gitwc/added-file &&
-	cd gitwc &&
-		git add added-file &&
-	cd .. &&
+	(
+		cd gitwc &&
+		git add added-file
+	) &&
 	cp gitwc/added-file svnwc/added-file &&
 	ptouch gitwc/added-file svnwc/added-file &&
-	cd svnwc &&
-		svn_cmd add added-file > /dev/null &&
-	cd .. &&
+	(
+		cd svnwc &&
+		svn_cmd add added-file > /dev/null
+	) &&
 	(cd svnwc; svn info added-file) > expected.info-added-file &&
 	(cd gitwc; git svn info added-file) > actual.info-added-file &&
 	test_cmp expected.info-added-file actual.info-added-file
@@ -160,12 +165,14 @@
 	mkdir gitwc/added-directory svnwc/added-directory &&
 	ptouch gitwc/added-directory svnwc/added-directory &&
 	touch gitwc/added-directory/.placeholder &&
-	cd svnwc &&
-		svn_cmd add added-directory > /dev/null &&
-	cd .. &&
-	cd gitwc &&
-		git add added-directory &&
-	cd .. &&
+	(
+		cd svnwc &&
+		svn_cmd add added-directory > /dev/null
+	) &&
+	(
+		cd gitwc &&
+		git add added-directory
+	) &&
 	(cd svnwc; svn info added-directory) \
 		> expected.info-added-directory &&
 	(cd gitwc; git svn info added-directory) \
@@ -179,14 +186,16 @@
 	'
 
 test_expect_success 'info added-symlink-file' "
-	cd gitwc &&
+	(
+		cd gitwc &&
 		ln -s added-file added-symlink-file &&
-		git add added-symlink-file &&
-	cd .. &&
-	cd svnwc &&
+		git add added-symlink-file
+	) &&
+	(
+		cd svnwc &&
 		ln -s added-file added-symlink-file &&
-		svn_cmd add added-symlink-file > /dev/null &&
-	cd .. &&
+		svn_cmd add added-symlink-file > /dev/null
+	) &&
 	ptouch gitwc/added-symlink-file svnwc/added-symlink-file &&
 	(cd svnwc; svn info added-symlink-file) \
 		> expected.info-added-symlink-file &&
@@ -202,14 +211,16 @@
 	'
 
 test_expect_success 'info added-symlink-directory' "
-	cd gitwc &&
+	(
+		cd gitwc &&
 		ln -s added-directory added-symlink-directory &&
-		git add added-symlink-directory &&
-	cd .. &&
-	cd svnwc &&
+		git add added-symlink-directory
+	) &&
+	(
+		cd svnwc &&
 		ln -s added-directory added-symlink-directory &&
-		svn_cmd add added-symlink-directory > /dev/null &&
-	cd .. &&
+		svn_cmd add added-symlink-directory > /dev/null
+	) &&
 	ptouch gitwc/added-symlink-directory svnwc/added-symlink-directory &&
 	(cd svnwc; svn info added-symlink-directory) \
 		> expected.info-added-symlink-directory &&
@@ -230,12 +241,14 @@
 # simply reuses the Last Changed Date.
 
 test_expect_success 'info deleted-file' "
-	cd gitwc &&
-		git rm -f file > /dev/null &&
-	cd .. &&
-	cd svnwc &&
-		svn_cmd rm --force file > /dev/null &&
-	cd .. &&
+	(
+		cd gitwc &&
+		git rm -f file > /dev/null
+	) &&
+	(
+		cd svnwc &&
+		svn_cmd rm --force file > /dev/null
+	) &&
 	(cd svnwc; svn info file) |
 	sed -e 's/^\(Text Last Updated:\).*/\1 TEXT-LAST-UPDATED-STRING/' \
 		> expected.info-deleted-file &&
@@ -251,12 +264,14 @@
 	'
 
 test_expect_success 'info deleted-directory' "
-	cd gitwc &&
-		git rm -r -f directory > /dev/null &&
-	cd .. &&
-	cd svnwc &&
-		svn_cmd rm --force directory > /dev/null &&
-	cd .. &&
+	(
+		cd gitwc &&
+		git rm -r -f directory > /dev/null
+	) &&
+	(
+		cd svnwc &&
+		svn_cmd rm --force directory > /dev/null
+	) &&
 	(cd svnwc; svn info directory) |
 	sed -e 's/^\(Text Last Updated:\).*/\1 TEXT-LAST-UPDATED-STRING/' \
 		> expected.info-deleted-directory &&
@@ -272,12 +287,14 @@
 	'
 
 test_expect_success 'info deleted-symlink-file' "
-	cd gitwc &&
-		git rm -f symlink-file > /dev/null &&
-	cd .. &&
-	cd svnwc &&
-		svn_cmd rm --force symlink-file > /dev/null &&
-	cd .. &&
+	(
+		cd gitwc &&
+		git rm -f symlink-file > /dev/null
+	) &&
+	(
+		cd svnwc &&
+		svn_cmd rm --force symlink-file > /dev/null
+	) &&
 	(cd svnwc; svn info symlink-file) |
 	sed -e 's/^\(Text Last Updated:\).*/\1 TEXT-LAST-UPDATED-STRING/' \
 		> expected.info-deleted-symlink-file &&
@@ -294,12 +311,14 @@
 	'
 
 test_expect_success 'info deleted-symlink-directory' "
-	cd gitwc &&
-		git rm -f symlink-directory > /dev/null &&
-	cd .. &&
-	cd svnwc &&
-		svn_cmd rm --force symlink-directory > /dev/null &&
-	cd .. &&
+	(
+		cd gitwc &&
+		git rm -f symlink-directory > /dev/null
+	) &&
+	(
+		cd svnwc &&
+		svn_cmd rm --force symlink-directory > /dev/null
+	) &&
 	(cd svnwc; svn info symlink-directory) |
 	sed -e 's/^\(Text Last Updated:\).*/\1 TEXT-LAST-UPDATED-STRING/' \
 		 > expected.info-deleted-symlink-directory &&
@@ -346,9 +365,10 @@
 	'
 
 test_expect_success 'info unknown-symlink-file' "
-	cd gitwc &&
-		ln -s unknown-file unknown-symlink-file &&
-	cd .. &&
+	(
+		cd gitwc &&
+		ln -s unknown-file unknown-symlink-file
+	) &&
 	(cd gitwc; test_must_fail git svn info unknown-symlink-file) \
 		 2> actual.info-unknown-symlink-file &&
 	grep unknown-symlink-file actual.info-unknown-symlink-file
@@ -361,9 +381,10 @@
 	'
 
 test_expect_success 'info unknown-symlink-directory' "
-	cd gitwc &&
-		ln -s unknown-directory unknown-symlink-directory &&
-	cd .. &&
+	(
+		cd gitwc &&
+		ln -s unknown-directory unknown-symlink-directory
+	) &&
 	(cd gitwc; test_must_fail git svn info unknown-symlink-directory) \
 		 2> actual.info-unknown-symlink-directory &&
 	grep unknown-symlink-directory actual.info-unknown-symlink-directory
diff --git a/t/t9120-git-svn-clone-with-percent-escapes.sh b/t/t9120-git-svn-clone-with-percent-escapes.sh
index 9d9ebd5..1d92c05 100755
--- a/t/t9120-git-svn-clone-with-percent-escapes.sh
+++ b/t/t9120-git-svn-clone-with-percent-escapes.sh
@@ -20,9 +20,10 @@
 
 test_expect_success 'test clone with percent escapes' '
 	git svn clone "$svnrepo/pr%20ject" clone &&
-	cd clone &&
-		git rev-parse refs/${remotes_git_svn} &&
-	cd ..
+	(
+		cd clone &&
+		git rev-parse refs/${remotes_git_svn}
+	)
 '
 
 # SVN works either way, so should we...
diff --git a/t/t9123-git-svn-rebuild-with-rewriteroot.sh b/t/t9123-git-svn-rebuild-with-rewriteroot.sh
index 0455216..0ed90d9 100755
--- a/t/t9123-git-svn-rebuild-with-rewriteroot.sh
+++ b/t/t9123-git-svn-rebuild-with-rewriteroot.sh
@@ -8,10 +8,10 @@
 . ./lib-git-svn.sh
 
 mkdir import
-cd import
+(cd import
 	touch foo
 	svn_cmd import -m 'import for git svn' . "$svnrepo" >/dev/null
-cd ..
+)
 rm -rf import
 
 test_expect_success 'init, fetch and checkout repository' '
diff --git a/t/t9125-git-svn-multi-glob-branch-names.sh b/t/t9125-git-svn-multi-glob-branch-names.sh
index c194186..096abd1 100755
--- a/t/t9125-git-svn-multi-glob-branch-names.sh
+++ b/t/t9125-git-svn-multi-glob-branch-names.sh
@@ -19,19 +19,19 @@
 test_expect_success 'test clone with multi-glob in branch names' '
 	git svn clone -T trunk -b branches/*/* -t tags \
 	              "$svnrepo/project" project &&
-	cd project &&
+	(cd project &&
 		git rev-parse "refs/remotes/v14.1/beta" &&
-		git rev-parse "refs/remotes/v14.1/gold" &&
-	cd ..
+		git rev-parse "refs/remotes/v14.1/gold"
+	)
 	'
 
 test_expect_success 'test dcommit to multi-globbed branch' "
-	cd project &&
+	(cd project &&
 	git reset --hard 'refs/remotes/v14.1/gold' &&
 	echo hello >> foo &&
 	git commit -m 'hello' -- foo &&
-	git svn dcommit &&
-	cd ..
+	git svn dcommit
+	)
 	"
 
 test_done
diff --git a/t/t9127-git-svn-partial-rebuild.sh b/t/t9127-git-svn-partial-rebuild.sh
index 4aab8ec..2e4789d 100755
--- a/t/t9127-git-svn-partial-rebuild.sh
+++ b/t/t9127-git-svn-partial-rebuild.sh
@@ -9,27 +9,27 @@
 test_expect_success 'initialize svnrepo' '
 	mkdir import &&
 	(
-		cd import &&
+		(cd import &&
 		mkdir trunk branches tags &&
-		cd trunk &&
-		echo foo > foo &&
-		cd .. &&
+		(cd trunk &&
+		echo foo > foo
+		) &&
 		svn_cmd import -m "import for git-svn" . "$svnrepo" >/dev/null &&
 		svn_cmd copy "$svnrepo"/trunk "$svnrepo"/branches/a \
-			-m "created branch a" &&
-		cd .. &&
+			-m "created branch a"
+		) &&
 		rm -rf import &&
 		svn_cmd co "$svnrepo"/trunk trunk &&
-		cd trunk &&
+		(cd trunk &&
 		echo bar >> foo &&
-		svn_cmd ci -m "updated trunk" &&
-		cd .. &&
+		svn_cmd ci -m "updated trunk"
+		) &&
 		svn_cmd co "$svnrepo"/branches/a a &&
-		cd a &&
+		(cd a &&
 		echo baz >> a &&
 		svn_cmd add a &&
-		svn_cmd ci -m "updated a" &&
-		cd .. &&
+		svn_cmd ci -m "updated a"
+		) &&
 		git svn init --stdlayout "$svnrepo"
 	)
 '
@@ -41,11 +41,11 @@
 test_expect_success 'make full git mirror of SVN' '
 	mkdir mirror &&
 	(
-		cd mirror &&
+		(cd mirror &&
 		git init &&
 		git svn init --stdlayout "$svnrepo" &&
-		git svn fetch &&
-		cd ..
+		git svn fetch
+		)
 	)
 '
 
diff --git a/t/t9128-git-svn-cmd-branch.sh b/t/t9128-git-svn-cmd-branch.sh
index 807e494..4b034a6 100755
--- a/t/t9128-git-svn-cmd-branch.sh
+++ b/t/t9128-git-svn-cmd-branch.sh
@@ -9,19 +9,19 @@
 test_expect_success 'initialize svnrepo' '
 	mkdir import &&
 	(
-		cd import &&
+		(cd import &&
 		mkdir trunk branches tags &&
-		cd trunk &&
-		echo foo > foo &&
-		cd .. &&
-		svn_cmd import -m "import for git-svn" . "$svnrepo" >/dev/null &&
-		cd .. &&
+		(cd trunk &&
+		echo foo > foo
+		) &&
+		svn_cmd import -m "import for git-svn" . "$svnrepo" >/dev/null
+		) &&
 		rm -rf import &&
 		svn_cmd co "$svnrepo"/trunk trunk &&
-		cd trunk &&
+		(cd trunk &&
 		echo bar >> foo &&
-		svn_cmd ci -m "updated trunk" &&
-		cd .. &&
+		svn_cmd ci -m "updated trunk"
+		) &&
 		rm -rf trunk
 	)
 '
diff --git a/t/t9137-git-svn-dcommit-clobber-series.sh b/t/t9137-git-svn-dcommit-clobber-series.sh
index 636ca0a..d60da63 100755
--- a/t/t9137-git-svn-dcommit-clobber-series.sh
+++ b/t/t9137-git-svn-dcommit-clobber-series.sh
@@ -6,10 +6,10 @@
 
 test_expect_success 'initialize repo' '
 	mkdir import &&
-	cd import &&
+	(cd import &&
 	awk "BEGIN { for (i = 1; i < 64; i++) { print i } }" > file
-	svn_cmd import -m "initial" . "$svnrepo" &&
-	cd .. &&
+	svn_cmd import -m "initial" . "$svnrepo"
+	) &&
 	git svn init "$svnrepo" &&
 	git svn fetch &&
 	test -e file
@@ -19,14 +19,14 @@
 	test x"`sed -n -e 58p < file`" = x58 &&
 	test x"`sed -n -e 61p < file`" = x61 &&
 	svn_cmd co "$svnrepo" tmp &&
-	cd tmp &&
+	(cd tmp &&
 		perl -i.bak -p -e "s/^58$/5588/" file &&
 		perl -i.bak -p -e "s/^61$/6611/" file &&
 		poke file &&
 		test x"`sed -n -e 58p < file`" = x5588 &&
 		test x"`sed -n -e 61p < file`" = x6611 &&
-		svn_cmd commit -m "58 => 5588, 61 => 6611" &&
-		cd ..
+		svn_cmd commit -m "58 => 5588, 61 => 6611"
+	)
 	'
 
 test_expect_success 'some unrelated changes to git' "
diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh
index 96d07f1..7c05920 100755
--- a/t/t9300-fast-import.sh
+++ b/t/t9300-fast-import.sh
@@ -1110,11 +1110,10 @@
 	'P: supermodule & submodule mix' \
 	'git fast-import <input &&
 	 git checkout subuse1 &&
-	 rm -rf sub && mkdir sub && cd sub &&
+	 rm -rf sub && mkdir sub && (cd sub &&
 	 git init &&
 	 git fetch --update-head-ok .. refs/heads/sub:refs/heads/master &&
-	 git checkout master &&
-	 cd .. &&
+	 git checkout master) &&
 	 git submodule init &&
 	 git submodule update'
 
diff --git a/t/t9401-git-cvsserver-crlf.sh b/t/t9401-git-cvsserver-crlf.sh
index 925bd0f..1bbfd82 100755
--- a/t/t9401-git-cvsserver-crlf.sh
+++ b/t/t9401-git-cvsserver-crlf.sh
@@ -129,21 +129,22 @@
 '
 
 test_expect_success 'adding files' '
-    cd cvswork/subdir &&
+    (cd cvswork &&
+    (cd subdir &&
     echo "more text" > src.c &&
     GIT_CONFIG="$git_config" cvs -Q add src.c >cvs.log 2>&1 &&
     marked_as . src.c "" &&
-    echo "psuedo-binary" > temp.bin &&
-    cd .. &&
+    echo "psuedo-binary" > temp.bin
+    ) &&
     GIT_CONFIG="$git_config" cvs -Q add subdir/temp.bin >cvs.log 2>&1 &&
     marked_as subdir temp.bin "-kb" &&
     cd subdir &&
     GIT_CONFIG="$git_config" cvs -Q ci -m "adding files" >cvs.log 2>&1 &&
     marked_as . temp.bin "-kb" &&
     marked_as . src.c ""
+    )
 '
 
-cd "$WORKDIR"
 test_expect_success 'updating' '
     git pull gitcvs.git &&
     echo 'hi' > subdir/newfile.bin &&
@@ -153,9 +154,9 @@
     git add subdir/newfile.bin subdir/file.h subdir/newfile.c binfile.bin &&
     git commit -q -m "Add and change some files" &&
     git push gitcvs.git >/dev/null &&
-    cd cvswork &&
-    GIT_CONFIG="$git_config" cvs -Q update &&
-    cd .. &&
+    (cd cvswork &&
+    GIT_CONFIG="$git_config" cvs -Q update
+    ) &&
     marked_as cvswork textfile.c "" &&
     marked_as cvswork binfile.bin -kb &&
     marked_as cvswork .gitattributes "" &&
@@ -233,35 +234,35 @@
 '
 
 test_expect_success 'add text (guess)' '
-    cd cvswork &&
+    (cd cvswork &&
     echo "simpleText" > simpleText.c &&
-    GIT_CONFIG="$git_config" cvs -Q add simpleText.c &&
-    cd .. &&
+    GIT_CONFIG="$git_config" cvs -Q add simpleText.c
+    ) &&
     marked_as cvswork simpleText.c ""
 '
 
 test_expect_success 'add bin (guess)' '
-    cd cvswork &&
+    (cd cvswork &&
     echo "simpleBin: NUL: Q <- there" | q_to_nul > simpleBin.bin &&
-    GIT_CONFIG="$git_config" cvs -Q add simpleBin.bin &&
-    cd .. &&
+    GIT_CONFIG="$git_config" cvs -Q add simpleBin.bin
+    ) &&
     marked_as cvswork simpleBin.bin -kb
 '
 
 test_expect_success 'remove files (guess)' '
-    cd cvswork &&
+    (cd cvswork &&
     GIT_CONFIG="$git_config" cvs -Q rm -f subdir/file.h &&
-    cd subdir &&
-    GIT_CONFIG="$git_config" cvs -Q rm -f withCr.bin &&
-    cd ../.. &&
+    (cd subdir &&
+    GIT_CONFIG="$git_config" cvs -Q rm -f withCr.bin
+    )) &&
     marked_as cvswork/subdir withCr.bin -kb &&
     marked_as cvswork/subdir file.h ""
 '
 
 test_expect_success 'cvs ci (guess)' '
-    cd cvswork &&
-    GIT_CONFIG="$git_config" cvs -Q ci -m "add/rm files" >cvs.log 2>&1 &&
-    cd .. &&
+    (cd cvswork &&
+    GIT_CONFIG="$git_config" cvs -Q ci -m "add/rm files" >cvs.log 2>&1
+    ) &&
     marked_as cvswork textfile.c "" &&
     marked_as cvswork binfile.bin -kb &&
     marked_as cvswork .gitattributes "" &&
@@ -278,9 +279,9 @@
 '
 
 test_expect_success 'update subdir of other copy (guess)' '
-    cd cvswork2/subdir &&
-    GIT_CONFIG="$git_config" cvs -Q update &&
-    cd ../.. &&
+    (cd cvswork2/subdir &&
+    GIT_CONFIG="$git_config" cvs -Q update
+    ) &&
     marked_as cvswork2 textfile.c "" &&
     marked_as cvswork2 binfile.bin -kb &&
     marked_as cvswork2 .gitattributes "" &&
@@ -304,11 +305,11 @@
     git add multilineTxt.c &&
     git commit -q -m "modify multiline file" >> "${WORKDIR}/marked.log" &&
     git push gitcvs.git >/dev/null &&
-    cd cvswork2 &&
+    (cd cvswork2 &&
     sed "s/1/replaced_1/" < multilineTxt.c > ml.temp &&
     mv ml.temp multilineTxt.c &&
-    GIT_CONFIG="$git_config" cvs update > cvs.log 2>&1 &&
-    cd .. &&
+    GIT_CONFIG="$git_config" cvs update > cvs.log 2>&1
+    ) &&
     marked_as cvswork2 textfile.c "" &&
     marked_as cvswork2 binfile.bin -kb &&
     marked_as cvswork2 .gitattributes "" &&
diff --git a/t/t9600-cvsimport.sh b/t/t9600-cvsimport.sh
index 559ce41..432b82e 100755
--- a/t/t9600-cvsimport.sh
+++ b/t/t9600-cvsimport.sh
@@ -14,7 +14,7 @@
 
 	mkdir "$CVSROOT/module" &&
 	$CVS co -d module-cvs module &&
-	cd module-cvs &&
+	(cd module-cvs &&
 	cat <<EOF >o_fortuna &&
 O Fortuna
 velut luna
@@ -38,8 +38,8 @@
 
 These public domain lyrics make an excellent sample text.
 EOF
-	$CVS commit -F message &&
-	cd ..
+	$CVS commit -F message
+	)
 '
 
 test_expect_success PERL 'import a trivial module' '
@@ -49,7 +49,7 @@
 
 '
 
-test_expect_success PERL 'pack refs' 'cd module-git && git gc && cd ..'
+test_expect_success PERL 'pack refs' '(cd module-git && git gc)'
 
 test_expect_success PERL 'initial import has correct .git/cvs-revisions' '
 
@@ -59,8 +59,7 @@
 '
 
 test_expect_success PERL 'update cvs module' '
-
-	cd module-cvs &&
+	(cd module-cvs &&
 	cat <<EOF >o_fortuna &&
 O Fortune,
 like the moon
@@ -83,16 +82,16 @@
 
 My Latin is terrible.
 EOF
-	$CVS commit -F message &&
-	cd ..
+	$CVS commit -F message
+	)
 '
 
 test_expect_success PERL 'update git module' '
 
-	cd module-git &&
+	(cd module-git &&
 	git cvsimport -a -R -z 0 module &&
-	git merge origin &&
-	cd .. &&
+	git merge origin
+	) &&
 	test_cmp module-cvs/o_fortuna module-git/o_fortuna
 
 '
@@ -107,21 +106,20 @@
 
 test_expect_success PERL 'update cvs module' '
 
-	cd module-cvs &&
+	(cd module-cvs &&
 		echo 1 >tick &&
 		$CVS add tick &&
 		$CVS commit -m 1
-	cd ..
-
+	)
 '
 
 test_expect_success PERL 'cvsimport.module config works' '
 
-	cd module-git &&
+	(cd module-git &&
 		git config cvsimport.module module &&
 		git cvsimport -a -R -z0 &&
-		git merge origin &&
-	cd .. &&
+		git merge origin
+	) &&
 	test_cmp module-cvs/tick module-git/tick
 
 '
@@ -138,12 +136,12 @@
 test_expect_success PERL 'import from a CVS working tree' '
 
 	$CVS co -d import-from-wt module &&
-	cd import-from-wt &&
+	(cd import-from-wt &&
 		git cvsimport -a -z0 &&
 		echo 1 >expect &&
 		git log -1 --pretty=format:%s%n >actual &&
-		test_cmp actual expect &&
-	cd ..
+		test_cmp actual expect
+	)
 
 '
 
diff --git a/t/t9603-cvsimport-patchsets.sh b/t/t9603-cvsimport-patchsets.sh
index 93c4fa8..52034c8 100755
--- a/t/t9603-cvsimport-patchsets.sh
+++ b/t/t9603-cvsimport-patchsets.sh
@@ -19,12 +19,12 @@
 test_expect_failure 'import with criss cross times on revisions' '
 
     git cvsimport -p"-x" -C module-git module &&
-    cd module-git &&
+    (cd module-git &&
         git log --pretty=format:%s > ../actual-master &&
         git log A~2..A --pretty="format:%s %ad" -- > ../actual-A &&
         echo "" >> ../actual-master &&
-        echo "" >> ../actual-A &&
-    cd .. &&
+	echo "" >> ../actual-A
+    ) &&
     echo "Rev 4
 Rev 3
 Rev 2