# [PATCH] t7610: use test_path_is_* helpers

2 messages from 2026-09-14 to 2026-09-14. Participants: Tanishq Singh via B4 Relay, Junio C Hamano.
Thread: https://gitlist.dev/t/66329

## Tanishq Singh via B4 Relay, 2026-09-14 14:49

Subject: [PATCH] t7610: use test_path_is_* helpers
Message-ID: <20260914-t7610-test-path-helpers-v1-1-4824812314c7@tanishqsingh.com>

```
From: Tanishq Singh <hello@tanishqsingh.com>

Replace 'test -f', 'test -d' and 'test ! -e' with the
test_path_is_file(), test_path_is_dir() and test_path_is_missing()
helpers. The helpers print the directory listing on failure, which
makes diagnosing a broken test easier than non-zero exit status
offered by 'test'.

Signed-off-by: Tanishq Singh <hello@tanishqsingh.com>
---
Verified with `cd t && ./t7610-mergetool.sh`,
and all tests pass.
---
 t/t7610-mergetool.sh | 30 +++++++++++++++---------------
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/t/t7610-mergetool.sh b/t/t7610-mergetool.sh
index 0128b14452..92ac8f3fb6 100755
--- a/t/t7610-mergetool.sh
+++ b/t/t7610-mergetool.sh
@@ -382,15 +382,15 @@ test_expect_success 'mergetool delete/delete conflict' '
 	git checkout -b test$test_count move-to-c &&
 	test_must_fail git merge move-to-b &&
 	echo d | git mergetool a/a/file.txt &&
-	! test -f a/a/file.txt &&
+	! test_path_is_file a/a/file.txt &&
 	git reset --hard &&
 	test_must_fail git merge move-to-b &&
 	echo m | git mergetool a/a/file.txt &&
-	test -f b/b/file.txt &&
+	test_path_is_file b/b/file.txt &&
 	git reset --hard &&
 	test_must_fail git merge move-to-b &&
 	! echo a | git mergetool a/a/file.txt &&
-	! test -f a/a/file.txt
+	! test_path_is_file a/a/file.txt
 '
 
 test_expect_success 'mergetool produces no errors when keepBackup is used' '
@@ -400,7 +400,7 @@ test_expect_success 'mergetool produces no errors when keepBackup is used' '
 	test_must_fail git merge move-to-b &&
 	echo d | git mergetool a/a/file.txt 2>actual &&
 	test_must_be_empty actual &&
-	! test -d a
+	! test_path_is_dir a
 '
 
 test_expect_success 'mergetool honors tempfile config for deleted files' '
@@ -409,7 +409,7 @@ test_expect_success 'mergetool honors tempfile config for deleted files' '
 	test_config mergetool.keepTemporaries false &&
 	test_must_fail git merge move-to-b &&
 	echo d | git mergetool a/a/file.txt &&
-	! test -d a
+	! test_path_is_dir a
 '
 
 test_expect_success 'mergetool keeps tempfiles when aborting delete/delete' '
@@ -419,7 +419,7 @@ test_expect_success 'mergetool keeps tempfiles when aborting delete/delete' '
 	test_config mergetool.keepTemporaries true &&
 	test_must_fail git merge move-to-b &&
 	! test_write_lines a n | git mergetool a/a/file.txt &&
-	test -d a/a &&
+	test_path_is_dir a/a &&
 	cat >expect <<-\EOF &&
 	file_BASE_.txt
 	file_LOCAL_.txt
@@ -462,7 +462,7 @@ test_expect_success 'deleted vs modified submodule' '
 	yes "" | git mergetool both &&
 	yes "d" | git mergetool file11 file12 &&
 	yes "l" | git mergetool submod &&
-	test ! -e submod &&
+	test_path_is_missing submod &&
 	output="$(git mergetool --no-prompt)" &&
 	test "$output" = "No files need merging" &&
 	git commit -m "Merge resolved by deleting module" &&
@@ -476,8 +476,8 @@ test_expect_success 'deleted vs modified submodule' '
 	yes "" | git mergetool both &&
 	yes "d" | git mergetool file11 file12 &&
 	yes "r" | git mergetool submod &&
-	test ! -e submod &&
-	test -d submod.orig &&
+	test_path_is_missing submod &&
+	test_path_is_dir submod.orig &&
 	git submodule update -N &&
 	output="$(git mergetool --no-prompt)" &&
 	test "$output" = "No files need merging" &&
@@ -547,7 +547,7 @@ test_expect_success 'file vs modified submodule' '
 
 	git checkout -b test$test_count.c main &&
 	rmdir submod && mv submod-movedaside submod &&
-	test ! -e submod.orig &&
+	test_path_is_missing submod.orig &&
 	git submodule update -N &&
 	test_must_fail git merge test$test_count &&
 	test -n "$(git ls-files -u)" &&
@@ -558,7 +558,7 @@ test_expect_success 'file vs modified submodule' '
 	git rm --cached submod &&
 	yes "c" | git mergetool submod~test19 &&
 	git mv submod~test19 submod &&
-	test -d submod.orig &&
+	test_path_is_dir submod.orig &&
 	git submodule update -N &&
 	echo "not a submodule" >expect &&
 	test_cmp expect submod &&
@@ -672,11 +672,11 @@ test_expect_success 'directory vs modified submodule' '
 	git reset --hard &&
 	test_must_fail git merge main &&
 	test -n "$(git ls-files -u)" &&
-	test ! -e submod.orig &&
+	test_path_is_missing submod.orig &&
 	yes "r" | git mergetool submod~main &&
 	git mv submod submod.orig &&
 	git mv submod~main submod &&
-	test -d submod.orig &&
+	test_path_is_dir submod.orig &&
 	echo "not a submodule" >expect &&
 	test_cmp expect submod.orig/file16 &&
 	rm -r submod.orig &&
@@ -701,7 +701,7 @@ test_expect_success 'directory vs modified submodule' '
 	git submodule update -N &&
 	test_must_fail git merge test$test_count &&
 	test -n "$(git ls-files -u)" &&
-	test ! -e submod.orig &&
+	test_path_is_missing submod.orig &&
 	yes "r" | git mergetool submod &&
 	echo "not a submodule" >expect &&
 	test_cmp expect submod/file16 &&
@@ -743,7 +743,7 @@ test_expect_success 'filenames seen by tools start with ./' '
 
 test_lazy_prereq MKTEMP '
 	tempdir=$(mktemp -d -t foo.XXXXXX) &&
-	test -d "$tempdir" &&
+	test_path_is_dir "$tempdir" &&
 	rmdir "$tempdir"
 '
 

---
base-commit: 47ce80527c56f462cb97db4ca8125342204d3783
change-id: 20260914-t7610-test-path-helpers-134ded7da9df



```

## Junio C Hamano, 2026-09-14 15:42

Subject: Re: [PATCH] t7610: use test_path_is_* helpers
Message-ID: <xmqqy0d36dq7.fsf@gitster.g>
In-Reply-To: <20260914-t7610-test-path-helpers-v1-1-4824812314c7@tanishqsingh.com>

```
Tanishq Singh via B4 Relay
<devnull+hello.tanishqsingh.com@kernel.org> writes:

>  	echo d | git mergetool a/a/file.txt &&
> -	! test -f a/a/file.txt &&
> +	! test_path_is_file a/a/file.txt &&

This is wrong.  Consider why you would prefer test_path_is_file()
over test -f in the first place.

The goal is to be much louder when the expectation is not met,
while remaining as silent as test -f in the happy case.  This grabs
the attention of those running tests.  We want to be loud when
things break, and silent otherwise.

test_path_is_file() expects file X to exist and will not complain
when X is a file.

However, the test "! test -f a/a/file.txt" in this case expects
something totally different.  It ensures that such a path does not
exist.  It is an error if a/a/file.txt exists here.  You want the
helper to be loud when the file exists, and silent when it does not.

test_path_is_file() called on a/a/file.txt, with or without a
leading !, behaves incorrectly for the purpose of this conversion,
even though the polarity of the returned status may be correct
(i.e., test_path_is_file(), just like test -f, exits with status 0
when the file a/a/file.txt exists, and a leading ! negates it,
making the test line fail when a/a/file.txt exists).

If the expectation is that a/a/file.txt does not exist, use
test_path_is_missing().  Please read through t/test-lib.sh and
t/test-lib-functions.sh to familiarize yourself with the helpers
these files offer before going further.

Thanks.

```
