[PATCH] ls-tree: test for the regression in 9c4d58ff2c3

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add a test for the regression introduced in my 9c4d58ff2c3 (ls-tree:
split up "fast path" callbacks, 2022-03-23) and fixed in
350296cc789 (ls-tree: `-l` should not imply recursive listing,
2022-04-04), and test for the test of ls-tree option/mode combinations
to make sure we don't have other blind spots.

The setup for these tests can be shared with those added in the
1041d58b4d9 (Merge branch 'tl/ls-tree-oid-only', 2022-04-04) topic, so
let's create a new t/lib-t3100.sh to help them share data.

The existing tests in "t3104-ls-tree-format.sh" didn't deal with a
submodule, which they'll now encounter with as the
setup_basic_ls_tree_data() sets one up.

This extensive testing should give us confidence that there were no
further regressions in this area. The lack of testing was noted back
in [1], but unfortunately we didn't cover that blind-spot before
9c4d58ff2c3.

1. https://lore.kernel.org/git/211115.86o86lqe3c.gmgdl@xxxxxxxxxxxxxxxxxxx/

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@xxxxxxxxx>
---

On Thu, Apr 07 2022, Junio C Hamano wrote:

> Ævar Arnfjörð Bjarmason <avarab@xxxxxxxxx> writes:
>
>>>>> Let's not go too cute like this.  This forces the caller to remember
>>>>> which among 6, 7, and 8 corresponds to which option.  It is too ugly
>>>>> to live.
>>>>
>>>> I think it's rather elegant actually, but to be fair it would, per:
>>>>
>>>>    git grep '<&[1-9]| [1-9]<<-'
>>>>
>>>> Be the user with the most FD's using this sort of pattern.
>>>
>>> Please give a clear explanation why "-d" has to be 6, "-r" 7 and
>>> "-t" 8, that can be used by developers as a memory aid to help them
>>> write new tests using the helper.
>>
>> It's documented when test-lib.sh does the redirection, since Fabian
>> Stelzer's a6714088e0c (test-lib: make BAIL_OUT() work in tests and
>> prereq, 2021-12-01).
>
> Sorry, but that is not what I asked.  I know what we use lower file
> descriptors for, and I didn't ask why we start from 6 (as opposed to
> 3).
>
> The updated helper forces our developers to know that the expected
> result for "-d" has to go to #6 (not #7 or #8), and "-r" to #7 (not
> #6 or #8), etc., in order to write new tests using it, and in order
> to spot a mistake while reviewing such new tests.
>
> It is an invitation to unmaintainable mess.  Don't encourage it.

I came up with this at the time, but didn't submit it since we were in
the rc period.

But since we're past that I think it makes sense to have a test for
the regression we fixed, the below is a lot less magical, but larger
by line count. I think this alternate test implementation should
address the concerns you had.

Range-diff:
1:  ed83b3b74ab ! 1:  0fdfec624eb ls-tree: fix --long implying -r regression in 9c4d58ff2c3
    @@ Metadata
     Author: Ævar Arnfjörð Bjarmason <avarab@xxxxxxxxx>
     
      ## Commit message ##
    -    ls-tree: fix --long implying -r regression in 9c4d58ff2c3
    +    ls-tree: test for the regression in 9c4d58ff2c3
     
    -    Fix a regression introduced in 9c4d58ff2c3 (ls-tree: split up "fast
    -    path" callbacks, 2022-03-23), and improve the tests added in the
    -    1041d58b4d9 (Merge branch 'tl/ls-tree-oid-only', 2022-04-04) topic it
    -    was merged as part of to test the full expected output of various
    -    "ls-tree" options with and without -r.
    +    Add a test for the regression introduced in my 9c4d58ff2c3 (ls-tree:
    +    split up "fast path" callbacks, 2022-03-23) and fixed in
    +    350296cc789 (ls-tree: `-l` should not imply recursive listing,
    +    2022-04-04), and test for the test of ls-tree option/mode combinations
    +    to make sure we don't have other blind spots.
     
    -    Let's fix it, and also add tests not only for that blindspot, but also
    -    any other potential blindspots. To that end test the "modes" of -d, -r
    -    and -t (as well as "no mode") against all of the format options.
    +    The setup for these tests can be shared with those added in the
    +    1041d58b4d9 (Merge branch 'tl/ls-tree-oid-only', 2022-04-04) topic, so
    +    let's create a new t/lib-t3100.sh to help them share data.
     
    -    These tests all pass with that topic reverted (except those that would
    -    fail because they're testing the new --object-only feature introduced
    -    in that topic), which should give us confidence that there were no
    -    further regressions in this area.
    +    The existing tests in "t3104-ls-tree-format.sh" didn't deal with a
    +    submodule, which they'll now encounter with as the
    +    setup_basic_ls_tree_data() sets one up.
    +
    +    This extensive testing should give us confidence that there were no
    +    further regressions in this area. The lack of testing was noted back
    +    in [1], but unfortunately we didn't cover that blind-spot before
    +    9c4d58ff2c3.
    +
    +    1. https://lore.kernel.org/git/211115.86o86lqe3c.gmgdl@xxxxxxxxxxxxxxxxxxx/
     
    -    Reported-By: Josh Steadmon <steadmon@xxxxxxxxxx>
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@xxxxxxxxx>
     
    - ## builtin/ls-tree.c ##
    -@@ builtin/ls-tree.c: static int show_tree_long(const struct object_id *oid, struct strbuf *base,
    - 	printf("%06o %s %s %7s\t", data.mode, type_name(data.type),
    - 	       find_unique_abbrev(data.oid, abbrev), size_text);
    - 	show_tree_common_default_long(base, pathname, data.base->len);
    --	return 1;
    -+	return recurse;
    - }
    - 
    - static int show_tree_name_only(const struct object_id *oid, struct strbuf *base,
    + ## t/lib-t3100.sh (new) ##
    +@@
    ++#!/bin/sh
    ++
    ++setup_basic_ls_tree_data () {
    ++	mkdir dir &&
    ++	test_commit dir/sub-file &&
    ++	test_commit top-file &&
    ++	git clone . submodule &&
    ++	git submodule add ./submodule &&
    ++	git commit -m"add submodule"
    ++}
     
      ## t/t3104-ls-tree-format.sh ##
    -@@ t/t3104-ls-tree-format.sh: test_ls_tree_format () {
    - 	fmtopts=$3 &&
    - 	shift 2 &&
    +@@ t/t3104-ls-tree-format.sh: test_description='ls-tree --format'
    + 
    + TEST_PASSES_SANITIZE_LEAK=true
    + . ./test-lib.sh
    ++. "$TEST_DIRECTORY"/lib-t3100.sh
    + 
    + test_expect_success 'ls-tree --format usage' '
    + 	test_expect_code 129 git ls-tree --format=fmt -l HEAD &&
    +@@ t/t3104-ls-tree-format.sh: test_expect_success 'ls-tree --format usage' '
    + '
    + 
    + test_expect_success 'setup' '
    +-	mkdir dir &&
    +-	test_commit dir/sub-file &&
    +-	test_commit top-file
    ++	setup_basic_ls_tree_data
    + '
      
    + test_ls_tree_format () {
    +
    + ## t/t3105-ls-tree-output.sh (new) ##
    +@@
    ++#!/bin/sh
    ++
    ++test_description='ls-tree output'
    ++
    ++TEST_PASSES_SANITIZE_LEAK=true
    ++. ./test-lib.sh
    ++. "$TEST_DIRECTORY"/lib-t3100.sh
    ++
    ++test_expect_success 'ls-tree --format usage' '
    ++	test_expect_code 129 git ls-tree --format=fmt -l HEAD &&
    ++	test_expect_code 129 git ls-tree --format=fmt --name-only HEAD &&
    ++	test_expect_code 129 git ls-tree --format=fmt --name-status HEAD
    ++'
    ++
    ++test_expect_success 'setup' '
    ++	setup_basic_ls_tree_data
    ++'
    ++
    ++test_ls_tree_format_mode_output () {
    ++	local opts=$1 &&
    ++	shift &&
     +	cat >expect &&
    -+	cat <&6 >expect.-d &&
    -+	cat <&7 >expect.-r &&
    -+	cat <&8 >expect.-t &&
     +
    -+	for opt in '' '-d' '-r' '-t'
    ++	while test $# -gt 0
     +	do
    -+		test_expect_success "'ls-tree $opts${opt:+ $opt}' output" '
    -+			git ls-tree ${opt:+$opt }$opts $opt HEAD >actual &&
    -+			test_cmp expect${opt:+.$opt} actual
    ++		local mode="$1" &&
    ++		shift &&
    ++
    ++		test_expect_success "'ls-tree $opts${mode:+ $mode}' output" '
    ++			git ls-tree ${mode:+$mode }$opts HEAD >actual &&
    ++			test_cmp expect actual
     +		'
    ++
    ++		case "$opts" in
    ++		--full-tree)
    ++			test_expect_success "'ls-tree $opts${mode:+ $mode}' output (via subdir, fails)" '
    ++				test_must_fail git -C dir ls-tree --full-name ${mode:+$mode }$opts HEAD -- ../
    ++			'
    ++			;;
    ++		*)
    ++			test_expect_success "'ls-tree $opts${mode:+ $mode}' output (via subdir)" '
    ++				git -C dir ls-tree --full-name ${mode:+$mode }$opts HEAD -- ../ >actual &&
    ++				test_cmp expect actual
    ++			'
    ++			;;
    ++		esac
     +	done
    ++}
     +
    - 	test_expect_success "ls-tree '--format=<$format>' is like options '$opts $fmtopts'" '
    - 		git ls-tree $opts -r HEAD >expect &&
    - 		git ls-tree --format="$format" -r $fmtopts HEAD >actual &&
    -@@ t/t3104-ls-tree-format.sh: test_ls_tree_format () {
    - 
    - test_ls_tree_format \
    - 	"%(objectmode) %(objecttype) %(objectname)%x09%(path)" \
    --	""
    -+	"" \
    -+	<<-OUT 6<<-OUT_D 7<<-OUT_R 8<<-OUT_T
    -+	040000 tree $(git rev-parse HEAD:dir)	dir
    -+	100644 blob $(git rev-parse HEAD:top-file.t)	top-file.t
    -+	OUT
    -+	040000 tree $(git rev-parse HEAD:dir)	dir
    -+	OUT_D
    -+	100644 blob $(git rev-parse HEAD:dir/sub-file.t)	dir/sub-file.t
    -+	100644 blob $(git rev-parse HEAD:top-file.t)	top-file.t
    -+	OUT_R
    -+	040000 tree $(git rev-parse HEAD:dir)	dir
    -+	100644 blob $(git rev-parse HEAD:top-file.t)	top-file.t
    -+	OUT_T
    - 
    - test_ls_tree_format \
    - 	"%(objectmode) %(objecttype) %(objectname) %(objectsize:padded)%x09%(path)" \
    --	"--long"
    -+	"--long" \
    -+	<<-OUT 6<<-OUT_D 7<<-OUT_R 8<<-OUT_T
    -+	040000 tree $(git rev-parse HEAD:dir)       -	dir
    -+	100644 blob $(git rev-parse HEAD:top-file.t)       9	top-file.t
    -+	OUT
    -+	040000 tree $(git rev-parse HEAD:dir)       -	dir
    -+	OUT_D
    -+	100644 blob $(git rev-parse HEAD:dir/sub-file.t)      13	dir/sub-file.t
    -+	100644 blob $(git rev-parse HEAD:top-file.t)       9	top-file.t
    -+	OUT_R
    -+	040000 tree $(git rev-parse HEAD:dir)       -	dir
    -+	100644 blob $(git rev-parse HEAD:top-file.t)       9	top-file.t
    -+	OUT_T
    - 
    - test_ls_tree_format \
    - 	"%(path)" \
    --	"--name-only"
    -+	"--name-only" \
    -+	<<-OUT 6<<-OUT_D 7<<-OUT_R 8<<-OUT_T
    ++# test exact output of option (none, --long, ...) and mode (none and
    ++# -d, -r -t) and combinations
    ++test_expect_success 'setup: HEAD_* variables' '
    ++	HEAD_gitmodules=$(git rev-parse HEAD:.gitmodules) &&
    ++	HEAD_dir=$(git rev-parse HEAD:dir) &&
    ++	HEAD_top_file=$(git rev-parse HEAD:top-file.t) &&
    ++	HEAD_submodule=$(git rev-parse HEAD:submodule) &&
    ++	HEAD_dir_sub_file=$(git rev-parse HEAD:dir/sub-file.t)
    ++'
    ++## opt =
    ++test_ls_tree_format_mode_output "" "" "-t" <<-EOF
    ++	100644 blob $HEAD_gitmodules	.gitmodules
    ++	040000 tree $HEAD_dir	dir
    ++	160000 commit $HEAD_submodule	submodule
    ++	100644 blob $HEAD_top_file	top-file.t
    ++	EOF
    ++test_ls_tree_format_mode_output "" "-d" <<-EOF
    ++	040000 tree $HEAD_dir	dir
    ++	160000 commit $HEAD_submodule	submodule
    ++	EOF
    ++test_ls_tree_format_mode_output "" "-r" <<-EOF
    ++	100644 blob $HEAD_gitmodules	.gitmodules
    ++	100644 blob $HEAD_dir_sub_file	dir/sub-file.t
    ++	160000 commit $HEAD_submodule	submodule
    ++	100644 blob $HEAD_top_file	top-file.t
    ++	EOF
    ++## opt = --long
    ++test_ls_tree_format_mode_output "--long" "" "-t" <<-EOF
    ++	100644 blob $HEAD_gitmodules      61	.gitmodules
    ++	040000 tree $HEAD_dir       -	dir
    ++	160000 commit $HEAD_submodule       -	submodule
    ++	100644 blob $HEAD_top_file       9	top-file.t
    ++	EOF
    ++test_ls_tree_format_mode_output "--long" "-d" <<-EOF
    ++	040000 tree $HEAD_dir       -	dir
    ++	160000 commit $HEAD_submodule       -	submodule
    ++	EOF
    ++test_ls_tree_format_mode_output "--long" "-r" <<-EOF
    ++	100644 blob $HEAD_gitmodules      61	.gitmodules
    ++	100644 blob $HEAD_dir_sub_file      13	dir/sub-file.t
    ++	160000 commit $HEAD_submodule       -	submodule
    ++	100644 blob $HEAD_top_file       9	top-file.t
    ++	EOF
    ++## opt = --name-only
    ++test_ls_tree_format_mode_output "--name-only" "" "-t" <<-EOF
    ++	.gitmodules
     +	dir
    ++	submodule
     +	top-file.t
    -+	OUT
    ++	EOF
    ++test_ls_tree_format_mode_output "--name-only" "-d" <<-EOF
     +	dir
    -+	OUT_D
    ++	submodule
    ++	EOF
    ++test_ls_tree_format_mode_output "--name-only" "-r" <<-EOF
    ++	.gitmodules
     +	dir/sub-file.t
    ++	submodule
     +	top-file.t
    -+	OUT_R
    -+	dir
    -+	top-file.t
    -+	OUT_T
    - 
    - test_ls_tree_format \
    - 	"%(objectname)" \
    --	"--object-only"
    -+	"--object-only" \
    -+	<<-OUT 6<<-OUT_D 7<<-OUT_R 8<<-OUT_T
    -+	$(git rev-parse HEAD:dir)
    -+	$(git rev-parse HEAD:top-file.t)
    -+	OUT
    -+	$(git rev-parse HEAD:dir)
    -+	OUT_D
    -+	$(git rev-parse HEAD:dir/sub-file.t)
    -+	$(git rev-parse HEAD:top-file.t)
    -+	OUT_R
    -+	$(git rev-parse HEAD:dir)
    -+	$(git rev-parse HEAD:top-file.t)
    -+	OUT_T
    - 
    - test_ls_tree_format \
    - 	"%(objectname)" \
    - 	"--object-only --abbrev" \
    --	"--abbrev"
    -+	"--abbrev" \
    -+	<<-OUT 6<<-OUT_D 7<<-OUT_R 8<<-OUT_T
    -+	$(git rev-parse HEAD:dir | test_copy_bytes 7)
    -+	$(git rev-parse HEAD:top-file.t| test_copy_bytes 7)
    -+	OUT
    -+	$(git rev-parse HEAD:dir | test_copy_bytes 7)
    -+	OUT_D
    -+	$(git rev-parse HEAD:dir/sub-file.t | test_copy_bytes 7)
    -+	$(git rev-parse HEAD:top-file.t | test_copy_bytes 7)
    -+	OUT_R
    -+	$(git rev-parse HEAD:dir | test_copy_bytes 7)
    -+	$(git rev-parse HEAD:top-file.t | test_copy_bytes 7)
    -+	OUT_T
    - 
    - test_ls_tree_format \
    - 	"%(objectmode) %(objecttype) %(objectname)%x09%(path)" \
    - 	"-t" \
    --	"-t"
    -+	"-t" \
    -+	<<-OUT 6<<-OUT_D 7<<-OUT_R 8<<-OUT_T
    -+	040000 tree $(git rev-parse HEAD:dir)	dir
    -+	100644 blob $(git rev-parse HEAD:top-file.t)	top-file.t
    -+	OUT
    -+	040000 tree $(git rev-parse HEAD:dir)	dir
    -+	OUT_D
    -+	040000 tree $(git rev-parse HEAD:dir)	dir
    -+	100644 blob $(git rev-parse HEAD:dir/sub-file.t)	dir/sub-file.t
    -+	100644 blob $(git rev-parse HEAD:top-file.t)	top-file.t
    -+	OUT_R
    -+	040000 tree $(git rev-parse HEAD:dir)	dir
    -+	100644 blob $(git rev-parse HEAD:top-file.t)	top-file.t
    -+	OUT_T
    - 
    - test_ls_tree_format \
    - 	"%(objectmode) %(objecttype) %(objectname)%x09%(path)" \
    - 	"--full-name" \
    --	"--full-name"
    -+	"--full-name" \
    -+	<<-OUT 6<<-OUT_D 7<<-OUT_R 8<<-OUT_T
    -+	040000 tree $(git rev-parse HEAD:dir)	dir
    -+	100644 blob $(git rev-parse HEAD:top-file.t)	top-file.t
    -+	OUT
    -+	040000 tree $(git rev-parse HEAD:dir)	dir
    -+	OUT_D
    -+	100644 blob $(git rev-parse HEAD:dir/sub-file.t)	dir/sub-file.t
    -+	100644 blob $(git rev-parse HEAD:top-file.t)	top-file.t
    -+	OUT_R
    -+	040000 tree $(git rev-parse HEAD:dir)	dir
    -+	100644 blob $(git rev-parse HEAD:top-file.t)	top-file.t
    -+	OUT_T
    - 
    - test_ls_tree_format \
    - 	"%(objectmode) %(objecttype) %(objectname)%x09%(path)" \
    - 	"--full-tree" \
    --	"--full-tree"
    -+	"--full-tree" \
    -+	<<-OUT 6<<-OUT_D 7<<-OUT_R 8<<-OUT_T
    -+	040000 tree $(git rev-parse HEAD:dir)	dir
    -+	100644 blob $(git rev-parse HEAD:top-file.t)	top-file.t
    -+	OUT
    -+	040000 tree $(git rev-parse HEAD:dir)	dir
    -+	OUT_D
    -+	100644 blob $(git rev-parse HEAD:dir/sub-file.t)	dir/sub-file.t
    -+	100644 blob $(git rev-parse HEAD:top-file.t)	top-file.t
    -+	OUT_R
    -+	040000 tree $(git rev-parse HEAD:dir)	dir
    -+	100644 blob $(git rev-parse HEAD:top-file.t)	top-file.t
    -+	OUT_T
    - 
    - test_done
    ++	EOF
    ++## opt = --object-only
    ++test_ls_tree_format_mode_output "--object-only" "" "-t" <<-EOF
    ++	$HEAD_gitmodules
    ++	$HEAD_dir
    ++	$HEAD_submodule
    ++	$HEAD_top_file
    ++	EOF
    ++test_ls_tree_format_mode_output "--object-only" "-d" <<-EOF
    ++	$HEAD_dir
    ++	$HEAD_submodule
    ++	EOF
    ++test_ls_tree_format_mode_output "--object-only" "-r" <<-EOF
    ++	$HEAD_gitmodules
    ++	$HEAD_dir_sub_file
    ++	$HEAD_submodule
    ++	$HEAD_top_file
    ++	EOF
    ++## opt = --object-only --abbrev
    ++test_expect_success 'setup: HEAD_short_* variables' '
    ++	HEAD_short_gitmodules=$(git rev-parse --short HEAD:.gitmodules) &&
    ++	HEAD_short_dir=$(git rev-parse --short HEAD:dir) &&
    ++	HEAD_short_top_file=$(git rev-parse --short HEAD:top-file.t) &&
    ++	HEAD_short_submodule=$(git rev-parse --short HEAD:submodule) &&
    ++	HEAD_short_dir_sub_file=$(git rev-parse --short HEAD:dir/sub-file.t)
    ++'
    ++test_ls_tree_format_mode_output "--object-only --abbrev" "" "-t" <<-EOF
    ++	$HEAD_short_gitmodules
    ++	$HEAD_short_dir
    ++	$HEAD_short_submodule
    ++	$HEAD_short_top_file
    ++	EOF
    ++test_ls_tree_format_mode_output "--object-only --abbrev" "-d" <<-EOF
    ++	$HEAD_short_dir
    ++	$HEAD_short_submodule
    ++	EOF
    ++test_ls_tree_format_mode_output "--object-only --abbrev" "-r" <<-EOF
    ++	$HEAD_short_gitmodules
    ++	$HEAD_short_dir_sub_file
    ++	$HEAD_short_submodule
    ++	$HEAD_short_top_file
    ++	EOF
    ++## opt = --full-name
    ++test_ls_tree_format_mode_output "--full-name" "" <<-EOF
    ++	100644 blob $HEAD_gitmodules	.gitmodules
    ++	040000 tree $HEAD_dir	dir
    ++	160000 commit $HEAD_submodule	submodule
    ++	100644 blob $HEAD_top_file	top-file.t
    ++	EOF
    ++test_ls_tree_format_mode_output "--full-name" "-d" <<-EOF
    ++	040000 tree $HEAD_dir	dir
    ++	160000 commit $HEAD_submodule	submodule
    ++	EOF
    ++test_ls_tree_format_mode_output "--full-name" "-r" <<-EOF
    ++	100644 blob $HEAD_gitmodules	.gitmodules
    ++	100644 blob $HEAD_dir_sub_file	dir/sub-file.t
    ++	160000 commit $HEAD_submodule	submodule
    ++	100644 blob $HEAD_top_file	top-file.t
    ++	EOF
    ++test_ls_tree_format_mode_output "--full-name" "-t" <<-EOF
    ++	100644 blob $HEAD_gitmodules	.gitmodules
    ++	040000 tree $HEAD_dir	dir
    ++	160000 commit $HEAD_submodule	submodule
    ++	100644 blob $HEAD_top_file	top-file.t
    ++	EOF
    ++## opt = --full-tree
    ++test_ls_tree_format_mode_output "--full-tree" "" "-t" <<-EOF
    ++	100644 blob $HEAD_gitmodules	.gitmodules
    ++	040000 tree $HEAD_dir	dir
    ++	160000 commit $HEAD_submodule	submodule
    ++	100644 blob $HEAD_top_file	top-file.t
    ++	EOF
    ++test_ls_tree_format_mode_output "--full-tree" "-d" <<-EOF
    ++	040000 tree $HEAD_dir	dir
    ++	160000 commit $HEAD_submodule	submodule
    ++	EOF
    ++test_ls_tree_format_mode_output "--full-tree" "-r" <<-EOF
    ++	100644 blob $HEAD_gitmodules	.gitmodules
    ++	100644 blob $HEAD_dir_sub_file	dir/sub-file.t
    ++	160000 commit $HEAD_submodule	submodule
    ++	100644 blob $HEAD_top_file	top-file.t
    ++	EOF
    ++
    ++test_done

 t/lib-t3100.sh            |  10 ++
 t/t3104-ls-tree-format.sh |   5 +-
 t/t3105-ls-tree-output.sh | 192 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 204 insertions(+), 3 deletions(-)
 create mode 100644 t/lib-t3100.sh
 create mode 100755 t/t3105-ls-tree-output.sh

diff --git a/t/lib-t3100.sh b/t/lib-t3100.sh
new file mode 100644
index 00000000000..eabb5fd8034
--- /dev/null
+++ b/t/lib-t3100.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+setup_basic_ls_tree_data () {
+	mkdir dir &&
+	test_commit dir/sub-file &&
+	test_commit top-file &&
+	git clone . submodule &&
+	git submodule add ./submodule &&
+	git commit -m"add submodule"
+}
diff --git a/t/t3104-ls-tree-format.sh b/t/t3104-ls-tree-format.sh
index 0769a933d69..383896667b6 100755
--- a/t/t3104-ls-tree-format.sh
+++ b/t/t3104-ls-tree-format.sh
@@ -4,6 +4,7 @@ test_description='ls-tree --format'
 
 TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
+. "$TEST_DIRECTORY"/lib-t3100.sh
 
 test_expect_success 'ls-tree --format usage' '
 	test_expect_code 129 git ls-tree --format=fmt -l HEAD &&
@@ -12,9 +13,7 @@ test_expect_success 'ls-tree --format usage' '
 '
 
 test_expect_success 'setup' '
-	mkdir dir &&
-	test_commit dir/sub-file &&
-	test_commit top-file
+	setup_basic_ls_tree_data
 '
 
 test_ls_tree_format () {
diff --git a/t/t3105-ls-tree-output.sh b/t/t3105-ls-tree-output.sh
new file mode 100755
index 00000000000..29511d9331b
--- /dev/null
+++ b/t/t3105-ls-tree-output.sh
@@ -0,0 +1,192 @@
+#!/bin/sh
+
+test_description='ls-tree output'
+
+TEST_PASSES_SANITIZE_LEAK=true
+. ./test-lib.sh
+. "$TEST_DIRECTORY"/lib-t3100.sh
+
+test_expect_success 'ls-tree --format usage' '
+	test_expect_code 129 git ls-tree --format=fmt -l HEAD &&
+	test_expect_code 129 git ls-tree --format=fmt --name-only HEAD &&
+	test_expect_code 129 git ls-tree --format=fmt --name-status HEAD
+'
+
+test_expect_success 'setup' '
+	setup_basic_ls_tree_data
+'
+
+test_ls_tree_format_mode_output () {
+	local opts=$1 &&
+	shift &&
+	cat >expect &&
+
+	while test $# -gt 0
+	do
+		local mode="$1" &&
+		shift &&
+
+		test_expect_success "'ls-tree $opts${mode:+ $mode}' output" '
+			git ls-tree ${mode:+$mode }$opts HEAD >actual &&
+			test_cmp expect actual
+		'
+
+		case "$opts" in
+		--full-tree)
+			test_expect_success "'ls-tree $opts${mode:+ $mode}' output (via subdir, fails)" '
+				test_must_fail git -C dir ls-tree --full-name ${mode:+$mode }$opts HEAD -- ../
+			'
+			;;
+		*)
+			test_expect_success "'ls-tree $opts${mode:+ $mode}' output (via subdir)" '
+				git -C dir ls-tree --full-name ${mode:+$mode }$opts HEAD -- ../ >actual &&
+				test_cmp expect actual
+			'
+			;;
+		esac
+	done
+}
+
+# test exact output of option (none, --long, ...) and mode (none and
+# -d, -r -t) and combinations
+test_expect_success 'setup: HEAD_* variables' '
+	HEAD_gitmodules=$(git rev-parse HEAD:.gitmodules) &&
+	HEAD_dir=$(git rev-parse HEAD:dir) &&
+	HEAD_top_file=$(git rev-parse HEAD:top-file.t) &&
+	HEAD_submodule=$(git rev-parse HEAD:submodule) &&
+	HEAD_dir_sub_file=$(git rev-parse HEAD:dir/sub-file.t)
+'
+## opt =
+test_ls_tree_format_mode_output "" "" "-t" <<-EOF
+	100644 blob $HEAD_gitmodules	.gitmodules
+	040000 tree $HEAD_dir	dir
+	160000 commit $HEAD_submodule	submodule
+	100644 blob $HEAD_top_file	top-file.t
+	EOF
+test_ls_tree_format_mode_output "" "-d" <<-EOF
+	040000 tree $HEAD_dir	dir
+	160000 commit $HEAD_submodule	submodule
+	EOF
+test_ls_tree_format_mode_output "" "-r" <<-EOF
+	100644 blob $HEAD_gitmodules	.gitmodules
+	100644 blob $HEAD_dir_sub_file	dir/sub-file.t
+	160000 commit $HEAD_submodule	submodule
+	100644 blob $HEAD_top_file	top-file.t
+	EOF
+## opt = --long
+test_ls_tree_format_mode_output "--long" "" "-t" <<-EOF
+	100644 blob $HEAD_gitmodules      61	.gitmodules
+	040000 tree $HEAD_dir       -	dir
+	160000 commit $HEAD_submodule       -	submodule
+	100644 blob $HEAD_top_file       9	top-file.t
+	EOF
+test_ls_tree_format_mode_output "--long" "-d" <<-EOF
+	040000 tree $HEAD_dir       -	dir
+	160000 commit $HEAD_submodule       -	submodule
+	EOF
+test_ls_tree_format_mode_output "--long" "-r" <<-EOF
+	100644 blob $HEAD_gitmodules      61	.gitmodules
+	100644 blob $HEAD_dir_sub_file      13	dir/sub-file.t
+	160000 commit $HEAD_submodule       -	submodule
+	100644 blob $HEAD_top_file       9	top-file.t
+	EOF
+## opt = --name-only
+test_ls_tree_format_mode_output "--name-only" "" "-t" <<-EOF
+	.gitmodules
+	dir
+	submodule
+	top-file.t
+	EOF
+test_ls_tree_format_mode_output "--name-only" "-d" <<-EOF
+	dir
+	submodule
+	EOF
+test_ls_tree_format_mode_output "--name-only" "-r" <<-EOF
+	.gitmodules
+	dir/sub-file.t
+	submodule
+	top-file.t
+	EOF
+## opt = --object-only
+test_ls_tree_format_mode_output "--object-only" "" "-t" <<-EOF
+	$HEAD_gitmodules
+	$HEAD_dir
+	$HEAD_submodule
+	$HEAD_top_file
+	EOF
+test_ls_tree_format_mode_output "--object-only" "-d" <<-EOF
+	$HEAD_dir
+	$HEAD_submodule
+	EOF
+test_ls_tree_format_mode_output "--object-only" "-r" <<-EOF
+	$HEAD_gitmodules
+	$HEAD_dir_sub_file
+	$HEAD_submodule
+	$HEAD_top_file
+	EOF
+## opt = --object-only --abbrev
+test_expect_success 'setup: HEAD_short_* variables' '
+	HEAD_short_gitmodules=$(git rev-parse --short HEAD:.gitmodules) &&
+	HEAD_short_dir=$(git rev-parse --short HEAD:dir) &&
+	HEAD_short_top_file=$(git rev-parse --short HEAD:top-file.t) &&
+	HEAD_short_submodule=$(git rev-parse --short HEAD:submodule) &&
+	HEAD_short_dir_sub_file=$(git rev-parse --short HEAD:dir/sub-file.t)
+'
+test_ls_tree_format_mode_output "--object-only --abbrev" "" "-t" <<-EOF
+	$HEAD_short_gitmodules
+	$HEAD_short_dir
+	$HEAD_short_submodule
+	$HEAD_short_top_file
+	EOF
+test_ls_tree_format_mode_output "--object-only --abbrev" "-d" <<-EOF
+	$HEAD_short_dir
+	$HEAD_short_submodule
+	EOF
+test_ls_tree_format_mode_output "--object-only --abbrev" "-r" <<-EOF
+	$HEAD_short_gitmodules
+	$HEAD_short_dir_sub_file
+	$HEAD_short_submodule
+	$HEAD_short_top_file
+	EOF
+## opt = --full-name
+test_ls_tree_format_mode_output "--full-name" "" <<-EOF
+	100644 blob $HEAD_gitmodules	.gitmodules
+	040000 tree $HEAD_dir	dir
+	160000 commit $HEAD_submodule	submodule
+	100644 blob $HEAD_top_file	top-file.t
+	EOF
+test_ls_tree_format_mode_output "--full-name" "-d" <<-EOF
+	040000 tree $HEAD_dir	dir
+	160000 commit $HEAD_submodule	submodule
+	EOF
+test_ls_tree_format_mode_output "--full-name" "-r" <<-EOF
+	100644 blob $HEAD_gitmodules	.gitmodules
+	100644 blob $HEAD_dir_sub_file	dir/sub-file.t
+	160000 commit $HEAD_submodule	submodule
+	100644 blob $HEAD_top_file	top-file.t
+	EOF
+test_ls_tree_format_mode_output "--full-name" "-t" <<-EOF
+	100644 blob $HEAD_gitmodules	.gitmodules
+	040000 tree $HEAD_dir	dir
+	160000 commit $HEAD_submodule	submodule
+	100644 blob $HEAD_top_file	top-file.t
+	EOF
+## opt = --full-tree
+test_ls_tree_format_mode_output "--full-tree" "" "-t" <<-EOF
+	100644 blob $HEAD_gitmodules	.gitmodules
+	040000 tree $HEAD_dir	dir
+	160000 commit $HEAD_submodule	submodule
+	100644 blob $HEAD_top_file	top-file.t
+	EOF
+test_ls_tree_format_mode_output "--full-tree" "-d" <<-EOF
+	040000 tree $HEAD_dir	dir
+	160000 commit $HEAD_submodule	submodule
+	EOF
+test_ls_tree_format_mode_output "--full-tree" "-r" <<-EOF
+	100644 blob $HEAD_gitmodules	.gitmodules
+	100644 blob $HEAD_dir_sub_file	dir/sub-file.t
+	160000 commit $HEAD_submodule	submodule
+	100644 blob $HEAD_top_file	top-file.t
+	EOF
+
+test_done
-- 
2.36.1.1100.g16130010d07




[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux