[PATCH] ls-tree: test for the regression in 9c4d58ff2c3
- From
Ævar Arnfjörð Bjarmason <avarab@gmail.com>
- Date
- May 31, 2022, 17:21 UTC
- Message-ID
- <patch-1.1-0fdfec624eb-20220531T171908Z-avarab@gmail.com>
- In-Reply-To
- <xmqqee28spni.fsf@gitster.g>
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@evledraar.gmail.com/
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> ---
On Thu, Apr 07 2022, Junio C Hamano wrote:
Show 30 quoted lines
> Ævar Arnfjörð Bjarmason <avarab@gmail.com> 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@gmail.com>
## 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@evledraar.gmail.com/
- Reported-By: Josh Steadmon <steadmon@google.com>
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
- ## 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_donet/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