diff options
| author | Junio C Hamano <gitster@pobox.com> | 2020-02-14 12:54:22 -0800 |
|---|---|---|
| committer | Junio C Hamano <gitster@pobox.com> | 2020-02-14 12:54:22 -0800 |
| commit | 433b8aac2eb7a8bc3e383a072f7df7d15c4aabbb (patch) | |
| tree | eb79af1dec711d05bc19b0aff968675489d3d8de /t | |
| parent | 4a77434bc83c07c17ddc321b3892337b5533eda1 (diff) | |
| parent | f998a3f1e588d73ed7285cb14ac4839f63f6dc82 (diff) | |
| download | git-433b8aac2eb7a8bc3e383a072f7df7d15c4aabbb.tar.xz | |
Merge branch 'ds/sparse-checkout-harden'
Some rough edges in the sparse-checkout feature, especially around
the cone mode, have been cleaned up.
* ds/sparse-checkout-harden:
sparse-checkout: fix cone mode behavior mismatch
sparse-checkout: improve docs around 'set' in cone mode
sparse-checkout: escape all glob characters on write
sparse-checkout: use C-style quotes in 'list' subcommand
sparse-checkout: unquote C-style strings over --stdin
sparse-checkout: write escaped patterns in cone mode
sparse-checkout: properly match escaped characters
sparse-checkout: warn on globs in cone patterns
sparse-checkout: detect short patterns
sparse-checkout: cone mode does not recognize "**"
sparse-checkout: fix documentation typo for core.sparseCheckoutCone
clone: fix --sparse option with URLs
sparse-checkout: create leading directories
t1091: improve here-docs
t1091: use check_files to reduce boilerplate
Diffstat (limited to 't')
| -rwxr-xr-x | t/t1091-sparse-checkout-builtin.sh | 352 |
1 files changed, 211 insertions, 141 deletions
diff --git a/t/t1091-sparse-checkout-builtin.sh b/t/t1091-sparse-checkout-builtin.sh index ff7f8f7a1f..7d982096fb 100755 --- a/t/t1091-sparse-checkout-builtin.sh +++ b/t/t1091-sparse-checkout-builtin.sh @@ -12,6 +12,13 @@ list_files() { (cd "$1" && printf '%s\n' *) } +check_files() { + list_files "$1" >actual && + shift && + printf "%s\n" $@ >expect && + test_cmp expect actual +} + test_expect_success 'setup' ' git init repo && ( @@ -39,11 +46,11 @@ test_expect_success 'git sparse-checkout list (empty)' ' test_expect_success 'git sparse-checkout list (populated)' ' test_when_finished rm -f repo/.git/info/sparse-checkout && - cat >repo/.git/info/sparse-checkout <<-EOF && - /folder1/* - /deep/ - **/a - !*bin* + cat >repo/.git/info/sparse-checkout <<-\EOF && + /folder1/* + /deep/ + **/a + !*bin* EOF cp repo/.git/info/sparse-checkout expect && git -C repo sparse-checkout list >list && @@ -52,22 +59,20 @@ test_expect_success 'git sparse-checkout list (populated)' ' test_expect_success 'git sparse-checkout init' ' git -C repo sparse-checkout init && - cat >expect <<-EOF && - /* - !/*/ + cat >expect <<-\EOF && + /* + !/*/ EOF test_cmp expect repo/.git/info/sparse-checkout && test_cmp_config -C repo true core.sparsecheckout && - list_files repo >dir && - echo a >expect && - test_cmp expect dir + check_files repo a ' test_expect_success 'git sparse-checkout list after init' ' git -C repo sparse-checkout list >actual && - cat >expect <<-EOF && - /* - !/*/ + cat >expect <<-\EOF && + /* + !/*/ EOF test_cmp expect actual ' @@ -75,32 +80,24 @@ test_expect_success 'git sparse-checkout list after init' ' test_expect_success 'init with existing sparse-checkout' ' echo "*folder*" >> repo/.git/info/sparse-checkout && git -C repo sparse-checkout init && - cat >expect <<-EOF && - /* - !/*/ - *folder* + cat >expect <<-\EOF && + /* + !/*/ + *folder* EOF test_cmp expect repo/.git/info/sparse-checkout && - list_files repo >dir && - cat >expect <<-EOF && - a - folder1 - folder2 - EOF - test_cmp expect dir + check_files repo a folder1 folder2 ' test_expect_success 'clone --sparse' ' - git clone --sparse repo clone && + git clone --sparse "file://$(pwd)/repo" clone && git -C clone sparse-checkout list >actual && - cat >expect <<-EOF && - /* - !/*/ + cat >expect <<-\EOF && + /* + !/*/ EOF test_cmp expect actual && - list_files clone >dir && - echo a >expect && - test_cmp expect dir + check_files clone a ' test_expect_success 'set enables config' ' @@ -119,41 +116,29 @@ test_expect_success 'set enables config' ' test_expect_success 'set sparse-checkout using builtin' ' git -C repo sparse-checkout set "/*" "!/*/" "*folder*" && - cat >expect <<-EOF && - /* - !/*/ - *folder* + cat >expect <<-\EOF && + /* + !/*/ + *folder* EOF git -C repo sparse-checkout list >actual && test_cmp expect actual && test_cmp expect repo/.git/info/sparse-checkout && - list_files repo >dir && - cat >expect <<-EOF && - a - folder1 - folder2 - EOF - test_cmp expect dir + check_files repo a folder1 folder2 ' test_expect_success 'set sparse-checkout using --stdin' ' - cat >expect <<-EOF && - /* - !/*/ - /folder1/ - /folder2/ + cat >expect <<-\EOF && + /* + !/*/ + /folder1/ + /folder2/ EOF git -C repo sparse-checkout set --stdin <expect && git -C repo sparse-checkout list >actual && test_cmp expect actual && test_cmp expect repo/.git/info/sparse-checkout && - list_files repo >dir && - cat >expect <<-EOF && - a - folder1 - folder2 - EOF - test_cmp expect dir + check_files repo "a folder1 folder2" ' test_expect_success 'cone mode: match patterns' ' @@ -162,13 +147,7 @@ test_expect_success 'cone mode: match patterns' ' git -C repo read-tree -mu HEAD 2>err && test_i18ngrep ! "disabling cone patterns" err && git -C repo reset --hard && - list_files repo >dir && - cat >expect <<-EOF && - a - folder1 - folder2 - EOF - test_cmp expect dir + check_files repo a folder1 folder2 ' test_expect_success 'cone mode: warn on bad pattern' ' @@ -185,14 +164,7 @@ test_expect_success 'sparse-checkout disable' ' test_path_is_file repo/.git/info/sparse-checkout && git -C repo config --list >config && test_must_fail git config core.sparseCheckout && - list_files repo >dir && - cat >expect <<-EOF && - a - deep - folder1 - folder2 - EOF - test_cmp expect dir + check_files repo a deep folder1 folder2 ' test_expect_success 'cone mode: init and set' ' @@ -204,52 +176,31 @@ test_expect_success 'cone mode: init and set' ' test_cmp expect dir && git -C repo sparse-checkout set deep/deeper1/deepest/ 2>err && test_must_be_empty err && - list_files repo >dir && - cat >expect <<-EOF && - a - deep - EOF - test_cmp expect dir && - list_files repo/deep >dir && - cat >expect <<-EOF && - a - deeper1 - EOF - test_cmp expect dir && - list_files repo/deep/deeper1 >dir && - cat >expect <<-EOF && - a - deepest - EOF - test_cmp expect dir && - cat >expect <<-EOF && - /* - !/*/ - /deep/ - !/deep/*/ - /deep/deeper1/ - !/deep/deeper1/*/ - /deep/deeper1/deepest/ + check_files repo a deep && + check_files repo/deep a deeper1 && + check_files repo/deep/deeper1 a deepest && + cat >expect <<-\EOF && + /* + !/*/ + /deep/ + !/deep/*/ + /deep/deeper1/ + !/deep/deeper1/*/ + /deep/deeper1/deepest/ EOF test_cmp expect repo/.git/info/sparse-checkout && - git -C repo sparse-checkout set --stdin 2>err <<-EOF && - folder1 - folder2 + git -C repo sparse-checkout set --stdin 2>err <<-\EOF && + folder1 + folder2 EOF test_must_be_empty err && - cat >expect <<-EOF && - a - folder1 - folder2 - EOF - list_files repo >dir && - test_cmp expect dir + check_files repo a folder1 folder2 ' test_expect_success 'cone mode: list' ' - cat >expect <<-EOF && - folder1 - folder2 + cat >expect <<-\EOF && + folder1 + folder2 EOF git -C repo sparse-checkout set --stdin <expect && git -C repo sparse-checkout list >actual 2>err && @@ -260,10 +211,10 @@ test_expect_success 'cone mode: list' ' test_expect_success 'cone mode: set with nested folders' ' git -C repo sparse-checkout set deep deep/deeper1/deepest 2>err && test_line_count = 0 err && - cat >expect <<-EOF && - /* - !/*/ - /deep/ + cat >expect <<-\EOF && + /* + !/*/ + /deep/ EOF test_cmp repo/.git/info/sparse-checkout expect ' @@ -275,13 +226,7 @@ test_expect_success 'revert to old sparse-checkout on bad update' ' test_must_fail git -C repo sparse-checkout set deep/deeper1 2>err && test_i18ngrep "cannot set sparse-checkout patterns" err && test_cmp repo/.git/info/sparse-checkout expect && - list_files repo/deep >dir && - cat >expect <<-EOF && - a - deeper1 - deeper2 - EOF - test_cmp dir expect + check_files repo/deep a deeper1 deeper2 ' test_expect_success 'revert to old sparse-checkout on empty update' ' @@ -326,18 +271,13 @@ test_expect_success 'sparse-checkout (init|set|disable) fails with dirty status' test_expect_success 'cone mode: set with core.ignoreCase=true' ' git -C repo sparse-checkout init --cone && git -C repo -c core.ignoreCase=true sparse-checkout set folder1 && - cat >expect <<-EOF && - /* - !/*/ - /folder1/ + cat >expect <<-\EOF && + /* + !/*/ + /folder1/ EOF test_cmp expect repo/.git/info/sparse-checkout && - list_files repo >dir && - cat >expect <<-EOF && - a - folder1 - EOF - test_cmp expect dir + check_files repo a folder1 ' test_expect_success 'interaction with submodules' ' @@ -351,21 +291,151 @@ test_expect_success 'interaction with submodules' ' git sparse-checkout init --cone && git sparse-checkout set folder1 ) && - list_files super >dir && + check_files super a folder1 modules && + check_files super/modules/child a deep folder1 folder2 +' + +test_expect_success 'different sparse-checkouts with worktrees' ' + git -C repo worktree add --detach ../worktree && + check_files worktree "a deep folder1 folder2" && + git -C worktree sparse-checkout init --cone && + git -C repo sparse-checkout set folder1 && + git -C worktree sparse-checkout set deep/deeper1 && + check_files repo a folder1 && + check_files worktree a deep +' + +test_expect_success 'set using filename keeps file on-disk' ' + git -C repo sparse-checkout set a deep && cat >expect <<-\EOF && - a - folder1 - modules + /* + !/*/ + /a/ + /deep/ EOF - test_cmp expect dir && - list_files super/modules/child >dir && + test_cmp expect repo/.git/info/sparse-checkout && + check_files repo a deep +' + +check_read_tree_errors () { + REPO=$1 + FILES=$2 + ERRORS=$3 + git -C $REPO -c core.sparseCheckoutCone=false read-tree -mu HEAD 2>err && + test_must_be_empty err && + check_files $REPO "$FILES" && + git -C $REPO read-tree -mu HEAD 2>err && + if test -z "$ERRORS" + then + test_must_be_empty err + else + test_i18ngrep "$ERRORS" err + fi && + check_files $REPO $FILES +} + +test_expect_success 'pattern-checks: /A/**' ' + cat >repo/.git/info/sparse-checkout <<-\EOF && + /* + !/*/ + /folder1/** + EOF + check_read_tree_errors repo "a folder1" "disabling cone pattern matching" +' + +test_expect_success 'pattern-checks: /A/**/B/' ' + cat >repo/.git/info/sparse-checkout <<-\EOF && + /* + !/*/ + /deep/**/deepest + EOF + check_read_tree_errors repo "a deep" "disabling cone pattern matching" && + check_files repo/deep "deeper1" && + check_files repo/deep/deeper1 "deepest" +' + +test_expect_success 'pattern-checks: too short' ' + cat >repo/.git/info/sparse-checkout <<-\EOF && + /* + !/*/ + /a + EOF + check_read_tree_errors repo "a" "disabling cone pattern matching" +' + +test_expect_success 'pattern-checks: trailing "*"' ' + cat >repo/.git/info/sparse-checkout <<-\EOF && + /* + !/*/ + /a* + EOF + check_read_tree_errors repo "a" "disabling cone pattern matching" +' + +test_expect_success 'pattern-checks: starting "*"' ' + cat >repo/.git/info/sparse-checkout <<-\EOF && + /* + !/*/ + *eep/ + EOF + check_read_tree_errors repo "a deep" "disabling cone pattern matching" +' + +test_expect_success 'pattern-checks: contained glob characters' ' + for c in "[a]" "\\" "?" "*" + do + cat >repo/.git/info/sparse-checkout <<-EOF && + /* + !/*/ + something$c-else/ + EOF + check_read_tree_errors repo "a" "disabling cone pattern matching" + done +' + +test_expect_success BSLASHPSPEC 'pattern-checks: escaped characters' ' + git clone repo escaped && + TREEOID=$(git -C escaped rev-parse HEAD:folder1) && + NEWTREE=$(git -C escaped mktree <<-EOF + $(git -C escaped ls-tree HEAD) + 040000 tree $TREEOID zbad\\dir + 040000 tree $TREEOID zdoes*exist + 040000 tree $TREEOID zglob[!a]? + EOF + ) && + COMMIT=$(git -C escaped commit-tree $NEWTREE -p HEAD) && + git -C escaped reset --hard $COMMIT && + check_files escaped "a deep folder1 folder2 zbad\\dir zdoes*exist" zglob[!a]? && + git -C escaped sparse-checkout init --cone && + git -C escaped sparse-checkout set zbad\\dir/bogus "zdoes*not*exist" "zdoes*exist" "zglob[!a]?" && + cat >expect <<-\EOF && + /* + !/*/ + /zbad\\dir/ + !/zbad\\dir/*/ + /zbad\\dir/bogus/ + /zdoes\*exist/ + /zdoes\*not\*exist/ + /zglob\[!a]\?/ + EOF + test_cmp expect escaped/.git/info/sparse-checkout && + check_read_tree_errors escaped "a zbad\\dir zdoes*exist zglob[!a]?" && + git -C escaped ls-tree -d --name-only HEAD >list-expect && + git -C escaped sparse-checkout set --stdin <list-expect && cat >expect <<-\EOF && - a - deep - folder1 - folder2 + /* + !/*/ + /deep/ + /folder1/ + /folder2/ + /zbad\\dir/ + /zdoes\*exist/ + /zglob\[!a]\?/ EOF - test_cmp expect dir + test_cmp expect escaped/.git/info/sparse-checkout && + check_files escaped "a deep folder1 folder2 zbad\\dir zdoes*exist" zglob[!a]? && + git -C escaped sparse-checkout list >list-actual && + test_cmp list-expect list-actual ' test_done |
