{"thread":{"id":"57165","subject":"[PATCH 0/2] sparse checkout: custom bash completion updates","startedAt":"2021-12-30T00:32:37Z","lastAt":"2022-04-06T14:04:42Z","messageCount":95,"participants":["Lessley Dennington via GitGitGadget","Derrick Stolee","Lessley Dennington","Elijah Newren","Junio C Hamano","Taylor Blau","SZEDER Gábor","Ævar Arnfjörð Bjarmason","Adam Dinwoodie"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"445204","messageId":"pull.1108.git.1640824351.gitgitgadget@gmail.com","threadId":"57165","inReplyTo":null,"subject":"[PATCH 0/2] sparse checkout: custom bash completion updates","fromName":"Lessley Dennington via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-12-30T00:32:29Z","receivedAt":"2021-12-30T00:32:37Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"This series updates custom tab completion for the sparse-checkout command.\nSpecifically, it corrects the following issues with the current method:\n\n 1. git sparse-checkout <TAB> results in an incomplete list of subcommands\n    (it is missing reapply and add).\n 2. git sparse-checkout --<TAB> does not complete the help option.\n 3. Options for subcommands are not tab-completable.\n 4. git sparse-checkout set <TAB> and git sparse-checkout add <TAB> show\n    both file names and directory names.\n\nThe first commit in this series is a set of failing tests that highlight\neach of the above issues. The next commit updates the _git_sparse_checkout\nmethod in git-completion.bash to enable each of these tests to pass.\n\nThanks, Lessley\n\nLessley Dennington (2):\n  sparse-checkout: custom tab completion tests\n  sparse-checkout: custom tab completion\n\n contrib/completion/git-completion.bash | 34 +++++++-----\n t/t9902-completion.sh                  | 74 ++++++++++++++++++++++++++\n 2 files changed, 96 insertions(+), 12 deletions(-)\n\n\nbase-commit: 2ae0a9cb8298185a94e5998086f380a355dd8907\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-1108%2Fldennington%2Fsparse-checkout-bash-completion-v1\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1108/ldennington/sparse-checkout-bash-completion-v1\nPull-Request: https://github.com/gitgitgadget/git/pull/1108\n-- \ngitgitgadget\n"},{"id":"445205","messageId":"ab51236d18ce10ada89e8cde85f678130a0ab1fd.1640824351.git.gitgitgadget@gmail.com","threadId":"57165","inReplyTo":"pull.1108.git.1640824351.gitgitgadget@gmail.com","subject":"[PATCH 2/2] sparse-checkout: custom tab completion","fromName":"Lessley Dennington via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-12-30T00:32:31Z","receivedAt":"2021-12-30T00:32:38Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"From: Lessley Dennington <lessleydennington@gmail.com>\n\nFix custom tab completion for sparse-checkout command. This will ensure:\n\n1. The full list of subcommands is provided when users enter git\nsparse-checkout <TAB>.\n2. The --help option is tab-completable.\n3. Subcommand options are tab-completable.\n4. A list of directories (but not files) is provided when users enter git\nsparse-checkout add <TAB> or git sparse-checkout set <TAB>.\n\nFailing tests that were added in the previous commit to verify these\nscenarios are now passing with these updates.\n\nSigned-off-by: Lessley Dennington <lessleydennington@gmail.com>\n---\n contrib/completion/git-completion.bash | 34 +++++++++++++++++---------\n t/t9902-completion.sh                  |  8 +++---\n 2 files changed, 26 insertions(+), 16 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 377d6c5494a..b8f1caece83 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -2986,24 +2986,34 @@ _git_show_branch ()\n \t__git_complete_revlist\n }\n \n+__git_sparse_checkout_init_opts=\"--cone --sparse-index --no-sparse-index\"\n+\n _git_sparse_checkout ()\n {\n-\tlocal subcommands=\"list init set disable\"\n+\tlocal subcommands=\"list init set disable add reapply\"\n \tlocal subcommand=\"$(__git_find_on_cmdline \"$subcommands\")\"\n+\n \tif [ -z \"$subcommand\" ]; then\n-\t\t__gitcomp \"$subcommands\"\n-\t\treturn\n+\t\tcase \"$cur\" in\n+\t\t\t--*)\n+\t\t\t\t__gitcomp \"--help\"\n+\t\t\t\t;;\n+\t\t\t*)\n+\t\t\t\t__gitcomp \"$subcommands\"\n+\t\t\t\t;;\n+\t\tesac\n \tfi\n \n-\tcase \"$subcommand,$cur\" in\n-\tinit,--*)\n-\t\t__gitcomp \"--cone\"\n-\t\t;;\n-\tset,--*)\n-\t\t__gitcomp \"--stdin\"\n-\t\t;;\n-\t*)\n-\t\t;;\n+\tcase \"$prev\" in\n+\t\tinit)\n+\t\t\t__gitcomp \"$__git_sparse_checkout_init_opts\"\n+\t\t\t;;\n+\t\tadd|set)\n+\t\t\t__gitcomp \"--stdin\"\n+\t\t\t__gitcomp \"$(git ls-tree -d -r HEAD --name-only)\"\n+\t\t\t;;\n+\t\t*)\n+\t\t\t;;\n \tesac\n }\n \ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex 22271ac2f3b..9f6eb06fbab 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -1444,7 +1444,7 @@ test_expect_success 'git checkout - with --detach, complete only references' '\n \tEOF\n '\n \n-test_expect_failure 'sparse-checkout completes subcommands' '\n+test_expect_success 'sparse-checkout completes subcommands' '\n \ttest_completion \"git sparse-checkout \" <<-\\EOF\n \tlist Z\n \tinit Z\n@@ -1455,13 +1455,13 @@ test_expect_failure 'sparse-checkout completes subcommands' '\n \tEOF\n '\n \n-test_expect_failure 'sparse-checkout completes options' '\n+test_expect_success 'sparse-checkout completes options' '\n \ttest_completion \"git sparse-checkout --\" <<-\\EOF\n \t--help Z\n \tEOF\n '\n \n-test_expect_failure 'sparse-checkout completes subcommand options' '\n+test_expect_success 'sparse-checkout completes subcommand options' '\n \ttest_completion \"git sparse-checkout init --\" <<-\\EOF &&\n \t--cone Z\n \t--sparse-index Z\n@@ -1477,7 +1477,7 @@ test_expect_failure 'sparse-checkout completes subcommand options' '\n \tEOF\n '\n \n-test_expect_failure 'sparse-checkout completes directory names' '\n+test_expect_success 'sparse-checkout completes directory names' '\n \t# set up sparse-checkout repo\n \tgit init sparse-checkout &&\n \t(\n-- \ngitgitgadget\n"},{"id":"445206","messageId":"a7f3ae5cddaed61a618a5fa2f9d9c888e0dd7d99.1640824351.git.gitgitgadget@gmail.com","threadId":"57165","inReplyTo":"pull.1108.git.1640824351.gitgitgadget@gmail.com","subject":"[PATCH 1/2] sparse-checkout: custom tab completion tests","fromName":"Lessley Dennington via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-12-30T00:32:30Z","receivedAt":"2021-12-30T00:32:38Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"From: Lessley Dennington <lessleydennington@gmail.com>\n\nAdd tests for missing/incorrect components of custom tab completion for the\nsparse-checkout command. These tests specifically highlight the following:\n\n1. git sparse-checkout <TAB> results in an incomplete list of subcommands\n(it is missing reapply and add).\n2. git sparse-checkout --<TAB> does not complete the help option.\n3. Options for subcommands are not tab-completable.\n4. git sparse-checkout set <TAB> and git sparse-checkout add <TAB> show\nboth file names and directory names.\n\nAlthough these tests currently fail, they will succeed with the\nsparse-checkout modifications in git-completion.bash in the next commit in\nthis series.\n\nSigned-off-by: Lessley Dennington <lessleydennington@gmail.com>\n---\n t/t9902-completion.sh | 74 +++++++++++++++++++++++++++++++++++++++++++\n 1 file changed, 74 insertions(+)\n\ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex 0f28c4ad940..22271ac2f3b 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -1444,6 +1444,80 @@ test_expect_success 'git checkout - with --detach, complete only references' '\n \tEOF\n '\n \n+test_expect_failure 'sparse-checkout completes subcommands' '\n+\ttest_completion \"git sparse-checkout \" <<-\\EOF\n+\tlist Z\n+\tinit Z\n+\tset Z\n+\tadd Z\n+\treapply Z\n+\tdisable Z\n+\tEOF\n+'\n+\n+test_expect_failure 'sparse-checkout completes options' '\n+\ttest_completion \"git sparse-checkout --\" <<-\\EOF\n+\t--help Z\n+\tEOF\n+'\n+\n+test_expect_failure 'sparse-checkout completes subcommand options' '\n+\ttest_completion \"git sparse-checkout init --\" <<-\\EOF &&\n+\t--cone Z\n+\t--sparse-index Z\n+\t--no-sparse-index Z\n+\tEOF\n+\n+\ttest_completion \"git sparse-checkout set --\" <<-\\EOF &&\n+\t--stdin Z\n+\tEOF\n+\n+\ttest_completion \"git sparse-checkout add --\" <<-\\EOF\n+\t--stdin Z\n+\tEOF\n+'\n+\n+test_expect_failure 'sparse-checkout completes directory names' '\n+\t# set up sparse-checkout repo\n+\tgit init sparse-checkout &&\n+\t(\n+\t\tcd sparse-checkout &&\n+\t\tmkdir -p folder1/0/1 folder2/0 folder3 &&\n+\t\ttouch folder1/0/1/t.txt &&\n+\t\ttouch folder2/0/t.txt &&\n+\t\ttouch folder3/t.txt &&\n+\t\tgit add . &&\n+\t\tgit commit -am \"Initial commit\"\n+\t) &&\n+\n+\t# initialize sparse-checkout definitions\n+\tgit -C sparse-checkout config index.sparse false &&\n+\tgit -C sparse-checkout sparse-checkout init --cone &&\n+\tgit -C sparse-checkout sparse-checkout set folder1/0 folder3 &&\n+\n+\t# test tab completion\n+\t(\n+\t\tcd sparse-checkout &&\n+\t\ttest_completion \"git sparse-checkout set f\" <<-\\EOF\n+\t\tfolder1 Z\n+\t\tfolder1/0 Z\n+\t\tfolder1/0/1 Z\n+\t\tfolder2 Z\n+\t\tfolder2/0 Z\n+\t\tfolder3 Z\n+\t\tEOF\n+\t) &&\n+\n+\t(\n+\t\tcd sparse-checkout/folder1 &&\n+\t\ttest_completion \"git sparse-checkout add \" <<-\\EOF\n+\t\t./ Z\n+\t\t0 Z\n+\t\t0/1 Z\n+\t\tEOF\n+\t)\n+'\n+\n test_expect_success 'git switch - with -d, complete all references' '\n \ttest_completion \"git switch -d \" <<-\\EOF\n \tHEAD Z\n-- \ngitgitgadget\n\n"},{"id":"445221","messageId":"cd190111-1930-9538-a844-4d9aa08d98b0@gmail.com","threadId":"57165","inReplyTo":"a7f3ae5cddaed61a618a5fa2f9d9c888e0dd7d99.1640824351.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 1/2] sparse-checkout: custom tab completion tests","fromName":"Derrick Stolee","fromEmail":"stolee@gmail.com","sentAt":"2021-12-30T13:43:21Z","receivedAt":"2021-12-30T13:43:26Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"On 12/29/2021 7:32 PM, Lessley Dennington via GitGitGadget wrote:\n> From: Lessley Dennington <lessleydennington@gmail.com>\n> \n> Add tests for missing/incorrect components of custom tab completion for the\n> sparse-checkout command. These tests specifically highlight the following:\n> \n> 1. git sparse-checkout <TAB> results in an incomplete list of subcommands\n> (it is missing reapply and add).\n> 2. git sparse-checkout --<TAB> does not complete the help option.\n> 3. Options for subcommands are not tab-completable.\n> 4. git sparse-checkout set <TAB> and git sparse-checkout add <TAB> show\n> both file names and directory names.\n\nThanks for these. I've never looked at this test script before, but\nI can surmise how it works from your tests.\n \n> Although these tests currently fail, they will succeed with the\n> sparse-checkout modifications in git-completion.bash in the next commit in\n> this series.\n\n> +test_expect_failure 'sparse-checkout completes subcommand options' '\n> +\ttest_completion \"git sparse-checkout init --\" <<-\\EOF &&\n> +\t--cone Z\n> +\t--sparse-index Z\n> +\t--no-sparse-index Z\n> +\tEOF\n> +\n> +\ttest_completion \"git sparse-checkout set --\" <<-\\EOF &&\n> +\t--stdin Z\n\nIn en/sparse-checkout-set, the 'set' subcommand learns the options\nfor init, including --cone, --sparse-index, and --no-sparse-index.\nI think technically, --no-cone is in there, too.\n\nFurther, the 'reapply' subcommand learns these options in that\nseries and I see you do not include that subcommand in this test.\n\nYou might want to rebase onto en/sparse-checkout-set and adjust\nthese tests for the new options (plus change the next patch that\nimplements the completion).\n\n> +\tEOF\n> +\n> +\ttest_completion \"git sparse-checkout add --\" <<-\\EOF\n> +\t--stdin Z\n> +\tEOF\n> +'\n\n> +test_expect_failure 'sparse-checkout completes directory names' '\n> +\t# set up sparse-checkout repo\n> +\tgit init sparse-checkout &&\n> +\t(\n> +\t\tcd sparse-checkout &&\n> +\t\tmkdir -p folder1/0/1 folder2/0 folder3 &&\n> +\t\ttouch folder1/0/1/t.txt &&\n> +\t\ttouch folder2/0/t.txt &&\n> +\t\ttouch folder3/t.txt &&\n> +\t\tgit add . &&\n> +\t\tgit commit -am \"Initial commit\"\n> +\t) &&\n> +\n> +\t# initialize sparse-checkout definitions\n> +\tgit -C sparse-checkout config index.sparse false &&\n\nI'm guessing that the implementation actually requires this, but\nI'll take a look in the next patch. It might just be slow to expand\nthe full list of directories in the sparse index case.\n\n> +\tgit -C sparse-checkout sparse-checkout init --cone &&\n> +\tgit -C sparse-checkout sparse-checkout set folder1/0 folder3 &&\n> +\n> +\t# test tab completion\n> +\t(\n> +\t\tcd sparse-checkout &&\n> +\t\ttest_completion \"git sparse-checkout set f\" <<-\\EOF\n> +\t\tfolder1 Z\n> +\t\tfolder1/0 Z\n> +\t\tfolder1/0/1 Z\n> +\t\tfolder2 Z\n> +\t\tfolder2/0 Z\n> +\t\tfolder3 Z\n\nThis tab-completion doing a full directory walk seems like it could\nbe expensive for a large repository, but I suppose it is the only way\nto allow the following sequence:\n\n\tfol<tab> -> folder\n\tfolder1/<tab> -> folder1/0\n\tfolder1/0/<tab> -> folder1/0/1\n\n(Hopefully that makes sense.)\n\nIt would be more efficient to only go one level deep at a time, but\nthat might not be possible with the tab completion mechanisms.\n\n> +\t\tEOF\n> +\t) &&\n> +\n> +\t(\n> +\t\tcd sparse-checkout/folder1 &&\n> +\t\ttest_completion \"git sparse-checkout add \" <<-\\EOF\n> +\t\t./ Z\n> +\t\t0 Z\n> +\t\t0/1 Z\n> +\t\tEOF\nI do like seeing this test within a directory. Thanks!\n\n-Stolee\n"},{"id":"445222","messageId":"c79ccf4a-4da9-1c60-32eb-124d3fa94400@gmail.com","threadId":"57165","inReplyTo":"ab51236d18ce10ada89e8cde85f678130a0ab1fd.1640824351.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 2/2] sparse-checkout: custom tab completion","fromName":"Derrick Stolee","fromEmail":"stolee@gmail.com","sentAt":"2021-12-30T13:50:31Z","receivedAt":"2021-12-30T13:50:34Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"On 12/29/2021 7:32 PM, Lessley Dennington via GitGitGadget wrote:\n> From: Lessley Dennington <lessleydennington@gmail.com>\n> \n> Fix custom tab completion for sparse-checkout command. This will ensure:\n> \n> 1. The full list of subcommands is provided when users enter git\n> sparse-checkout <TAB>.\n> 2. The --help option is tab-completable.\n> 3. Subcommand options are tab-completable.\n> 4. A list of directories (but not files) is provided when users enter git\n> sparse-checkout add <TAB> or git sparse-checkout set <TAB>.\n> \n> Failing tests that were added in the previous commit to verify these\n> scenarios are now passing with these updates.\n> \n> Signed-off-by: Lessley Dennington <lessleydennington@gmail.com>\n> ---\n>  contrib/completion/git-completion.bash | 34 +++++++++++++++++---------\n>  t/t9902-completion.sh                  |  8 +++---\n>  2 files changed, 26 insertions(+), 16 deletions(-)\n> \n> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\n> index 377d6c5494a..b8f1caece83 100644\n> --- a/contrib/completion/git-completion.bash\n> +++ b/contrib/completion/git-completion.bash\n> @@ -2986,24 +2986,34 @@ _git_show_branch ()\n>  \t__git_complete_revlist\n>  }\n>  \n> +__git_sparse_checkout_init_opts=\"--cone --sparse-index --no-sparse-index\"\n> +\n>  _git_sparse_checkout ()\n>  {\n> -\tlocal subcommands=\"list init set disable\"\n> +\tlocal subcommands=\"list init set disable add reapply\"\n>  \tlocal subcommand=\"$(__git_find_on_cmdline \"$subcommands\")\"\n> +\n>  \tif [ -z \"$subcommand\" ]; then\n> -\t\t__gitcomp \"$subcommands\"\n> -\t\treturn\n> +\t\tcase \"$cur\" in\n> +\t\t\t--*)\n> +\t\t\t\t__gitcomp \"--help\"\n> +\t\t\t\t;;\n> +\t\t\t*)\n> +\t\t\t\t__gitcomp \"$subcommands\"\n> +\t\t\t\t;;\n> +\t\tesac\n\nThis part fixes the --<tab> completion. I suppose if someone\ndid \"-<tab>\" then nothing would show up?\n\n>  \tfi\n>  \n> -\tcase \"$subcommand,$cur\" in\n> -\tinit,--*)\n> -\t\t__gitcomp \"--cone\"\n> -\t\t;;\n> -\tset,--*)\n> -\t\t__gitcomp \"--stdin\"\n> -\t\t;;\n> -\t*)\n> -\t\t;;\n> +\tcase \"$prev\" in\n> +\t\tinit)\n> +\t\t\t__gitcomp \"$__git_sparse_checkout_init_opts\"\n> +\t\t\t;;\n> +\t\tadd|set)\n> +\t\t\t__gitcomp \"--stdin\"\n> +\t\t\t__gitcomp \"$(git ls-tree -d -r HEAD --name-only)\"> +\t\t\t;;\n\nWith the thinking of rebasing onto en/sparse-checkout-set, this\ncould possibly be rearranged so the add|set) cases pass-through\ninto the init) and reapply) cases (skip the ;; between) to save\nsome duplication. Or, it is possible that doesn't work, but it\nmight be worth a try.\n\nAlso, since you are using 'git ls-tree' and not 'git ls-files',\nthe sparse index will not have an effect on the performance.\nThere will be some corner cases where a directory exists in one\nof HEAD or the index but not the other. That's probably still\nthe right way to go since 'git ls-files' doesn't have a way to\nonly list directories. It just means that you probably don't\nneed to explicitly disable the sparse index in your test.\n\nThanks,\n-Stolee\n"},{"id":"445224","messageId":"e6728ed1-52c6-05eb-e816-a9d919d3e9d1@gmail.com","threadId":"57165","inReplyTo":"cd190111-1930-9538-a844-4d9aa08d98b0@gmail.com","subject":"Re: [PATCH 1/2] sparse-checkout: custom tab completion tests","fromName":"Lessley Dennington","fromEmail":"lessleydennington@gmail.com","sentAt":"2021-12-30T16:19:53Z","receivedAt":"2021-12-30T16:19:59Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"On 12/30/21 7:43 AM, Derrick Stolee wrote:\n>> +test_expect_failure 'sparse-checkout completes subcommand options' '\n>> +\ttest_completion \"git sparse-checkout init --\" <<-\\EOF &&\n>> +\t--cone Z\n>> +\t--sparse-index Z\n>> +\t--no-sparse-index Z\n>> +\tEOF\n>> +\n>> +\ttest_completion \"git sparse-checkout set --\" <<-\\EOF &&\n>> +\t--stdin Z\n> \n> In en/sparse-checkout-set, the 'set' subcommand learns the options\n> for init, including --cone, --sparse-index, and --no-sparse-index.\n> I think technically, --no-cone is in there, too.\n> \n> Further, the 'reapply' subcommand learns these options in that\n> series and I see you do not include that subcommand in this test.\n> \n> You might want to rebase onto en/sparse-checkout-set and adjust\n> these tests for the new options (plus change the next patch that\n> implements the completion).\n> \nAh great point - I was going off of the sparse-checkout docs and\nforgot about Elijah's changes. I will do the rebase and make your\nsuggested corrections in v2.\n>> +\tgit -C sparse-checkout config index.sparse false &&\n> \n> I'm guessing that the implementation actually requires this, but\n> I'll take a look in the next patch. It might just be slow to expand\n> the full list of directories in the sparse index case.\n> \nI'll plan to remove in v2 per your comments in [1].>> +\t# test tab completion\n>> +\t(\n>> +\t\tcd sparse-checkout &&\n>> +\t\ttest_completion \"git sparse-checkout set f\" <<-\\EOF\n>> +\t\tfolder1 Z\n>> +\t\tfolder1/0 Z\n>> +\t\tfolder1/0/1 Z\n>> +\t\tfolder2 Z\n>> +\t\tfolder2/0 Z\n>> +\t\tfolder3 Z\n> \n> This tab-completion doing a full directory walk seems like it could\n> be expensive for a large repository, but I suppose it is the only way\n> to allow the following sequence:\n> \n> \tfol<tab> -> folder\n> \tfolder1/<tab> -> folder1/0\n> \tfolder1/0/<tab> -> folder1/0/1\n> \n> (Hopefully that makes sense.)\n> \nYes, it does.\n> It would be more efficient to only go one level deep at a time, but\n> that might not be possible with the tab completion mechanisms.\n> \nWhen you say one level deep, do you mean that from the sparse-checkout\ndirectory, tab completion would only show the following?\n\t\n\tfolder1\n\tfolder2\n\tfolder3\n\n-Lessley\n\n[1]: \nhttps://lore.kernel.org/git/c79ccf4a-4da9-1c60-32eb-124d3fa94400@gmail.com/\n"},{"id":"445225","messageId":"8032da64-64da-56be-f9d1-2a833a7768d3@gmail.com","threadId":"57165","inReplyTo":"c79ccf4a-4da9-1c60-32eb-124d3fa94400@gmail.com","subject":"Re: [PATCH 2/2] sparse-checkout: custom tab completion","fromName":"Lessley Dennington","fromEmail":"lessleydennington@gmail.com","sentAt":"2021-12-30T16:24:58Z","receivedAt":"2021-12-30T16:25:01Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"On 12/30/21 7:50 AM, Derrick Stolee wrote:\n>> +__git_sparse_checkout_init_opts=\"--cone --sparse-index --no-sparse-index\"\n>> +\n>>   _git_sparse_checkout ()\n>>   {\n>> -\tlocal subcommands=\"list init set disable\"\n>> +\tlocal subcommands=\"list init set disable add reapply\"\n>>   \tlocal subcommand=\"$(__git_find_on_cmdline \"$subcommands\")\"\n>> +\n>>   \tif [ -z \"$subcommand\" ]; then\n>> -\t\t__gitcomp \"$subcommands\"\n>> -\t\treturn\n>> +\t\tcase \"$cur\" in\n>> +\t\t\t--*)\n>> +\t\t\t\t__gitcomp \"--help\"\n>> +\t\t\t\t;;\n>> +\t\t\t*)\n>> +\t\t\t\t__gitcomp \"$subcommands\"\n>> +\t\t\t\t;;\n>> +\t\tesac\n> \n> This part fixes the --<tab> completion. I suppose if someone\n> did \"-<tab>\" then nothing would show up?\n> \nIt actually shows a list of files that contain -- (if any exist).\n>>   \tfi\n>>   \n>> -\tcase \"$subcommand,$cur\" in\n>> -\tinit,--*)\n>> -\t\t__gitcomp \"--cone\"\n>> -\t\t;;\n>> -\tset,--*)\n>> -\t\t__gitcomp \"--stdin\"\n>> -\t\t;;\n>> -\t*)\n>> -\t\t;;\n>> +\tcase \"$prev\" in\n>> +\t\tinit)\n>> +\t\t\t__gitcomp \"$__git_sparse_checkout_init_opts\"\n>> +\t\t\t;;\n>> +\t\tadd|set)\n>> +\t\t\t__gitcomp \"--stdin\"\n>> +\t\t\t__gitcomp \"$(git ls-tree -d -r HEAD --name-only)\"> +\t\t\t;;\n> \n> With the thinking of rebasing onto en/sparse-checkout-set, this\n> could possibly be rearranged so the add|set) cases pass-through\n> into the init) and reapply) cases (skip the ;; between) to save\n> some duplication. Or, it is possible that doesn't work, but it\n> might be worth a try.\n> \nThanks, I'll give this a go!\n> Also, since you are using 'git ls-tree' and not 'git ls-files',\n> the sparse index will not have an effect on the performance.\n> There will be some corner cases where a directory exists in one\n> of HEAD or the index but not the other. That's probably still\n> the right way to go since 'git ls-files' doesn't have a way to\n> only list directories. It just means that you probably don't\n> need to explicitly disable the sparse index in your test.\n> \nWill correct in v2.\n\n-Lessley\n"},{"id":"445231","messageId":"63bb7366-71f6-d4c3-529f-c52d3610c1cd@gmail.com","threadId":"57165","inReplyTo":"e6728ed1-52c6-05eb-e816-a9d919d3e9d1@gmail.com","subject":"Re: [PATCH 1/2] sparse-checkout: custom tab completion tests","fromName":"Derrick Stolee","fromEmail":"stolee@gmail.com","sentAt":"2021-12-30T17:43:51Z","receivedAt":"2021-12-30T17:43:55Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"On 12/30/2021 11:19 AM, Lessley Dennington wrote:\n> On 12/30/21 7:43 AM, Derrick Stolee wrote:\n\n>>> +    (\n>>> +        cd sparse-checkout &&\n>>> +        test_completion \"git sparse-checkout set f\" <<-\\EOF\n>>> +        folder1 Z\n>>> +        folder1/0 Z\n>>> +        folder1/0/1 Z\n>>> +        folder2 Z\n>>> +        folder2/0 Z\n>>> +        folder3 Z\n>>\n>> This tab-completion doing a full directory walk seems like it could\n>> be expensive for a large repository, but I suppose it is the only way\n>> to allow the following sequence:\n>>\n>>     fol<tab> -> folder\n>>     folder1/<tab> -> folder1/0\n>>     folder1/0/<tab> -> folder1/0/1\n>>\n>> (Hopefully that makes sense.)\n>>\n> Yes, it does.\n>> It would be more efficient to only go one level deep at a time, but\n>> that might not be possible with the tab completion mechanisms.\n>>\n> When you say one level deep, do you mean that from the sparse-checkout\n> directory, tab completion would only show the following?\n>     \n>     folder1\n>     folder2\n>     folder3\n\nThat's what I mean by one level deep at a time, but I also am not\nsure that that is the correct functionality. I would leave the full\nexpansion as you have now as the design.\n\nThanks,\n-Stolee\n"},{"id":"445234","messageId":"pull.1108.v2.git.1640892413.gitgitgadget@gmail.com","threadId":"57165","inReplyTo":"pull.1108.git.1640824351.gitgitgadget@gmail.com","subject":"[PATCH v2 0/2] sparse checkout: custom bash completion updates","fromName":"Lessley Dennington via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-12-30T19:26:51Z","receivedAt":"2021-12-30T19:27:00Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"This series is based on en/sparse-checkout-set. It updates custom tab\ncompletion for the sparse-checkout command. Specifically, it corrects the\nfollowing issues with the current method:\n\n 1. git sparse-checkout <TAB> results in an incomplete list of subcommands\n    (it is missing reapply and add).\n 2. git sparse-checkout --<TAB> does not complete the help option.\n 3. Options for subcommands are not tab-completable.\n 4. git sparse-checkout set <TAB> and git sparse-checkout add <TAB> show\n    both file names and directory names.\n\nThe first commit in this series is a set of failing tests that highlight\neach of the above issues. The next commit updates the _git_sparse_checkout\nmethod in git-completion.bash to enable each of these tests to pass.\n\n\nChanges since V1\n================\n\n * Rebase onto en/sparse-checkout-set.\n * Add subcommand options (including --no-cone) for set and reapply.\n * Extend 'sparse-checkout completes subcommand options' test to validate\n   new set/reapply subcommand options.\n * No longer set index.sparse to false in 'sparse-checkout completes\n   directory names' test.\n\nThanks, Lessley\n\nLessley Dennington (2):\n  sparse-checkout: custom tab completion tests\n  sparse-checkout: custom tab completion\n\n contrib/completion/git-completion.bash | 38 ++++++++----\n t/t9902-completion.sh                  | 85 ++++++++++++++++++++++++++\n 2 files changed, 111 insertions(+), 12 deletions(-)\n\n\nbase-commit: dfac9b609f86cd4f6ce896df9e1172d2a02cde48\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-1108%2Fldennington%2Fsparse-checkout-bash-completion-v2\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1108/ldennington/sparse-checkout-bash-completion-v2\nPull-Request: https://github.com/gitgitgadget/git/pull/1108\n\nRange-diff vs v1:\n\n 1:  a7f3ae5cdda ! 1:  955fcab0052 sparse-checkout: custom tab completion tests\n     @@ t/t9902-completion.sh: test_expect_success 'git checkout - with --detach, comple\n      +test_expect_failure 'sparse-checkout completes subcommand options' '\n      +\ttest_completion \"git sparse-checkout init --\" <<-\\EOF &&\n      +\t--cone Z\n     ++\t--no-cone Z\n      +\t--sparse-index Z\n      +\t--no-sparse-index Z\n      +\tEOF\n      +\n      +\ttest_completion \"git sparse-checkout set --\" <<-\\EOF &&\n     ++\t--cone Z\n     ++\t--no-cone Z\n     ++\t--sparse-index Z\n     ++\t--no-sparse-index Z\n      +\t--stdin Z\n      +\tEOF\n      +\n     ++\ttest_completion \"git sparse-checkout reapply --\" <<-\\EOF &&\n     ++\t--cone Z\n     ++\t--no-cone Z\n     ++\t--sparse-index Z\n     ++\t--no-sparse-index Z\n     ++\tEOF\n     ++\n      +\ttest_completion \"git sparse-checkout add --\" <<-\\EOF\n      +\t--stdin Z\n      +\tEOF\n     @@ t/t9902-completion.sh: test_expect_success 'git checkout - with --detach, comple\n      +\t) &&\n      +\n      +\t# initialize sparse-checkout definitions\n     -+\tgit -C sparse-checkout config index.sparse false &&\n      +\tgit -C sparse-checkout sparse-checkout init --cone &&\n      +\tgit -C sparse-checkout sparse-checkout set folder1/0 folder3 &&\n      +\n 2:  ab51236d18c ! 2:  cecf501e076 sparse-checkout: custom tab completion\n     @@ contrib/completion/git-completion.bash: _git_show_branch ()\n       \t__git_complete_revlist\n       }\n       \n     -+__git_sparse_checkout_init_opts=\"--cone --sparse-index --no-sparse-index\"\n     ++__git_sparse_checkout_subcommand_opts=\"--cone --no-cone --sparse-index --no-sparse-index\"\n      +\n       _git_sparse_checkout ()\n       {\n     @@ contrib/completion/git-completion.bash: _git_show_branch ()\n      -\t*)\n      -\t\t;;\n      +\tcase \"$prev\" in\n     -+\t\tinit)\n     -+\t\t\t__gitcomp \"$__git_sparse_checkout_init_opts\"\n     ++\t\tset)\n     ++\t\t\t__gitcomp \"$__git_sparse_checkout_subcommand_opts --stdin\"\n     ++\t\t\t__gitcomp \"$(git ls-tree -d -r HEAD --name-only)\"\n      +\t\t\t;;\n     -+\t\tadd|set)\n     ++\t\tadd)\n      +\t\t\t__gitcomp \"--stdin\"\n      +\t\t\t__gitcomp \"$(git ls-tree -d -r HEAD --name-only)\"\n      +\t\t\t;;\n     ++\t\tinit|reapply)\n     ++\t\t\t__gitcomp \"$__git_sparse_checkout_subcommand_opts\"\n     ++\t\t\t;;\n      +\t\t*)\n      +\t\t\t;;\n       \tesac\n     @@ t/t9902-completion.sh: test_expect_failure 'sparse-checkout completes subcommand\n      +test_expect_success 'sparse-checkout completes subcommand options' '\n       \ttest_completion \"git sparse-checkout init --\" <<-\\EOF &&\n       \t--cone Z\n     - \t--sparse-index Z\n     + \t--no-cone Z\n      @@ t/t9902-completion.sh: test_expect_failure 'sparse-checkout completes subcommand options' '\n       \tEOF\n       '\n\n-- \ngitgitgadget\n"},{"id":"445235","messageId":"955fcab00528464b5450bd22b45c89ffc2283e39.1640892413.git.gitgitgadget@gmail.com","threadId":"57165","inReplyTo":"pull.1108.v2.git.1640892413.gitgitgadget@gmail.com","subject":"[PATCH v2 1/2] sparse-checkout: custom tab completion tests","fromName":"Lessley Dennington via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-12-30T19:26:52Z","receivedAt":"2021-12-30T19:27:00Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"From: Lessley Dennington <lessleydennington@gmail.com>\n\nAdd tests for missing/incorrect components of custom tab completion for the\nsparse-checkout command. These tests specifically highlight the following:\n\n1. git sparse-checkout <TAB> results in an incomplete list of subcommands\n(it is missing reapply and add).\n2. git sparse-checkout --<TAB> does not complete the help option.\n3. Options for subcommands are not tab-completable.\n4. git sparse-checkout set <TAB> and git sparse-checkout add <TAB> show\nboth file names and directory names.\n\nAlthough these tests currently fail, they will succeed with the\nsparse-checkout modifications in git-completion.bash in the next commit in\nthis series.\n\nSigned-off-by: Lessley Dennington <lessleydennington@gmail.com>\n---\n t/t9902-completion.sh | 85 +++++++++++++++++++++++++++++++++++++++++++\n 1 file changed, 85 insertions(+)\n\ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex 518203fbe07..51d0f2d93a1 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -1447,6 +1447,91 @@ test_expect_success 'git checkout - with --detach, complete only references' '\n \tEOF\n '\n \n+test_expect_failure 'sparse-checkout completes subcommands' '\n+\ttest_completion \"git sparse-checkout \" <<-\\EOF\n+\tlist Z\n+\tinit Z\n+\tset Z\n+\tadd Z\n+\treapply Z\n+\tdisable Z\n+\tEOF\n+'\n+\n+test_expect_failure 'sparse-checkout completes options' '\n+\ttest_completion \"git sparse-checkout --\" <<-\\EOF\n+\t--help Z\n+\tEOF\n+'\n+\n+test_expect_failure 'sparse-checkout completes subcommand options' '\n+\ttest_completion \"git sparse-checkout init --\" <<-\\EOF &&\n+\t--cone Z\n+\t--no-cone Z\n+\t--sparse-index Z\n+\t--no-sparse-index Z\n+\tEOF\n+\n+\ttest_completion \"git sparse-checkout set --\" <<-\\EOF &&\n+\t--cone Z\n+\t--no-cone Z\n+\t--sparse-index Z\n+\t--no-sparse-index Z\n+\t--stdin Z\n+\tEOF\n+\n+\ttest_completion \"git sparse-checkout reapply --\" <<-\\EOF &&\n+\t--cone Z\n+\t--no-cone Z\n+\t--sparse-index Z\n+\t--no-sparse-index Z\n+\tEOF\n+\n+\ttest_completion \"git sparse-checkout add --\" <<-\\EOF\n+\t--stdin Z\n+\tEOF\n+'\n+\n+test_expect_failure 'sparse-checkout completes directory names' '\n+\t# set up sparse-checkout repo\n+\tgit init sparse-checkout &&\n+\t(\n+\t\tcd sparse-checkout &&\n+\t\tmkdir -p folder1/0/1 folder2/0 folder3 &&\n+\t\ttouch folder1/0/1/t.txt &&\n+\t\ttouch folder2/0/t.txt &&\n+\t\ttouch folder3/t.txt &&\n+\t\tgit add . &&\n+\t\tgit commit -am \"Initial commit\"\n+\t) &&\n+\n+\t# initialize sparse-checkout definitions\n+\tgit -C sparse-checkout sparse-checkout init --cone &&\n+\tgit -C sparse-checkout sparse-checkout set folder1/0 folder3 &&\n+\n+\t# test tab completion\n+\t(\n+\t\tcd sparse-checkout &&\n+\t\ttest_completion \"git sparse-checkout set f\" <<-\\EOF\n+\t\tfolder1 Z\n+\t\tfolder1/0 Z\n+\t\tfolder1/0/1 Z\n+\t\tfolder2 Z\n+\t\tfolder2/0 Z\n+\t\tfolder3 Z\n+\t\tEOF\n+\t) &&\n+\n+\t(\n+\t\tcd sparse-checkout/folder1 &&\n+\t\ttest_completion \"git sparse-checkout add \" <<-\\EOF\n+\t\t./ Z\n+\t\t0 Z\n+\t\t0/1 Z\n+\t\tEOF\n+\t)\n+'\n+\n test_expect_success 'git switch - with -d, complete all references' '\n \ttest_completion \"git switch -d \" <<-\\EOF\n \tHEAD Z\n-- \ngitgitgadget\n\n"},{"id":"445236","messageId":"cecf501e07645b7408dc75f276d477b9b712ab17.1640892413.git.gitgitgadget@gmail.com","threadId":"57165","inReplyTo":"pull.1108.v2.git.1640892413.gitgitgadget@gmail.com","subject":"[PATCH v2 2/2] sparse-checkout: custom tab completion","fromName":"Lessley Dennington via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-12-30T19:26:53Z","receivedAt":"2021-12-30T19:27:03Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"From: Lessley Dennington <lessleydennington@gmail.com>\n\nFix custom tab completion for sparse-checkout command. This will ensure:\n\n1. The full list of subcommands is provided when users enter git\nsparse-checkout <TAB>.\n2. The --help option is tab-completable.\n3. Subcommand options are tab-completable.\n4. A list of directories (but not files) is provided when users enter git\nsparse-checkout add <TAB> or git sparse-checkout set <TAB>.\n\nFailing tests that were added in the previous commit to verify these\nscenarios are now passing with these updates.\n\nSigned-off-by: Lessley Dennington <lessleydennington@gmail.com>\n---\n contrib/completion/git-completion.bash | 38 ++++++++++++++++++--------\n t/t9902-completion.sh                  |  8 +++---\n 2 files changed, 30 insertions(+), 16 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex c82ccaebcc7..7de997ee64e 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -2986,24 +2986,38 @@ _git_show_branch ()\n \t__git_complete_revlist\n }\n \n+__git_sparse_checkout_subcommand_opts=\"--cone --no-cone --sparse-index --no-sparse-index\"\n+\n _git_sparse_checkout ()\n {\n-\tlocal subcommands=\"list init set disable\"\n+\tlocal subcommands=\"list init set disable add reapply\"\n \tlocal subcommand=\"$(__git_find_on_cmdline \"$subcommands\")\"\n+\n \tif [ -z \"$subcommand\" ]; then\n-\t\t__gitcomp \"$subcommands\"\n-\t\treturn\n+\t\tcase \"$cur\" in\n+\t\t\t--*)\n+\t\t\t\t__gitcomp \"--help\"\n+\t\t\t\t;;\n+\t\t\t*)\n+\t\t\t\t__gitcomp \"$subcommands\"\n+\t\t\t\t;;\n+\t\tesac\n \tfi\n \n-\tcase \"$subcommand,$cur\" in\n-\tinit,--*)\n-\t\t__gitcomp \"--cone\"\n-\t\t;;\n-\tset,--*)\n-\t\t__gitcomp \"--stdin\"\n-\t\t;;\n-\t*)\n-\t\t;;\n+\tcase \"$prev\" in\n+\t\tset)\n+\t\t\t__gitcomp \"$__git_sparse_checkout_subcommand_opts --stdin\"\n+\t\t\t__gitcomp \"$(git ls-tree -d -r HEAD --name-only)\"\n+\t\t\t;;\n+\t\tadd)\n+\t\t\t__gitcomp \"--stdin\"\n+\t\t\t__gitcomp \"$(git ls-tree -d -r HEAD --name-only)\"\n+\t\t\t;;\n+\t\tinit|reapply)\n+\t\t\t__gitcomp \"$__git_sparse_checkout_subcommand_opts\"\n+\t\t\t;;\n+\t\t*)\n+\t\t\t;;\n \tesac\n }\n \ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex 51d0f2d93a1..4dc93ee0595 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -1447,7 +1447,7 @@ test_expect_success 'git checkout - with --detach, complete only references' '\n \tEOF\n '\n \n-test_expect_failure 'sparse-checkout completes subcommands' '\n+test_expect_success 'sparse-checkout completes subcommands' '\n \ttest_completion \"git sparse-checkout \" <<-\\EOF\n \tlist Z\n \tinit Z\n@@ -1458,13 +1458,13 @@ test_expect_failure 'sparse-checkout completes subcommands' '\n \tEOF\n '\n \n-test_expect_failure 'sparse-checkout completes options' '\n+test_expect_success 'sparse-checkout completes options' '\n \ttest_completion \"git sparse-checkout --\" <<-\\EOF\n \t--help Z\n \tEOF\n '\n \n-test_expect_failure 'sparse-checkout completes subcommand options' '\n+test_expect_success 'sparse-checkout completes subcommand options' '\n \ttest_completion \"git sparse-checkout init --\" <<-\\EOF &&\n \t--cone Z\n \t--no-cone Z\n@@ -1492,7 +1492,7 @@ test_expect_failure 'sparse-checkout completes subcommand options' '\n \tEOF\n '\n \n-test_expect_failure 'sparse-checkout completes directory names' '\n+test_expect_success 'sparse-checkout completes directory names' '\n \t# set up sparse-checkout repo\n \tgit init sparse-checkout &&\n \t(\n-- \ngitgitgadget\n"},{"id":"445293","messageId":"CABPp-BGun+v3BCuutPW2L1q3wzdB+Etuh_0Jz1aFanivZmyXWQ@mail.gmail.com","threadId":"57165","inReplyTo":"63bb7366-71f6-d4c3-529f-c52d3610c1cd@gmail.com","subject":"Re: [PATCH 1/2] sparse-checkout: custom tab completion tests","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2021-12-31T19:27:31Z","receivedAt":"2021-12-31T19:27:46Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Fri, Dec 31, 2021 at 2:30 AM Derrick Stolee <stolee@gmail.com> wrote:\n>\n> On 12/30/2021 11:19 AM, Lessley Dennington wrote:\n> > On 12/30/21 7:43 AM, Derrick Stolee wrote:\n>\n> >>> +    (\n> >>> +        cd sparse-checkout &&\n> >>> +        test_completion \"git sparse-checkout set f\" <<-\\EOF\n> >>> +        folder1 Z\n> >>> +        folder1/0 Z\n> >>> +        folder1/0/1 Z\n> >>> +        folder2 Z\n> >>> +        folder2/0 Z\n> >>> +        folder3 Z\n> >>\n> >> This tab-completion doing a full directory walk seems like it could\n> >> be expensive for a large repository, but I suppose it is the only way\n> >> to allow the following sequence:\n> >>\n> >>     fol<tab> -> folder\n> >>     folder1/<tab> -> folder1/0\n> >>     folder1/0/<tab> -> folder1/0/1\n> >>\n> >> (Hopefully that makes sense.)\n> >>\n> > Yes, it does.\n> >> It would be more efficient to only go one level deep at a time, but\n> >> that might not be possible with the tab completion mechanisms.\n> >>\n> > When you say one level deep, do you mean that from the sparse-checkout\n> > directory, tab completion would only show the following?\n> >\n> >     folder1\n> >     folder2\n> >     folder3\n>\n> That's what I mean by one level deep at a time, but I also am not\n> sure that that is the correct functionality. I would leave the full\n> expansion as you have now as the design.\n\nI think one level at a time is better and is the optimal design.  By\nway of comparison, note that if I do the following:\n\nmkdir tmp\ncd tmp\nmkdir -p a/b/c/d\ntouch a/b/c/d/e\ncd <TAB>\n\nI do not see a/b/c/d as the completion, I only get \"a/\" as the\ncompletion.  If I hit tab again, then I get \"a/b/\".  Tab again, and I\nget \"a/b/c/\".\n\nI don't think normal tab completion recursively checks directories, so\nit'd be better for us to not do so with git either.  However, if it's\nhard to avoid automatically completing just a directory at a time,\nthen I think a fair first cut is completing to full depths, but call\nit out as something we'd like to fix in the commit message.\n"},{"id":"445294","messageId":"CABPp-BGdr54XgCXw8k1xRCgkwBtDonyODS3O+_nS_QY3SOEFGQ@mail.gmail.com","threadId":"57165","inReplyTo":"955fcab00528464b5450bd22b45c89ffc2283e39.1640892413.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v2 1/2] sparse-checkout: custom tab completion tests","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2021-12-31T20:03:04Z","receivedAt":"2021-12-31T20:03:19Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Fri, Dec 31, 2021 at 2:32 AM Lessley Dennington via GitGitGadget\n<gitgitgadget@gmail.com> wrote:\n>\n> From: Lessley Dennington <lessleydennington@gmail.com>\n>\n> Add tests for missing/incorrect components of custom tab completion for the\n> sparse-checkout command. These tests specifically highlight the following:\n>\n> 1. git sparse-checkout <TAB> results in an incomplete list of subcommands\n> (it is missing reapply and add).\n> 2. git sparse-checkout --<TAB> does not complete the help option.\n> 3. Options for subcommands are not tab-completable.\n> 4. git sparse-checkout set <TAB> and git sparse-checkout add <TAB> show\n> both file names and directory names.\n\nTwo thoughts on this last item:\n\nI completely agree that only directories should be completed in cone\nmode, but completing on both might technically be considered correct\nbehavior for non-cone mode.  However, even in non-cone mode, I kind of\nlike the idea of encouraging people to sparsify only on directories so\nI'm totally fine with us only tab-completing directories.  (I have a\nbit of a disdain for non-cone mode, though, so my desire to deprecate\nit might be showing through.  At the very least, I'm still thinking we\nshould make cone mode the default in each of `sparse-checkout init`,\n`sparse-checkout set`, and `clone --sparse`[1])\n\n[1] https://lore.kernel.org/git/6e09ab19-7ffb-e58e-7b08-6e560b421c06@gmail.com/\n\n\nSecond, and this item is unrelated to your series but your comment\nmade me realize it....sparse-checkout unfortunately ignores prefix and\ncreates a bad .git/info/sparse-checkout file.  For example:\n\n$ git init -b main tmp\n$ cd tmp\n$ mkdir -p a/b/c\n$ touch a/b/c/d a/b/c/e\n$ git add a/\n$ git commit -m \"initial\"\n$ cd a/  # Not at the toplevel anymore\n$ git sparse-checkout set --cone b/c  # So we expect that a/b/c will\nbe the specified sparsity path\n$ git -C .. sparse-checkout list\nb/c\n$ cat ../.git/info/sparse-checkout\n/*\n!/*/\n/b/\n!/b/*/\n/b/c/\n$ pwd -P\npwd: error retrieving current directory: getcwd: cannot access parent\ndirectories: No such file or directory\n\nI think the loss of the current working directory will be fixed by the\nen/keep-cwd directory (currently in next and marked for merging to\nmaster), but the fact that the wrong paths end up in the\nsparse-checkout file is unfortunate.  It basically means that the\n`set` and `add` subcommands of `sparse-checkout` can only be safely\nrun from the toplevel directory.\n\n> Although these tests currently fail, they will succeed with the\n> sparse-checkout modifications in git-completion.bash in the next commit in\n> this series.\n>\n> Signed-off-by: Lessley Dennington <lessleydennington@gmail.com>\n> ---\n>  t/t9902-completion.sh | 85 +++++++++++++++++++++++++++++++++++++++++++\n>  1 file changed, 85 insertions(+)\n>\n> diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\n> index 518203fbe07..51d0f2d93a1 100755\n> --- a/t/t9902-completion.sh\n> +++ b/t/t9902-completion.sh\n> @@ -1447,6 +1447,91 @@ test_expect_success 'git checkout - with --detach, complete only references' '\n>         EOF\n>  '\n>\n> +test_expect_failure 'sparse-checkout completes subcommands' '\n> +       test_completion \"git sparse-checkout \" <<-\\EOF\n> +       list Z\n> +       init Z\n> +       set Z\n> +       add Z\n> +       reapply Z\n> +       disable Z\n> +       EOF\n> +'\n> +\n> +test_expect_failure 'sparse-checkout completes options' '\n> +       test_completion \"git sparse-checkout --\" <<-\\EOF\n> +       --help Z\n> +       EOF\n> +'\n> +\n> +test_expect_failure 'sparse-checkout completes subcommand options' '\n> +       test_completion \"git sparse-checkout init --\" <<-\\EOF &&\n> +       --cone Z\n> +       --no-cone Z\n> +       --sparse-index Z\n> +       --no-sparse-index Z\n> +       EOF\n> +\n> +       test_completion \"git sparse-checkout set --\" <<-\\EOF &&\n> +       --cone Z\n> +       --no-cone Z\n> +       --sparse-index Z\n> +       --no-sparse-index Z\n> +       --stdin Z\n> +       EOF\n> +\n> +       test_completion \"git sparse-checkout reapply --\" <<-\\EOF &&\n> +       --cone Z\n> +       --no-cone Z\n> +       --sparse-index Z\n> +       --no-sparse-index Z\n> +       EOF\n> +\n> +       test_completion \"git sparse-checkout add --\" <<-\\EOF\n> +       --stdin Z\n> +       EOF\n> +'\n> +\n> +test_expect_failure 'sparse-checkout completes directory names' '\n> +       # set up sparse-checkout repo\n> +       git init sparse-checkout &&\n> +       (\n> +               cd sparse-checkout &&\n> +               mkdir -p folder1/0/1 folder2/0 folder3 &&\n> +               touch folder1/0/1/t.txt &&\n> +               touch folder2/0/t.txt &&\n> +               touch folder3/t.txt &&\n> +               git add . &&\n> +               git commit -am \"Initial commit\"\n> +       ) &&\n> +\n> +       # initialize sparse-checkout definitions\n> +       git -C sparse-checkout sparse-checkout init --cone &&\n> +       git -C sparse-checkout sparse-checkout set folder1/0 folder3 &&\n> +\n> +       # test tab completion\n> +       (\n> +               cd sparse-checkout &&\n> +               test_completion \"git sparse-checkout set f\" <<-\\EOF\n> +               folder1 Z\n> +               folder1/0 Z\n> +               folder1/0/1 Z\n> +               folder2 Z\n> +               folder2/0 Z\n> +               folder3 Z\n> +               EOF\n> +       ) &&\n> +\n> +       (\n> +               cd sparse-checkout/folder1 &&\n> +               test_completion \"git sparse-checkout add \" <<-\\EOF\n> +               ./ Z\n> +               0 Z\n> +               0/1 Z\n> +               EOF\n> +       )\n> +'\n> +\n>  test_expect_success 'git switch - with -d, complete all references' '\n>         test_completion \"git switch -d \" <<-\\EOF\n>         HEAD Z\n> --\n> gitgitgadget\n\nPatch looks okay to me, but we might want to add some kind of wording\naround the directories-only decision and cone vs. non-cone mode to the\ncommit message.\n"},{"id":"445295","messageId":"xmqqy240l8l1.fsf@gitster.g","threadId":"57165","inReplyTo":"CABPp-BGdr54XgCXw8k1xRCgkwBtDonyODS3O+_nS_QY3SOEFGQ@mail.gmail.com","subject":"Re: [PATCH v2 1/2] sparse-checkout: custom tab completion tests","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-12-31T22:20:58Z","receivedAt":"2021-12-31T22:21:05Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Elijah Newren <newren@gmail.com> writes:\n\n> Second, and this item is unrelated to your series but your comment\n> made me realize it....sparse-checkout unfortunately ignores prefix and\n> creates a bad .git/info/sparse-checkout file.  For example:\n> ...\n> I think the loss of the current working directory will be fixed by the\n> en/keep-cwd directory (currently in next and marked for merging to\n> master), but the fact that the wrong paths end up in the\n> sparse-checkout file is unfortunate.  It basically means that the\n> `set` and `add` subcommands of `sparse-checkout` can only be safely\n> run from the toplevel directory.\n\nYou made it sound as if this is a fundamental limitation, but it\nsounds more like a bug that needs to be fixed (outside the\ncompletion series, of course) to me.\n\n"},{"id":"445296","messageId":"CABPp-BGKtggHwXF-Xo6ryKCXNq9mgWDHiKz6VfCvrdKxvf0Uug@mail.gmail.com","threadId":"57165","inReplyTo":"xmqqy240l8l1.fsf@gitster.g","subject":"Re: [PATCH v2 1/2] sparse-checkout: custom tab completion tests","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2021-12-31T22:25:45Z","receivedAt":"2021-12-31T22:25:59Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Fri, Dec 31, 2021 at 2:21 PM Junio C Hamano <gitster@pobox.com> wrote:\n>\n> Elijah Newren <newren@gmail.com> writes:\n>\n> > Second, and this item is unrelated to your series but your comment\n> > made me realize it....sparse-checkout unfortunately ignores prefix and\n> > creates a bad .git/info/sparse-checkout file.  For example:\n> > ...\n> > I think the loss of the current working directory will be fixed by the\n> > en/keep-cwd directory (currently in next and marked for merging to\n> > master), but the fact that the wrong paths end up in the\n> > sparse-checkout file is unfortunate.  It basically means that the\n> > `set` and `add` subcommands of `sparse-checkout` can only be safely\n> > run from the toplevel directory.\n>\n> You made it sound as if this is a fundamental limitation, but it\n> sounds more like a bug that needs to be fixed (outside the\n> completion series, of course) to me.\n\nOh, sorry, I didn't mean to imply that.  I meant the same thing you\nsay here: it's another bug we need to fix, in a separate series.\n"},{"id":"445297","messageId":"CABPp-BG_Jgyr89z_D355Ytzz31J40nBGX=2cr+aXtcf3U1y6Dg@mail.gmail.com","threadId":"57165","inReplyTo":"cecf501e07645b7408dc75f276d477b9b712ab17.1640892413.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v2 2/2] sparse-checkout: custom tab completion","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2021-12-31T22:52:20Z","receivedAt":"2021-12-31T22:52:37Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Fri, Dec 31, 2021 at 2:33 AM Lessley Dennington via GitGitGadget\n<gitgitgadget@gmail.com> wrote:\n>\n> From: Lessley Dennington <lessleydennington@gmail.com>\n>\n> Fix custom tab completion for sparse-checkout command. This will ensure:\n>\n> 1. The full list of subcommands is provided when users enter git\n> sparse-checkout <TAB>.\n> 2. The --help option is tab-completable.\n> 3. Subcommand options are tab-completable.\n> 4. A list of directories (but not files) is provided when users enter git\n> sparse-checkout add <TAB> or git sparse-checkout set <TAB>.\n>\n> Failing tests that were added in the previous commit to verify these\n> scenarios are now passing with these updates.\n>\n> Signed-off-by: Lessley Dennington <lessleydennington@gmail.com>\n> ---\n>  contrib/completion/git-completion.bash | 38 ++++++++++++++++++--------\n>  t/t9902-completion.sh                  |  8 +++---\n>  2 files changed, 30 insertions(+), 16 deletions(-)\n>\n> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\n> index c82ccaebcc7..7de997ee64e 100644\n> --- a/contrib/completion/git-completion.bash\n> +++ b/contrib/completion/git-completion.bash\n> @@ -2986,24 +2986,38 @@ _git_show_branch ()\n>         __git_complete_revlist\n>  }\n>\n> +__git_sparse_checkout_subcommand_opts=\"--cone --no-cone --sparse-index --no-sparse-index\"\n> +\n>  _git_sparse_checkout ()\n>  {\n> -       local subcommands=\"list init set disable\"\n> +       local subcommands=\"list init set disable add reapply\"\n>         local subcommand=\"$(__git_find_on_cmdline \"$subcommands\")\"\n> +\n>         if [ -z \"$subcommand\" ]; then\n> -               __gitcomp \"$subcommands\"\n> -               return\n> +               case \"$cur\" in\n> +                       --*)\n> +                               __gitcomp \"--help\"\n> +                               ;;\n> +                       *)\n> +                               __gitcomp \"$subcommands\"\n> +                               ;;\n> +               esac\n>         fi\n>\n> -       case \"$subcommand,$cur\" in\n> -       init,--*)\n> -               __gitcomp \"--cone\"\n> -               ;;\n> -       set,--*)\n> -               __gitcomp \"--stdin\"\n> -               ;;\n> -       *)\n> -               ;;\n> +       case \"$prev\" in\n\nShouldn't this be \"$subcommand\" rather than \"$prev\"?  I think with\nprev, it will only correctly complete the first path after \"set\",\n\"add\", etc.\n\n> +               set)\n> +                       __gitcomp \"$__git_sparse_checkout_subcommand_opts --stdin\"\n> +                       __gitcomp \"$(git ls-tree -d -r HEAD --name-only)\"\n> +                       ;;\n> +               add)\n> +                       __gitcomp \"--stdin\"\n> +                       __gitcomp \"$(git ls-tree -d -r HEAD --name-only)\"\n\nI was going to make a simple suggestion for making it just complete\none additional level at a time and leaving out the -r, and then tried\nit out and found out it wasn't simple.  I got something working,\neventually, but it's slightly ugly...so it probably belongs in a\nseparate patch anyway.  If you're curious, it's basically replacing\nthe second __gitcomp... call for each of set and add with\n`__gitcomp_directories`, after first defining:\n\n__gitcomp_directories ()\n{\n    local _tmp_dir _tmp_completions\n\n    # Get the directory of the current token; this differs from dirname\n    # in that it keeps up to the final trailing slash.  If no slash found\n    # that's fine too.\n    [[ \"$cur\" =~ .*/ ]]\n    _tmp_dir=$BASH_REMATCH\n\n    # Find possible directory completions, adding trailing '/' characters\n    _tmp_completions=\"$(git ls-tree -d --name-only HEAD $_tmp_dir |\n        sed -e s%$%/%)\"\n\n    if [[ -n \"$_tmp_completions\" ]]; then\n        # There were some directory completions, so find ones that\n        # start with \"$cur\", the current token, and put those in COMPREPLY\n        local i=0 c IFS=$' \\t\\n'\n        for c in $_tmp_completions; do\n            if [[ $c == \"$cur\"* ]]; then\n                COMPREPLY+=(\"$c\")\n            fi\n        done\n    elif [[ \"$cur\" =~ /$ ]]; then\n        # No possible further completions any deeper, so assume we're at\n        # a leaf directory and just consider it complete\n        __gitcomp_direct_append \"$cur \"\n    fi\n}\n\nBut I don't think that needs to be part of this series; I can submit\nit later and hopefully get a completion expert to point out\nbetter/cleaner ways of what I've done above.\n\n> +                       ;;\n> +               init|reapply)\n> +                       __gitcomp \"$__git_sparse_checkout_subcommand_opts\"\n> +                       ;;\n> +               *)\n> +                       ;;\n>         esac\n>  }\n>\n> diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\n> index 51d0f2d93a1..4dc93ee0595 100755\n> --- a/t/t9902-completion.sh\n> +++ b/t/t9902-completion.sh\n> @@ -1447,7 +1447,7 @@ test_expect_success 'git checkout - with --detach, complete only references' '\n>         EOF\n>  '\n>\n> -test_expect_failure 'sparse-checkout completes subcommands' '\n> +test_expect_success 'sparse-checkout completes subcommands' '\n>         test_completion \"git sparse-checkout \" <<-\\EOF\n>         list Z\n>         init Z\n> @@ -1458,13 +1458,13 @@ test_expect_failure 'sparse-checkout completes subcommands' '\n>         EOF\n>  '\n>\n> -test_expect_failure 'sparse-checkout completes options' '\n> +test_expect_success 'sparse-checkout completes options' '\n>         test_completion \"git sparse-checkout --\" <<-\\EOF\n>         --help Z\n>         EOF\n>  '\n>\n> -test_expect_failure 'sparse-checkout completes subcommand options' '\n> +test_expect_success 'sparse-checkout completes subcommand options' '\n>         test_completion \"git sparse-checkout init --\" <<-\\EOF &&\n>         --cone Z\n>         --no-cone Z\n> @@ -1492,7 +1492,7 @@ test_expect_failure 'sparse-checkout completes subcommand options' '\n>         EOF\n>  '\n>\n> -test_expect_failure 'sparse-checkout completes directory names' '\n> +test_expect_success 'sparse-checkout completes directory names' '\n>         # set up sparse-checkout repo\n>         git init sparse-checkout &&\n>         (\n> --\n> gitgitgadget\n\nPatch looks good to me, other than the $prev vs. $subcommand thing.\n"},{"id":"445457","messageId":"bad4de96-cf76-ab25-29e5-eb14325e2918@gmail.com","threadId":"57165","inReplyTo":"CABPp-BGun+v3BCuutPW2L1q3wzdB+Etuh_0Jz1aFanivZmyXWQ@mail.gmail.com","subject":"Re: [PATCH 1/2] sparse-checkout: custom tab completion tests","fromName":"Lessley Dennington","fromEmail":"lessleydennington@gmail.com","sentAt":"2022-01-04T19:19:17Z","receivedAt":"2022-01-04T19:19:21Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"\n\nOn 12/31/21 1:27 PM, Elijah Newren wrote:\n> On Fri, Dec 31, 2021 at 2:30 AM Derrick Stolee <stolee@gmail.com> wrote:\n>>\n>> On 12/30/2021 11:19 AM, Lessley Dennington wrote:\n>>> On 12/30/21 7:43 AM, Derrick Stolee wrote:\n>>\n>>>>> +    (\n>>>>> +        cd sparse-checkout &&\n>>>>> +        test_completion \"git sparse-checkout set f\" <<-\\EOF\n>>>>> +        folder1 Z\n>>>>> +        folder1/0 Z\n>>>>> +        folder1/0/1 Z\n>>>>> +        folder2 Z\n>>>>> +        folder2/0 Z\n>>>>> +        folder3 Z\n>>>>\n>>>> This tab-completion doing a full directory walk seems like it could\n>>>> be expensive for a large repository, but I suppose it is the only way\n>>>> to allow the following sequence:\n>>>>\n>>>>      fol<tab> -> folder\n>>>>      folder1/<tab> -> folder1/0\n>>>>      folder1/0/<tab> -> folder1/0/1\n>>>>\n>>>> (Hopefully that makes sense.)\n>>>>\n>>> Yes, it does.\n>>>> It would be more efficient to only go one level deep at a time, but\n>>>> that might not be possible with the tab completion mechanisms.\n>>>>\n>>> When you say one level deep, do you mean that from the sparse-checkout\n>>> directory, tab completion would only show the following?\n>>>\n>>>      folder1\n>>>      folder2\n>>>      folder3\n>>\n>> That's what I mean by one level deep at a time, but I also am not\n>> sure that that is the correct functionality. I would leave the full\n>> expansion as you have now as the design.\n> \n> I think one level at a time is better and is the optimal design.  By\n> way of comparison, note that if I do the following:\n> \n> mkdir tmp\n> cd tmp\n> mkdir -p a/b/c/d\n> touch a/b/c/d/e\n> cd <TAB>\n> \n> I do not see a/b/c/d as the completion, I only get \"a/\" as the\n> completion.  If I hit tab again, then I get \"a/b/\".  Tab again, and I\n> get \"a/b/c/\".\n> \n> I don't think normal tab completion recursively checks directories, so\n> it'd be better for us to not do so with git either.  However, if it's\n> hard to avoid automatically completing just a directory at a time,\n> then I think a fair first cut is completing to full depths, but call\n> it out as something we'd like to fix in the commit message.\n\nThank you for the feedback! This is fine by me - I'll respond further to\nyour comments in [1].\n\n[1] \nhttps://lore.kernel.org/git/CABPp-BG_Jgyr89z_D355Ytzz31J40nBGX=2cr+aXtcf3U1y6Dg@mail.gmail.com/\n"},{"id":"445458","messageId":"8dfb06d4-480c-ced8-9de0-de3e81014453@gmail.com","threadId":"57165","inReplyTo":"CABPp-BGdr54XgCXw8k1xRCgkwBtDonyODS3O+_nS_QY3SOEFGQ@mail.gmail.com","subject":"Re: [PATCH v2 1/2] sparse-checkout: custom tab completion tests","fromName":"Lessley Dennington","fromEmail":"lessleydennington@gmail.com","sentAt":"2022-01-04T19:24:56Z","receivedAt":"2022-01-04T19:25:01Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"\n\nOn 12/31/21 2:03 PM, Elijah Newren wrote:\n> On Fri, Dec 31, 2021 at 2:32 AM Lessley Dennington via GitGitGadget\n> <gitgitgadget@gmail.com> wrote:\n>>\n>> From: Lessley Dennington <lessleydennington@gmail.com>\n>>\n>> Add tests for missing/incorrect components of custom tab completion for the\n>> sparse-checkout command. These tests specifically highlight the following:\n>>\n>> 1. git sparse-checkout <TAB> results in an incomplete list of subcommands\n>> (it is missing reapply and add).\n>> 2. git sparse-checkout --<TAB> does not complete the help option.\n>> 3. Options for subcommands are not tab-completable.\n>> 4. git sparse-checkout set <TAB> and git sparse-checkout add <TAB> show\n>> both file names and directory names.\n> \n> Two thoughts on this last item:\n> \n> I completely agree that only directories should be completed in cone\n> mode, but completing on both might technically be considered correct\n> behavior for non-cone mode.  However, even in non-cone mode, I kind of\n> like the idea of encouraging people to sparsify only on directories so\n> I'm totally fine with us only tab-completing directories.  (I have a\n> bit of a disdain for non-cone mode, though, so my desire to deprecate\n> it might be showing through.  At the very least, I'm still thinking we\n> should make cone mode the default in each of `sparse-checkout init`,\n> `sparse-checkout set`, and `clone --sparse`[1])\n> \n> [1] https://lore.kernel.org/git/6e09ab19-7ffb-e58e-7b08-6e560b421c06@gmail.com/\n> \n> \nI'm still supportive of this 😊. I'll chat with others who are heavily\ninvolved with sparse-checkout to make sure I have buy-in. If so, I can\npick it up as my next work item.\n> Second, and this item is unrelated to your series but your comment\n> made me realize it....sparse-checkout unfortunately ignores prefix and\n> creates a bad .git/info/sparse-checkout file.  For example:\n> \n> $ git init -b main tmp\n> $ cd tmp\n> $ mkdir -p a/b/c\n> $ touch a/b/c/d a/b/c/e\n> $ git add a/\n> $ git commit -m \"initial\"\n> $ cd a/  # Not at the toplevel anymore\n> $ git sparse-checkout set --cone b/c  # So we expect that a/b/c will\n> be the specified sparsity path\n> $ git -C .. sparse-checkout list\n> b/c\n> $ cat ../.git/info/sparse-checkout\n> /*\n> !/*/\n> /b/\n> !/b/*/\n> /b/c/\n> $ pwd -P\n> pwd: error retrieving current directory: getcwd: cannot access parent\n> directories: No such file or directory\n> \n> I think the loss of the current working directory will be fixed by the\n> en/keep-cwd directory (currently in next and marked for merging to\n> master), but the fact that the wrong paths end up in the\n> sparse-checkout file is unfortunate.  It basically means that the\n> `set` and `add` subcommands of `sparse-checkout` can only be safely\n> run from the toplevel directory.\n> \n>> Although these tests currently fail, they will succeed with the\n>> sparse-checkout modifications in git-completion.bash in the next commit in\n>> this series.\n>>\n>> Signed-off-by: Lessley Dennington <lessleydennington@gmail.com>\n>> ---\n>>   t/t9902-completion.sh | 85 +++++++++++++++++++++++++++++++++++++++++++\n>>   1 file changed, 85 insertions(+)\n>>\n>> diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\n>> index 518203fbe07..51d0f2d93a1 100755\n>> --- a/t/t9902-completion.sh\n>> +++ b/t/t9902-completion.sh\n>> @@ -1447,6 +1447,91 @@ test_expect_success 'git checkout - with --detach, complete only references' '\n>>          EOF\n>>   '\n>>\n>> +test_expect_failure 'sparse-checkout completes subcommands' '\n>> +       test_completion \"git sparse-checkout \" <<-\\EOF\n>> +       list Z\n>> +       init Z\n>> +       set Z\n>> +       add Z\n>> +       reapply Z\n>> +       disable Z\n>> +       EOF\n>> +'\n>> +\n>> +test_expect_failure 'sparse-checkout completes options' '\n>> +       test_completion \"git sparse-checkout --\" <<-\\EOF\n>> +       --help Z\n>> +       EOF\n>> +'\n>> +\n>> +test_expect_failure 'sparse-checkout completes subcommand options' '\n>> +       test_completion \"git sparse-checkout init --\" <<-\\EOF &&\n>> +       --cone Z\n>> +       --no-cone Z\n>> +       --sparse-index Z\n>> +       --no-sparse-index Z\n>> +       EOF\n>> +\n>> +       test_completion \"git sparse-checkout set --\" <<-\\EOF &&\n>> +       --cone Z\n>> +       --no-cone Z\n>> +       --sparse-index Z\n>> +       --no-sparse-index Z\n>> +       --stdin Z\n>> +       EOF\n>> +\n>> +       test_completion \"git sparse-checkout reapply --\" <<-\\EOF &&\n>> +       --cone Z\n>> +       --no-cone Z\n>> +       --sparse-index Z\n>> +       --no-sparse-index Z\n>> +       EOF\n>> +\n>> +       test_completion \"git sparse-checkout add --\" <<-\\EOF\n>> +       --stdin Z\n>> +       EOF\n>> +'\n>> +\n>> +test_expect_failure 'sparse-checkout completes directory names' '\n>> +       # set up sparse-checkout repo\n>> +       git init sparse-checkout &&\n>> +       (\n>> +               cd sparse-checkout &&\n>> +               mkdir -p folder1/0/1 folder2/0 folder3 &&\n>> +               touch folder1/0/1/t.txt &&\n>> +               touch folder2/0/t.txt &&\n>> +               touch folder3/t.txt &&\n>> +               git add . &&\n>> +               git commit -am \"Initial commit\"\n>> +       ) &&\n>> +\n>> +       # initialize sparse-checkout definitions\n>> +       git -C sparse-checkout sparse-checkout init --cone &&\n>> +       git -C sparse-checkout sparse-checkout set folder1/0 folder3 &&\n>> +\n>> +       # test tab completion\n>> +       (\n>> +               cd sparse-checkout &&\n>> +               test_completion \"git sparse-checkout set f\" <<-\\EOF\n>> +               folder1 Z\n>> +               folder1/0 Z\n>> +               folder1/0/1 Z\n>> +               folder2 Z\n>> +               folder2/0 Z\n>> +               folder3 Z\n>> +               EOF\n>> +       ) &&\n>> +\n>> +       (\n>> +               cd sparse-checkout/folder1 &&\n>> +               test_completion \"git sparse-checkout add \" <<-\\EOF\n>> +               ./ Z\n>> +               0 Z\n>> +               0/1 Z\n>> +               EOF\n>> +       )\n>> +'\n>> +\n>>   test_expect_success 'git switch - with -d, complete all references' '\n>>          test_completion \"git switch -d \" <<-\\EOF\n>>          HEAD Z\n>> --\n>> gitgitgadget\n> \n> Patch looks okay to me, but we might want to add some kind of wording\n> around the directories-only decision and cone vs. non-cone mode to the\n> commit message.\n\nCan do! Stay tuned for v3.\n"},{"id":"445459","messageId":"d65bf6bf-8f60-31c2-7d01-e57ea6f4a5e3@gmail.com","threadId":"57165","inReplyTo":"xmqqy240l8l1.fsf@gitster.g","subject":"Re: [PATCH v2 1/2] sparse-checkout: custom tab completion tests","fromName":"Lessley Dennington","fromEmail":"lessleydennington@gmail.com","sentAt":"2022-01-04T19:25:47Z","receivedAt":"2022-01-04T19:26:02Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"\n\nOn 12/31/21 4:20 PM, Junio C Hamano wrote:\n> Elijah Newren <newren@gmail.com> writes:\n> \n>> Second, and this item is unrelated to your series but your comment\n>> made me realize it....sparse-checkout unfortunately ignores prefix and\n>> creates a bad .git/info/sparse-checkout file.  For example:\n>> ...\n>> I think the loss of the current working directory will be fixed by the\n>> en/keep-cwd directory (currently in next and marked for merging to\n>> master), but the fact that the wrong paths end up in the\n>> sparse-checkout file is unfortunate.  It basically means that the\n>> `set` and `add` subcommands of `sparse-checkout` can only be safely\n>> run from the toplevel directory.\n> \n> You made it sound as if this is a fundamental limitation, but it\n> sounds more like a bug that needs to be fixed (outside the\n> completion series, of course) to me.\n> \nI can file a bug report if that's the correct way to proceed.\n"},{"id":"445462","messageId":"676e8408-5ac3-4293-22ee-c43e9bd6916b@gmail.com","threadId":"57165","inReplyTo":"CABPp-BG_Jgyr89z_D355Ytzz31J40nBGX=2cr+aXtcf3U1y6Dg@mail.gmail.com","subject":"Re: [PATCH v2 2/2] sparse-checkout: custom tab completion","fromName":"Lessley Dennington","fromEmail":"lessleydennington@gmail.com","sentAt":"2022-01-04T19:41:36Z","receivedAt":"2022-01-04T19:41:40Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"\n\nOn 12/31/21 4:52 PM, Elijah Newren wrote:\n> On Fri, Dec 31, 2021 at 2:33 AM Lessley Dennington via GitGitGadget\n> <gitgitgadget@gmail.com> wrote:\n>>\n>> From: Lessley Dennington <lessleydennington@gmail.com>\n>>\n>> Fix custom tab completion for sparse-checkout command. This will ensure:\n>>\n>> 1. The full list of subcommands is provided when users enter git\n>> sparse-checkout <TAB>.\n>> 2. The --help option is tab-completable.\n>> 3. Subcommand options are tab-completable.\n>> 4. A list of directories (but not files) is provided when users enter git\n>> sparse-checkout add <TAB> or git sparse-checkout set <TAB>.\n>>\n>> Failing tests that were added in the previous commit to verify these\n>> scenarios are now passing with these updates.\n>>\n>> Signed-off-by: Lessley Dennington <lessleydennington@gmail.com>\n>> ---\n>>   contrib/completion/git-completion.bash | 38 ++++++++++++++++++--------\n>>   t/t9902-completion.sh                  |  8 +++---\n>>   2 files changed, 30 insertions(+), 16 deletions(-)\n>>\n>> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\n>> index c82ccaebcc7..7de997ee64e 100644\n>> --- a/contrib/completion/git-completion.bash\n>> +++ b/contrib/completion/git-completion.bash\n>> @@ -2986,24 +2986,38 @@ _git_show_branch ()\n>>          __git_complete_revlist\n>>   }\n>>\n>> +__git_sparse_checkout_subcommand_opts=\"--cone --no-cone --sparse-index --no-sparse-index\"\n>> +\n>>   _git_sparse_checkout ()\n>>   {\n>> -       local subcommands=\"list init set disable\"\n>> +       local subcommands=\"list init set disable add reapply\"\n>>          local subcommand=\"$(__git_find_on_cmdline \"$subcommands\")\"\n>> +\n>>          if [ -z \"$subcommand\" ]; then\n>> -               __gitcomp \"$subcommands\"\n>> -               return\n>> +               case \"$cur\" in\n>> +                       --*)\n>> +                               __gitcomp \"--help\"\n>> +                               ;;\n>> +                       *)\n>> +                               __gitcomp \"$subcommands\"\n>> +                               ;;\n>> +               esac\n>>          fi\n>>\n>> -       case \"$subcommand,$cur\" in\n>> -       init,--*)\n>> -               __gitcomp \"--cone\"\n>> -               ;;\n>> -       set,--*)\n>> -               __gitcomp \"--stdin\"\n>> -               ;;\n>> -       *)\n>> -               ;;\n>> +       case \"$prev\" in\n> \n> Shouldn't this be \"$subcommand\" rather than \"$prev\"?  I think with\n> prev, it will only correctly complete the first path after \"set\",\n> \"add\", etc.\n> \nGood catch, thank you! Fixing in v3.\n>> +               set)\n>> +                       __gitcomp \"$__git_sparse_checkout_subcommand_opts --stdin\"\n>> +                       __gitcomp \"$(git ls-tree -d -r HEAD --name-only)\"\n>> +                       ;;\n>> +               add)\n>> +                       __gitcomp \"--stdin\"\n>> +                       __gitcomp \"$(git ls-tree -d -r HEAD --name-only)\"\n> \n> I was going to make a simple suggestion for making it just complete\n> one additional level at a time and leaving out the -r, and then tried\n> it out and found out it wasn't simple.  I got something working,\n> eventually, but it's slightly ugly...so it probably belongs in a\n> separate patch anyway.  If you're curious, it's basically replacing\n> the second __gitcomp... call for each of set and add with\n> `__gitcomp_directories`, after first defining:\n> \n> __gitcomp_directories ()\n> {\n>      local _tmp_dir _tmp_completions\n> \n>      # Get the directory of the current token; this differs from dirname\n>      # in that it keeps up to the final trailing slash.  If no slash found\n>      # that's fine too.\n>      [[ \"$cur\" =~ .*/ ]]\n>      _tmp_dir=$BASH_REMATCH\n> \n>      # Find possible directory completions, adding trailing '/' characters\n>      _tmp_completions=\"$(git ls-tree -d --name-only HEAD $_tmp_dir |\n>          sed -e s%$%/%)\"\n> \n>      if [[ -n \"$_tmp_completions\" ]]; then\n>          # There were some directory completions, so find ones that\n>          # start with \"$cur\", the current token, and put those in COMPREPLY\n>          local i=0 c IFS=$' \\t\\n'\n>          for c in $_tmp_completions; do\n>              if [[ $c == \"$cur\"* ]]; then\n>                  COMPREPLY+=(\"$c\")\n>              fi\n>          done\n>      elif [[ \"$cur\" =~ /$ ]]; then\n>          # No possible further completions any deeper, so assume we're at\n>          # a leaf directory and just consider it complete\n>          __gitcomp_direct_append \"$cur \"\n>      fi\n> }\n> \n> But I don't think that needs to be part of this series; I can submit\n> it later and hopefully get a completion expert to point out\n> better/cleaner ways of what I've done above.\n> \nI'm admittedly curious about what made this so difficult. I removed the \n'-r' and updated my tests to expect only directories at one level, and\nthey passed. But I imagine I'm being too simplistic.\n>> +                       ;;\n>> +               init|reapply)\n>> +                       __gitcomp \"$__git_sparse_checkout_subcommand_opts\"\n>> +                       ;;\n>> +               *)\n>> +                       ;;\n>>          esac\n>>   }\n>>\n>> diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\n>> index 51d0f2d93a1..4dc93ee0595 100755\n>> --- a/t/t9902-completion.sh\n>> +++ b/t/t9902-completion.sh\n>> @@ -1447,7 +1447,7 @@ test_expect_success 'git checkout - with --detach, complete only references' '\n>>          EOF\n>>   '\n>>\n>> -test_expect_failure 'sparse-checkout completes subcommands' '\n>> +test_expect_success 'sparse-checkout completes subcommands' '\n>>          test_completion \"git sparse-checkout \" <<-\\EOF\n>>          list Z\n>>          init Z\n>> @@ -1458,13 +1458,13 @@ test_expect_failure 'sparse-checkout completes subcommands' '\n>>          EOF\n>>   '\n>>\n>> -test_expect_failure 'sparse-checkout completes options' '\n>> +test_expect_success 'sparse-checkout completes options' '\n>>          test_completion \"git sparse-checkout --\" <<-\\EOF\n>>          --help Z\n>>          EOF\n>>   '\n>>\n>> -test_expect_failure 'sparse-checkout completes subcommand options' '\n>> +test_expect_success 'sparse-checkout completes subcommand options' '\n>>          test_completion \"git sparse-checkout init --\" <<-\\EOF &&\n>>          --cone Z\n>>          --no-cone Z\n>> @@ -1492,7 +1492,7 @@ test_expect_failure 'sparse-checkout completes subcommand options' '\n>>          EOF\n>>   '\n>>\n>> -test_expect_failure 'sparse-checkout completes directory names' '\n>> +test_expect_success 'sparse-checkout completes directory names' '\n>>          # set up sparse-checkout repo\n>>          git init sparse-checkout &&\n>>          (\n>> --\n>> gitgitgadget\n> \n> Patch looks good to me, other than the $prev vs. $subcommand thing.\n\nThanks!\n"},{"id":"445468","messageId":"CABPp-BGSVzEwk83EzhPn3+5jOt5q6=CQ2W_Uz6GfUR=2=AhgNg@mail.gmail.com","threadId":"57165","inReplyTo":"d65bf6bf-8f60-31c2-7d01-e57ea6f4a5e3@gmail.com","subject":"Re: [PATCH v2 1/2] sparse-checkout: custom tab completion tests","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2022-01-04T20:25:53Z","receivedAt":"2022-01-04T20:26:08Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Tue, Jan 4, 2022 at 11:26 AM Lessley Dennington\n<lessleydennington@gmail.com> wrote:\n>\n>\n>\n> On 12/31/21 4:20 PM, Junio C Hamano wrote:\n> > Elijah Newren <newren@gmail.com> writes:\n> >\n> >> Second, and this item is unrelated to your series but your comment\n> >> made me realize it....sparse-checkout unfortunately ignores prefix and\n> >> creates a bad .git/info/sparse-checkout file.  For example:\n> >> ...\n> >> I think the loss of the current working directory will be fixed by the\n> >> en/keep-cwd directory (currently in next and marked for merging to\n> >> master), but the fact that the wrong paths end up in the\n> >> sparse-checkout file is unfortunate.  It basically means that the\n> >> `set` and `add` subcommands of `sparse-checkout` can only be safely\n> >> run from the toplevel directory.\n> >\n> > You made it sound as if this is a fundamental limitation, but it\n> > sounds more like a bug that needs to be fixed (outside the\n> > completion series, of course) to me.\n> >\n> I can file a bug report if that's the correct way to proceed.\n\nWe don't really have a bug tracker.\n\nWe often just file an email, and add additional searchable strings\n(e.g. #leftoverbits, though that doesn't apply here), and then search\nvia https://lore.kernel.org/git/.\n\nThere is 'git bugreport', but it just generates an email to send to\nthe mailing list...but we already have the emails in this thread.\n\nThere is https://bugs.chromium.org/p/git/issues/list, which is used by\na few folks, but I suspect I'm the only one who has looked at it that\ntouches sparse-checkout related stuff.\n\nThere is https://github.com/git-for-windows/git/issues, but this isn't\nWindows specific.  (Sometimes they'll track stuff that isn't windows\nspecific, but I've seen Dscho close out issues after being reported to\nthis list.)\n\nI've also kept private files with lists of things to work on.  Doesn't\nhelp anyone else track it.  (Which is why I'll sometimes use one of\nthe two above trackers instead.)\n\n...not sure if that helps, but that's the basic state of our \"bug tracking\".\n"},{"id":"445471","messageId":"CABPp-BFJF7hyr5onMFQNC7r_x+XfJVn9wXhxyMV6Lu+pxbfyPA@mail.gmail.com","threadId":"57165","inReplyTo":"676e8408-5ac3-4293-22ee-c43e9bd6916b@gmail.com","subject":"Re: [PATCH v2 2/2] sparse-checkout: custom tab completion","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2022-01-04T20:42:34Z","receivedAt":"2022-01-04T20:42:48Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Tue, Jan 4, 2022 at 11:41 AM Lessley Dennington\n<lessleydennington@gmail.com> wrote:\n>\n>\n>\n> On 12/31/21 4:52 PM, Elijah Newren wrote:\n> > On Fri, Dec 31, 2021 at 2:33 AM Lessley Dennington via GitGitGadget\n> > <gitgitgadget@gmail.com> wrote:\n> >>\n> >> From: Lessley Dennington <lessleydennington@gmail.com>\n> >>\n> >> Fix custom tab completion for sparse-checkout command. This will ensure:\n> >>\n> >> 1. The full list of subcommands is provided when users enter git\n> >> sparse-checkout <TAB>.\n> >> 2. The --help option is tab-completable.\n> >> 3. Subcommand options are tab-completable.\n> >> 4. A list of directories (but not files) is provided when users enter git\n> >> sparse-checkout add <TAB> or git sparse-checkout set <TAB>.\n> >>\n> >> Failing tests that were added in the previous commit to verify these\n> >> scenarios are now passing with these updates.\n> >>\n> >> Signed-off-by: Lessley Dennington <lessleydennington@gmail.com>\n> >> ---\n> >>   contrib/completion/git-completion.bash | 38 ++++++++++++++++++--------\n> >>   t/t9902-completion.sh                  |  8 +++---\n> >>   2 files changed, 30 insertions(+), 16 deletions(-)\n> >>\n> >> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\n> >> index c82ccaebcc7..7de997ee64e 100644\n> >> --- a/contrib/completion/git-completion.bash\n> >> +++ b/contrib/completion/git-completion.bash\n> >> @@ -2986,24 +2986,38 @@ _git_show_branch ()\n> >>          __git_complete_revlist\n> >>   }\n> >>\n> >> +__git_sparse_checkout_subcommand_opts=\"--cone --no-cone --sparse-index --no-sparse-index\"\n> >> +\n> >>   _git_sparse_checkout ()\n> >>   {\n> >> -       local subcommands=\"list init set disable\"\n> >> +       local subcommands=\"list init set disable add reapply\"\n> >>          local subcommand=\"$(__git_find_on_cmdline \"$subcommands\")\"\n> >> +\n> >>          if [ -z \"$subcommand\" ]; then\n> >> -               __gitcomp \"$subcommands\"\n> >> -               return\n> >> +               case \"$cur\" in\n> >> +                       --*)\n> >> +                               __gitcomp \"--help\"\n> >> +                               ;;\n> >> +                       *)\n> >> +                               __gitcomp \"$subcommands\"\n> >> +                               ;;\n> >> +               esac\n> >>          fi\n> >>\n> >> -       case \"$subcommand,$cur\" in\n> >> -       init,--*)\n> >> -               __gitcomp \"--cone\"\n> >> -               ;;\n> >> -       set,--*)\n> >> -               __gitcomp \"--stdin\"\n> >> -               ;;\n> >> -       *)\n> >> -               ;;\n> >> +       case \"$prev\" in\n> >\n> > Shouldn't this be \"$subcommand\" rather than \"$prev\"?  I think with\n> > prev, it will only correctly complete the first path after \"set\",\n> > \"add\", etc.\n> >\n> Good catch, thank you! Fixing in v3.\n> >> +               set)\n> >> +                       __gitcomp \"$__git_sparse_checkout_subcommand_opts --stdin\"\n> >> +                       __gitcomp \"$(git ls-tree -d -r HEAD --name-only)\"\n> >> +                       ;;\n> >> +               add)\n> >> +                       __gitcomp \"--stdin\"\n> >> +                       __gitcomp \"$(git ls-tree -d -r HEAD --name-only)\"\n> >\n> > I was going to make a simple suggestion for making it just complete\n> > one additional level at a time and leaving out the -r, and then tried\n> > it out and found out it wasn't simple.  I got something working,\n> > eventually, but it's slightly ugly...so it probably belongs in a\n> > separate patch anyway.  If you're curious, it's basically replacing\n> > the second __gitcomp... call for each of set and add with\n> > `__gitcomp_directories`, after first defining:\n> >\n> > __gitcomp_directories ()\n> > {\n> >      local _tmp_dir _tmp_completions\n> >\n> >      # Get the directory of the current token; this differs from dirname\n> >      # in that it keeps up to the final trailing slash.  If no slash found\n> >      # that's fine too.\n> >      [[ \"$cur\" =~ .*/ ]]\n> >      _tmp_dir=$BASH_REMATCH\n> >\n> >      # Find possible directory completions, adding trailing '/' characters\n> >      _tmp_completions=\"$(git ls-tree -d --name-only HEAD $_tmp_dir |\n> >          sed -e s%$%/%)\"\n> >\n> >      if [[ -n \"$_tmp_completions\" ]]; then\n> >          # There were some directory completions, so find ones that\n> >          # start with \"$cur\", the current token, and put those in COMPREPLY\n> >          local i=0 c IFS=$' \\t\\n'\n> >          for c in $_tmp_completions; do\n> >              if [[ $c == \"$cur\"* ]]; then\n> >                  COMPREPLY+=(\"$c\")\n> >              fi\n> >          done\n> >      elif [[ \"$cur\" =~ /$ ]]; then\n> >          # No possible further completions any deeper, so assume we're at\n> >          # a leaf directory and just consider it complete\n> >          __gitcomp_direct_append \"$cur \"\n> >      fi\n> > }\n> >\n> > But I don't think that needs to be part of this series; I can submit\n> > it later and hopefully get a completion expert to point out\n> > better/cleaner ways of what I've done above.\n> >\n> I'm admittedly curious about what made this so difficult. I removed the\n> '-r' and updated my tests to expect only directories at one level, and\n> they passed. But I imagine I'm being too simplistic.\n\nI've forgotten some details since last Saturday, but I think the\nproblem was that doing that would only ever complete toplevel\ndirectories; after completing those you could keep tabbing to get a\ndeeper directory.  First, let's get a comparison point; ignoring\nsparse-checkout, I can do:\n\n    cd $GIT_CLONE\n    cd cont<TAB>b<TAB><TAB>\n\nand the ls line will replace those <TAB>s so that I see\n\n    ls contrib/buildsystems/Generators\n\nNow, if we just removed the '-r' from your git-completion.bash\nchanges, and then typed\n\n    git sparse-checkout set cont<TAB>b<TAB><TAB>\n\nThen you'd see\n\n    git sparse-checkout set contrib\n\nand see 'bin-wrappers', 'block-sha1', and 'builtin' as potential\ncompletions, but not as subdirs of contrib but instead sibling dirs to\ncontrib.  That completion rule wouldn't let you look within contrib/.\nMy more complicated rule had to avoid calling __gitcomp to avoid\nadding spaces so that completions could continue (but should add them\nif we have tabbed all the way down and there are no more\nsubdirectories), had to add trailing '/' characters so that we know\nwhen we have the full directory name to pass along to ls-tree, and\nthen had to manually do the work that __gitcomp would manually do with\nmaking sure to only provide completions relevant to what has been\ntyped so far.\n"},{"id":"445521","messageId":"52d638fc-e7e7-1b0a-482b-cff7c9500b92@gmail.com","threadId":"57165","inReplyTo":"CABPp-BGSVzEwk83EzhPn3+5jOt5q6=CQ2W_Uz6GfUR=2=AhgNg@mail.gmail.com","subject":"Re: [PATCH v2 1/2] sparse-checkout: custom tab completion tests","fromName":"Lessley Dennington","fromEmail":"lessleydennington@gmail.com","sentAt":"2022-01-05T14:05:17Z","receivedAt":"2022-01-05T14:05:21Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"\n\nOn 1/4/22 2:25 PM, Elijah Newren wrote:\n> On Tue, Jan 4, 2022 at 11:26 AM Lessley Dennington\n> <lessleydennington@gmail.com> wrote:\n>>\n>>\n>>\n>> On 12/31/21 4:20 PM, Junio C Hamano wrote:\n>>> Elijah Newren <newren@gmail.com> writes:\n>>>\n>>>> Second, and this item is unrelated to your series but your comment\n>>>> made me realize it....sparse-checkout unfortunately ignores prefix and\n>>>> creates a bad .git/info/sparse-checkout file.  For example:\n>>>> ...\n>>>> I think the loss of the current working directory will be fixed by the\n>>>> en/keep-cwd directory (currently in next and marked for merging to\n>>>> master), but the fact that the wrong paths end up in the\n>>>> sparse-checkout file is unfortunate.  It basically means that the\n>>>> `set` and `add` subcommands of `sparse-checkout` can only be safely\n>>>> run from the toplevel directory.\n>>>\n>>> You made it sound as if this is a fundamental limitation, but it\n>>> sounds more like a bug that needs to be fixed (outside the\n>>> completion series, of course) to me.\n>>>\n>> I can file a bug report if that's the correct way to proceed.\n> \n> We don't really have a bug tracker.\n> \n> We often just file an email, and add additional searchable strings\n> (e.g. #leftoverbits, though that doesn't apply here), and then search\n> via https://lore.kernel.org/git/.\n> \n> There is 'git bugreport', but it just generates an email to send to\n> the mailing list...but we already have the emails in this thread.\n> \n> There is https://bugs.chromium.org/p/git/issues/list, which is used by\n> a few folks, but I suspect I'm the only one who has looked at it that\n> touches sparse-checkout related stuff.\n> \n> There is https://github.com/git-for-windows/git/issues, but this isn't\n> Windows specific.  (Sometimes they'll track stuff that isn't windows\n> specific, but I've seen Dscho close out issues after being reported to\n> this list.)\n> \n> I've also kept private files with lists of things to work on.  Doesn't\n> help anyone else track it.  (Which is why I'll sometimes use one of\n> the two above trackers instead.)\n> \n> ...not sure if that helps, but that's the basic state of our \"bug tracking\".\n\nThis is actually great context - thanks for providing! I'll go with the\nemail strategy for visibility and will base my format off [1].\n\n[1]: \nhttps://lore.kernel.org/git/CABceR4bZmtC4rCwgxZ1BBYZP69VOUca1f_moJoP989vTUZWu9Q@mail.gmail.com/\n"},{"id":"445574","messageId":"8202614a-022f-b71c-cf88-d5a3788cc150@gmail.com","threadId":"57165","inReplyTo":"CABPp-BFJF7hyr5onMFQNC7r_x+XfJVn9wXhxyMV6Lu+pxbfyPA@mail.gmail.com","subject":"Re: [PATCH v2 2/2] sparse-checkout: custom tab completion","fromName":"Lessley Dennington","fromEmail":"lessleydennington@gmail.com","sentAt":"2022-01-05T20:20:21Z","receivedAt":"2022-01-05T20:20:31Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"\n\nOn 1/4/22 2:42 PM, Elijah Newren wrote:\n> On Tue, Jan 4, 2022 at 11:41 AM Lessley Dennington\n> <lessleydennington@gmail.com> wrote:\n>>\n>>\n>>\n>> On 12/31/21 4:52 PM, Elijah Newren wrote:\n>>> On Fri, Dec 31, 2021 at 2:33 AM Lessley Dennington via GitGitGadget\n>>> <gitgitgadget@gmail.com> wrote:\n>>>>\n>>>> From: Lessley Dennington <lessleydennington@gmail.com>\n>>>>\n>>>> Fix custom tab completion for sparse-checkout command. This will ensure:\n>>>>\n>>>> 1. The full list of subcommands is provided when users enter git\n>>>> sparse-checkout <TAB>.\n>>>> 2. The --help option is tab-completable.\n>>>> 3. Subcommand options are tab-completable.\n>>>> 4. A list of directories (but not files) is provided when users enter git\n>>>> sparse-checkout add <TAB> or git sparse-checkout set <TAB>.\n>>>>\n>>>> Failing tests that were added in the previous commit to verify these\n>>>> scenarios are now passing with these updates.\n>>>>\n>>>> Signed-off-by: Lessley Dennington <lessleydennington@gmail.com>\n>>>> ---\n>>>>    contrib/completion/git-completion.bash | 38 ++++++++++++++++++--------\n>>>>    t/t9902-completion.sh                  |  8 +++---\n>>>>    2 files changed, 30 insertions(+), 16 deletions(-)\n>>>>\n>>>> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\n>>>> index c82ccaebcc7..7de997ee64e 100644\n>>>> --- a/contrib/completion/git-completion.bash\n>>>> +++ b/contrib/completion/git-completion.bash\n>>>> @@ -2986,24 +2986,38 @@ _git_show_branch ()\n>>>>           __git_complete_revlist\n>>>>    }\n>>>>\n>>>> +__git_sparse_checkout_subcommand_opts=\"--cone --no-cone --sparse-index --no-sparse-index\"\n>>>> +\n>>>>    _git_sparse_checkout ()\n>>>>    {\n>>>> -       local subcommands=\"list init set disable\"\n>>>> +       local subcommands=\"list init set disable add reapply\"\n>>>>           local subcommand=\"$(__git_find_on_cmdline \"$subcommands\")\"\n>>>> +\n>>>>           if [ -z \"$subcommand\" ]; then\n>>>> -               __gitcomp \"$subcommands\"\n>>>> -               return\n>>>> +               case \"$cur\" in\n>>>> +                       --*)\n>>>> +                               __gitcomp \"--help\"\n>>>> +                               ;;\n>>>> +                       *)\n>>>> +                               __gitcomp \"$subcommands\"\n>>>> +                               ;;\n>>>> +               esac\n>>>>           fi\n>>>>\n>>>> -       case \"$subcommand,$cur\" in\n>>>> -       init,--*)\n>>>> -               __gitcomp \"--cone\"\n>>>> -               ;;\n>>>> -       set,--*)\n>>>> -               __gitcomp \"--stdin\"\n>>>> -               ;;\n>>>> -       *)\n>>>> -               ;;\n>>>> +       case \"$prev\" in\n>>>\n>>> Shouldn't this be \"$subcommand\" rather than \"$prev\"?  I think with\n>>> prev, it will only correctly complete the first path after \"set\",\n>>> \"add\", etc.\n>>>\n>> Good catch, thank you! Fixing in v3.\n>>>> +               set)\n>>>> +                       __gitcomp \"$__git_sparse_checkout_subcommand_opts --stdin\"\n>>>> +                       __gitcomp \"$(git ls-tree -d -r HEAD --name-only)\"\n>>>> +                       ;;\n>>>> +               add)\n>>>> +                       __gitcomp \"--stdin\"\n>>>> +                       __gitcomp \"$(git ls-tree -d -r HEAD --name-only)\"\n>>>\n>>> I was going to make a simple suggestion for making it just complete\n>>> one additional level at a time and leaving out the -r, and then tried\n>>> it out and found out it wasn't simple.  I got something working,\n>>> eventually, but it's slightly ugly...so it probably belongs in a\n>>> separate patch anyway.  If you're curious, it's basically replacing\n>>> the second __gitcomp... call for each of set and add with\n>>> `__gitcomp_directories`, after first defining:\n>>>\n>>> __gitcomp_directories ()\n>>> {\n>>>       local _tmp_dir _tmp_completions\n>>>\n>>>       # Get the directory of the current token; this differs from dirname\n>>>       # in that it keeps up to the final trailing slash.  If no slash found\n>>>       # that's fine too.\n>>>       [[ \"$cur\" =~ .*/ ]]\n>>>       _tmp_dir=$BASH_REMATCH\n>>>\n>>>       # Find possible directory completions, adding trailing '/' characters\n>>>       _tmp_completions=\"$(git ls-tree -d --name-only HEAD $_tmp_dir |\n>>>           sed -e s%$%/%)\"\n>>>\n>>>       if [[ -n \"$_tmp_completions\" ]]; then\n>>>           # There were some directory completions, so find ones that\n>>>           # start with \"$cur\", the current token, and put those in COMPREPLY\n>>>           local i=0 c IFS=$' \\t\\n'\n>>>           for c in $_tmp_completions; do\n>>>               if [[ $c == \"$cur\"* ]]; then\n>>>                   COMPREPLY+=(\"$c\")\n>>>               fi\n>>>           done\n>>>       elif [[ \"$cur\" =~ /$ ]]; then\n>>>           # No possible further completions any deeper, so assume we're at\n>>>           # a leaf directory and just consider it complete\n>>>           __gitcomp_direct_append \"$cur \"\n>>>       fi\n>>> }\n>>>\n>>> But I don't think that needs to be part of this series; I can submit\n>>> it later and hopefully get a completion expert to point out\n>>> better/cleaner ways of what I've done above.\n>>>\n>> I'm admittedly curious about what made this so difficult. I removed the\n>> '-r' and updated my tests to expect only directories at one level, and\n>> they passed. But I imagine I'm being too simplistic.\n> \n> I've forgotten some details since last Saturday, but I think the\n> problem was that doing that would only ever complete toplevel\n> directories; after completing those you could keep tabbing to get a\n> deeper directory.  First, let's get a comparison point; ignoring\n> sparse-checkout, I can do:\n> \n>      cd $GIT_CLONE\n>      cd cont<TAB>b<TAB><TAB>\n> \n> and the ls line will replace those <TAB>s so that I see\n> \n>      ls contrib/buildsystems/Generators\n> \n> Now, if we just removed the '-r' from your git-completion.bash\n> changes, and then typed\n> \n>      git sparse-checkout set cont<TAB>b<TAB><TAB>\n> \n> Then you'd see\n> \n>      git sparse-checkout set contrib\n> \n> and see 'bin-wrappers', 'block-sha1', and 'builtin' as potential\n> completions, but not as subdirs of contrib but instead sibling dirs to\n> contrib.  That completion rule wouldn't let you look within contrib/.\n> My more complicated rule had to avoid calling __gitcomp to avoid\n> adding spaces so that completions could continue (but should add them\n> if we have tabbed all the way down and there are no more\n> subdirectories), had to add trailing '/' characters so that we know\n> when we have the full directory name to pass along to ls-tree, and\n> then had to manually do the work that __gitcomp would manually do with\n> making sure to only provide completions relevant to what has been\n> typed so far.\nAh, I see. Thank you so much for the thorough explanation. I know you said\nthis series could go through without that update, but I feel like it\nshould probably be added. Don't want to start off with the wrong behavior.\n"},{"id":"445586","messageId":"CABPp-BG4xA6G0E9FeognvFoAns8tg+9SRr8d4O6s0QT4L71uTA@mail.gmail.com","threadId":"57165","inReplyTo":"8202614a-022f-b71c-cf88-d5a3788cc150@gmail.com","subject":"Re: [PATCH v2 2/2] sparse-checkout: custom tab completion","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2022-01-05T22:55:47Z","receivedAt":"2022-01-05T22:56:07Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Wed, Jan 5, 2022 at 12:20 PM Lessley Dennington\n<lessleydennington@gmail.com> wrote:\n>\n> On 1/4/22 2:42 PM, Elijah Newren wrote:\n> > On Tue, Jan 4, 2022 at 11:41 AM Lessley Dennington\n> > <lessleydennington@gmail.com> wrote:\n> >>\n> >>\n> >>\n> >> On 12/31/21 4:52 PM, Elijah Newren wrote:\n> >>> On Fri, Dec 31, 2021 at 2:33 AM Lessley Dennington via GitGitGadget\n> >>> <gitgitgadget@gmail.com> wrote:\n> >>>>\n> >>>> From: Lessley Dennington <lessleydennington@gmail.com>\n> >>>>\n> >>>> Fix custom tab completion for sparse-checkout command. This will ensure:\n> >>>>\n> >>>> 1. The full list of subcommands is provided when users enter git\n> >>>> sparse-checkout <TAB>.\n> >>>> 2. The --help option is tab-completable.\n> >>>> 3. Subcommand options are tab-completable.\n> >>>> 4. A list of directories (but not files) is provided when users enter git\n> >>>> sparse-checkout add <TAB> or git sparse-checkout set <TAB>.\n> >>>>\n> >>>> Failing tests that were added in the previous commit to verify these\n> >>>> scenarios are now passing with these updates.\n> >>>>\n> >>>> Signed-off-by: Lessley Dennington <lessleydennington@gmail.com>\n> >>>> ---\n> >>>>    contrib/completion/git-completion.bash | 38 ++++++++++++++++++--------\n> >>>>    t/t9902-completion.sh                  |  8 +++---\n> >>>>    2 files changed, 30 insertions(+), 16 deletions(-)\n> >>>>\n> >>>> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\n> >>>> index c82ccaebcc7..7de997ee64e 100644\n> >>>> --- a/contrib/completion/git-completion.bash\n> >>>> +++ b/contrib/completion/git-completion.bash\n> >>>> @@ -2986,24 +2986,38 @@ _git_show_branch ()\n> >>>>           __git_complete_revlist\n> >>>>    }\n> >>>>\n> >>>> +__git_sparse_checkout_subcommand_opts=\"--cone --no-cone --sparse-index --no-sparse-index\"\n> >>>> +\n> >>>>    _git_sparse_checkout ()\n> >>>>    {\n> >>>> -       local subcommands=\"list init set disable\"\n> >>>> +       local subcommands=\"list init set disable add reapply\"\n> >>>>           local subcommand=\"$(__git_find_on_cmdline \"$subcommands\")\"\n> >>>> +\n> >>>>           if [ -z \"$subcommand\" ]; then\n> >>>> -               __gitcomp \"$subcommands\"\n> >>>> -               return\n> >>>> +               case \"$cur\" in\n> >>>> +                       --*)\n> >>>> +                               __gitcomp \"--help\"\n> >>>> +                               ;;\n> >>>> +                       *)\n> >>>> +                               __gitcomp \"$subcommands\"\n> >>>> +                               ;;\n> >>>> +               esac\n> >>>>           fi\n> >>>>\n> >>>> -       case \"$subcommand,$cur\" in\n> >>>> -       init,--*)\n> >>>> -               __gitcomp \"--cone\"\n> >>>> -               ;;\n> >>>> -       set,--*)\n> >>>> -               __gitcomp \"--stdin\"\n> >>>> -               ;;\n> >>>> -       *)\n> >>>> -               ;;\n> >>>> +       case \"$prev\" in\n> >>>\n> >>> Shouldn't this be \"$subcommand\" rather than \"$prev\"?  I think with\n> >>> prev, it will only correctly complete the first path after \"set\",\n> >>> \"add\", etc.\n> >>>\n> >> Good catch, thank you! Fixing in v3.\n> >>>> +               set)\n> >>>> +                       __gitcomp \"$__git_sparse_checkout_subcommand_opts --stdin\"\n> >>>> +                       __gitcomp \"$(git ls-tree -d -r HEAD --name-only)\"\n> >>>> +                       ;;\n> >>>> +               add)\n> >>>> +                       __gitcomp \"--stdin\"\n> >>>> +                       __gitcomp \"$(git ls-tree -d -r HEAD --name-only)\"\n> >>>\n> >>> I was going to make a simple suggestion for making it just complete\n> >>> one additional level at a time and leaving out the -r, and then tried\n> >>> it out and found out it wasn't simple.  I got something working,\n> >>> eventually, but it's slightly ugly...so it probably belongs in a\n> >>> separate patch anyway.  If you're curious, it's basically replacing\n> >>> the second __gitcomp... call for each of set and add with\n> >>> `__gitcomp_directories`, after first defining:\n> >>>\n> >>> __gitcomp_directories ()\n> >>> {\n> >>>       local _tmp_dir _tmp_completions\n> >>>\n> >>>       # Get the directory of the current token; this differs from dirname\n> >>>       # in that it keeps up to the final trailing slash.  If no slash found\n> >>>       # that's fine too.\n> >>>       [[ \"$cur\" =~ .*/ ]]\n> >>>       _tmp_dir=$BASH_REMATCH\n> >>>\n> >>>       # Find possible directory completions, adding trailing '/' characters\n> >>>       _tmp_completions=\"$(git ls-tree -d --name-only HEAD $_tmp_dir |\n> >>>           sed -e s%$%/%)\"\n> >>>\n> >>>       if [[ -n \"$_tmp_completions\" ]]; then\n> >>>           # There were some directory completions, so find ones that\n> >>>           # start with \"$cur\", the current token, and put those in COMPREPLY\n> >>>           local i=0 c IFS=$' \\t\\n'\n> >>>           for c in $_tmp_completions; do\n> >>>               if [[ $c == \"$cur\"* ]]; then\n> >>>                   COMPREPLY+=(\"$c\")\n> >>>               fi\n> >>>           done\n> >>>       elif [[ \"$cur\" =~ /$ ]]; then\n> >>>           # No possible further completions any deeper, so assume we're at\n> >>>           # a leaf directory and just consider it complete\n> >>>           __gitcomp_direct_append \"$cur \"\n> >>>       fi\n> >>> }\n> >>>\n> >>> But I don't think that needs to be part of this series; I can submit\n> >>> it later and hopefully get a completion expert to point out\n> >>> better/cleaner ways of what I've done above.\n> >>>\n> >> I'm admittedly curious about what made this so difficult. I removed the\n> >> '-r' and updated my tests to expect only directories at one level, and\n> >> they passed. But I imagine I'm being too simplistic.\n> >\n> > I've forgotten some details since last Saturday, but I think the\n> > problem was that doing that would only ever complete toplevel\n> > directories; after completing those you could keep tabbing to get a\n> > deeper directory.  First, let's get a comparison point; ignoring\n> > sparse-checkout, I can do:\n> >\n> >      cd $GIT_CLONE\n> >      cd cont<TAB>b<TAB><TAB>\n> >\n> > and the ls line will replace those <TAB>s so that I see\n> >\n> >      ls contrib/buildsystems/Generators\n> >\n> > Now, if we just removed the '-r' from your git-completion.bash\n> > changes, and then typed\n> >\n> >      git sparse-checkout set cont<TAB>b<TAB><TAB>\n> >\n> > Then you'd see\n> >\n> >      git sparse-checkout set contrib\n> >\n> > and see 'bin-wrappers', 'block-sha1', and 'builtin' as potential\n> > completions, but not as subdirs of contrib but instead sibling dirs to\n> > contrib.  That completion rule wouldn't let you look within contrib/.\n> > My more complicated rule had to avoid calling __gitcomp to avoid\n> > adding spaces so that completions could continue (but should add them\n> > if we have tabbed all the way down and there are no more\n> > subdirectories), had to add trailing '/' characters so that we know\n> > when we have the full directory name to pass along to ls-tree, and\n> > then had to manually do the work that __gitcomp would manually do with\n> > making sure to only provide completions relevant to what has been\n> > typed so far.\n>\n> Ah, I see. Thank you so much for the thorough explanation. I know you said\n> this series could go through without that update, but I feel like it\n> should probably be added. Don't want to start off with the wrong behavior.\n\nThe wrong behavior only occurs if you drop the `-r` from your patch.\nIf you keep the `-r`, as in your patch submission, you get the right\nbehavior, it just might be a bit slow.  The only reason I investigated\ndropping the `-r` and then following up with all the extra workarounds\nneeded when the `-r` was dropped was because some repositories may be\nbig enough that immediately recursing trees down to the lowest depths\nmay be expensive.\n\nFor example, in linux.git (very small compared to the Microsoft\nrepos): `time git ls-tree -rd HEAD >/dev/null` was 0.785s (cold cache;\na mere 0.084s on second run).  If repositories get much bigger than\nthat, folks might not like the slowness of using `-r`.  But I think\nwhat you have is fine as a first cut.\n\nThat said, if you want to add a patch to this series that switches\nyour straightforward implementation to my much more complex but faster\nalternative, that's fine too.\n"},{"id":"445859","messageId":"pull.1108.v3.git.1641841193.gitgitgadget@gmail.com","threadId":"57165","inReplyTo":"pull.1108.v2.git.1640892413.gitgitgadget@gmail.com","subject":"[PATCH v3 0/3] sparse checkout: custom bash completion updates","fromName":"Lessley Dennington via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-01-10T18:59:49Z","receivedAt":"2022-01-10T18:59:59Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"This series is based on en/sparse-checkout-set. It updates custom tab\ncompletion for the sparse-checkout command. Specifically, it corrects the\nfollowing issues with the current method:\n\n 1. git sparse-checkout <TAB> results in an incomplete list of subcommands\n    (it is missing reapply and add).\n 2. git sparse-checkout --<TAB> does not complete the help option.\n 3. Options for subcommands are not tab-completable.\n 4. git sparse-checkout set <TAB> and git sparse-checkout add <TAB> show\n    both file names and directory names.\n\nThe first commit in this series is a set of failing tests that highlight\neach of the above issues. The next commit updates the _git_sparse_checkout\nmethod in git-completion.bash to enable each of these tests to pass. The\nfinal commit modifies the original implementation (which recursively printed\nprospective directories for completion) to only print directories at the\ncurrent level for improved performance.\n\n\nChanges since V2\n================\n\n * Change use of $prev to $subcommand in _git_sparse_checkout() method in\n   git-completion.bash.\n * State explicitly that directory completion applies in both cone and\n   non-cone mode in 'sparse-checkout: custom tab completion' commit\n * Add new patch with __gitcomp_directories method to improve performance by\n   only outputting directories at the current level.\n\n\nChanges since V1\n================\n\n * Rebase onto en/sparse-checkout-set.\n * Add subcommand options (including --no-cone) for set and reapply.\n * Extend 'sparse-checkout completes subcommand options' test to validate\n   new set/reapply subcommand options.\n * No longer set index.sparse to false in 'sparse-checkout completes\n   directory names' test.\n\nThanks, Lessley\n\nLessley Dennington (3):\n  sparse-checkout: custom tab completion tests\n  sparse-checkout: custom tab completion\n  sparse-checkout: limit tab completion to a single level\n\n contrib/completion/git-completion.bash | 68 +++++++++++++++----\n t/t9902-completion.sh                  | 94 ++++++++++++++++++++++++++\n 2 files changed, 150 insertions(+), 12 deletions(-)\n\n\nbase-commit: dfac9b609f86cd4f6ce896df9e1172d2a02cde48\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-1108%2Fldennington%2Fsparse-checkout-bash-completion-v3\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1108/ldennington/sparse-checkout-bash-completion-v3\nPull-Request: https://github.com/gitgitgadget/git/pull/1108\n\nRange-diff vs v2:\n\n 1:  955fcab0052 = 1:  bbc2d21e1d1 sparse-checkout: custom tab completion tests\n 2:  cecf501e076 ! 2:  256e5f034c6 sparse-checkout: custom tab completion\n     @@ Commit message\n          2. The --help option is tab-completable.\n          3. Subcommand options are tab-completable.\n          4. A list of directories (but not files) is provided when users enter git\n     -    sparse-checkout add <TAB> or git sparse-checkout set <TAB>.\n     +    sparse-checkout add <TAB> or git sparse-checkout set <TAB>. It is\n     +    important to note that this will apply for both cone mode and non-cone\n     +    mode (even though non-cone mode matches on patterns rather than\n     +    directories).\n      \n          Failing tests that were added in the previous commit to verify these\n          scenarios are now passing with these updates.\n     @@ contrib/completion/git-completion.bash: _git_show_branch ()\n      -\t\t;;\n      -\t*)\n      -\t\t;;\n     -+\tcase \"$prev\" in\n     ++\tcase \"$subcommand\" in\n      +\t\tset)\n      +\t\t\t__gitcomp \"$__git_sparse_checkout_subcommand_opts --stdin\"\n      +\t\t\t__gitcomp \"$(git ls-tree -d -r HEAD --name-only)\"\n -:  ----------- > 3:  aa9ea67180d sparse-checkout: limit tab completion to a single level\n\n-- \ngitgitgadget\n"},{"id":"445860","messageId":"256e5f034c6072b6e3621adfa96c5c6319752fae.1641841193.git.gitgitgadget@gmail.com","threadId":"57165","inReplyTo":"pull.1108.v3.git.1641841193.gitgitgadget@gmail.com","subject":"[PATCH v3 2/3] sparse-checkout: custom tab completion","fromName":"Lessley Dennington via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-01-10T18:59:51Z","receivedAt":"2022-01-10T19:00:00Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"From: Lessley Dennington <lessleydennington@gmail.com>\n\nFix custom tab completion for sparse-checkout command. This will ensure:\n\n1. The full list of subcommands is provided when users enter git\nsparse-checkout <TAB>.\n2. The --help option is tab-completable.\n3. Subcommand options are tab-completable.\n4. A list of directories (but not files) is provided when users enter git\nsparse-checkout add <TAB> or git sparse-checkout set <TAB>. It is\nimportant to note that this will apply for both cone mode and non-cone\nmode (even though non-cone mode matches on patterns rather than\ndirectories).\n\nFailing tests that were added in the previous commit to verify these\nscenarios are now passing with these updates.\n\nSigned-off-by: Lessley Dennington <lessleydennington@gmail.com>\n---\n contrib/completion/git-completion.bash | 38 ++++++++++++++++++--------\n t/t9902-completion.sh                  |  8 +++---\n 2 files changed, 30 insertions(+), 16 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex c82ccaebcc7..f478883f51c 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -2986,24 +2986,38 @@ _git_show_branch ()\n \t__git_complete_revlist\n }\n \n+__git_sparse_checkout_subcommand_opts=\"--cone --no-cone --sparse-index --no-sparse-index\"\n+\n _git_sparse_checkout ()\n {\n-\tlocal subcommands=\"list init set disable\"\n+\tlocal subcommands=\"list init set disable add reapply\"\n \tlocal subcommand=\"$(__git_find_on_cmdline \"$subcommands\")\"\n+\n \tif [ -z \"$subcommand\" ]; then\n-\t\t__gitcomp \"$subcommands\"\n-\t\treturn\n+\t\tcase \"$cur\" in\n+\t\t\t--*)\n+\t\t\t\t__gitcomp \"--help\"\n+\t\t\t\t;;\n+\t\t\t*)\n+\t\t\t\t__gitcomp \"$subcommands\"\n+\t\t\t\t;;\n+\t\tesac\n \tfi\n \n-\tcase \"$subcommand,$cur\" in\n-\tinit,--*)\n-\t\t__gitcomp \"--cone\"\n-\t\t;;\n-\tset,--*)\n-\t\t__gitcomp \"--stdin\"\n-\t\t;;\n-\t*)\n-\t\t;;\n+\tcase \"$subcommand\" in\n+\t\tset)\n+\t\t\t__gitcomp \"$__git_sparse_checkout_subcommand_opts --stdin\"\n+\t\t\t__gitcomp \"$(git ls-tree -d -r HEAD --name-only)\"\n+\t\t\t;;\n+\t\tadd)\n+\t\t\t__gitcomp \"--stdin\"\n+\t\t\t__gitcomp \"$(git ls-tree -d -r HEAD --name-only)\"\n+\t\t\t;;\n+\t\tinit|reapply)\n+\t\t\t__gitcomp \"$__git_sparse_checkout_subcommand_opts\"\n+\t\t\t;;\n+\t\t*)\n+\t\t\t;;\n \tesac\n }\n \ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex 51d0f2d93a1..4dc93ee0595 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -1447,7 +1447,7 @@ test_expect_success 'git checkout - with --detach, complete only references' '\n \tEOF\n '\n \n-test_expect_failure 'sparse-checkout completes subcommands' '\n+test_expect_success 'sparse-checkout completes subcommands' '\n \ttest_completion \"git sparse-checkout \" <<-\\EOF\n \tlist Z\n \tinit Z\n@@ -1458,13 +1458,13 @@ test_expect_failure 'sparse-checkout completes subcommands' '\n \tEOF\n '\n \n-test_expect_failure 'sparse-checkout completes options' '\n+test_expect_success 'sparse-checkout completes options' '\n \ttest_completion \"git sparse-checkout --\" <<-\\EOF\n \t--help Z\n \tEOF\n '\n \n-test_expect_failure 'sparse-checkout completes subcommand options' '\n+test_expect_success 'sparse-checkout completes subcommand options' '\n \ttest_completion \"git sparse-checkout init --\" <<-\\EOF &&\n \t--cone Z\n \t--no-cone Z\n@@ -1492,7 +1492,7 @@ test_expect_failure 'sparse-checkout completes subcommand options' '\n \tEOF\n '\n \n-test_expect_failure 'sparse-checkout completes directory names' '\n+test_expect_success 'sparse-checkout completes directory names' '\n \t# set up sparse-checkout repo\n \tgit init sparse-checkout &&\n \t(\n-- \ngitgitgadget\n\n"},{"id":"445861","messageId":"bbc2d21e1d19f968fcf70d681d50f52d2235b8fa.1641841193.git.gitgitgadget@gmail.com","threadId":"57165","inReplyTo":"pull.1108.v3.git.1641841193.gitgitgadget@gmail.com","subject":"[PATCH v3 1/3] sparse-checkout: custom tab completion tests","fromName":"Lessley Dennington via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-01-10T18:59:50Z","receivedAt":"2022-01-10T19:00:01Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"From: Lessley Dennington <lessleydennington@gmail.com>\n\nAdd tests for missing/incorrect components of custom tab completion for the\nsparse-checkout command. These tests specifically highlight the following:\n\n1. git sparse-checkout <TAB> results in an incomplete list of subcommands\n(it is missing reapply and add).\n2. git sparse-checkout --<TAB> does not complete the help option.\n3. Options for subcommands are not tab-completable.\n4. git sparse-checkout set <TAB> and git sparse-checkout add <TAB> show\nboth file names and directory names.\n\nAlthough these tests currently fail, they will succeed with the\nsparse-checkout modifications in git-completion.bash in the next commit in\nthis series.\n\nSigned-off-by: Lessley Dennington <lessleydennington@gmail.com>\n---\n t/t9902-completion.sh | 85 +++++++++++++++++++++++++++++++++++++++++++\n 1 file changed, 85 insertions(+)\n\ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex 518203fbe07..51d0f2d93a1 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -1447,6 +1447,91 @@ test_expect_success 'git checkout - with --detach, complete only references' '\n \tEOF\n '\n \n+test_expect_failure 'sparse-checkout completes subcommands' '\n+\ttest_completion \"git sparse-checkout \" <<-\\EOF\n+\tlist Z\n+\tinit Z\n+\tset Z\n+\tadd Z\n+\treapply Z\n+\tdisable Z\n+\tEOF\n+'\n+\n+test_expect_failure 'sparse-checkout completes options' '\n+\ttest_completion \"git sparse-checkout --\" <<-\\EOF\n+\t--help Z\n+\tEOF\n+'\n+\n+test_expect_failure 'sparse-checkout completes subcommand options' '\n+\ttest_completion \"git sparse-checkout init --\" <<-\\EOF &&\n+\t--cone Z\n+\t--no-cone Z\n+\t--sparse-index Z\n+\t--no-sparse-index Z\n+\tEOF\n+\n+\ttest_completion \"git sparse-checkout set --\" <<-\\EOF &&\n+\t--cone Z\n+\t--no-cone Z\n+\t--sparse-index Z\n+\t--no-sparse-index Z\n+\t--stdin Z\n+\tEOF\n+\n+\ttest_completion \"git sparse-checkout reapply --\" <<-\\EOF &&\n+\t--cone Z\n+\t--no-cone Z\n+\t--sparse-index Z\n+\t--no-sparse-index Z\n+\tEOF\n+\n+\ttest_completion \"git sparse-checkout add --\" <<-\\EOF\n+\t--stdin Z\n+\tEOF\n+'\n+\n+test_expect_failure 'sparse-checkout completes directory names' '\n+\t# set up sparse-checkout repo\n+\tgit init sparse-checkout &&\n+\t(\n+\t\tcd sparse-checkout &&\n+\t\tmkdir -p folder1/0/1 folder2/0 folder3 &&\n+\t\ttouch folder1/0/1/t.txt &&\n+\t\ttouch folder2/0/t.txt &&\n+\t\ttouch folder3/t.txt &&\n+\t\tgit add . &&\n+\t\tgit commit -am \"Initial commit\"\n+\t) &&\n+\n+\t# initialize sparse-checkout definitions\n+\tgit -C sparse-checkout sparse-checkout init --cone &&\n+\tgit -C sparse-checkout sparse-checkout set folder1/0 folder3 &&\n+\n+\t# test tab completion\n+\t(\n+\t\tcd sparse-checkout &&\n+\t\ttest_completion \"git sparse-checkout set f\" <<-\\EOF\n+\t\tfolder1 Z\n+\t\tfolder1/0 Z\n+\t\tfolder1/0/1 Z\n+\t\tfolder2 Z\n+\t\tfolder2/0 Z\n+\t\tfolder3 Z\n+\t\tEOF\n+\t) &&\n+\n+\t(\n+\t\tcd sparse-checkout/folder1 &&\n+\t\ttest_completion \"git sparse-checkout add \" <<-\\EOF\n+\t\t./ Z\n+\t\t0 Z\n+\t\t0/1 Z\n+\t\tEOF\n+\t)\n+'\n+\n test_expect_success 'git switch - with -d, complete all references' '\n \ttest_completion \"git switch -d \" <<-\\EOF\n \tHEAD Z\n-- \ngitgitgadget\n\n"},{"id":"445862","messageId":"aa9ea67180dd10ef8bdf17e8c23694da15828b21.1641841193.git.gitgitgadget@gmail.com","threadId":"57165","inReplyTo":"pull.1108.v3.git.1641841193.gitgitgadget@gmail.com","subject":"[PATCH v3 3/3] sparse-checkout: limit tab completion to a single level","fromName":"Lessley Dennington via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-01-10T18:59:52Z","receivedAt":"2022-01-10T19:00:03Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"From: Lessley Dennington <lessleydennington@gmail.com>\n\nEnsure only directories at the current level will be tab-completed with\nthe sparse-checkout command. For example, if paths a/b/c/ and a/d/ exist\nin the current directory, running a/<TAB> will result in:\n\n        a/b/\n        a/d/\n\nThe 'sparse-checkout completes directory names' test has also been\nupdated/extended according to these changes.\n\nCo-authored-by: Elijah Newren <newren@gmail.com>\nCo-authored-by: Lessley Dennington <lessleydennington@gmail.com>\nSigned-off-by: Lessley Dennington <lessleydennington@gmail.com>\n---\n contrib/completion/git-completion.bash | 34 ++++++++++++++++++++++++--\n t/t9902-completion.sh                  | 29 ++++++++++++++--------\n 2 files changed, 51 insertions(+), 12 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex f478883f51c..21875d08d03 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -2986,6 +2986,36 @@ _git_show_branch ()\n \t__git_complete_revlist\n }\n \n+__gitcomp_directories ()\n+{\n+     local _tmp_dir _tmp_completions\n+\n+     # Get the directory of the current token; this differs from dirname\n+     # in that it keeps up to the final trailing slash.  If no slash found\n+     # that's fine too.\n+     [[ \"$cur\" =~ .*/ ]]\n+     _tmp_dir=$BASH_REMATCH\n+\n+     # Find possible directory completions, adding trailing '/' characters\n+     _tmp_completions=\"$(git ls-tree -d --name-only HEAD $_tmp_dir |\n+         sed -e s%$%/%)\"\n+\n+     if [[ -n \"$_tmp_completions\" ]]; then\n+         # There were some directory completions, so find ones that\n+         # start with \"$cur\", the current token, and put those in COMPREPLY\n+         local i=0 c IFS=$' \\t\\n'\n+         for c in $_tmp_completions; do\n+             if [[ $c == \"$cur\"* ]]; then\n+                 COMPREPLY+=(\"$c\")\n+             fi\n+         done\n+     elif [[ \"$cur\" =~ /$ ]]; then\n+         # No possible further completions any deeper, so assume we're at\n+         # a leaf directory and just consider it complete\n+         __gitcomp_direct_append \"$cur \"\n+     fi\n+}\n+\n __git_sparse_checkout_subcommand_opts=\"--cone --no-cone --sparse-index --no-sparse-index\"\n \n _git_sparse_checkout ()\n@@ -3007,11 +3037,11 @@ _git_sparse_checkout ()\n \tcase \"$subcommand\" in\n \t\tset)\n \t\t\t__gitcomp \"$__git_sparse_checkout_subcommand_opts --stdin\"\n-\t\t\t__gitcomp \"$(git ls-tree -d -r HEAD --name-only)\"\n+\t\t\t__gitcomp_directories\n \t\t\t;;\n \t\tadd)\n \t\t\t__gitcomp \"--stdin\"\n-\t\t\t__gitcomp \"$(git ls-tree -d -r HEAD --name-only)\"\n+\t\t\t__gitcomp_directories\n \t\t\t;;\n \t\tinit|reapply)\n \t\t\t__gitcomp \"$__git_sparse_checkout_subcommand_opts\"\ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex 4dc93ee0595..e11ff0c2efe 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -1513,21 +1513,30 @@ test_expect_success 'sparse-checkout completes directory names' '\n \t(\n \t\tcd sparse-checkout &&\n \t\ttest_completion \"git sparse-checkout set f\" <<-\\EOF\n-\t\tfolder1 Z\n-\t\tfolder1/0 Z\n-\t\tfolder1/0/1 Z\n-\t\tfolder2 Z\n-\t\tfolder2/0 Z\n-\t\tfolder3 Z\n+\t\tfolder1/\n+\t\tfolder2/\n+\t\tfolder3/\n+\t\tEOF\n+\t) &&\n+\n+\t(\n+\t\tcd sparse-checkout &&\n+\t\ttest_completion \"git sparse-checkout set folder1/\" <<-\\EOF\n+\t\tfolder1/0/\n+\t\tEOF\n+\t) &&\n+\n+\t(\n+\t\tcd sparse-checkout &&\n+\t\ttest_completion \"git sparse-checkout set folder1/0/\" <<-\\EOF\n+\t\tfolder1/0/1/\n \t\tEOF\n \t) &&\n \n \t(\n \t\tcd sparse-checkout/folder1 &&\n-\t\ttest_completion \"git sparse-checkout add \" <<-\\EOF\n-\t\t./ Z\n-\t\t0 Z\n-\t\t0/1 Z\n+\t\ttest_completion \"git sparse-checkout add 0\" <<-\\EOF\n+\t\t0/\n \t\tEOF\n \t)\n '\n-- \ngitgitgadget\n"},{"id":"445876","messageId":"CABPp-BG=wr81CPtW1M12xFN_0dyS8mAZjM6o=77LA20Zge8Xng@mail.gmail.com","threadId":"57165","inReplyTo":"pull.1108.v3.git.1641841193.gitgitgadget@gmail.com","subject":"Re: [PATCH v3 0/3] sparse checkout: custom bash completion updates","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2022-01-10T20:38:53Z","receivedAt":"2022-01-10T20:39:07Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Mon, Jan 10, 2022 at 10:59 AM Lessley Dennington via GitGitGadget\n<gitgitgadget@gmail.com> wrote:\n>\n> This series is based on en/sparse-checkout-set. It updates custom tab\n> completion for the sparse-checkout command. Specifically, it corrects the\n> following issues with the current method:\n>\n>  1. git sparse-checkout <TAB> results in an incomplete list of subcommands\n>     (it is missing reapply and add).\n>  2. git sparse-checkout --<TAB> does not complete the help option.\n>  3. Options for subcommands are not tab-completable.\n>  4. git sparse-checkout set <TAB> and git sparse-checkout add <TAB> show\n>     both file names and directory names.\n>\n> The first commit in this series is a set of failing tests that highlight\n> each of the above issues. The next commit updates the _git_sparse_checkout\n> method in git-completion.bash to enable each of these tests to pass. The\n> final commit modifies the original implementation (which recursively printed\n> prospective directories for completion) to only print directories at the\n> current level for improved performance.\n>\n>\n> Changes since V2\n> ================\n>\n>  * Change use of $prev to $subcommand in _git_sparse_checkout() method in\n>    git-completion.bash.\n>  * State explicitly that directory completion applies in both cone and\n>    non-cone mode in 'sparse-checkout: custom tab completion' commit\n>  * Add new patch with __gitcomp_directories method to improve performance by\n>    only outputting directories at the current level.\n>\n>\n> Changes since V1\n> ================\n>\n>  * Rebase onto en/sparse-checkout-set.\n>  * Add subcommand options (including --no-cone) for set and reapply.\n>  * Extend 'sparse-checkout completes subcommand options' test to validate\n>    new set/reapply subcommand options.\n>  * No longer set index.sparse to false in 'sparse-checkout completes\n>    directory names' test.\n>\n> Thanks, Lessley\n>\n> Lessley Dennington (3):\n>   sparse-checkout: custom tab completion tests\n>   sparse-checkout: custom tab completion\n>   sparse-checkout: limit tab completion to a single level\n>\n>  contrib/completion/git-completion.bash | 68 +++++++++++++++----\n>  t/t9902-completion.sh                  | 94 ++++++++++++++++++++++++++\n>  2 files changed, 150 insertions(+), 12 deletions(-)\n>\n>\n> base-commit: dfac9b609f86cd4f6ce896df9e1172d2a02cde48\n> Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1108%2Fldennington%2Fsparse-checkout-bash-completion-v3\n> Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1108/ldennington/sparse-checkout-bash-completion-v3\n> Pull-Request: https://github.com/gitgitgadget/git/pull/1108\n>\n> Range-diff vs v2:\n>\n>  1:  955fcab0052 = 1:  bbc2d21e1d1 sparse-checkout: custom tab completion tests\n>  2:  cecf501e076 ! 2:  256e5f034c6 sparse-checkout: custom tab completion\n>      @@ Commit message\n>           2. The --help option is tab-completable.\n>           3. Subcommand options are tab-completable.\n>           4. A list of directories (but not files) is provided when users enter git\n>      -    sparse-checkout add <TAB> or git sparse-checkout set <TAB>.\n>      +    sparse-checkout add <TAB> or git sparse-checkout set <TAB>. It is\n>      +    important to note that this will apply for both cone mode and non-cone\n>      +    mode (even though non-cone mode matches on patterns rather than\n>      +    directories).\n\nI would instead phrase this as \"(even though non-cone mode can match\ngeneral gitignore patterns rather than just directories)\".\n\nThe basic idea behind the rewording is that I want to highlight that\nthe completions we provide are still valid in non-cone mode, they just\naren't comprehensive.  Since there's no way to provide a comprehensive\nlist of possible patterns for non-cone mode, I think what we are\nchoosing to provide is a pretty reasonable choice.\n\n>\n>           Failing tests that were added in the previous commit to verify these\n>           scenarios are now passing with these updates.\n>      @@ contrib/completion/git-completion.bash: _git_show_branch ()\n>       -         ;;\n>       - *)\n>       -         ;;\n>      -+ case \"$prev\" in\n>      ++ case \"$subcommand\" in\n>       +         set)\n>       +                 __gitcomp \"$__git_sparse_checkout_subcommand_opts --stdin\"\n>       +                 __gitcomp \"$(git ls-tree -d -r HEAD --name-only)\"\n>  -:  ----------- > 3:  aa9ea67180d sparse-checkout: limit tab completion to a single level\n\nOther than that one nit, patches 1-2 (and the testcases in patch 3) are:\n\nReviewed-by: Elijah Newren <newren@gmail.com>\n\nSince I wrote the new __gitcomp() function in patch 3, it might be\nnice if we can find another reviewer for it. Especially since I've\nonly lightly touched the completion code and there might be better\nways of achieving what I wrote there.\n"},{"id":"445933","messageId":"92913af3-7985-0789-eee0-c84601d2a31f@gmail.com","threadId":"57165","inReplyTo":"CABPp-BG=wr81CPtW1M12xFN_0dyS8mAZjM6o=77LA20Zge8Xng@mail.gmail.com","subject":"Re: [PATCH v3 0/3] sparse checkout: custom bash completion updates","fromName":"Lessley Dennington","fromEmail":"lessleydennington@gmail.com","sentAt":"2022-01-11T17:17:38Z","receivedAt":"2022-01-11T17:19:21Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"\n\nOn 1/10/22 2:38 PM, Elijah Newren wrote:\n> On Mon, Jan 10, 2022 at 10:59 AM Lessley Dennington via GitGitGadget\n> <gitgitgadget@gmail.com> wrote:\n>>\n>> This series is based on en/sparse-checkout-set. It updates custom tab\n>> completion for the sparse-checkout command. Specifically, it corrects the\n>> following issues with the current method:\n>>\n>>   1. git sparse-checkout <TAB> results in an incomplete list of subcommands\n>>      (it is missing reapply and add).\n>>   2. git sparse-checkout --<TAB> does not complete the help option.\n>>   3. Options for subcommands are not tab-completable.\n>>   4. git sparse-checkout set <TAB> and git sparse-checkout add <TAB> show\n>>      both file names and directory names.\n>>\n>> The first commit in this series is a set of failing tests that highlight\n>> each of the above issues. The next commit updates the _git_sparse_checkout\n>> method in git-completion.bash to enable each of these tests to pass. The\n>> final commit modifies the original implementation (which recursively printed\n>> prospective directories for completion) to only print directories at the\n>> current level for improved performance.\n>>\n>>\n>> Changes since V2\n>> ================\n>>\n>>   * Change use of $prev to $subcommand in _git_sparse_checkout() method in\n>>     git-completion.bash.\n>>   * State explicitly that directory completion applies in both cone and\n>>     non-cone mode in 'sparse-checkout: custom tab completion' commit\n>>   * Add new patch with __gitcomp_directories method to improve performance by\n>>     only outputting directories at the current level.\n>>\n>>\n>> Changes since V1\n>> ================\n>>\n>>   * Rebase onto en/sparse-checkout-set.\n>>   * Add subcommand options (including --no-cone) for set and reapply.\n>>   * Extend 'sparse-checkout completes subcommand options' test to validate\n>>     new set/reapply subcommand options.\n>>   * No longer set index.sparse to false in 'sparse-checkout completes\n>>     directory names' test.\n>>\n>> Thanks, Lessley\n>>\n>> Lessley Dennington (3):\n>>    sparse-checkout: custom tab completion tests\n>>    sparse-checkout: custom tab completion\n>>    sparse-checkout: limit tab completion to a single level\n>>\n>>   contrib/completion/git-completion.bash | 68 +++++++++++++++----\n>>   t/t9902-completion.sh                  | 94 ++++++++++++++++++++++++++\n>>   2 files changed, 150 insertions(+), 12 deletions(-)\n>>\n>>\n>> base-commit: dfac9b609f86cd4f6ce896df9e1172d2a02cde48\n>> Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1108%2Fldennington%2Fsparse-checkout-bash-completion-v3\n>> Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1108/ldennington/sparse-checkout-bash-completion-v3\n>> Pull-Request: https://github.com/gitgitgadget/git/pull/1108\n>>\n>> Range-diff vs v2:\n>>\n>>   1:  955fcab0052 = 1:  bbc2d21e1d1 sparse-checkout: custom tab completion tests\n>>   2:  cecf501e076 ! 2:  256e5f034c6 sparse-checkout: custom tab completion\n>>       @@ Commit message\n>>            2. The --help option is tab-completable.\n>>            3. Subcommand options are tab-completable.\n>>            4. A list of directories (but not files) is provided when users enter git\n>>       -    sparse-checkout add <TAB> or git sparse-checkout set <TAB>.\n>>       +    sparse-checkout add <TAB> or git sparse-checkout set <TAB>. It is\n>>       +    important to note that this will apply for both cone mode and non-cone\n>>       +    mode (even though non-cone mode matches on patterns rather than\n>>       +    directories).\n> \n> I would instead phrase this as \"(even though non-cone mode can match\n> general gitignore patterns rather than just directories)\".\n> \n> The basic idea behind the rewording is that I want to highlight that\n> the completions we provide are still valid in non-cone mode, they just\n> aren't comprehensive.  Since there's no way to provide a comprehensive\n> list of possible patterns for non-cone mode, I think what we are\n> choosing to provide is a pretty reasonable choice.\n> \nThank you! That is much better wording. Will update in v4 along with any\nfeedback I get on your function (see below).\n>>\n>>            Failing tests that were added in the previous commit to verify these\n>>            scenarios are now passing with these updates.\n>>       @@ contrib/completion/git-completion.bash: _git_show_branch ()\n>>        -         ;;\n>>        - *)\n>>        -         ;;\n>>       -+ case \"$prev\" in\n>>       ++ case \"$subcommand\" in\n>>        +         set)\n>>        +                 __gitcomp \"$__git_sparse_checkout_subcommand_opts --stdin\"\n>>        +                 __gitcomp \"$(git ls-tree -d -r HEAD --name-only)\"\n>>   -:  ----------- > 3:  aa9ea67180d sparse-checkout: limit tab completion to a single level\n> \n> Other than that one nit, patches 1-2 (and the testcases in patch 3) are:\n> \n> Reviewed-by: Elijah Newren <newren@gmail.com>\n> \n> Since I wrote the new __gitcomp() function in patch 3, it might be\n> nice if we can find another reviewer for it. Especially since I've\n> only lightly touched the completion code and there might be better\n> ways of achieving what I wrote there.\nI agree - I'll chat with some folks today to try to find the best person\nto take a look.\n"},{"id":"445960","messageId":"Yd3eXHzEG7nJi8ZB@nand.local","threadId":"57165","inReplyTo":"92913af3-7985-0789-eee0-c84601d2a31f@gmail.com","subject":"Re: [PATCH v3 0/3] sparse checkout: custom bash completion updates","fromName":"Taylor Blau","fromEmail":"me@ttaylorr.com","sentAt":"2022-01-11T19:45:32Z","receivedAt":"2022-01-11T19:45:35Z","isPatch":true,"sender":{"key":"me@ttaylorr.com","avatar":"https://avatars.githubusercontent.com/u/301000140?v=4"},"body":"On Tue, Jan 11, 2022 at 09:17:38AM -0800, Lessley Dennington wrote:\n> On 1/10/22 2:38 PM, Elijah Newren wrote:\n> > Other than that one nit, patches 1-2 (and the testcases in patch 3) are:\n> >\n> > Reviewed-by: Elijah Newren <newren@gmail.com>\n> >\n> > Since I wrote the new __gitcomp() function in patch 3, it might be\n> > nice if we can find another reviewer for it. Especially since I've\n> > only lightly touched the completion code and there might be better\n> > ways of achieving what I wrote there.\n>\n> I agree - I'll chat with some folks today to try to find the best person\n> to take a look.\n\nHaving another set of eyes on this code never hurts, but looking through\nthis file's shortlog (especially with `--since=1.year.ago`), I'm not\nsure how many active reviewers in this area we still have.\n\nPerhaps the best thing to do would be to grow some new area experts here\ninstead. If I were in Lessley's shoes, I would \"think aloud\" to make\nsure I agreed with your implementation for the new `__gitcomp()`\nfunction.\n\nIf other reviewers happen to be around (perhaps Denton, who I added to\nthe CC) that doesn't hurt either, but short of that...\n\n\nThanks,\nTaylor\n"},{"id":"446046","messageId":"b4a8fb17-ff20-aac9-73bf-54d872fb67b1@gmail.com","threadId":"57165","inReplyTo":"Yd3eXHzEG7nJi8ZB@nand.local","subject":"Re: [PATCH v3 0/3] sparse checkout: custom bash completion updates","fromName":"Lessley Dennington","fromEmail":"lessleydennington@gmail.com","sentAt":"2022-01-12T18:35:12Z","receivedAt":"2022-01-12T18:35:19Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"\n\nOn 1/11/22 1:45 PM, Taylor Blau wrote:\n> On Tue, Jan 11, 2022 at 09:17:38AM -0800, Lessley Dennington wrote:\n>> On 1/10/22 2:38 PM, Elijah Newren wrote:\n>>> Other than that one nit, patches 1-2 (and the testcases in patch 3) are:\n>>>\n>>> Reviewed-by: Elijah Newren <newren@gmail.com>\n>>>\n>>> Since I wrote the new __gitcomp() function in patch 3, it might be\n>>> nice if we can find another reviewer for it. Especially since I've\n>>> only lightly touched the completion code and there might be better\n>>> ways of achieving what I wrote there.\n>>\n>> I agree - I'll chat with some folks today to try to find the best person\n>> to take a look.\n> \n> Having another set of eyes on this code never hurts, but looking through\n> this file's shortlog (especially with `--since=1.year.ago`), I'm not\n> sure how many active reviewers in this area we still have.\n> \n> Perhaps the best thing to do would be to grow some new area experts here\n> instead. If I were in Lessley's shoes, I would \"think aloud\" to make\n> sure I agreed with your implementation for the new `__gitcomp()`\n> function.\n> \n> If other reviewers happen to be around (perhaps Denton, who I added to\n> the CC) that doesn't hurt either, but short of that...\n> \n> \n> Thanks,\n> Taylor\n\nThanks for the help here, Taylor! I like this suggestion and will add my\nthoughts to Elijah's __gitcomp_directories function.\n"},{"id":"446073","messageId":"0e4bb6f1-337e-38b3-75b2-fe11ff8d68b2@gmail.com","threadId":"57165","inReplyTo":"aa9ea67180dd10ef8bdf17e8c23694da15828b21.1641841193.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v3 3/3] sparse-checkout: limit tab completion to a single level","fromName":"Lessley Dennington","fromEmail":"lessleydennington@gmail.com","sentAt":"2022-01-12T23:43:26Z","receivedAt":"2022-01-12T23:43:32Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"> +__gitcomp_directories ()\n> +{\n> +     local _tmp_dir _tmp_completions\n> +\n> +     # Get the directory of the current token; this differs from dirname\n> +     # in that it keeps up to the final trailing slash.  If no slash found\n> +     # that's fine too.\n> +     [[ \"$cur\" =~ .*/ ]]\n> +     _tmp_dir=$BASH_REMATCH\n> +\n> +     # Find possible directory completions, adding trailing '/' characters\n> +     _tmp_completions=\"$(git ls-tree -d --name-only HEAD $_tmp_dir |\n> +         sed -e s%$%/%)\"\n> +\nI am admittedly unfamiliar with the use of this format in sed expressions\n(I'm generally more accustomed to '/' instead of '%'). It's definitely\nworking as it should, I'm just not quite sure of how.\n> +     if [[ -n \"$_tmp_completions\" ]]; then\n> +         # There were some directory completions, so find ones that\n> +         # start with \"$cur\", the current token, and put those in COMPREPLY\n> +         local i=0 c IFS=$' \\t\\n'\nDoes c need to be declared before the loop?\n> +         for c in $_tmp_completions; do\n> +             if [[ $c == \"$cur\"* ]]; then\n> +                 COMPREPLY+=(\"$c\")\n> +             fi\n> +         done\n> +     elif [[ \"$cur\" =~ /$ ]]; then\n> +         # No possible further completions any deeper, so assume we're at\n> +         # a leaf directory and just consider it complete\nThank you so much for the detailed comments on this change - it made it\nreally easy to parse.\n> +         __gitcomp_direct_append \"$cur \"\nWhat's the reason for the trailing space here?\n> +     fi\n> +}\n\nAdded my review as mentioned in [1].\n\n[1]: \nhttps://lore.kernel.org/git/pull.1108.v2.git.1640892413.gitgitgadget@gmail.com/T/#md3da435452988b0366ab4c2ee4bc06df2d17cb36\n"},{"id":"446075","messageId":"xmqq35lsld25.fsf@gitster.g","threadId":"57165","inReplyTo":"0e4bb6f1-337e-38b3-75b2-fe11ff8d68b2@gmail.com","subject":"Re: [PATCH v3 3/3] sparse-checkout: limit tab completion to a single level","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-01-13T00:00:34Z","receivedAt":"2022-01-13T00:00:44Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Lessley Dennington <lessleydennington@gmail.com> writes:\n\n>> +     # Find possible directory completions, adding trailing '/' characters\n>> +     _tmp_completions=\"$(git ls-tree -d --name-only HEAD $_tmp_dir |\n>> +         sed -e s%$%/%)\"\n>> +\n> I am admittedly unfamiliar with the use of this format in sed expressions\n> (I'm generally more accustomed to '/' instead of '%'). It's definitely\n> working as it should, I'm just not quite sure of how.\n\nThe substitution operator \"s\" in \"sed\" can take any letter as the\nmatch-replacement delimiter.  People use 's/match/replacement/'\nusually because that is how textbooks teach them, but whatever\nletter chosen as the delimiter, if it appears in either match or\nreplacement, it needs to be quoted, i.e. 's/match/replace\\/ment/'.\n\nUsing a delimiter letter other than '/' relieves you from having to\nquote a slash when slash is part of match-replacement.  Even though\nit is more common to use a letter that is a more clearly delimiter\nlooking, e.g. \"s|match|replace/ment|\", it is not a crime to use\nletters like '%' and '#', or even 's' ;-)\n\n>> +     if [[ -n \"$_tmp_completions\" ]]; then\n>> +         # There were some directory completions, so find ones that\n>> +         # start with \"$cur\", the current token, and put those in COMPREPLY\n>> +         local i=0 c IFS=$' \\t\\n'\n> Does c need to be declared before the loop?\n>> +         for c in $_tmp_completions; do\n\nbash completion script runs in the same namespace as the end-user's\ninteractive session, so we MUST be careful not to contaminate the\nnamespace or clobber variable the end-user is using.  \"local c\" before\nwe use $c for our own use is a way to make sure that when this function\nthat says \"local c\" is left, the value (or non-presence) of \"c\" is\nrestored to its original value before this function was entered.\n\n"},{"id":"446077","messageId":"CABPp-BEvUCPzcWhuVP==Rk=2pJXxRSGZVjdEzPuzbwTcw7kMRQ@mail.gmail.com","threadId":"57165","inReplyTo":"0e4bb6f1-337e-38b3-75b2-fe11ff8d68b2@gmail.com","subject":"Re: [PATCH v3 3/3] sparse-checkout: limit tab completion to a single level","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2022-01-13T00:38:34Z","receivedAt":"2022-01-13T00:38:49Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Wed, Jan 12, 2022 at 3:43 PM Lessley Dennington\n<lessleydennington@gmail.com> wrote:\n>\n> > +__gitcomp_directories ()\n> > +{\n> > +     local _tmp_dir _tmp_completions\n> > +\n> > +     # Get the directory of the current token; this differs from dirname\n> > +     # in that it keeps up to the final trailing slash.  If no slash found\n> > +     # that's fine too.\n> > +     [[ \"$cur\" =~ .*/ ]]\n> > +     _tmp_dir=$BASH_REMATCH\n> > +\n> > +     # Find possible directory completions, adding trailing '/' characters\n> > +     _tmp_completions=\"$(git ls-tree -d --name-only HEAD $_tmp_dir |\n> > +         sed -e s%$%/%)\"\n> > +\n> I am admittedly unfamiliar with the use of this format in sed expressions\n> (I'm generally more accustomed to '/' instead of '%'). It's definitely\n> working as it should, I'm just not quite sure of how.\n\nThese are the same in sed:\n   sed -e s/apple/banana/\n   sed -e s@apple@banana@\n   sed -e s%apple%banana%\n\nYou can pick any character you like, but '/' is what people most often\nuse.  My expression involved a '/', though, so I changed the delimiter\nto avoid ugly backslash escapes.\n\n> > +     if [[ -n \"$_tmp_completions\" ]]; then\n> > +         # There were some directory completions, so find ones that\n> > +         # start with \"$cur\", the current token, and put those in COMPREPLY\n> > +         local i=0 c IFS=$' \\t\\n'\n> Does c need to be declared before the loop?\n\nIt was, but it's super easy to miss.  Look at the \"local\" line just\nbefore your comment; it almost reads like line noise, but basically\nthere are three variables declared with two of them given initial\nvalues.  c is in the middle, without an initial value.\n\n> > +         for c in $_tmp_completions; do\n> > +             if [[ $c == \"$cur\"* ]]; then\n> > +                 COMPREPLY+=(\"$c\")\n> > +             fi\n> > +         done\n> > +     elif [[ \"$cur\" =~ /$ ]]; then\n> > +         # No possible further completions any deeper, so assume we're at\n> > +         # a leaf directory and just consider it complete\n> Thank you so much for the detailed comments on this change - it made it\n> really easy to parse.\n> > +         __gitcomp_direct_append \"$cur \"\n> What's the reason for the trailing space here?\n\nThe space was related to the \"just consider it complete\" aspect of the\ncomment above.  Anyway, to understand why the space character signals\nthe completion being final for this token, let's use some comparisons\nwith bash-completion of just a plain 'ls' command...\n\nIn git.git, at the toplevel, if I type\n  ls README.md <TAB>\n(note the space after README.md before pressing <TAB>), then\ncompletion assumes I'm trying to get another term besides just\nREADME.md, and can complete on anything in the directory.  In\ncontrast, if I type\n   ls README.md<TAB>\n(with no space between README.md and <TAB>), then completion figures\nI'm trying to find filenames that start with \"README.md\", finds only\none, and returns \"README.md \" (note the trailing space).  That\ntrailing space makes my command line become \"ls README.md \" (again,\nwith a trailing space), so that if I try to do any more tab\ncompletions, it's for adding another argument to the ls command, not\nextending the README.md one.\n\nYou can see similar things with ls and directories.  For example, if you type\n  ls Doc<TAB>tec<TAB>m<TAB>\n\nthen you'll note after the first <TAB> you'll see\n  ls Documentation/\nwith no trailing space; after the second <TAB> you'll see\n  ls Documentation/technical/\nwith no trailing space; and after the third <TAB> you'll see\n  ls Documentation/technical/multi-pack-index.txt\nWITH a trailing space.  In the first two cases, further completions\nwere possible so they didn't add a trailing space to signify the\ncompletion was final, but in the third case it is final and needed the\ntrailing space to denote that.\n\nDoes that help?\n\n> > +     fi\n> > +}\n>\n> Added my review as mentioned in [1].\n>\n> [1]:\n> https://lore.kernel.org/git/pull.1108.v2.git.1640892413.gitgitgadget@gmail.com/T/#md3da435452988b0366ab4c2ee4bc06df2d17cb36\n"},{"id":"446176","messageId":"92368b84-1d82-b594-9232-e67abcffe18a@gmail.com","threadId":"57165","inReplyTo":"CABPp-BEvUCPzcWhuVP==Rk=2pJXxRSGZVjdEzPuzbwTcw7kMRQ@mail.gmail.com","subject":"Re: [PATCH v3 3/3] sparse-checkout: limit tab completion to a single level","fromName":"Lessley Dennington","fromEmail":"lessleydennington@gmail.com","sentAt":"2022-01-13T19:02:37Z","receivedAt":"2022-01-13T19:02:40Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"\n\nOn 1/12/22 6:38 PM, Elijah Newren wrote:\n> On Wed, Jan 12, 2022 at 3:43 PM Lessley Dennington\n> <lessleydennington@gmail.com> wrote:\n>>\n>>> +__gitcomp_directories ()\n>>> +{\n>>> +     local _tmp_dir _tmp_completions\n>>> +\n>>> +     # Get the directory of the current token; this differs from dirname\n>>> +     # in that it keeps up to the final trailing slash.  If no slash found\n>>> +     # that's fine too.\n>>> +     [[ \"$cur\" =~ .*/ ]]\n>>> +     _tmp_dir=$BASH_REMATCH\n>>> +\n>>> +     # Find possible directory completions, adding trailing '/' characters\n>>> +     _tmp_completions=\"$(git ls-tree -d --name-only HEAD $_tmp_dir |\n>>> +         sed -e s%$%/%)\"\n>>> +\n>> I am admittedly unfamiliar with the use of this format in sed expressions\n>> (I'm generally more accustomed to '/' instead of '%'). It's definitely\n>> working as it should, I'm just not quite sure of how.\n> \n> These are the same in sed:\n>     sed -e s/apple/banana/\n>     sed -e s@apple@banana@\n>     sed -e s%apple%banana%\n> \n> You can pick any character you like, but '/' is what people most often\n> use.  My expression involved a '/', though, so I changed the delimiter\n> to avoid ugly backslash escapes.\n> \nGot it, thanks!\n>>> +     if [[ -n \"$_tmp_completions\" ]]; then\n>>> +         # There were some directory completions, so find ones that\n>>> +         # start with \"$cur\", the current token, and put those in COMPREPLY\n>>> +         local i=0 c IFS=$' \\t\\n'\n>> Does c need to be declared before the loop?\n> \n> It was, but it's super easy to miss.  Look at the \"local\" line just\n> before your comment; it almost reads like line noise, but basically\n> there are three variables declared with two of them given initial\n> values.  c is in the middle, without an initial value.\n> \nSorry, I should have made my question clearer - I saw that c is declared\nbefore the loop but was wondering if that was actually necessary. I\nremoved it locally and ran the tests, which seemed to work without it.\n>>> +         for c in $_tmp_completions; do\n>>> +             if [[ $c == \"$cur\"* ]]; then\n>>> +                 COMPREPLY+=(\"$c\")\n>>> +             fi\n>>> +         done\n>>> +     elif [[ \"$cur\" =~ /$ ]]; then\n>>> +         # No possible further completions any deeper, so assume we're at\n>>> +         # a leaf directory and just consider it complete\n>> Thank you so much for the detailed comments on this change - it made it\n>> really easy to parse.\n>>> +         __gitcomp_direct_append \"$cur \"\n>> What's the reason for the trailing space here?\n> \n> The space was related to the \"just consider it complete\" aspect of the\n> comment above.  Anyway, to understand why the space character signals\n> the completion being final for this token, let's use some comparisons\n> with bash-completion of just a plain 'ls' command...\n> \n> In git.git, at the toplevel, if I type\n>    ls README.md <TAB>\n> (note the space after README.md before pressing <TAB>), then\n> completion assumes I'm trying to get another term besides just\n> README.md, and can complete on anything in the directory.  In\n> contrast, if I type\n>     ls README.md<TAB>\n> (with no space between README.md and <TAB>), then completion figures\n> I'm trying to find filenames that start with \"README.md\", finds only\n> one, and returns \"README.md \" (note the trailing space).  That\n> trailing space makes my command line become \"ls README.md \" (again,\n> with a trailing space), so that if I try to do any more tab\n> completions, it's for adding another argument to the ls command, not\n> extending the README.md one.\n> \n> You can see similar things with ls and directories.  For example, if you type\n>    ls Doc<TAB>tec<TAB>m<TAB>\n> \n> then you'll note after the first <TAB> you'll see\n>    ls Documentation/\n> with no trailing space; after the second <TAB> you'll see\n>    ls Documentation/technical/\n> with no trailing space; and after the third <TAB> you'll see\n>    ls Documentation/technical/multi-pack-index.txt\n> WITH a trailing space.  In the first two cases, further completions\n> were possible so they didn't add a trailing space to signify the\n> completion was final, but in the third case it is final and needed the\n> trailing space to denote that.\n> \n> Does that help?\n> \nYes, very much! Thank you.\n>>> +     fi\n>>> +}\n>>\n>> Added my review as mentioned in [1].\n>>\n>> [1]:\n>> https://lore.kernel.org/git/pull.1108.v2.git.1640892413.gitgitgadget@gmail.com/T/#md3da435452988b0366ab4c2ee4bc06df2d17cb36\n"},{"id":"446290","messageId":"20220115095725.GA1738@szeder.dev","threadId":"57165","inReplyTo":"256e5f034c6072b6e3621adfa96c5c6319752fae.1641841193.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v3 2/3] sparse-checkout: custom tab completion","fromName":"SZEDER Gábor","fromEmail":"szeder.dev@gmail.com","sentAt":"2022-01-15T09:57:25Z","receivedAt":"2022-01-15T09:57:38Z","isPatch":true,"sender":{"key":"szeder.dev@gmail.com","avatar":"https://avatars.githubusercontent.com/u/116324?v=4"},"body":"On Mon, Jan 10, 2022 at 06:59:51PM +0000, Lessley Dennington via GitGitGadget wrote:\n> Subject: Re: [PATCH v3 2/3] sparse-checkout: custom tab completion\n\nNone of these patches touch sparse-checkout, but only the completion\nscript and its tests.  Therefore \"completion:\" would be a better\nmatching area prefix.\n\n> Fix custom tab completion for sparse-checkout command. This will ensure:\n> \n> 1. The full list of subcommands is provided when users enter git\n> sparse-checkout <TAB>.\n> 2. The --help option is tab-completable.\n\nThis is inconsistent with the rest of the completion script, because\nit doesn't list '--help' for any commands or subcommand (with the sole\nexception of 'git --<TAB>').\n\n> 3. Subcommand options are tab-completable.\n> 4. A list of directories (but not files) is provided when users enter git\n> sparse-checkout add <TAB> or git sparse-checkout set <TAB>.\n\nWhy limit completion only to directories?  Both of those subcommands\naccept files, and I think 'git sparse-checkout set README.md' is a\nperfectly reasonable command.\n\n> It is\n> important to note that this will apply for both cone mode and non-cone\n> mode (even though non-cone mode matches on patterns rather than\n> directories).\n> \n> Failing tests that were added in the previous commit to verify these\n> scenarios are now passing with these updates.\n> \n> Signed-off-by: Lessley Dennington <lessleydennington@gmail.com>\n> ---\n>  contrib/completion/git-completion.bash | 38 ++++++++++++++++++--------\n>  t/t9902-completion.sh                  |  8 +++---\n>  2 files changed, 30 insertions(+), 16 deletions(-)\n> \n> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\n> index c82ccaebcc7..f478883f51c 100644\n> --- a/contrib/completion/git-completion.bash\n> +++ b/contrib/completion/git-completion.bash\n> @@ -2986,24 +2986,38 @@ _git_show_branch ()\n>  \t__git_complete_revlist\n>  }\n>  \n> +__git_sparse_checkout_subcommand_opts=\"--cone --no-cone --sparse-index --no-sparse-index\"\n> +\n>  _git_sparse_checkout ()\n>  {\n> -\tlocal subcommands=\"list init set disable\"\n> +\tlocal subcommands=\"list init set disable add reapply\"\n>  \tlocal subcommand=\"$(__git_find_on_cmdline \"$subcommands\")\"\n> +\n>  \tif [ -z \"$subcommand\" ]; then\n> -\t\t__gitcomp \"$subcommands\"\n> -\t\treturn\n> +\t\tcase \"$cur\" in\n> +\t\t\t--*)\n> +\t\t\t\t__gitcomp \"--help\"\n> +\t\t\t\t;;\n> +\t\t\t*)\n> +\t\t\t\t__gitcomp \"$subcommands\"\n> +\t\t\t\t;;\n> +\t\tesac\n>  \tfi\n>  \n> -\tcase \"$subcommand,$cur\" in\n> -\tinit,--*)\n> -\t\t__gitcomp \"--cone\"\n> -\t\t;;\n> -\tset,--*)\n> -\t\t__gitcomp \"--stdin\"\n> -\t\t;;\n> -\t*)\n> -\t\t;;\n> +\tcase \"$subcommand\" in\n> +\t\tset)\n> +\t\t\t__gitcomp \"$__git_sparse_checkout_subcommand_opts --stdin\"\n\nOh, a hard-coded list of --options is so old school :)\n\nAll subcommands of 'git sparse-checkout' use parse-options (even those\nthat don't have any --options at the moment), so their options can be\ncompleted programmatically, and then we wouldn't have to worry about\nupdating the list of options in the completion script ever again.  It\nwould also make several tests added in the previous patch unnecessary.\n\nYou could use the completion function of 'git notes' for inspiration\non how to do that.\n\n> +\t\t\t__gitcomp \"$(git ls-tree -d -r HEAD --name-only)\"\n\nThis will have troubles with unusual characters in pathnames:\n\n  - If a pathname contains a space (or any other IFS character), then\n    the shell will split that into multiple words.  \n\n  - If a pathname contains a special character, e.g. double quote or\n    backslash, then 'git ls-tree' will quote that path.  Furthermore,\n    by default it will quote pathnames containing e.g. UTF-8\n    characters as well.\n\n  - The shell has its own special characteers that have to be\n    quoted/escaped on the command line to strip them from their\n    special meaning, that quoting/escaping will interfere with listing\n    only paths matching the current word to be completed.\n\nYou should use the __git_complete_index_file() helper function\ninstead, which takes care of most of this.\n\nFurthermore, these two subsequent __gitcomp() calls will offer both\noptions and paths for 'git sparse-checkout set <TAB>', which is\ninconsistent with the rest of the completion script.  Usually it lists\n--options only after e.g. 'git rm --<TAB>' or 'git log --<TAB>', but\nafter 'git rm <TAB>' and 'git log <TAB>' it lists only files and refs,\nrespectively.\n\n> +\t\t\t;;\n> +\t\tadd)\n> +\t\t\t__gitcomp \"--stdin\"\n> +\t\t\t__gitcomp \"$(git ls-tree -d -r HEAD --name-only)\"\n\nLikewise.\n\n> +\t\t\t;;\n> +\t\tinit|reapply)\n> +\t\t\t__gitcomp \"$__git_sparse_checkout_subcommand_opts\"\n> +\t\t\t;;\n> +\t\t*)\n> +\t\t\t;;\n>  \tesac\n>  }\n>  \n"},{"id":"446299","messageId":"CABPp-BGR+UrW5ej-8+XXHPkjMfFgURycd9rWC+2awUvYcr_PXA@mail.gmail.com","threadId":"57165","inReplyTo":"20220115095725.GA1738@szeder.dev","subject":"Re: [PATCH v3 2/3] sparse-checkout: custom tab completion","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2022-01-16T01:03:24Z","receivedAt":"2022-01-16T01:03:40Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Sat, Jan 15, 2022 at 1:57 AM SZEDER Gábor <szeder.dev@gmail.com> wrote:\n>\n> On Mon, Jan 10, 2022 at 06:59:51PM +0000, Lessley Dennington via GitGitGadget wrote:\n> > Subject: Re: [PATCH v3 2/3] sparse-checkout: custom tab completion\n>\n> None of these patches touch sparse-checkout, but only the completion\n> script and its tests.  Therefore \"completion:\" would be a better\n> matching area prefix.\n\nThanks for the detailed feedback and guidance in your review.  Very\nhelpful.  I'll omit quoting most of it here, but I do want to comment\non the point about directories.\n\n...\n> > 4. A list of directories (but not files) is provided when users enter git\n> > sparse-checkout add <TAB> or git sparse-checkout set <TAB>.\n>\n> Why limit completion only to directories?  Both of those subcommands\n> accept files,\n\nDiscussed in part at [1], but let me give a more detailed answer.\n\nBoth of these commands accept not only directories and files, but also\nnearly arbitrary input as far as I can tell.  (In cone-mode, it'll\naccept anything so long as it doesn't look like a relative path that\ntries to reach above the toplevel directory with '../' sequences.  In\nnon-cone mode, I think it accepts completely arbitrary input).  If our\nguide is merely what the command swallows, then we should forgo\ncompletion for these subcommands, because it's not possible to\nenumerate all possible completions.  I don't think that's a useful\nguide or starting point, so we instead need to discuss what are\nreasonable completions.\n\ncone-mode works exclusively on directories.  So, in that mode,\ndirectories are what we want to complete on.  (And if a file is\nspecified, cone-mode will treat it as a directory and add expressions\nfor including all the files under that \"directory\", which might be\nconfusing.  sparse-checkout doesn't verify it is a diretory, because\nit *might* name a directory in a different branch, including one not\nyet downloaded.  But \"might name a directory on another branch\" is no\nreason to suggest picking that pathname with completion.)\n\nIn non-cone mode, arbitrary expressions are valid and will be treated\nas gitignore-style expressions.  That again leaves us with either not\nproviding completions, or choosing a subset of possible inputs that\nare reasonable suggestions for users.  I prefer the latter, and in\nparticular I feel that directories are reasonable suggestions.  In\ncontrast, I don't think providing files is helpful, because it\nreinforces the design flaw of non-cone mode.  Non-cone mode has\nquadratic performance baked into its design, and since\nsparse-checkouts are about performance, non-cone mode kind of defeats\nthe purpose of the command.  (In addition to other problems[2].)  So,\nI think non-cone mode should be deprecated and excised.  Patches\nelsewhere are moving in the direction of deprecation already[3], and\nwe've already discussed multiple steps we'll likely take soon\ncontinuing in that direction.  In the meantime, providing just\ndirectories for completion seems like a good direction to me.\n\n[1] https://lore.kernel.org/git/CABPp-BG=wr81CPtW1M12xFN_0dyS8mAZjM6o=77LA20Zge8Xng@mail.gmail.com/\n[2] https://lore.kernel.org/git/CABPp-BF=-1aZd=nFHF6spo7Ksa7f7Wb7ervCt0QvtNitMY=ZBA@mail.gmail.com/\n[3] https://lore.kernel.org/git/0af00779128e594aff0ee4ec5378addeac8e88a2.1642175983.git.gitgitgadget@gmail.com/\n(\"This mode is harder to use and less performant, and is thus not\nrecommended.\")\n\n> and I think 'git sparse-checkout set README.md' is a\n> perfectly reasonable command.\n\nReasonable in what sense?  That it makes it (vastly) easier to\nimplement the completion and sparse-checkout set|add will swallow it,\nor that it's something that should actually be recommended for users\ndoing sparse-checkouts?  While the former certainly holds, I don't\nthink the latter does.\n"},{"id":"446330","messageId":"xmqqv8yjz5us.fsf@gitster.g","threadId":"57165","inReplyTo":"CABPp-BGR+UrW5ej-8+XXHPkjMfFgURycd9rWC+2awUvYcr_PXA@mail.gmail.com","subject":"Re: [PATCH v3 2/3] sparse-checkout: custom tab completion","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-01-16T22:13:47Z","receivedAt":"2022-01-16T22:13:54Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Elijah Newren <newren@gmail.com> writes:\n\n> ...  If our\n> guide is merely what the command swallows, then we should forgo\n> completion for these subcommands, because it's not possible to\n> enumerate all possible completions.\n\nI am not sure if I follow.  I do not think it makes sense to aim for\nenumerating EVERYTHING the command would accept.  But I do not know\nthat is the same as \"merely what the command swallows\".\n\n> I don't think that's a useful guide or starting point, so we\n> instead need to discuss what are reasonable completions.\n\nI do not think it is a good idea to refrain from suggesting anything\nthat has a possibility of being wring, either, though.  If a path\nthat is not a directory (either because it is a file in the current\ncheckout, or because it is a directory only in a different branch)\nis given, it might not make sense in the cone-mode for the current\ncheckout, but it may well make sense when a different branch is\nchecked out.  Or you may not even in the cone-mode, and in which\ncase, as SZEDER suggested, a single filename may perfectly make\nsense.  A user who said READM<TAB> and does not see it completed to\nREADME.md would be quite confused.\n\nAre we limiting ourselves to directories only when we know we are in\nthe cone-mode and showing both directories and files otherwise?\n\nI think the guiding principle ought to be that we show completion\nthat\n\n - is cheap enough to compute in interactive use (e.g. we should\n   refrain from looking for directories in all possible branches,\n   but instead just look at the working tree and possibly in the\n   index),\n\n - is simple enough to explain to the users to understand what the\n   rules are, and\n\n - gives useful enough candidates.\n\n\"We only look for directories (without going recursive) in the\nworking tree\" does satisfy the first two, but I am not sure it is\nmore useful than \"We show files and directories (without going\nrecursive) in the working tree\", which also satisfies the first\ntwo.\n\nOf course, if the completion limits to directories only in a\nrepository in the cone-mode, I would not worry about the exclusion\nof non-directories will confuse users.\n"},{"id":"446366","messageId":"CABPp-BErg-RtyycXaRXYfQHEQXA4q-FU9Q6nYkSHJsqL-04oXw@mail.gmail.com","threadId":"57165","inReplyTo":"xmqqv8yjz5us.fsf@gitster.g","subject":"Re: [PATCH v3 2/3] sparse-checkout: custom tab completion","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2022-01-17T18:14:58Z","receivedAt":"2022-01-17T18:15:13Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Sun, Jan 16, 2022 at 2:13 PM Junio C Hamano <gitster@pobox.com> wrote:\n>\n> Elijah Newren <newren@gmail.com> writes:\n>\n> > ...  If our\n> > guide is merely what the command swallows, then we should forgo\n> > completion for these subcommands, because it's not possible to\n> > enumerate all possible completions.\n>\n> I am not sure if I follow.  I do not think it makes sense to aim for\n> enumerating EVERYTHING the command would accept.  But I do not know\n> that is the same as \"merely what the command swallows\".\n\nI don't understand your distinction; I think your second sentence is\nthe same thing I said.\n\n> > I don't think that's a useful guide or starting point, so we\n> > instead need to discuss what are reasonable completions.\n>\n> I do not think it is a good idea to refrain from suggesting anything\n> that has a possibility of being wring, either, though.  If a path\n> that is not a directory (either because it is a file in the current\n> checkout, or because it is a directory only in a different branch)\n> is given, it might not make sense in the cone-mode for the current\n> checkout, but it may well make sense when a different branch is\n> checked out.\n\nCompleting on files and directories would be a reasonable first cut,\nbut that's what we already had before this series was proposed.  It\nhas the downsides of\n  * [cone-mode] making the majority of suggested completions wrong\n  * [non-cone mode] subtly recommending individually adding all wanted\nfiles, increasing the number of patterns and exacerbating the\nquadratic behavior that non-cone mode experiences with every\nunpack_trees() call that touches the working tree.\n  * [both modes] potentially making it hard to find or select the\nvalid choices you do want (there are many more files than directories)\n\nBut, despite all that, completing on files and directories is a\nsomewhat reasonable first cut.\n\nLessley was trying to aim higher with her submission, though, and I\ndon't see why she should be dissuaded.  Something better would be\nnice.\n\n>  Or you may not even in the cone-mode, and in which\n> case, as SZEDER suggested, a single filename may perfectly make\n> sense.  A user who said READM<TAB> and does not see it completed to\n> README.md would be quite confused.\n\nI'm not sure I follow.  READM<TAB> already doesn't complete to\nREADME.md in the following example command lines:\n   'cd READM<TAB>'\n   'ssh READM<TAB>'\nThat doesn't seem to cause user confusion, so I don't think\ndisallowing it in cone-mode would cause confusion.  Suggesting it, on\nthe other hand, may well cause confusion given that cone-mode is\nexplicitly about directories and is documented as such.\n\nIf you're only talking about non-cone mode, then this may be a\nreasonable objection, though I'm not sure I agree with it even then.\nIn addition to the fact that individual file completion can be\ndetrimental to the user in non-cone mode for performance reasons, the\ndocumentation never explicitly states files are acceptable to\nsparse-checkout {set,add}.  It always mentions \"directories\" and\n\"patterns\".  We can't complete all patterns, so we have to pick a\nsubset.  I don't see why \"directories and files\" is a better subset to\npick than \"just directories\".\n\n> Are we limiting ourselves to directories only when we know we are in\n> the cone-mode and showing both directories and files otherwise?\n\nThat is one possibility, though not the one Lessley proposed.\n\n> I think the guiding principle ought to be that we show completion\n> that\n>\n>  - is cheap enough to compute in interactive use (e.g. we should\n>    refrain from looking for directories in all possible branches,\n>    but instead just look at the working tree and possibly in the\n>    index),\n\nI agree, except with the suggestion to use the working tree or index\nin the case of sparse-checkouts.  The working tree shouldn't be used\nbecause it doesn't have the needed information:\n  * `git clone --sparse` starts with zero subdirectories present\n  * `set` and `add` are likely being used to change sparsity to\ninclude something not already present\n\nThe index shouldn't be used because it is not cheap for interactive use:\n  * it contains recursive entries below directories of interest that\nhave to be filtered out\n  * with the sparse-index, it may have sparse-directories hiding what\nwe want, forcing us to fully inflate the index to find the pieces we\ndo want\n\nI agree with Lessley's choice of using ls-tree and HEAD to achieve\ncheap interactive use.\n\n>  - is simple enough to explain to the users to understand what the\n>    rules are, and\n>\n>  - gives useful enough candidates.\n\nI agree with these 3 criteria.\n\n> \"We only look for directories (without going recursive) in the\n> working tree\" does satisfy the first two, but I am not sure it is\n> more useful than \"We show files and directories (without going\n> recursive) in the working tree\", which also satisfies the first\n> two.\n\nWell, Lessley certainly thought directories-only was more useful, and\nin fact labelled \"files and directories\" as a bug/issue in her cover\nletter.  Stolee commented on the series and also didn't see anything\nwrong with that claim.\n\n> Of course, if the completion limits to directories only in a\n> repository in the cone-mode, I would not worry about the exclusion\n> of non-directories will confuse users.\n\nI'd prefer directories-only for both modes, but could accept\ndirectories-only for cone mode and both-files-and-directories for\nnon-cone mode.\n\nEspecially since I think we're going to deprecate non-cone mode regardless.\n"},{"id":"446379","messageId":"xmqq7dayup5d.fsf@gitster.g","threadId":"57165","inReplyTo":"CABPp-BErg-RtyycXaRXYfQHEQXA4q-FU9Q6nYkSHJsqL-04oXw@mail.gmail.com","subject":"Re: [PATCH v3 2/3] sparse-checkout: custom tab completion","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-01-17T19:40:30Z","receivedAt":"2022-01-17T19:40:35Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Elijah Newren <newren@gmail.com> writes:\n\n> I'm not sure I follow.  READM<TAB> already doesn't complete to\n> README.md in the following example command lines:\n>    'cd READM<TAB>'\n>    'ssh READM<TAB>'\n\nIf the example were \"ls READM<TAB>\", it would have been worth the\ntime to read and think about this again, but all users expect \"cd\"\nto go into directories, and \"ssh\" to go visit another host, and\ntaking a local filename as a hint to complete would be nonsense.\n\nBut that is not what we are talking about (and it is frustrating\nthat you know it).  \n\nTo users, what sparse-checkout takes look like local pathnames, not\nnecessarily limited to directory names (if you disagree, go back and\nread what SZEDER wrote to trigger this thread).\n\nI know it is your preference to complete only directories and\nexclude filenames, but I question if the confusion such a design\ncauses to end-users is worth it.\n"},{"id":"446437","messageId":"ee58a0d5-5773-238d-706f-3fb264b6e8db@gmail.com","threadId":"57165","inReplyTo":"xmqq7dayup5d.fsf@gitster.g","subject":"Re: [PATCH v3 2/3] sparse-checkout: custom tab completion","fromName":"Lessley Dennington","fromEmail":"lessleydennington@gmail.com","sentAt":"2022-01-18T17:56:38Z","receivedAt":"2022-01-18T17:56:41Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"On 1/17/22 11:40 AM, Junio C Hamano wrote:\n> Elijah Newren <newren@gmail.com> writes:\n> \n>> I'm not sure I follow.  READM<TAB> already doesn't complete to\n>> README.md in the following example command lines:\n>>     'cd READM<TAB>'\n>>     'ssh READM<TAB>'\n> \n> If the example were \"ls READM<TAB>\", it would have been worth the\n> time to read and think about this again, but all users expect \"cd\"\n> to go into directories, and \"ssh\" to go visit another host, and\n> taking a local filename as a hint to complete would be nonsense.\n> \n> But that is not what we are talking about (and it is frustrating\n> that you know it).\n> \n> To users, what sparse-checkout takes look like local pathnames, not\n> necessarily limited to directory names (if you disagree, go back and\n> read what SZEDER wrote to trigger this thread).\n> \n> I know it is your preference to complete only directories and\n> exclude filenames, but I question if the confusion such a design\n> causes to end-users is worth it.\n\nI think perhaps we're a little caught up in exemplifying commands that\nare unrelated to sparse-checkout. As Elijah said in [1], the documentation\nstates that directories and patterns are acceptable to sparse-checkout but\nnot files. While it is not reasonable to try to offer every pattern a user\ncould possibly pass to sparse-checkout, it is reasonable to offer\ndirectories and (in my opinion) will help guide users toward correct usage\nof the command.\n\nHowever, since completion on directories is cone-mode-specific, I am\nwilling to accept the suggestion to only complete directories if we are in\na cone-mode sparse-checkout and apply it in v4 of this series.\n\n[1]: \nhttps://lore.kernel.org/git/CABPp-BErg-RtyycXaRXYfQHEQXA4q-FU9Q6nYkSHJsqL-04oXw@mail.gmail.com/\n"},{"id":"446438","messageId":"14ada2ac-9a10-9653-6ced-9cfc675b9419@gmail.com","threadId":"57165","inReplyTo":"CABPp-BGR+UrW5ej-8+XXHPkjMfFgURycd9rWC+2awUvYcr_PXA@mail.gmail.com","subject":"Re: [PATCH v3 2/3] sparse-checkout: custom tab completion","fromName":"Lessley Dennington","fromEmail":"lessleydennington@gmail.com","sentAt":"2022-01-18T17:59:14Z","receivedAt":"2022-01-18T17:59:22Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"\n\nOn 1/15/22 5:03 PM, Elijah Newren wrote:\n> On Sat, Jan 15, 2022 at 1:57 AM SZEDER Gábor <szeder.dev@gmail.com> wrote:\n>>\n>> On Mon, Jan 10, 2022 at 06:59:51PM +0000, Lessley Dennington via GitGitGadget wrote:\n>>> Subject: Re: [PATCH v3 2/3] sparse-checkout: custom tab completion\n>>\n>> None of these patches touch sparse-checkout, but only the completion\n>> script and its tests.  Therefore \"completion:\" would be a better\n>> matching area prefix.\n> \n> Thanks for the detailed feedback and guidance in your review.  Very\n> helpful.  I'll omit quoting most of it here, but I do want to comment\n> on the point about directories.\n> \nI second this - am planning to apply all feedback (with the exception of \ncompleting\non both files and directories) in v4 of this series.\n\n"},{"id":"446451","messageId":"20220118210205.GA2632@szeder.dev","threadId":"57165","inReplyTo":"CABPp-BErg-RtyycXaRXYfQHEQXA4q-FU9Q6nYkSHJsqL-04oXw@mail.gmail.com","subject":"Re: [PATCH v3 2/3] sparse-checkout: custom tab completion","fromName":"SZEDER Gábor","fromEmail":"szeder.dev@gmail.com","sentAt":"2022-01-18T21:02:05Z","receivedAt":"2022-01-18T21:02:13Z","isPatch":true,"sender":{"key":"szeder.dev@gmail.com","avatar":"https://avatars.githubusercontent.com/u/116324?v=4"},"body":"On Mon, Jan 17, 2022 at 10:14:58AM -0800, Elijah Newren wrote:\n> the\n> documentation never explicitly states files are acceptable to\n> sparse-checkout {set,add}.  It always mentions \"directories\" and\n> \"patterns\".\n\nThe \"Full Pattern Set\" section of the manpage does in fact explicitly\nstates that files are supported.\n\n"},{"id":"446454","messageId":"CABPp-BE=UTRnhSDugE46XqsEwMd9UWivAL76VTMzJygy4a3N6Q@mail.gmail.com","threadId":"57165","inReplyTo":"20220118210205.GA2632@szeder.dev","subject":"Re: [PATCH v3 2/3] sparse-checkout: custom tab completion","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2022-01-18T21:43:05Z","receivedAt":"2022-01-18T21:43:49Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Tue, Jan 18, 2022 at 1:02 PM SZEDER Gábor <szeder.dev@gmail.com> wrote:\n>\n> On Mon, Jan 17, 2022 at 10:14:58AM -0800, Elijah Newren wrote:\n> > the\n> > documentation never explicitly states files are acceptable to\n> > sparse-checkout {set,add}.  It always mentions \"directories\" and\n> > \"patterns\".\n>\n> The \"Full Pattern Set\" section of the manpage does in fact explicitly\n> states that files are supported.\n\nNot sure it matters since Junio has stated his position pretty\nstrongly, making it irrelevant at this point, but.... I'm not sure I'm\nfollowing you.  Is this the quote you're referring to?\n\n\"\"\"\nWhile $GIT_DIR/info/sparse-checkout is usually used to specify what\nfiles are included,\n\"\"\"\n\nIf so,\n    /foo[A-M]*/pref?x_*.c\ncould be an entry in the file \"used to specify what files are\nincluded\", but it's not a file.  The two example lines immediately\nfollowing aren't filenames either (though the '!'-prefixed line is\nclose).  Or are you referring to something else?\n"},{"id":"446458","messageId":"20220118222234.GB2632@szeder.dev","threadId":"57165","inReplyTo":"CABPp-BGR+UrW5ej-8+XXHPkjMfFgURycd9rWC+2awUvYcr_PXA@mail.gmail.com","subject":"Re: [PATCH v3 2/3] sparse-checkout: custom tab completion","fromName":"SZEDER Gábor","fromEmail":"szeder.dev@gmail.com","sentAt":"2022-01-18T22:22:34Z","receivedAt":"2022-01-18T22:22:46Z","isPatch":true,"sender":{"key":"szeder.dev@gmail.com","avatar":"https://avatars.githubusercontent.com/u/116324?v=4"},"body":"On Sat, Jan 15, 2022 at 05:03:24PM -0800, Elijah Newren wrote:\n> On Sat, Jan 15, 2022 at 1:57 AM SZEDER Gábor <szeder.dev@gmail.com> wrote:\n> >\n> > On Mon, Jan 10, 2022 at 06:59:51PM +0000, Lessley Dennington via GitGitGadget wrote:\n> > > Subject: Re: [PATCH v3 2/3] sparse-checkout: custom tab completion\n> >\n> > None of these patches touch sparse-checkout, but only the completion\n> > script and its tests.  Therefore \"completion:\" would be a better\n> > matching area prefix.\n> \n> Thanks for the detailed feedback and guidance in your review.  Very\n> helpful.  I'll omit quoting most of it here, but I do want to comment\n> on the point about directories.\n> \n> ...\n> > > 4. A list of directories (but not files) is provided when users enter git\n> > > sparse-checkout add <TAB> or git sparse-checkout set <TAB>.\n> >\n> > Why limit completion only to directories?  Both of those subcommands\n> > accept files,\n> \n> Discussed in part at [1], but let me give a more detailed answer.\n\nIt was a semi-rhetorical question.  Whether the reasons for expluding\nfiles are sound or not, it should be convincingly justified in the\ncommit message.\n\n> Both of these commands accept not only directories and files, but also\n> nearly arbitrary input as far as I can tell.  (In cone-mode, it'll\n> accept anything so long as it doesn't look like a relative path that\n> tries to reach above the toplevel directory with '../' sequences.  In\n> non-cone mode, I think it accepts completely arbitrary input).  If our\n> guide is merely what the command swallows, then we should forgo\n> completion for these subcommands, because it's not possible to\n> enumerate all possible completions.  I don't think that's a useful\n> guide or starting point, so we instead need to discuss what are\n> reasonable completions.\n> \n> cone-mode works exclusively on directories.  So, in that mode,\n> directories are what we want to complete on.  (And if a file is\n> specified, cone-mode will treat it as a directory and add expressions\n> for including all the files under that \"directory\", which might be\n> confusing.  sparse-checkout doesn't verify it is a diretory, because\n> it *might* name a directory in a different branch, including one not\n> yet downloaded.  But \"might name a directory on another branch\" is no\n> reason to suggest picking that pathname with completion.)\n> \n> In non-cone mode, arbitrary expressions are valid and will be treated\n> as gitignore-style expressions.  That again leaves us with either not\n> providing completions, or choosing a subset of possible inputs that\n> are reasonable suggestions for users.  I prefer the latter, and in\n> particular I feel that directories are reasonable suggestions.  In\n> contrast, I don't think providing files is helpful, because it\n> reinforces the design flaw of non-cone mode.  Non-cone mode has\n> quadratic performance baked into its design, and since\n> sparse-checkouts are about performance, non-cone mode kind of defeats\n> the purpose of the command.\n\nOr about disk space.  Which, because of the potentially significantly\nreduced number of files in the work tree can bring along significant\nperformance benefits, even with quadratic behavior.\n\n>  (In addition to other problems[2].)  So,\n> I think non-cone mode should be deprecated and excised.  Patches\n> elsewhere are moving in the direction of deprecation already[3], and\n> we've already discussed multiple steps we'll likely take soon\n> continuing in that direction.  In the meantime, providing just\n> directories for completion seems like a good direction to me.\n> \n> [1] https://lore.kernel.org/git/CABPp-BG=wr81CPtW1M12xFN_0dyS8mAZjM6o=77LA20Zge8Xng@mail.gmail.com/\n> [2] https://lore.kernel.org/git/CABPp-BF=-1aZd=nFHF6spo7Ksa7f7Wb7ervCt0QvtNitMY=ZBA@mail.gmail.com/\n> [3] https://lore.kernel.org/git/0af00779128e594aff0ee4ec5378addeac8e88a2.1642175983.git.gitgitgadget@gmail.com/\n> (\"This mode is harder to use and less performant, and is thus not\n> recommended.\")\n> \n> > and I think 'git sparse-checkout set README.md' is a\n> > perfectly reasonable command.\n> \n> Reasonable in what sense?  That it makes it (vastly) easier to\n> implement the completion and sparse-checkout set|add will swallow it,\n> or that it's something that should actually be recommended for users\n> doing sparse-checkouts?  While the former certainly holds, I don't\n> think the latter does.\n\nI used the following command to create a sparse-checkout from\nlinux.git to build and play with 'perf':\n\n  git sparse-checkout set tools/perf/ tools/scripts/ tools/build/ tools/include/ tools/arch/x86/ tools/lib/ /.gitignore /.gitattributes\n\nIncluding the top-level '.gitignore' and '.gitattributes' was\nimportant, becase those ignore object files and specify userdiff.\nNow, I wouldn't mind having other files present in the top-level\ndirectory, because there are only a handful of files there.  However,\nbeing able to specify just those two files to 'git sparse-checkout'\nwas great, because I didn't even have to think about what wildcard\npattern to use, and what negative pattern to use to exclude anything\nthat might have been included recursively.\n\nI don't remember having any performance issues with it, on the\ncontrary, I do remember that Git suddenly became much faster that in\nthe full worktree.\n\nSo I'm fairly convinced that specifying files to sparse-checkout is a\nfeature that can make users' life easier.  It certainly made my life\neasier.\n\n\nOn a related note: I just noticed the leading slashes in '/.gitignore'\nand '/.gitattributes'.  __git_complete_index_file() is not ready for\nthat, I'm afraid; but I don't think the proposed patches could deal\nwith that, either (but I didn't actually try).\n\nIt would be great if completion could cope with patterns starting with\n'/' and/or '!'.\n\n\n"},{"id":"446462","messageId":"CABPp-BEwMAPHGt5xD9jDU58grbrAqCdqNY9Nh8UJGLKuLbArXQ@mail.gmail.com","threadId":"57165","inReplyTo":"20220118222234.GB2632@szeder.dev","subject":"Re: [PATCH v3 2/3] sparse-checkout: custom tab completion","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2022-01-18T23:30:05Z","receivedAt":"2022-01-18T23:30:20Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Tue, Jan 18, 2022 at 2:22 PM SZEDER Gábor <szeder.dev@gmail.com> wrote:\n>\n> On Sat, Jan 15, 2022 at 05:03:24PM -0800, Elijah Newren wrote:\n> > On Sat, Jan 15, 2022 at 1:57 AM SZEDER Gábor <szeder.dev@gmail.com> wrote:\n> > >\n> > > On Mon, Jan 10, 2022 at 06:59:51PM +0000, Lessley Dennington via GitGitGadget wrote:\n...\n> > > > 4. A list of directories (but not files) is provided when users enter git\n> > > > sparse-checkout add <TAB> or git sparse-checkout set <TAB>.\n> > >\n> > > Why limit completion only to directories?  Both of those subcommands\n> > > accept files,\n> >\n> > Discussed in part at [1], but let me give a more detailed answer.\n>\n> It was a semi-rhetorical question.  Whether the reasons for expluding\n> files are sound or not, it should be convincingly justified in the\n> commit message.\n\nFair enough.\n\n...\n> I used the following command to create a sparse-checkout from\n> linux.git to build and play with 'perf':\n>\n>   git sparse-checkout set tools/perf/ tools/scripts/ tools/build/ tools/include/ tools/arch/x86/ tools/lib/ /.gitignore /.gitattributes\n>\n> Including the top-level '.gitignore' and '.gitattributes' was\n> important, becase those ignore object files and specify userdiff.\n> Now, I wouldn't mind having other files present in the top-level\n> directory, because there are only a handful of files there.  However,\n> being able to specify just those two files to 'git sparse-checkout'\n> was great, because I didn't even have to think about what wildcard\n> pattern to use, and what negative pattern to use to exclude anything\n> that might have been included recursively.\n\nYeah, we should really make cone mode the default, because then this\nsimplifies to:\n\n    git sparse-checkout set tools/perf/ tools/scripts/ tools/build/\ntools/include/ tools/arch/x86/ tools/lib/\n\nIn cone-mode you automatically get the directories specified PLUS:\n\n  * all files in the toplevel directory (you always get these in cone mode)\n  * all files directly within a parent (or ancestor) of one of the\ndirectories you specified (thus all files directly under tools/ and\ntools/arch/).\n\n> I don't remember having any performance issues with it, on the\n> contrary, I do remember that Git suddenly became much faster that in\n> the full worktree.\n\nCool, thanks for testing it out and reporting.\n\nIf I can be permitted to share a bit of my experience...\n\nIn this specific case, you did keep it to 8 patterns and the linux\nkernel \"only\" has ~60k files.  So O(N*M) isn't too bad here...but\nexperience at $DAYJOB is that even with only 60k files, the pattern\nlist tends to grow and it's not clear to users why there are so many\nugly pauses when \"Git used to be fast\".  Users tend to not make the\nconnection either between the sparsity patterns and the slowness for\nwhatever reason, and when I'm asked questions about the slowness, I\nmay have to check a few other possible causes before finally realizing\nthat it's just \"too many sparsity patterns\".\n\nAt least, that's the way it was at $DAYJOB before I switched our\ninternal \"sparsify\" tool to just use cone mode.  Then that type of\nproblem went away.\n\n> So I'm fairly convinced that specifying files to sparse-checkout is a\n> feature that can make users' life easier.  It certainly made my life\n> easier.\n\nOr we can make it even easier and faster by using cone mode.  That\nreally, really should be the default (as we've been talking about for\na couple cycles now), and I think your email reinforces my belief in\nit.  I've got a series ready after some other things merge down to\nnext.\n\n> On a related note: I just noticed the leading slashes in '/.gitignore'\n> and '/.gitattributes'.  __git_complete_index_file() is not ready for\n> that, I'm afraid; but I don't think the proposed patches could deal\n> with that, either (but I didn't actually try).\n>\n> It would be great if completion could cope with patterns starting with\n> '/' and/or '!'.\n\nAh, very good point.  The leading '/' is kind of critical here,\notherwise you get all .gitignore files in every directory at every\ndepth, so completing on files (as currently done) wouldn't really help\nat all in your case.\n\n\nSince you brought up a new good point here, can I also mention two\nothers not previously covered in this thread (i.e. besides scaling)?\n\n* If we complete file and directory names in non-cone mode, and those\nfile and directory names contain a leading '#' or '!' or contain\nanywhere in their names a '*', '?', '\\', '[', or ']', then the users\nmay be in for a very nasty surprise.  (Which perhaps suggests that in\nnon-cone mode, we shouldn't provide file OR directory completions for\nset/add?)\n\n* sparse-checkout currently ignores prefix[1], causing file and\ndirectory completions to be wrong if the user is running from a\nsubdirectory.  This is just a bug in cone mode, though I'm not sure if\nit's bug or feature in non-cone mode[2].  A decision about what it is\nmight have a bearing on what kinds of completions make sense in\nnon-cone mode (and might reinforce files/directories, or suggest\nsomething else.).\n\n[1] https://lore.kernel.org/git/29f0410e-6dfa-2e86-394d-b1fb735e7608@gmail.com/\n[2] https://lore.kernel.org/git/CABPp-BH5woi6KY7OBpnsS-M2EmgLHii9zs8rSwrgcPFkOAvn_A@mail.gmail.com/\n"},{"id":"446668","messageId":"78956982-f5fc-1681-1efe-42e408132a4f@gmail.com","threadId":"57165","inReplyTo":"ee58a0d5-5773-238d-706f-3fb264b6e8db@gmail.com","subject":"Re: [PATCH v3 2/3] sparse-checkout: custom tab completion","fromName":"Lessley Dennington","fromEmail":"lessleydennington@gmail.com","sentAt":"2022-01-22T01:07:52Z","receivedAt":"2022-01-22T01:07:56Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":">> I know it is your preference to complete only directories and\n>> exclude filenames, but I question if the confusion such a design\n>> causes to end-users is worth it.\n> \n> I think perhaps we're a little caught up in exemplifying commands that\n> are unrelated to sparse-checkout. As Elijah said in [1], the documentation\n> states that directories and patterns are acceptable to sparse-checkout but\n> not files. While it is not reasonable to try to offer every pattern a user\n> could possibly pass to sparse-checkout, it is reasonable to offer\n> directories and (in my opinion) will help guide users toward correct usage\n> of the command.\n> \n> However, since completion on directories is cone-mode-specific, I am\n> willing to accept the suggestion to only complete directories if we are in\n> a cone-mode sparse-checkout and apply it in v4 of this series.\n> \n> [1]: \n> https://lore.kernel.org/git/CABPp-BErg-RtyycXaRXYfQHEQXA4q-FU9Q6nYkSHJsqL-04oXw@mail.gmail.com/ \n> \n\nIn light of non-cone mode being removed in the near future (see [1]), it\nactually seems it does not make sense to add different behaviors for cone\nmode and non-cone mode. I also ran this by some other contributors, who\nthought it would be best to complete on both files and directories so as\nnot to confuse users (as Junio and Szeder have indicated). So, instead of\ndifferentiating between cone mode and non-cone mode in V4, I will plan to\nremove directory completion.\n\n[1]: \nhttps://lore.kernel.org/git/CABPp-BEwMAPHGt5xD9jDU58grbrAqCdqNY9Nh8UJGLKuLbArXQ@mail.gmail.com/\n"},{"id":"446669","messageId":"5e7e4858-10ea-06d4-0406-84b83c26dc43@gmail.com","threadId":"57165","inReplyTo":"78956982-f5fc-1681-1efe-42e408132a4f@gmail.com","subject":"Re: [PATCH v3 2/3] sparse-checkout: custom tab completion","fromName":"Lessley Dennington","fromEmail":"lessleydennington@gmail.com","sentAt":"2022-01-22T01:08:55Z","receivedAt":"2022-01-22T01:08:59Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"\n\nOn 1/21/22 5:07 PM, Lessley Dennington wrote:\n>>> I know it is your preference to complete only directories and\n>>> exclude filenames, but I question if the confusion such a design\n>>> causes to end-users is worth it.\n>>\n>> I think perhaps we're a little caught up in exemplifying commands that\n>> are unrelated to sparse-checkout. As Elijah said in [1], the documentation\n>> states that directories and patterns are acceptable to sparse-checkout but\n>> not files. While it is not reasonable to try to offer every pattern a user\n>> could possibly pass to sparse-checkout, it is reasonable to offer\n>> directories and (in my opinion) will help guide users toward correct usage\n>> of the command.\n>>\n>> However, since completion on directories is cone-mode-specific, I am\n>> willing to accept the suggestion to only complete directories if we are in\n>> a cone-mode sparse-checkout and apply it in v4 of this series.\n>>\n>> [1]: \n>> https://lore.kernel.org/git/CABPp-BErg-RtyycXaRXYfQHEQXA4q-FU9Q6nYkSHJsqL-04oXw@mail.gmail.com/ \n>>\n> \n> In light of non-cone mode being removed in the near future (see [1]), it\n> actually seems it does not make sense to add different behaviors for cone\n> mode and non-cone mode. I also ran this by some other contributors, who\n> thought it would be best to complete on both files and directories so as\n> not to confuse users (as Junio and Szeder have indicated). So, instead of\n> differentiating between cone mode and non-cone mode in V4, I will plan to\n> remove directory completion.\n> \n> [1]: \n> https://lore.kernel.org/git/CABPp-BEwMAPHGt5xD9jDU58grbrAqCdqNY9Nh8UJGLKuLbArXQ@mail.gmail.com/ \n> \nMy apologies, I will not remove directory completion, but rather will\nreturn to completing on both files and directories.\n"},{"id":"446673","messageId":"122b563a-3bb5-20de-6530-c79f02da792b@gmail.com","threadId":"57165","inReplyTo":"5e7e4858-10ea-06d4-0406-84b83c26dc43@gmail.com","subject":"Re: [PATCH v3 2/3] sparse-checkout: custom tab completion","fromName":"Lessley Dennington","fromEmail":"lessleydennington@gmail.com","sentAt":"2022-01-22T02:11:22Z","receivedAt":"2022-01-22T02:11:28Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"\n\nOn 1/21/22 5:08 PM, Lessley Dennington wrote:\n> \n> \n> On 1/21/22 5:07 PM, Lessley Dennington wrote:\n>>>> I know it is your preference to complete only directories and\n>>>> exclude filenames, but I question if the confusion such a design\n>>>> causes to end-users is worth it.\n>>>\n>>> I think perhaps we're a little caught up in exemplifying commands that\n>>> are unrelated to sparse-checkout. As Elijah said in [1], the documentation\n>>> states that directories and patterns are acceptable to sparse-checkout but\n>>> not files. While it is not reasonable to try to offer every pattern a user\n>>> could possibly pass to sparse-checkout, it is reasonable to offer\n>>> directories and (in my opinion) will help guide users toward correct usage\n>>> of the command.\n>>>\n>>> However, since completion on directories is cone-mode-specific, I am\n>>> willing to accept the suggestion to only complete directories if we are in\n>>> a cone-mode sparse-checkout and apply it in v4 of this series.\n>>>\n>>> [1]: \n>>> https://lore.kernel.org/git/CABPp-BErg-RtyycXaRXYfQHEQXA4q-FU9Q6nYkSHJsqL-04oXw@mail.gmail.com/ \n>>>\n>>\n>> In light of non-cone mode being removed in the near future (see [1]), it\n>> actually seems it does not make sense to add different behaviors for cone\n>> mode and non-cone mode. I also ran this by some other contributors, who\n>> thought it would be best to complete on both files and directories so as\n>> not to confuse users (as Junio and Szeder have indicated). So, instead of\n>> differentiating between cone mode and non-cone mode in V4, I will plan to\n>> remove directory completion.\n>>\n>> [1]: \n>> https://lore.kernel.org/git/CABPp-BEwMAPHGt5xD9jDU58grbrAqCdqNY9Nh8UJGLKuLbArXQ@mail.gmail.com/ \n>>\n> My apologies, I will not remove directory completion, but rather will\n> return to completing on both files and directories.\n\nMy apologies again, I think I mistakenly assumed Junio did not want\ndirectory-only completion for cone mode based on this comment from [1]:\n\nIf a path that is not a directory (either because it is a file in the\ncurrent checkout, or because it is a directory only in a different branch)\nis given, it might not make sense in the cone-mode for the current\ncheckout, but it may well make sense when a different branch is\nchecked out.\n\nHowever, this line (which I overlooked when I was re-reading this\nevening), leads me to believe that is not the case:\n\nAre we limiting ourselves to directories only when we know we are in\nthe cone-mode and showing both directories and files otherwise?\n\nIt has also been pointed out to me that saying cone mode is going away is\nincorrect - it is just being deprecated.\n\nSo, I will stick to my original plan of continuing to complete on\ndirectories for cone mode and completing on both files and directories\nfor non-cone mode.\n\nAgain, apologies for the noise.\n\n[1]: https://lore.kernel.org/git/xmqqv8yjz5us.fsf@gitster.g/\n"},{"id":"447131","messageId":"pull.1108.v4.git.1643318514.gitgitgadget@gmail.com","threadId":"57165","inReplyTo":"pull.1108.v3.git.1641841193.gitgitgadget@gmail.com","subject":"[PATCH v4 0/3] completion: sparse-checkout updates","fromName":"Lessley Dennington via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-01-27T21:21:51Z","receivedAt":"2022-01-27T21:21:59Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"This series is based on en/sparse-checkout-set. It updates custom tab\ncompletion for the sparse-checkout command. Specifically, it corrects the\nfollowing issues with the current method:\n\n 1. git sparse-checkout <TAB> results in an incomplete list of subcommands\n    (it is missing reapply and add).\n 2. Options for subcommands are not tab-completable.\n 3. git sparse-checkout set <TAB> and git sparse-checkout add <TAB> show\n    both file names and directory names. While this is the desired behavior\n    for non-cone mode, we want to only show directories in cone mode.\n\nThe first commit in this series is a set of tests that highlight each of the\nabove issues. The next commit updates the _git_sparse_checkout method in\ngit-completion.bash to enable previously-failing tests to pass. The final\ncommit modifies the original implementation (which recursively printed\nprospective directories for completion) to only print directories at the\ncurrent level for improved performance.\n\n\nChanges since V3\n================\n\n * Update commit descriptions to begin with completion instead of\n   sparse-checkout.\n * Remove explicit completion of --help, as this is inconsistent with the\n   rest of the completion script.\n * Use __gitcomp_builtin to auto-complete subcommand options (and remove\n   option completion test from previous iterations, as it is no longer\n   necessary).\n * Use __git_complete_index_file helper function in place of __gitcomp\n   \"$(git ls-tree -d -r HEAD --name-only).\n * If in cone-mode sparse checkout, only show directory completions. If in\n   non-cone mode sparse checkout show both files and directories.\n\n\nChanges since V2\n================\n\n * Change use of $prev to $subcommand in _git_sparse_checkout() method in\n   git-completion.bash.\n * State explicitly that directory completion applies in both cone and\n   non-cone mode in 'sparse-checkout: custom tab completion' commit\n * Add new patch with __gitcomp_directories method to improve performance by\n   only outputting directories at the current level.\n\n\nChanges since V1\n================\n\n * Rebase onto en/sparse-checkout-set.\n * Add subcommand options (including --no-cone) for set and reapply.\n * Extend 'sparse-checkout completes subcommand options' test to validate\n   new set/reapply subcommand options.\n * No longer set index.sparse to false in 'sparse-checkout completes\n   directory names' test.\n\nThanks, Lessley\n\nLessley Dennington (3):\n  completion: add sparse-checkout tests\n  completion: sparse-checkout updates\n  completion: ensure cone mode completion with multiple <TAB>s\n\n contrib/completion/git-completion.bash | 44 ++++++++++++---\n t/t9902-completion.sh                  | 75 ++++++++++++++++++++++++++\n 2 files changed, 112 insertions(+), 7 deletions(-)\n\n\nbase-commit: dfac9b609f86cd4f6ce896df9e1172d2a02cde48\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-1108%2Fldennington%2Fsparse-checkout-bash-completion-v4\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1108/ldennington/sparse-checkout-bash-completion-v4\nPull-Request: https://github.com/gitgitgadget/git/pull/1108\n\nRange-diff vs v3:\n\n 1:  bbc2d21e1d1 ! 1:  5bb598a055d sparse-checkout: custom tab completion tests\n     @@ Metadata\n      Author: Lessley Dennington <lessleydennington@gmail.com>\n      \n       ## Commit message ##\n     -    sparse-checkout: custom tab completion tests\n     +    completion: add sparse-checkout tests\n      \n     -    Add tests for missing/incorrect components of custom tab completion for the\n     -    sparse-checkout command. These tests specifically highlight the following:\n     +    Add tests for missing/incorrect components of custom tab completion for\n     +    the sparse-checkout command. These tests specifically highlight the\n     +    following:\n      \n          1. git sparse-checkout <TAB> results in an incomplete list of subcommands\n          (it is missing reapply and add).\n     -    2. git sparse-checkout --<TAB> does not complete the help option.\n     -    3. Options for subcommands are not tab-completable.\n     -    4. git sparse-checkout set <TAB> and git sparse-checkout add <TAB> show\n     -    both file names and directory names.\n     +    2. git sparse-checkout set <TAB> and git sparse-checkout add <TAB> show\n     +    both file names and directory names. While this is the correct behavior\n     +    for non-cone mode, cone mode sparse checkouts should complete only\n     +    directory names.\n      \n     -    Although these tests currently fail, they will succeed with the\n     -    sparse-checkout modifications in git-completion.bash in the next commit in\n     -    this series.\n     +    Although the first two of these tests currently fail, they will succeed\n     +    with the sparse-checkout modifications in git-completion.bash in the next\n     +    commit in this series.\n      \n          Signed-off-by: Lessley Dennington <lessleydennington@gmail.com>\n      \n     @@ t/t9902-completion.sh: test_expect_success 'git checkout - with --detach, comple\n      +\tEOF\n      +'\n      +\n     -+test_expect_failure 'sparse-checkout completes options' '\n     -+\ttest_completion \"git sparse-checkout --\" <<-\\EOF\n     -+\t--help Z\n     -+\tEOF\n     -+'\n     -+\n     -+test_expect_failure 'sparse-checkout completes subcommand options' '\n     -+\ttest_completion \"git sparse-checkout init --\" <<-\\EOF &&\n     -+\t--cone Z\n     -+\t--no-cone Z\n     -+\t--sparse-index Z\n     -+\t--no-sparse-index Z\n     -+\tEOF\n     -+\n     -+\ttest_completion \"git sparse-checkout set --\" <<-\\EOF &&\n     -+\t--cone Z\n     -+\t--no-cone Z\n     -+\t--sparse-index Z\n     -+\t--no-sparse-index Z\n     -+\t--stdin Z\n     -+\tEOF\n     -+\n     -+\ttest_completion \"git sparse-checkout reapply --\" <<-\\EOF &&\n     -+\t--cone Z\n     -+\t--no-cone Z\n     -+\t--sparse-index Z\n     -+\t--no-sparse-index Z\n     -+\tEOF\n     -+\n     -+\ttest_completion \"git sparse-checkout add --\" <<-\\EOF\n     -+\t--stdin Z\n     -+\tEOF\n     -+'\n     -+\n     -+test_expect_failure 'sparse-checkout completes directory names' '\n     ++test_expect_failure 'cone mode sparse-checkout completes directory names' '\n      +\t# set up sparse-checkout repo\n      +\tgit init sparse-checkout &&\n      +\t(\n     @@ t/t9902-completion.sh: test_expect_success 'git checkout - with --detach, comple\n      +\t) &&\n      +\n      +\t# initialize sparse-checkout definitions\n     -+\tgit -C sparse-checkout sparse-checkout init --cone &&\n     -+\tgit -C sparse-checkout sparse-checkout set folder1/0 folder3 &&\n     ++\tgit -C sparse-checkout sparse-checkout set --cone folder1/0 folder3 &&\n      +\n      +\t# test tab completion\n      +\t(\n      +\t\tcd sparse-checkout &&\n      +\t\ttest_completion \"git sparse-checkout set f\" <<-\\EOF\n     -+\t\tfolder1 Z\n     -+\t\tfolder1/0 Z\n     -+\t\tfolder1/0/1 Z\n     -+\t\tfolder2 Z\n     -+\t\tfolder2/0 Z\n     -+\t\tfolder3 Z\n     ++\t\tfolder1\n     ++\t\tfolder2\n     ++\t\tfolder3\n     ++\t\tEOF\n     ++\t) &&\n     ++\n     ++\t(\n     ++\t\tcd sparse-checkout &&\n     ++\t\ttest_completion \"git sparse-checkout set folder1/\" <<-\\EOF\n     ++\t\tfolder1/0\n     ++\t\tEOF\n     ++\t) &&\n     ++\n     ++\t(\n     ++\t\tcd sparse-checkout &&\n     ++\t\ttest_completion \"git sparse-checkout set folder1/0/\" <<-\\EOF\n     ++\t\tfolder1/0/1\n      +\t\tEOF\n      +\t) &&\n      +\n      +\t(\n      +\t\tcd sparse-checkout/folder1 &&\n     -+\t\ttest_completion \"git sparse-checkout add \" <<-\\EOF\n     -+\t\t./ Z\n     -+\t\t0 Z\n     -+\t\t0/1 Z\n     ++\t\ttest_completion \"git sparse-checkout add 0\" <<-\\EOF\n     ++\t\t0\n     ++\t\tEOF\n     ++\t)\n     ++'\n     ++\n     ++test_expect_success 'non-cone mode sparse-checkout uses bash completion' '\n     ++\t# reset sparse-checkout repo to non-cone mode\n     ++\tgit -C sparse-checkout sparse-checkout disable &&\n     ++\tgit -C sparse-checkout sparse-checkout set &&\n     ++\n     ++\t# test tab completion\n     ++\t(\n     ++\t\tcd sparse-checkout &&\n     ++\t\t# expected to be empty since we have not configured\n     ++\t\t# custom completion for non-cone mode\n     ++\t\ttest_completion \"git sparse-checkout set f\" <<-\\EOF\n     ++\n      +\t\tEOF\n      +\t)\n      +'\n 2:  256e5f034c6 ! 2:  7d70beb2a6b sparse-checkout: custom tab completion\n     @@ Metadata\n      Author: Lessley Dennington <lessleydennington@gmail.com>\n      \n       ## Commit message ##\n     -    sparse-checkout: custom tab completion\n     +    completion: sparse-checkout updates\n      \n     -    Fix custom tab completion for sparse-checkout command. This will ensure:\n     +    Fix custom tab completion for the sparse-checkout command. This will\n     +    ensure:\n      \n          1. The full list of subcommands is provided when users enter git\n          sparse-checkout <TAB>.\n     -    2. The --help option is tab-completable.\n     -    3. Subcommand options are tab-completable.\n     -    4. A list of directories (but not files) is provided when users enter git\n     -    sparse-checkout add <TAB> or git sparse-checkout set <TAB>. It is\n     -    important to note that this will apply for both cone mode and non-cone\n     -    mode (even though non-cone mode matches on patterns rather than\n     -    directories).\n     +    2. Subcommand options are tab-completable.\n     +    3. A list of directories (but not files) is provided when users enter git\n     +    sparse-checkout add <TAB> or git sparse-checkout set <TAB> in cone mode\n     +    only. In non-cone mode, these commands will continue to complete both\n     +    directory and file names.\n      \n          Failing tests that were added in the previous commit to verify these\n          scenarios are now passing with these updates.\n     @@ Commit message\n      \n       ## contrib/completion/git-completion.bash ##\n      @@ contrib/completion/git-completion.bash: _git_show_branch ()\n     - \t__git_complete_revlist\n     - }\n       \n     -+__git_sparse_checkout_subcommand_opts=\"--cone --no-cone --sparse-index --no-sparse-index\"\n     -+\n       _git_sparse_checkout ()\n       {\n      -\tlocal subcommands=\"list init set disable\"\n     @@ contrib/completion/git-completion.bash: _git_show_branch ()\n       \tlocal subcommand=\"$(__git_find_on_cmdline \"$subcommands\")\"\n      +\n       \tif [ -z \"$subcommand\" ]; then\n     --\t\t__gitcomp \"$subcommands\"\n     --\t\treturn\n     -+\t\tcase \"$cur\" in\n     -+\t\t\t--*)\n     -+\t\t\t\t__gitcomp \"--help\"\n     -+\t\t\t\t;;\n     -+\t\t\t*)\n     -+\t\t\t\t__gitcomp \"$subcommands\"\n     -+\t\t\t\t;;\n     -+\t\tesac\n     + \t\t__gitcomp \"$subcommands\"\n     + \t\treturn\n       \tfi\n       \n     --\tcase \"$subcommand,$cur\" in\n     + \tcase \"$subcommand,$cur\" in\n      -\tinit,--*)\n      -\t\t__gitcomp \"--cone\"\n      -\t\t;;\n      -\tset,--*)\n      -\t\t__gitcomp \"--stdin\"\n     --\t\t;;\n     ++\t\t*,--*)\n     ++\t\t\t__gitcomp_builtin sparse-checkout_$subcommand \"\" \"--\"\n     + \t\t;;\n      -\t*)\n     --\t\t;;\n     -+\tcase \"$subcommand\" in\n     -+\t\tset)\n     -+\t\t\t__gitcomp \"$__git_sparse_checkout_subcommand_opts --stdin\"\n     -+\t\t\t__gitcomp \"$(git ls-tree -d -r HEAD --name-only)\"\n     -+\t\t\t;;\n     -+\t\tadd)\n     -+\t\t\t__gitcomp \"--stdin\"\n     -+\t\t\t__gitcomp \"$(git ls-tree -d -r HEAD --name-only)\"\n     -+\t\t\t;;\n     -+\t\tinit|reapply)\n     -+\t\t\t__gitcomp \"$__git_sparse_checkout_subcommand_opts\"\n     -+\t\t\t;;\n     -+\t\t*)\n     -+\t\t\t;;\n     ++\t\tset,*|add,*)\n     ++\t\t\tif [ $(__git config core.sparseCheckoutCone) ]; then\n     ++\t\t\t\t__git_complete_index_file \"--directory\"\n     ++\t\t\tfi\n     + \t\t;;\n       \tesac\n       }\n     - \n      \n       ## t/t9902-completion.sh ##\n      @@ t/t9902-completion.sh: test_expect_success 'git checkout - with --detach, complete only references' '\n     @@ t/t9902-completion.sh: test_expect_failure 'sparse-checkout completes subcommand\n       \tEOF\n       '\n       \n     --test_expect_failure 'sparse-checkout completes options' '\n     -+test_expect_success 'sparse-checkout completes options' '\n     - \ttest_completion \"git sparse-checkout --\" <<-\\EOF\n     - \t--help Z\n     - \tEOF\n     - '\n     - \n     --test_expect_failure 'sparse-checkout completes subcommand options' '\n     -+test_expect_success 'sparse-checkout completes subcommand options' '\n     - \ttest_completion \"git sparse-checkout init --\" <<-\\EOF &&\n     - \t--cone Z\n     - \t--no-cone Z\n     -@@ t/t9902-completion.sh: test_expect_failure 'sparse-checkout completes subcommand options' '\n     - \tEOF\n     - '\n     - \n     --test_expect_failure 'sparse-checkout completes directory names' '\n     -+test_expect_success 'sparse-checkout completes directory names' '\n     +-test_expect_failure 'cone mode sparse-checkout completes directory names' '\n     ++test_expect_success 'cone mode sparse-checkout completes directory names' '\n       \t# set up sparse-checkout repo\n       \tgit init sparse-checkout &&\n       \t(\n 3:  aa9ea67180d ! 3:  760cae85bd4 sparse-checkout: limit tab completion to a single level\n     @@ Metadata\n      Author: Lessley Dennington <lessleydennington@gmail.com>\n      \n       ## Commit message ##\n     -    sparse-checkout: limit tab completion to a single level\n     +    completion: ensure cone mode completion with multiple <TAB>s\n      \n     -    Ensure only directories at the current level will be tab-completed with\n     -    the sparse-checkout command. For example, if paths a/b/c/ and a/d/ exist\n     -    in the current directory, running a/<TAB> will result in:\n     +    Ensure users in a cone mode sparse checkout can tab-complete to\n     +    directories at multiple levels with multiple <TAB>s. For example, if path\n     +    a/b/c/ exists in the current directory, running a<TAB>b<TAB> will result\n     +    in:\n      \n     -            a/b/\n     -            a/d/\n     +            a/b/c/\n      \n          The 'sparse-checkout completes directory names' test has also been\n     -    updated/extended according to these changes.\n     +    updated with trailing slashes according to these changes.\n      \n          Co-authored-by: Elijah Newren <newren@gmail.com>\n          Co-authored-by: Lessley Dennington <lessleydennington@gmail.com>\n     @@ contrib/completion/git-completion.bash: _git_show_branch ()\n      +     fi\n      +}\n      +\n     - __git_sparse_checkout_subcommand_opts=\"--cone --no-cone --sparse-index --no-sparse-index\"\n     - \n       _git_sparse_checkout ()\n     + {\n     + \tlocal subcommands=\"list init set disable add reapply\"\n     + \tlocal subcommand=\"$(__git_find_on_cmdline \"$subcommands\")\"\n     +-\n     + \tif [ -z \"$subcommand\" ]; then\n     + \t\t__gitcomp \"$subcommands\"\n     + \t\treturn\n      @@ contrib/completion/git-completion.bash: _git_sparse_checkout ()\n     - \tcase \"$subcommand\" in\n     - \t\tset)\n     - \t\t\t__gitcomp \"$__git_sparse_checkout_subcommand_opts --stdin\"\n     --\t\t\t__gitcomp \"$(git ls-tree -d -r HEAD --name-only)\"\n     -+\t\t\t__gitcomp_directories\n     - \t\t\t;;\n     - \t\tadd)\n     - \t\t\t__gitcomp \"--stdin\"\n     --\t\t\t__gitcomp \"$(git ls-tree -d -r HEAD --name-only)\"\n     -+\t\t\t__gitcomp_directories\n     - \t\t\t;;\n     - \t\tinit|reapply)\n     - \t\t\t__gitcomp \"$__git_sparse_checkout_subcommand_opts\"\n     + \t\t;;\n     + \t\tset,*|add,*)\n     + \t\t\tif [ $(__git config core.sparseCheckoutCone) ]; then\n     +-\t\t\t\t__git_complete_index_file \"--directory\"\n     ++\t\t\t\t__gitcomp_directories\n     + \t\t\tfi\n     + \t\t;;\n     + \tesac\n      \n       ## t/t9902-completion.sh ##\n     -@@ t/t9902-completion.sh: test_expect_success 'sparse-checkout completes directory names' '\n     +@@ t/t9902-completion.sh: test_expect_success 'cone mode sparse-checkout completes directory names' '\n       \t(\n       \t\tcd sparse-checkout &&\n       \t\ttest_completion \"git sparse-checkout set f\" <<-\\EOF\n     --\t\tfolder1 Z\n     --\t\tfolder1/0 Z\n     --\t\tfolder1/0/1 Z\n     --\t\tfolder2 Z\n     --\t\tfolder2/0 Z\n     --\t\tfolder3 Z\n     +-\t\tfolder1\n     +-\t\tfolder2\n     +-\t\tfolder3\n      +\t\tfolder1/\n      +\t\tfolder2/\n      +\t\tfolder3/\n     -+\t\tEOF\n     -+\t) &&\n     -+\n     -+\t(\n     -+\t\tcd sparse-checkout &&\n     -+\t\ttest_completion \"git sparse-checkout set folder1/\" <<-\\EOF\n     + \t\tEOF\n     + \t) &&\n     + \n     + \t(\n     + \t\tcd sparse-checkout &&\n     + \t\ttest_completion \"git sparse-checkout set folder1/\" <<-\\EOF\n     +-\t\tfolder1/0\n      +\t\tfolder1/0/\n     -+\t\tEOF\n     -+\t) &&\n     -+\n     -+\t(\n     -+\t\tcd sparse-checkout &&\n     -+\t\ttest_completion \"git sparse-checkout set folder1/0/\" <<-\\EOF\n     + \t\tEOF\n     + \t) &&\n     + \n     + \t(\n     + \t\tcd sparse-checkout &&\n     + \t\ttest_completion \"git sparse-checkout set folder1/0/\" <<-\\EOF\n     +-\t\tfolder1/0/1\n      +\t\tfolder1/0/1/\n       \t\tEOF\n       \t) &&\n       \n       \t(\n       \t\tcd sparse-checkout/folder1 &&\n     --\t\ttest_completion \"git sparse-checkout add \" <<-\\EOF\n     --\t\t./ Z\n     --\t\t0 Z\n     --\t\t0/1 Z\n     -+\t\ttest_completion \"git sparse-checkout add 0\" <<-\\EOF\n     + \t\ttest_completion \"git sparse-checkout add 0\" <<-\\EOF\n     +-\t\t0\n      +\t\t0/\n       \t\tEOF\n       \t)\n\n-- \ngitgitgadget\n"},{"id":"447130","messageId":"5bb598a055dd8121ad5c7228b11618b037029478.1643318514.git.gitgitgadget@gmail.com","threadId":"57165","inReplyTo":"pull.1108.v4.git.1643318514.gitgitgadget@gmail.com","subject":"[PATCH v4 1/3] completion: add sparse-checkout tests","fromName":"Lessley Dennington via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-01-27T21:21:52Z","receivedAt":"2022-01-27T21:22:00Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"From: Lessley Dennington <lessleydennington@gmail.com>\n\nAdd tests for missing/incorrect components of custom tab completion for\nthe sparse-checkout command. These tests specifically highlight the\nfollowing:\n\n1. git sparse-checkout <TAB> results in an incomplete list of subcommands\n(it is missing reapply and add).\n2. git sparse-checkout set <TAB> and git sparse-checkout add <TAB> show\nboth file names and directory names. While this is the correct behavior\nfor non-cone mode, cone mode sparse checkouts should complete only\ndirectory names.\n\nAlthough the first two of these tests currently fail, they will succeed\nwith the sparse-checkout modifications in git-completion.bash in the next\ncommit in this series.\n\nSigned-off-by: Lessley Dennington <lessleydennington@gmail.com>\n---\n t/t9902-completion.sh | 75 +++++++++++++++++++++++++++++++++++++++++++\n 1 file changed, 75 insertions(+)\n\ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex 518203fbe07..6004d854102 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -1447,6 +1447,81 @@ test_expect_success 'git checkout - with --detach, complete only references' '\n \tEOF\n '\n \n+test_expect_failure 'sparse-checkout completes subcommands' '\n+\ttest_completion \"git sparse-checkout \" <<-\\EOF\n+\tlist Z\n+\tinit Z\n+\tset Z\n+\tadd Z\n+\treapply Z\n+\tdisable Z\n+\tEOF\n+'\n+\n+test_expect_failure 'cone mode sparse-checkout completes directory names' '\n+\t# set up sparse-checkout repo\n+\tgit init sparse-checkout &&\n+\t(\n+\t\tcd sparse-checkout &&\n+\t\tmkdir -p folder1/0/1 folder2/0 folder3 &&\n+\t\ttouch folder1/0/1/t.txt &&\n+\t\ttouch folder2/0/t.txt &&\n+\t\ttouch folder3/t.txt &&\n+\t\tgit add . &&\n+\t\tgit commit -am \"Initial commit\"\n+\t) &&\n+\n+\t# initialize sparse-checkout definitions\n+\tgit -C sparse-checkout sparse-checkout set --cone folder1/0 folder3 &&\n+\n+\t# test tab completion\n+\t(\n+\t\tcd sparse-checkout &&\n+\t\ttest_completion \"git sparse-checkout set f\" <<-\\EOF\n+\t\tfolder1\n+\t\tfolder2\n+\t\tfolder3\n+\t\tEOF\n+\t) &&\n+\n+\t(\n+\t\tcd sparse-checkout &&\n+\t\ttest_completion \"git sparse-checkout set folder1/\" <<-\\EOF\n+\t\tfolder1/0\n+\t\tEOF\n+\t) &&\n+\n+\t(\n+\t\tcd sparse-checkout &&\n+\t\ttest_completion \"git sparse-checkout set folder1/0/\" <<-\\EOF\n+\t\tfolder1/0/1\n+\t\tEOF\n+\t) &&\n+\n+\t(\n+\t\tcd sparse-checkout/folder1 &&\n+\t\ttest_completion \"git sparse-checkout add 0\" <<-\\EOF\n+\t\t0\n+\t\tEOF\n+\t)\n+'\n+\n+test_expect_success 'non-cone mode sparse-checkout uses bash completion' '\n+\t# reset sparse-checkout repo to non-cone mode\n+\tgit -C sparse-checkout sparse-checkout disable &&\n+\tgit -C sparse-checkout sparse-checkout set &&\n+\n+\t# test tab completion\n+\t(\n+\t\tcd sparse-checkout &&\n+\t\t# expected to be empty since we have not configured\n+\t\t# custom completion for non-cone mode\n+\t\ttest_completion \"git sparse-checkout set f\" <<-\\EOF\n+\n+\t\tEOF\n+\t)\n+'\n+\n test_expect_success 'git switch - with -d, complete all references' '\n \ttest_completion \"git switch -d \" <<-\\EOF\n \tHEAD Z\n-- \ngitgitgadget\n\n"},{"id":"447133","messageId":"7d70beb2a6b3967c51d1d7feb34bfb9368066cdb.1643318514.git.gitgitgadget@gmail.com","threadId":"57165","inReplyTo":"pull.1108.v4.git.1643318514.gitgitgadget@gmail.com","subject":"[PATCH v4 2/3] completion: sparse-checkout updates","fromName":"Lessley Dennington via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-01-27T21:21:53Z","receivedAt":"2022-01-27T21:22:01Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"From: Lessley Dennington <lessleydennington@gmail.com>\n\nFix custom tab completion for the sparse-checkout command. This will\nensure:\n\n1. The full list of subcommands is provided when users enter git\nsparse-checkout <TAB>.\n2. Subcommand options are tab-completable.\n3. A list of directories (but not files) is provided when users enter git\nsparse-checkout add <TAB> or git sparse-checkout set <TAB> in cone mode\nonly. In non-cone mode, these commands will continue to complete both\ndirectory and file names.\n\nFailing tests that were added in the previous commit to verify these\nscenarios are now passing with these updates.\n\nSigned-off-by: Lessley Dennington <lessleydennington@gmail.com>\n---\n contrib/completion/git-completion.bash | 15 ++++++++-------\n t/t9902-completion.sh                  |  4 ++--\n 2 files changed, 10 insertions(+), 9 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex c82ccaebcc7..a920cdab201 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -2988,21 +2988,22 @@ _git_show_branch ()\n \n _git_sparse_checkout ()\n {\n-\tlocal subcommands=\"list init set disable\"\n+\tlocal subcommands=\"list init set disable add reapply\"\n \tlocal subcommand=\"$(__git_find_on_cmdline \"$subcommands\")\"\n+\n \tif [ -z \"$subcommand\" ]; then\n \t\t__gitcomp \"$subcommands\"\n \t\treturn\n \tfi\n \n \tcase \"$subcommand,$cur\" in\n-\tinit,--*)\n-\t\t__gitcomp \"--cone\"\n-\t\t;;\n-\tset,--*)\n-\t\t__gitcomp \"--stdin\"\n+\t\t*,--*)\n+\t\t\t__gitcomp_builtin sparse-checkout_$subcommand \"\" \"--\"\n \t\t;;\n-\t*)\n+\t\tset,*|add,*)\n+\t\t\tif [ $(__git config core.sparseCheckoutCone) ]; then\n+\t\t\t\t__git_complete_index_file \"--directory\"\n+\t\t\tfi\n \t\t;;\n \tesac\n }\ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex 6004d854102..f56ba3f64c9 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -1447,7 +1447,7 @@ test_expect_success 'git checkout - with --detach, complete only references' '\n \tEOF\n '\n \n-test_expect_failure 'sparse-checkout completes subcommands' '\n+test_expect_success 'sparse-checkout completes subcommands' '\n \ttest_completion \"git sparse-checkout \" <<-\\EOF\n \tlist Z\n \tinit Z\n@@ -1458,7 +1458,7 @@ test_expect_failure 'sparse-checkout completes subcommands' '\n \tEOF\n '\n \n-test_expect_failure 'cone mode sparse-checkout completes directory names' '\n+test_expect_success 'cone mode sparse-checkout completes directory names' '\n \t# set up sparse-checkout repo\n \tgit init sparse-checkout &&\n \t(\n-- \ngitgitgadget\n\n"},{"id":"447132","messageId":"760cae85bd4163d9cbef1585186cda60c8c3b35b.1643318514.git.gitgitgadget@gmail.com","threadId":"57165","inReplyTo":"pull.1108.v4.git.1643318514.gitgitgadget@gmail.com","subject":"[PATCH v4 3/3] completion: ensure cone mode completion with multiple <TAB>s","fromName":"Lessley Dennington via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-01-27T21:21:54Z","receivedAt":"2022-01-27T21:22:02Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"From: Lessley Dennington <lessleydennington@gmail.com>\n\nEnsure users in a cone mode sparse checkout can tab-complete to\ndirectories at multiple levels with multiple <TAB>s. For example, if path\na/b/c/ exists in the current directory, running a<TAB>b<TAB> will result\nin:\n\n        a/b/c/\n\nThe 'sparse-checkout completes directory names' test has also been\nupdated with trailing slashes according to these changes.\n\nCo-authored-by: Elijah Newren <newren@gmail.com>\nCo-authored-by: Lessley Dennington <lessleydennington@gmail.com>\nSigned-off-by: Lessley Dennington <lessleydennington@gmail.com>\n---\n contrib/completion/git-completion.bash | 33 ++++++++++++++++++++++++--\n t/t9902-completion.sh                  | 12 +++++-----\n 2 files changed, 37 insertions(+), 8 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex a920cdab201..defcc8560c1 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -2986,11 +2986,40 @@ _git_show_branch ()\n \t__git_complete_revlist\n }\n \n+__gitcomp_directories ()\n+{\n+     local _tmp_dir _tmp_completions\n+\n+     # Get the directory of the current token; this differs from dirname\n+     # in that it keeps up to the final trailing slash.  If no slash found\n+     # that's fine too.\n+     [[ \"$cur\" =~ .*/ ]]\n+     _tmp_dir=$BASH_REMATCH\n+\n+     # Find possible directory completions, adding trailing '/' characters\n+     _tmp_completions=\"$(git ls-tree -d --name-only HEAD $_tmp_dir |\n+         sed -e s%$%/%)\"\n+\n+     if [[ -n \"$_tmp_completions\" ]]; then\n+         # There were some directory completions, so find ones that\n+         # start with \"$cur\", the current token, and put those in COMPREPLY\n+         local i=0 c IFS=$' \\t\\n'\n+         for c in $_tmp_completions; do\n+             if [[ $c == \"$cur\"* ]]; then\n+                 COMPREPLY+=(\"$c\")\n+             fi\n+         done\n+     elif [[ \"$cur\" =~ /$ ]]; then\n+         # No possible further completions any deeper, so assume we're at\n+         # a leaf directory and just consider it complete\n+         __gitcomp_direct_append \"$cur \"\n+     fi\n+}\n+\n _git_sparse_checkout ()\n {\n \tlocal subcommands=\"list init set disable add reapply\"\n \tlocal subcommand=\"$(__git_find_on_cmdline \"$subcommands\")\"\n-\n \tif [ -z \"$subcommand\" ]; then\n \t\t__gitcomp \"$subcommands\"\n \t\treturn\n@@ -3002,7 +3031,7 @@ _git_sparse_checkout ()\n \t\t;;\n \t\tset,*|add,*)\n \t\t\tif [ $(__git config core.sparseCheckoutCone) ]; then\n-\t\t\t\t__git_complete_index_file \"--directory\"\n+\t\t\t\t__gitcomp_directories\n \t\t\tfi\n \t\t;;\n \tesac\ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex f56ba3f64c9..c04fc25fa32 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -1478,30 +1478,30 @@ test_expect_success 'cone mode sparse-checkout completes directory names' '\n \t(\n \t\tcd sparse-checkout &&\n \t\ttest_completion \"git sparse-checkout set f\" <<-\\EOF\n-\t\tfolder1\n-\t\tfolder2\n-\t\tfolder3\n+\t\tfolder1/\n+\t\tfolder2/\n+\t\tfolder3/\n \t\tEOF\n \t) &&\n \n \t(\n \t\tcd sparse-checkout &&\n \t\ttest_completion \"git sparse-checkout set folder1/\" <<-\\EOF\n-\t\tfolder1/0\n+\t\tfolder1/0/\n \t\tEOF\n \t) &&\n \n \t(\n \t\tcd sparse-checkout &&\n \t\ttest_completion \"git sparse-checkout set folder1/0/\" <<-\\EOF\n-\t\tfolder1/0/1\n+\t\tfolder1/0/1/\n \t\tEOF\n \t) &&\n \n \t(\n \t\tcd sparse-checkout/folder1 &&\n \t\ttest_completion \"git sparse-checkout add 0\" <<-\\EOF\n-\t\t0\n+\t\t0/\n \t\tEOF\n \t)\n '\n-- \ngitgitgadget\n"},{"id":"447148","messageId":"CABPp-BFdaLpmcnU2DUy0Wx1rapsWckz4=aG5yTGdCcM3U3on8Q@mail.gmail.com","threadId":"57165","inReplyTo":"5bb598a055dd8121ad5c7228b11618b037029478.1643318514.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v4 1/3] completion: add sparse-checkout tests","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2022-01-28T00:08:20Z","receivedAt":"2022-01-28T00:08:37Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Thu, Jan 27, 2022 at 1:21 PM Lessley Dennington via GitGitGadget\n<gitgitgadget@gmail.com> wrote:\n>\n> From: Lessley Dennington <lessleydennington@gmail.com>\n>\n> Add tests for missing/incorrect components of custom tab completion for\n> the sparse-checkout command. These tests specifically highlight the\n> following:\n>\n> 1. git sparse-checkout <TAB> results in an incomplete list of subcommands\n> (it is missing reapply and add).\n> 2. git sparse-checkout set <TAB> and git sparse-checkout add <TAB> show\n> both file names and directory names. While this is the correct behavior\n\ns/is/may be/\n\n(Yes, Junio declared it to be the behavior he wanted to see, but\nthere's a difference between \"this is clearly desired behavior\" and\n\"here's the official edict declaring which bad option is the lesser\nevil\" situation.  As Junio pointed out, completing on files and\ndirectories avoids one type of surprise for users -- but as I've\npointed out elsewhere, it introduces multiple other types of negative\nsurprises.)\n\n> for non-cone mode, cone mode sparse checkouts should complete only\n> directory names.\n>\n> Although the first two of these tests currently fail, they will succeed\n> with the sparse-checkout modifications in git-completion.bash in the next\n> commit in this series.\n>\n> Signed-off-by: Lessley Dennington <lessleydennington@gmail.com>\n> ---\n>  t/t9902-completion.sh | 75 +++++++++++++++++++++++++++++++++++++++++++\n>  1 file changed, 75 insertions(+)\n>\n> diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\n> index 518203fbe07..6004d854102 100755\n> --- a/t/t9902-completion.sh\n> +++ b/t/t9902-completion.sh\n> @@ -1447,6 +1447,81 @@ test_expect_success 'git checkout - with --detach, complete only references' '\n>         EOF\n>  '\n>\n> +test_expect_failure 'sparse-checkout completes subcommands' '\n> +       test_completion \"git sparse-checkout \" <<-\\EOF\n> +       list Z\n> +       init Z\n> +       set Z\n> +       add Z\n> +       reapply Z\n> +       disable Z\n> +       EOF\n> +'\n> +\n> +test_expect_failure 'cone mode sparse-checkout completes directory names' '\n> +       # set up sparse-checkout repo\n> +       git init sparse-checkout &&\n> +       (\n> +               cd sparse-checkout &&\n> +               mkdir -p folder1/0/1 folder2/0 folder3 &&\n> +               touch folder1/0/1/t.txt &&\n> +               touch folder2/0/t.txt &&\n> +               touch folder3/t.txt &&\n> +               git add . &&\n> +               git commit -am \"Initial commit\"\n> +       ) &&\n> +\n> +       # initialize sparse-checkout definitions\n> +       git -C sparse-checkout sparse-checkout set --cone folder1/0 folder3 &&\n> +\n> +       # test tab completion\n> +       (\n> +               cd sparse-checkout &&\n> +               test_completion \"git sparse-checkout set f\" <<-\\EOF\n> +               folder1\n> +               folder2\n> +               folder3\n> +               EOF\n> +       ) &&\n> +\n> +       (\n> +               cd sparse-checkout &&\n> +               test_completion \"git sparse-checkout set folder1/\" <<-\\EOF\n> +               folder1/0\n> +               EOF\n> +       ) &&\n> +\n> +       (\n> +               cd sparse-checkout &&\n> +               test_completion \"git sparse-checkout set folder1/0/\" <<-\\EOF\n> +               folder1/0/1\n> +               EOF\n> +       ) &&\n> +\n> +       (\n> +               cd sparse-checkout/folder1 &&\n> +               test_completion \"git sparse-checkout add 0\" <<-\\EOF\n> +               0\n> +               EOF\n> +       )\n> +'\n> +\n> +test_expect_success 'non-cone mode sparse-checkout uses bash completion' '\n> +       # reset sparse-checkout repo to non-cone mode\n> +       git -C sparse-checkout sparse-checkout disable &&\n> +       git -C sparse-checkout sparse-checkout set &&\n\nCan we add a --no-cone here in preparation for the default to switch?\n\n\n> +\n> +       # test tab completion\n> +       (\n> +               cd sparse-checkout &&\n> +               # expected to be empty since we have not configured\n> +               # custom completion for non-cone mode\n> +               test_completion \"git sparse-checkout set f\" <<-\\EOF\n> +\n> +               EOF\n> +       )\n> +'\n> +\n>  test_expect_success 'git switch - with -d, complete all references' '\n>         test_completion \"git switch -d \" <<-\\EOF\n>         HEAD Z\n> --\n> gitgitgadget\n>\n"},{"id":"447163","messageId":"CABPp-BFG6fD3hDTrG_HZP9qv0qYaHBFxV3idik6YHE53cnFt6Q@mail.gmail.com","threadId":"57165","inReplyTo":"7d70beb2a6b3967c51d1d7feb34bfb9368066cdb.1643318514.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v4 2/3] completion: sparse-checkout updates","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2022-01-28T01:21:47Z","receivedAt":"2022-01-28T01:22:02Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Thu, Jan 27, 2022 at 1:21 PM Lessley Dennington via GitGitGadget\n<gitgitgadget@gmail.com> wrote:\n>\n> From: Lessley Dennington <lessleydennington@gmail.com>\n>\n> Fix custom tab completion for the sparse-checkout command. This will\n> ensure:\n>\n> 1. The full list of subcommands is provided when users enter git\n> sparse-checkout <TAB>.\n> 2. Subcommand options are tab-completable.\n> 3. A list of directories (but not files) is provided when users enter git\n> sparse-checkout add <TAB> or git sparse-checkout set <TAB> in cone mode\n> only. In non-cone mode, these commands will continue to complete both\n> directory and file names.\n>\n> Failing tests that were added in the previous commit to verify these\n> scenarios are now passing with these updates.\n>\n> Signed-off-by: Lessley Dennington <lessleydennington@gmail.com>\n> ---\n>  contrib/completion/git-completion.bash | 15 ++++++++-------\n>  t/t9902-completion.sh                  |  4 ++--\n>  2 files changed, 10 insertions(+), 9 deletions(-)\n>\n> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\n> index c82ccaebcc7..a920cdab201 100644\n> --- a/contrib/completion/git-completion.bash\n> +++ b/contrib/completion/git-completion.bash\n> @@ -2988,21 +2988,22 @@ _git_show_branch ()\n>\n>  _git_sparse_checkout ()\n>  {\n> -       local subcommands=\"list init set disable\"\n> +       local subcommands=\"list init set disable add reapply\"\n>         local subcommand=\"$(__git_find_on_cmdline \"$subcommands\")\"\n> +\n>         if [ -z \"$subcommand\" ]; then\n>                 __gitcomp \"$subcommands\"\n>                 return\n>         fi\n>\n>         case \"$subcommand,$cur\" in\n> -       init,--*)\n> -               __gitcomp \"--cone\"\n> -               ;;\n> -       set,--*)\n> -               __gitcomp \"--stdin\"\n> +               *,--*)\n> +                       __gitcomp_builtin sparse-checkout_$subcommand \"\" \"--\"\n>                 ;;\n> -       *)\n> +               set,*|add,*)\n> +                       if [ $(__git config core.sparseCheckoutCone) ]; then\n> +                               __git_complete_index_file \"--directory\"\n> +                       fi\n\n--directory only affects how untracked files are presented in `git\nls-files` (which _git_complete_index_file uses), and you're not asking\nfor untracked paths at all here.  So you've got a useless flag.\n\nTesting this commit out, I can verify that it completes on all tracked\npaths in the index.  Perhaps that was an intended intermediate step,\nbut if so the commit message needs to be changed since it claims this\ncommit is doing something else.\n\nThere's also a problem in that `git sparse-checkout --cone path<TAB>`\nis not using this codepath.  If the user specifies --cone, then we\nshould give them cone-mode-style completion the same as if they\nalready have the config setting set.  Or, we at least need to mention\nin the commit message that we don't yet correctly check for the\n`--cone` option to get the right style of completion and are leaving\nit for future work.\n\n>                 ;;\n>         esac\n>  }\n> diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\n> index 6004d854102..f56ba3f64c9 100755\n> --- a/t/t9902-completion.sh\n> +++ b/t/t9902-completion.sh\n> @@ -1447,7 +1447,7 @@ test_expect_success 'git checkout - with --detach, complete only references' '\n>         EOF\n>  '\n>\n> -test_expect_failure 'sparse-checkout completes subcommands' '\n> +test_expect_success 'sparse-checkout completes subcommands' '\n>         test_completion \"git sparse-checkout \" <<-\\EOF\n>         list Z\n>         init Z\n> @@ -1458,7 +1458,7 @@ test_expect_failure 'sparse-checkout completes subcommands' '\n>         EOF\n>  '\n>\n> -test_expect_failure 'cone mode sparse-checkout completes directory names' '\n> +test_expect_success 'cone mode sparse-checkout completes directory names' '\n>         # set up sparse-checkout repo\n>         git init sparse-checkout &&\n>         (\n> --\n> gitgitgadget\n>\n"},{"id":"447165","messageId":"CABPp-BEq9pTqsy_R_SR1DSgUK58ubNR1Gk4G1RoL8wkadyo6zw@mail.gmail.com","threadId":"57165","inReplyTo":"760cae85bd4163d9cbef1585186cda60c8c3b35b.1643318514.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v4 3/3] completion: ensure cone mode completion with multiple <TAB>s","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2022-01-28T01:53:20Z","receivedAt":"2022-01-28T01:53:36Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Thu, Jan 27, 2022 at 1:21 PM Lessley Dennington via GitGitGadget\n<gitgitgadget@gmail.com> wrote:\n>\n> From: Lessley Dennington <lessleydennington@gmail.com>\n>\n> Ensure users in a cone mode sparse checkout can tab-complete to\n> directories at multiple levels with multiple <TAB>s. For example, if path\n> a/b/c/ exists in the current directory, running a<TAB>b<TAB> will result\n> in:\n>\n>         a/b/c/\n\nUm, didn't that already happen before this commit (other than the\ntrailing slash)?\n\nIn my mind, the reasons to switch from __git_complete_index_file to\n__gitcomp_directories are:\n\n  * __git_complete_index_file() completes on files, and we want only directories\n  * __git_complete_index_file() can only complete on paths stored in\nthe index.  With --sparse-index mode, the directory (and all files\nunder it) we want to complete on may not exist in the index.\n\nBoth of these things make __git_complete_index_file() unsuitable.\n\n> The 'sparse-checkout completes directory names' test has also been\n> updated with trailing slashes according to these changes.\n>\n> Co-authored-by: Elijah Newren <newren@gmail.com>\n> Co-authored-by: Lessley Dennington <lessleydennington@gmail.com>\n> Signed-off-by: Lessley Dennington <lessleydennington@gmail.com>\n> ---\n>  contrib/completion/git-completion.bash | 33 ++++++++++++++++++++++++--\n>  t/t9902-completion.sh                  | 12 +++++-----\n>  2 files changed, 37 insertions(+), 8 deletions(-)\n>\n> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\n> index a920cdab201..defcc8560c1 100644\n> --- a/contrib/completion/git-completion.bash\n> +++ b/contrib/completion/git-completion.bash\n> @@ -2986,11 +2986,40 @@ _git_show_branch ()\n>         __git_complete_revlist\n>  }\n>\n> +__gitcomp_directories ()\n> +{\n> +     local _tmp_dir _tmp_completions\n> +\n> +     # Get the directory of the current token; this differs from dirname\n> +     # in that it keeps up to the final trailing slash.  If no slash found\n> +     # that's fine too.\n> +     [[ \"$cur\" =~ .*/ ]]\n> +     _tmp_dir=$BASH_REMATCH\n> +\n> +     # Find possible directory completions, adding trailing '/' characters\n> +     _tmp_completions=\"$(git ls-tree -d --name-only HEAD $_tmp_dir |\n> +         sed -e s%$%/%)\"\n> +\n> +     if [[ -n \"$_tmp_completions\" ]]; then\n> +         # There were some directory completions, so find ones that\n> +         # start with \"$cur\", the current token, and put those in COMPREPLY\n> +         local i=0 c IFS=$' \\t\\n'\n> +         for c in $_tmp_completions; do\n> +             if [[ $c == \"$cur\"* ]]; then\n> +                 COMPREPLY+=(\"$c\")\n> +             fi\n> +         done\n> +     elif [[ \"$cur\" =~ /$ ]]; then\n> +         # No possible further completions any deeper, so assume we're at\n> +         # a leaf directory and just consider it complete\n> +         __gitcomp_direct_append \"$cur \"\n> +     fi\n> +}\n\nAs noted at [1], this is going to have problems with special\ncharacters.  In the testcase setup in t9902, modify the repository as\nfollows:\n\n   mkdir \"spaces are evil\"\n   mkdir \"$(printf \"tabs\\tare\\tworse\")\"\n   >\"spaces are evil/randomfile\"\n   >\"$(printf \"tabs\\tare\\tworse\")/randomfile\"\n   git add .\n   git commit -m \"Add directories containing unusual characters\"\n\nand then try to complete any of these:\n\n  git sparse-checkout set --cone spa<TAB>\n  git sparse-checkout set --cone tab<TAB>\n  git sparse-checkout set --cone ev<TAB>\n  git sparse-checkout set --cone \"tab<TAB>\n\nYou'll see it either gets the wrong thing, or doesn't get nothing (and\nwhen it should get nothing, it gets something instead).\n\nWe do definitely want to use some form of __gitcomp_directories as I\nnoted above, but we'll have to lift some of the intelligent quoting\nlogic out of __git_complete_index_file.  It may be a little easier\nsince we don't have to worry about \"full file path needs to be quoted\neven though leading directory does not need to be\".\n\n(Also, if it makes it easier to deal with the testcases, you can just\nuse non-ascii characters instead of the tab character -- just run `git\nshortlog -sn origin/master` in git.git, find someone's name with such\na character and copy and paste it into the directory name.  For\nexample, you could use the á from Gábor)\n\n[1] https://lore.kernel.org/git/20220115095725.GA1738@szeder.dev/\n\n\n\n\n> +\n>  _git_sparse_checkout ()\n>  {\n>         local subcommands=\"list init set disable add reapply\"\n>         local subcommand=\"$(__git_find_on_cmdline \"$subcommands\")\"\n> -\n>         if [ -z \"$subcommand\" ]; then\n>                 __gitcomp \"$subcommands\"\n>                 return\n> @@ -3002,7 +3031,7 @@ _git_sparse_checkout ()\n>                 ;;\n>                 set,*|add,*)\n>                         if [ $(__git config core.sparseCheckoutCone) ]; then\n> -                               __git_complete_index_file \"--directory\"\n> +                               __gitcomp_directories\n>                         fi\n>                 ;;\n>         esac\n> diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\n> index f56ba3f64c9..c04fc25fa32 100755\n> --- a/t/t9902-completion.sh\n> +++ b/t/t9902-completion.sh\n> @@ -1478,30 +1478,30 @@ test_expect_success 'cone mode sparse-checkout completes directory names' '\n>         (\n>                 cd sparse-checkout &&\n>                 test_completion \"git sparse-checkout set f\" <<-\\EOF\n> -               folder1\n> -               folder2\n> -               folder3\n> +               folder1/\n> +               folder2/\n> +               folder3/\n>                 EOF\n>         ) &&\n>\n>         (\n>                 cd sparse-checkout &&\n>                 test_completion \"git sparse-checkout set folder1/\" <<-\\EOF\n> -               folder1/0\n> +               folder1/0/\n>                 EOF\n>         ) &&\n>\n>         (\n>                 cd sparse-checkout &&\n>                 test_completion \"git sparse-checkout set folder1/0/\" <<-\\EOF\n> -               folder1/0/1\n> +               folder1/0/1/\n>                 EOF\n>         ) &&\n>\n>         (\n>                 cd sparse-checkout/folder1 &&\n>                 test_completion \"git sparse-checkout add 0\" <<-\\EOF\n> -               0\n> +               0/\n>                 EOF\n>         )\n>  '\n> --\n> gitgitgadget\n"},{"id":"447167","messageId":"xmqqtudoy653.fsf@gitster.g","threadId":"57165","inReplyTo":"CABPp-BFdaLpmcnU2DUy0Wx1rapsWckz4=aG5yTGdCcM3U3on8Q@mail.gmail.com","subject":"Re: [PATCH v4 1/3] completion: add sparse-checkout tests","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-01-28T01:56:56Z","receivedAt":"2022-01-28T01:57:00Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Elijah Newren <newren@gmail.com> writes:\n\n> On Thu, Jan 27, 2022 at 1:21 PM Lessley Dennington via GitGitGadget\n> <gitgitgadget@gmail.com> wrote:\n>>\n>> From: Lessley Dennington <lessleydennington@gmail.com>\n>>\n>> Add tests for missing/incorrect components of custom tab completion for\n>> the sparse-checkout command. These tests specifically highlight the\n>> following:\n>>\n>> 1. git sparse-checkout <TAB> results in an incomplete list of subcommands\n>> (it is missing reapply and add).\n>> 2. git sparse-checkout set <TAB> and git sparse-checkout add <TAB> show\n>> both file names and directory names. While this is the correct behavior\n>\n> s/is/may be/\n\nI would stop at \"this may be a less surprising behaviour\" without\ngoing into \"correctness\".\n\n>> +test_expect_success 'non-cone mode sparse-checkout uses bash completion' '\n>> +       # reset sparse-checkout repo to non-cone mode\n>> +       git -C sparse-checkout sparse-checkout disable &&\n>> +       git -C sparse-checkout sparse-checkout set &&\n>\n> Can we add a --no-cone here in preparation for the default to switch?\n\nIt would be good to do so, if we plan to switch the default.\n"},{"id":"447170","messageId":"CABPp-BH0ED=6+tcjaxDFypdopH3LtQsDYWbBUW0B9icZjTGMKw@mail.gmail.com","threadId":"57165","inReplyTo":"xmqqtudoy653.fsf@gitster.g","subject":"Re: [PATCH v4 1/3] completion: add sparse-checkout tests","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2022-01-28T02:04:16Z","receivedAt":"2022-01-28T02:04:30Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Thu, Jan 27, 2022 at 5:56 PM Junio C Hamano <gitster@pobox.com> wrote:\n>\n> Elijah Newren <newren@gmail.com> writes:\n>\n> > On Thu, Jan 27, 2022 at 1:21 PM Lessley Dennington via GitGitGadget\n> > <gitgitgadget@gmail.com> wrote:\n> >>\n> >> From: Lessley Dennington <lessleydennington@gmail.com>\n> >>\n> >> Add tests for missing/incorrect components of custom tab completion for\n> >> the sparse-checkout command. These tests specifically highlight the\n> >> following:\n> >>\n> >> 1. git sparse-checkout <TAB> results in an incomplete list of subcommands\n> >> (it is missing reapply and add).\n> >> 2. git sparse-checkout set <TAB> and git sparse-checkout add <TAB> show\n> >> both file names and directory names. While this is the correct behavior\n> >\n> > s/is/may be/\n>\n> I would stop at \"this may be a less surprising behaviour\" without\n> going into \"correctness\".\n\nOoh, I like that wording even better.\n\n> >> +test_expect_success 'non-cone mode sparse-checkout uses bash completion' '\n> >> +       # reset sparse-checkout repo to non-cone mode\n> >> +       git -C sparse-checkout sparse-checkout disable &&\n> >> +       git -C sparse-checkout sparse-checkout set &&\n> >\n> > Can we add a --no-cone here in preparation for the default to switch?\n>\n> It would be good to do so, if we plan to switch the default.\n\nWe've talked about it for a few cycles, so I created a patch series to\ndo so.  But it depends on two or three in-flight series (from\nVictoria, myself, and now Stolee) to avoid textual conflicts, so I've\nbeen waiting for those to settle.\n"},{"id":"447358","messageId":"82bb12d0-0505-1997-21ba-b9863bfdf2c8@gmail.com","threadId":"57165","inReplyTo":"CABPp-BFG6fD3hDTrG_HZP9qv0qYaHBFxV3idik6YHE53cnFt6Q@mail.gmail.com","subject":"Re: [PATCH v4 2/3] completion: sparse-checkout updates","fromName":"Lessley Dennington","fromEmail":"lessleydennington@gmail.com","sentAt":"2022-01-31T20:03:46Z","receivedAt":"2022-01-31T20:03:52Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"\n\nOn 1/27/22 5:21 PM, Elijah Newren wrote:\n> On Thu, Jan 27, 2022 at 1:21 PM Lessley Dennington via GitGitGadget\n> <gitgitgadget@gmail.com> wrote:\n>>\n>> From: Lessley Dennington <lessleydennington@gmail.com>\n>>\n>> Fix custom tab completion for the sparse-checkout command. This will\n>> ensure:\n>>\n>> 1. The full list of subcommands is provided when users enter git\n>> sparse-checkout <TAB>.\n>> 2. Subcommand options are tab-completable.\n>> 3. A list of directories (but not files) is provided when users enter git\n>> sparse-checkout add <TAB> or git sparse-checkout set <TAB> in cone mode\n>> only. In non-cone mode, these commands will continue to complete both\n>> directory and file names.\n>>\n>> Failing tests that were added in the previous commit to verify these\n>> scenarios are now passing with these updates.\n>>\n>> Signed-off-by: Lessley Dennington <lessleydennington@gmail.com>\n>> ---\n>>   contrib/completion/git-completion.bash | 15 ++++++++-------\n>>   t/t9902-completion.sh                  |  4 ++--\n>>   2 files changed, 10 insertions(+), 9 deletions(-)\n>>\n>> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\n>> index c82ccaebcc7..a920cdab201 100644\n>> --- a/contrib/completion/git-completion.bash\n>> +++ b/contrib/completion/git-completion.bash\n>> @@ -2988,21 +2988,22 @@ _git_show_branch ()\n>>\n>>   _git_sparse_checkout ()\n>>   {\n>> -       local subcommands=\"list init set disable\"\n>> +       local subcommands=\"list init set disable add reapply\"\n>>          local subcommand=\"$(__git_find_on_cmdline \"$subcommands\")\"\n>> +\n>>          if [ -z \"$subcommand\" ]; then\n>>                  __gitcomp \"$subcommands\"\n>>                  return\n>>          fi\n>>\n>>          case \"$subcommand,$cur\" in\n>> -       init,--*)\n>> -               __gitcomp \"--cone\"\n>> -               ;;\n>> -       set,--*)\n>> -               __gitcomp \"--stdin\"\n>> +               *,--*)\n>> +                       __gitcomp_builtin sparse-checkout_$subcommand \"\" \"--\"\n>>                  ;;\n>> -       *)\n>> +               set,*|add,*)\n>> +                       if [ $(__git config core.sparseCheckoutCone) ]; then\n>> +                               __git_complete_index_file \"--directory\"\n>> +                       fi\n> \n> --directory only affects how untracked files are presented in `git\n> ls-files` (which _git_complete_index_file uses), and you're not asking\n> for untracked paths at all here.  So you've got a useless flag.\n> \n> Testing this commit out, I can verify that it completes on all tracked\n> paths in the index.  Perhaps that was an intended intermediate step,\n> but if so the commit message needs to be changed since it claims this\n> commit is doing something else.\n> \n> There's also a problem in that `git sparse-checkout --cone path<TAB>`\n> is not using this codepath.  If the user specifies --cone, then we\n> should give them cone-mode-style completion the same as if they\n> already have the config setting set.  Or, we at least need to mention\n> in the commit message that we don't yet correctly check for the\n> `--cone` option to get the right style of completion and are leaving\n> it for future work.\n\n> \nThank you for your feedback, it is very helpful. As I've been thinking\nabout this, it feels like this commit should perhaps be dropped in favor\nof the __gitcomp_directories commit (with some modifications per [1]). I\nknow you initially said to add the __gitcomp_directories commit in\naddition to what I had, though, so I wanted to confirm whether removing\nthis is the right course of action.\n\n[1]: \nhttps://lore.kernel.org/git/CABPp-BEq9pTqsy_R_SR1DSgUK58ubNR1Gk4G1RoL8wkadyo6zw@mail.gmail.com/\n"},{"id":"447364","messageId":"CABPp-BGyH029hidv2t5hmx6=LLt=9m1R_7vZLK7JYizybmaFgQ@mail.gmail.com","threadId":"57165","inReplyTo":"82bb12d0-0505-1997-21ba-b9863bfdf2c8@gmail.com","subject":"Re: [PATCH v4 2/3] completion: sparse-checkout updates","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2022-01-31T21:37:40Z","receivedAt":"2022-01-31T21:37:57Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Mon, Jan 31, 2022 at 12:03 PM Lessley Dennington\n<lessleydennington@gmail.com> wrote:\n>\n> On 1/27/22 5:21 PM, Elijah Newren wrote:\n> > On Thu, Jan 27, 2022 at 1:21 PM Lessley Dennington via GitGitGadget\n> > <gitgitgadget@gmail.com> wrote:\n> >>\n> >> From: Lessley Dennington <lessleydennington@gmail.com>\n> >>\n> >> Fix custom tab completion for the sparse-checkout command. This will\n> >> ensure:\n> >>\n> >> 1. The full list of subcommands is provided when users enter git\n> >> sparse-checkout <TAB>.\n> >> 2. Subcommand options are tab-completable.\n> >> 3. A list of directories (but not files) is provided when users enter git\n> >> sparse-checkout add <TAB> or git sparse-checkout set <TAB> in cone mode\n> >> only. In non-cone mode, these commands will continue to complete both\n> >> directory and file names.\n> >>\n> >> Failing tests that were added in the previous commit to verify these\n> >> scenarios are now passing with these updates.\n> >>\n> >> Signed-off-by: Lessley Dennington <lessleydennington@gmail.com>\n> >> ---\n> >>   contrib/completion/git-completion.bash | 15 ++++++++-------\n> >>   t/t9902-completion.sh                  |  4 ++--\n> >>   2 files changed, 10 insertions(+), 9 deletions(-)\n> >>\n> >> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\n> >> index c82ccaebcc7..a920cdab201 100644\n> >> --- a/contrib/completion/git-completion.bash\n> >> +++ b/contrib/completion/git-completion.bash\n> >> @@ -2988,21 +2988,22 @@ _git_show_branch ()\n> >>\n> >>   _git_sparse_checkout ()\n> >>   {\n> >> -       local subcommands=\"list init set disable\"\n> >> +       local subcommands=\"list init set disable add reapply\"\n> >>          local subcommand=\"$(__git_find_on_cmdline \"$subcommands\")\"\n> >> +\n> >>          if [ -z \"$subcommand\" ]; then\n> >>                  __gitcomp \"$subcommands\"\n> >>                  return\n> >>          fi\n> >>\n> >>          case \"$subcommand,$cur\" in\n> >> -       init,--*)\n> >> -               __gitcomp \"--cone\"\n> >> -               ;;\n> >> -       set,--*)\n> >> -               __gitcomp \"--stdin\"\n> >> +               *,--*)\n> >> +                       __gitcomp_builtin sparse-checkout_$subcommand \"\" \"--\"\n> >>                  ;;\n> >> -       *)\n> >> +               set,*|add,*)\n> >> +                       if [ $(__git config core.sparseCheckoutCone) ]; then\n> >> +                               __git_complete_index_file \"--directory\"\n> >> +                       fi\n> >\n> > --directory only affects how untracked files are presented in `git\n> > ls-files` (which _git_complete_index_file uses), and you're not asking\n> > for untracked paths at all here.  So you've got a useless flag.\n> >\n> > Testing this commit out, I can verify that it completes on all tracked\n> > paths in the index.  Perhaps that was an intended intermediate step,\n> > but if so the commit message needs to be changed since it claims this\n> > commit is doing something else.\n> >\n> > There's also a problem in that `git sparse-checkout --cone path<TAB>`\n> > is not using this codepath.  If the user specifies --cone, then we\n> > should give them cone-mode-style completion the same as if they\n> > already have the config setting set.  Or, we at least need to mention\n> > in the commit message that we don't yet correctly check for the\n> > `--cone` option to get the right style of completion and are leaving\n> > it for future work.\n>\n> >\n> Thank you for your feedback, it is very helpful. As I've been thinking\n> about this, it feels like this commit should perhaps be dropped in favor\n> of the __gitcomp_directories commit (with some modifications per [1]). I\n> know you initially said to add the __gitcomp_directories commit in\n> addition to what I had, though, so I wanted to confirm whether removing\n> this is the right course of action.\n>\n> [1]:\n> https://lore.kernel.org/git/CABPp-BEq9pTqsy_R_SR1DSgUK58ubNR1Gk4G1RoL8wkadyo6zw@mail.gmail.com/\n\nI think the link you meant was\nhttps://lore.kernel.org/git/CABPp-BG_Jgyr89z_D355Ytzz31J40nBGX=2cr+aXtcf3U1y6Dg@mail.gmail.com/.\nAnyway...\n\nI thought the \"git ls-tree -d -r --name-only HEAD\" step you did\npreviously was a useful intermediate step because it was really simple\nand it highlighted the direction we wanted to go for cone mode -- it\njust had some caveats (it was potentially slow, and it has the same\nquoting issues that my patch had).  I feel that sometimes an\nintermediate step helps reviewers -- both current ones and folks\ndigging through the code years from now.\n\nI think __git_complete_index_file() is a step in the wrong direction,\nand as such adding a patch that uses it does not help people\nunderstand the path to the end goal.  So, if the choice is about\n__git_complete_index_file(), then yeah, we shouldn't include that\nstep.  But your old step 2 might have value.\n\nI think there's a few possible choices you could make to replace your\ncurrent patches 2 & 3; including:\n  * 1 patch: Just use the __gitcomp_directories commit, modified to\nhandle the special quoting needed\n  * 2 patches: Insert your old \"git ls-tree -d -r --name-only HEAD\"\npatch, made specific to cone mode, mentioning the performance and\nquoting shortcomings in the commit message and stating that a\nsubsequent commit will address those issues.  Then add the\n__gitcomp_directories commit, modified to handle special quoting\n  * 3 patches: First commit same as the case above.  Then add the\n__gitcomp_directories commit without changing it to handle special\npath quoting (i.e. the second patch only addresses the performance\nshortcoming).  Then add a 3rd commit handling the special path quoting\n(addressing the remaining issue).\n  * some other split that occurs to you while you do the work.\n\nOf the first three, I have a small preference for replacing patches 2\n& 3 from this round with the 3-patch replacement above (making your\nseries be 4 patches total), because it provides a \"10,000 ft overview\"\nbefore jumping into the weeds, it naturally documents why a simpler\nsolution that might occur to folks isn't good enough, it allows\nreviewers to focus on just performance or on just special quoting when\nreviewing so they don't have to try to guess which end goal each line\nof code is working to achieve as they attempt to review.  But I'm\npartially guessing at how much work is involved in the special path\nquoting, and at how localized each part of the solution might be.  If\neither of the performance or special quoting concerns are nicely\nlocalized in the patch anyway, then the separation of commits becomes\nless important.  And perhaps a comment in the commit message is good\nenough to provide the 10,000 ft overview so you don't need the\nexplicit \"git ls-tree -d -r --name-only HEAD\" step.\n\nAnyway, that's how I think about it.  Other than the fact that\n__git_complete_index_file() should not be included as a step, any of\nthe choices could be fine so I'll leave it up to you.\n"},{"id":"447650","messageId":"a1c46c763fd4c832a6784e2a368199efedce17e9.1643921091.git.gitgitgadget@gmail.com","threadId":"57165","inReplyTo":"pull.1108.v5.git.1643921091.gitgitgadget@gmail.com","subject":"[PATCH v5 1/3] completion: address sparse-checkout issues","fromName":"Lessley Dennington via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-02-03T20:44:49Z","receivedAt":"2022-02-03T20:47:04Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"From: Lessley Dennington <lessleydennington@gmail.com>\n\nCorrect multiple issues with tab completion of the git sparse-checkout\ncommand. These issues were:\n\n1. git sparse-checkout <TAB> previously resulted in an incomplete list of\nsubcommands (it was missing reapply and add).\n2. Subcommand options were not tab-completable.\n3. git sparse-checkout set <TAB> and git sparse-checkout add <TAB> showed\nboth file names and directory names. While this may be a less surprising\nbehavior for non-cone mode, cone mode sparse checkouts should complete\nonly directory names.\n\nNote that while the new strategy of just using git ls-tree to complete on\ndirectory names is simple and a step in the right direction, it does have\nsome caveats. These are:\n\n1. Likelihood of poor performance in large monorepos (as a result of\nrecursively completing directory names).\n2. Inability to handle paths containing unusual characters.\n\nThese caveats will be fixed by subsequent commits in this series.\n\nSigned-off-by: Lessley Dennington <lessleydennington@gmail.com>\n---\n contrib/completion/git-completion.bash | 16 ++---\n t/t9902-completion.sh                  | 83 ++++++++++++++++++++++++++\n 2 files changed, 91 insertions(+), 8 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex c82ccaebcc7..2976f63747f 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -2988,7 +2988,7 @@ _git_show_branch ()\n \n _git_sparse_checkout ()\n {\n-\tlocal subcommands=\"list init set disable\"\n+\tlocal subcommands=\"list init set disable add reapply\"\n \tlocal subcommand=\"$(__git_find_on_cmdline \"$subcommands\")\"\n \tif [ -z \"$subcommand\" ]; then\n \t\t__gitcomp \"$subcommands\"\n@@ -2996,14 +2996,14 @@ _git_sparse_checkout ()\n \tfi\n \n \tcase \"$subcommand,$cur\" in\n-\tinit,--*)\n-\t\t__gitcomp \"--cone\"\n-\t\t;;\n-\tset,--*)\n-\t\t__gitcomp \"--stdin\"\n-\t\t;;\n-\t*)\n+\t*,--*)\n+\t\t__gitcomp_builtin sparse-checkout_$subcommand \"\" \"--\"\n \t\t;;\n+\tset,*|add,*)\n+\t\tif [ $(__git config core.sparseCheckoutCone) ] ||\n+\t\t[ \"$(__git_find_on_cmdline --cone)\" ]; then\n+\t\t\t__gitcomp \"$(git ls-tree -d -r HEAD --name-only)\"\n+\t\tfi\n \tesac\n }\n \ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex 518203fbe07..f6eeb9aa035 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -1447,6 +1447,89 @@ test_expect_success 'git checkout - with --detach, complete only references' '\n \tEOF\n '\n \n+test_expect_success 'setup sparse-checkout tests' '\n+\t# set up sparse-checkout repo\n+\tgit init sparse-checkout &&\n+\t(\n+\t\tcd sparse-checkout &&\n+\t\tmkdir -p folder1/0/1 folder2/0 folder3 &&\n+\t\ttouch folder1/0/1/t.txt &&\n+\t\ttouch folder2/0/t.txt &&\n+\t\ttouch folder3/t.txt &&\n+\t\tgit add . &&\n+\t\tgit commit -am \"Initial commit\"\n+\t)\n+'\n+\n+test_expect_success 'sparse-checkout completes subcommands' '\n+\ttest_completion \"git sparse-checkout \" <<-\\EOF\n+\tlist Z\n+\tinit Z\n+\tset Z\n+\tadd Z\n+\treapply Z\n+\tdisable Z\n+\tEOF\n+'\n+\n+test_expect_success 'cone mode sparse-checkout completes directory names' '\n+\t# initialize sparse-checkout definitions\n+\tgit -C sparse-checkout sparse-checkout set --cone folder1/0 folder3 &&\n+\n+\t# test tab completion\n+\t(\n+\t\tcd sparse-checkout &&\n+\t\ttest_completion \"git sparse-checkout set f\" <<-\\EOF\n+\t\tfolder1 Z\n+\t\tfolder1/0 Z\n+\t\tfolder1/0/1 Z\n+\t\tfolder2 Z\n+\t\tfolder2/0 Z\n+\t\tfolder3 Z\n+\t\tEOF\n+\t) &&\n+\n+\t(\n+\t\tcd sparse-checkout/folder1 &&\n+\t\ttest_completion \"git sparse-checkout add \" <<-\\EOF\n+\t\t./ Z\n+\t\t0 Z\n+\t\t0/1 Z\n+\t\tEOF\n+\t)\n+'\n+\n+test_expect_success 'non-cone mode sparse-checkout uses bash completion' '\n+\t# reset sparse-checkout repo to non-cone mode\n+\tgit -C sparse-checkout sparse-checkout disable &&\n+\tgit -C sparse-checkout sparse-checkout set --no-cone &&\n+\n+\t(\n+\t\tcd sparse-checkout &&\n+\t\t# expected to be empty since we have not configured\n+\t\t# custom completion for non-cone mode\n+\t\ttest_completion \"git sparse-checkout set f\" <<-\\EOF\n+\n+\t\tEOF\n+\t)\n+'\n+\n+test_expect_success 'git sparse-checkout set --cone completes directory names' '\n+\tgit -C sparse-checkout sparse-checkout disable &&\n+\n+\t(\n+\t\tcd sparse-checkout &&\n+\t\ttest_completion \"git sparse-checkout set --cone f\" <<-\\EOF\n+\t\tfolder1 Z\n+\t\tfolder1/0 Z\n+\t\tfolder1/0/1 Z\n+\t\tfolder2 Z\n+\t\tfolder2/0 Z\n+\t\tfolder3 Z\n+\t\tEOF\n+\t)\n+'\n+\n test_expect_success 'git switch - with -d, complete all references' '\n \ttest_completion \"git switch -d \" <<-\\EOF\n \tHEAD Z\n-- \ngitgitgadget\n\n"},{"id":"447651","messageId":"pull.1108.v5.git.1643921091.gitgitgadget@gmail.com","threadId":"57165","inReplyTo":"pull.1108.v4.git.1643318514.gitgitgadget@gmail.com","subject":"[PATCH v5 0/3] completion: sparse-checkout updates","fromName":"Lessley Dennington via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-02-03T20:44:48Z","receivedAt":"2022-02-03T20:47:05Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"This series is based on en/sparse-checkout-set. It updates custom tab\ncompletion for the sparse-checkout command. Specifically, it corrects the\nfollowing issues with the current method:\n\n 1. git sparse-checkout <TAB> results in an incomplete list of subcommands\n    (it is missing reapply and add).\n 2. Options for subcommands are not tab-completable.\n 3. git sparse-checkout set <TAB> and git sparse-checkout add <TAB> show\n    both file names and directory names. While this may be a less surprising\n    behavior for non-cone mode, we want to only show directories in cone\n    mode.\n\nThe first commit in this series is an intermediate step that fixes issues 1\nand 2 above and introduces a simple fix for issue 3 with some performance\nand unusual character-related caveats. The next commit adds a new\n__gitcomp_directories method that fixes the performance-related caveat from\nthe first commit by completing just a single level of directories. The final\ncommit modifies __gitcomp_directories to handle unusual characters in\ndirectory names.\n\n\nChanges since V4\n================\n\n * Clarify that completing on files and directories is a less-surprising\n   behavior in non-cone mode (rather than definitely the correct behavior)\n   in commit message and cover letter.\n * Add explicit --no-cone to non-cone mode sparse-checkout completion test.\n * Replace use of __git_complete_index_file with a new version of\n   __gitcomp_directories that is able to handle unusual characters.\n * Ensure that users running git sparse-checkout set --cone get cone\n   mode-style completion whether or not they already have the cone mode\n   config set.\n * Refactor creation of sparse-checkout test repo into a sparse-checkout\n   setup test.\n\n\nChanges since V3\n================\n\n * Update commit descriptions to begin with completion instead of\n   sparse-checkout.\n * Remove explicit completion of --help, as this is inconsistent with the\n   rest of the completion script.\n * Use __gitcomp_builtin to auto-complete subcommand options (and remove\n   option completion test from previous iterations, as it is no longer\n   necessary).\n * Use __git_complete_index_file helper function in place of __gitcomp\n   \"$(git ls-tree -d -r HEAD --name-only).\n * If in cone-mode sparse checkout, only show directory completions. If in\n   non-cone mode sparse checkout show both files and directories.\n\n\nChanges since V2\n================\n\n * Change use of $prev to $subcommand in _git_sparse_checkout() method in\n   git-completion.bash.\n * State explicitly that directory completion applies in both cone and\n   non-cone mode in 'sparse-checkout: custom tab completion' commit\n * Add new patch with __gitcomp_directories method to improve performance by\n   only outputting directories at the current level.\n\n\nChanges since V1\n================\n\n * Rebase onto en/sparse-checkout-set.\n * Add subcommand options (including --no-cone) for set and reapply.\n * Extend 'sparse-checkout completes subcommand options' test to validate\n   new set/reapply subcommand options.\n * No longer set index.sparse to false in 'sparse-checkout completes\n   directory names' test.\n * Refactor creation of sparse-checkout repo into a setup test.\n\nThanks, Lessley\n\nLessley Dennington (3):\n  completion: address sparse-checkout issues\n  completion: improve sparse-checkout cone mode directory completion\n  completion: handle unusual characters for sparse-checkout\n\n contrib/completion/git-completion.bash |  44 ++++++++--\n t/t9902-completion.sh                  | 117 +++++++++++++++++++++++++\n 2 files changed, 153 insertions(+), 8 deletions(-)\n\n\nbase-commit: dfac9b609f86cd4f6ce896df9e1172d2a02cde48\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-1108%2Fldennington%2Fsparse-checkout-bash-completion-v5\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1108/ldennington/sparse-checkout-bash-completion-v5\nPull-Request: https://github.com/gitgitgadget/git/pull/1108\n\nRange-diff vs v4:\n\n 1:  5bb598a055d ! 1:  a1c46c763fd completion: add sparse-checkout tests\n     @@ Metadata\n      Author: Lessley Dennington <lessleydennington@gmail.com>\n      \n       ## Commit message ##\n     -    completion: add sparse-checkout tests\n     +    completion: address sparse-checkout issues\n      \n     -    Add tests for missing/incorrect components of custom tab completion for\n     -    the sparse-checkout command. These tests specifically highlight the\n     -    following:\n     +    Correct multiple issues with tab completion of the git sparse-checkout\n     +    command. These issues were:\n      \n     -    1. git sparse-checkout <TAB> results in an incomplete list of subcommands\n     -    (it is missing reapply and add).\n     -    2. git sparse-checkout set <TAB> and git sparse-checkout add <TAB> show\n     -    both file names and directory names. While this is the correct behavior\n     -    for non-cone mode, cone mode sparse checkouts should complete only\n     -    directory names.\n     +    1. git sparse-checkout <TAB> previously resulted in an incomplete list of\n     +    subcommands (it was missing reapply and add).\n     +    2. Subcommand options were not tab-completable.\n     +    3. git sparse-checkout set <TAB> and git sparse-checkout add <TAB> showed\n     +    both file names and directory names. While this may be a less surprising\n     +    behavior for non-cone mode, cone mode sparse checkouts should complete\n     +    only directory names.\n      \n     -    Although the first two of these tests currently fail, they will succeed\n     -    with the sparse-checkout modifications in git-completion.bash in the next\n     -    commit in this series.\n     +    Note that while the new strategy of just using git ls-tree to complete on\n     +    directory names is simple and a step in the right direction, it does have\n     +    some caveats. These are:\n     +\n     +    1. Likelihood of poor performance in large monorepos (as a result of\n     +    recursively completing directory names).\n     +    2. Inability to handle paths containing unusual characters.\n     +\n     +    These caveats will be fixed by subsequent commits in this series.\n      \n          Signed-off-by: Lessley Dennington <lessleydennington@gmail.com>\n      \n     + ## contrib/completion/git-completion.bash ##\n     +@@ contrib/completion/git-completion.bash: _git_show_branch ()\n     + \n     + _git_sparse_checkout ()\n     + {\n     +-\tlocal subcommands=\"list init set disable\"\n     ++\tlocal subcommands=\"list init set disable add reapply\"\n     + \tlocal subcommand=\"$(__git_find_on_cmdline \"$subcommands\")\"\n     + \tif [ -z \"$subcommand\" ]; then\n     + \t\t__gitcomp \"$subcommands\"\n     +@@ contrib/completion/git-completion.bash: _git_sparse_checkout ()\n     + \tfi\n     + \n     + \tcase \"$subcommand,$cur\" in\n     +-\tinit,--*)\n     +-\t\t__gitcomp \"--cone\"\n     +-\t\t;;\n     +-\tset,--*)\n     +-\t\t__gitcomp \"--stdin\"\n     +-\t\t;;\n     +-\t*)\n     ++\t*,--*)\n     ++\t\t__gitcomp_builtin sparse-checkout_$subcommand \"\" \"--\"\n     + \t\t;;\n     ++\tset,*|add,*)\n     ++\t\tif [ $(__git config core.sparseCheckoutCone) ] ||\n     ++\t\t[ \"$(__git_find_on_cmdline --cone)\" ]; then\n     ++\t\t\t__gitcomp \"$(git ls-tree -d -r HEAD --name-only)\"\n     ++\t\tfi\n     + \tesac\n     + }\n     + \n     +\n       ## t/t9902-completion.sh ##\n      @@ t/t9902-completion.sh: test_expect_success 'git checkout - with --detach, complete only references' '\n       \tEOF\n       '\n       \n     -+test_expect_failure 'sparse-checkout completes subcommands' '\n     -+\ttest_completion \"git sparse-checkout \" <<-\\EOF\n     -+\tlist Z\n     -+\tinit Z\n     -+\tset Z\n     -+\tadd Z\n     -+\treapply Z\n     -+\tdisable Z\n     -+\tEOF\n     -+'\n     -+\n     -+test_expect_failure 'cone mode sparse-checkout completes directory names' '\n     ++test_expect_success 'setup sparse-checkout tests' '\n      +\t# set up sparse-checkout repo\n      +\tgit init sparse-checkout &&\n      +\t(\n     @@ t/t9902-completion.sh: test_expect_success 'git checkout - with --detach, comple\n      +\t\ttouch folder3/t.txt &&\n      +\t\tgit add . &&\n      +\t\tgit commit -am \"Initial commit\"\n     -+\t) &&\n     ++\t)\n     ++'\n     ++\n     ++test_expect_success 'sparse-checkout completes subcommands' '\n     ++\ttest_completion \"git sparse-checkout \" <<-\\EOF\n     ++\tlist Z\n     ++\tinit Z\n     ++\tset Z\n     ++\tadd Z\n     ++\treapply Z\n     ++\tdisable Z\n     ++\tEOF\n     ++'\n      +\n     ++test_expect_success 'cone mode sparse-checkout completes directory names' '\n      +\t# initialize sparse-checkout definitions\n      +\tgit -C sparse-checkout sparse-checkout set --cone folder1/0 folder3 &&\n      +\n     @@ t/t9902-completion.sh: test_expect_success 'git checkout - with --detach, comple\n      +\t(\n      +\t\tcd sparse-checkout &&\n      +\t\ttest_completion \"git sparse-checkout set f\" <<-\\EOF\n     -+\t\tfolder1\n     -+\t\tfolder2\n     -+\t\tfolder3\n     -+\t\tEOF\n     -+\t) &&\n     -+\n     -+\t(\n     -+\t\tcd sparse-checkout &&\n     -+\t\ttest_completion \"git sparse-checkout set folder1/\" <<-\\EOF\n     -+\t\tfolder1/0\n     -+\t\tEOF\n     -+\t) &&\n     -+\n     -+\t(\n     -+\t\tcd sparse-checkout &&\n     -+\t\ttest_completion \"git sparse-checkout set folder1/0/\" <<-\\EOF\n     -+\t\tfolder1/0/1\n     ++\t\tfolder1 Z\n     ++\t\tfolder1/0 Z\n     ++\t\tfolder1/0/1 Z\n     ++\t\tfolder2 Z\n     ++\t\tfolder2/0 Z\n     ++\t\tfolder3 Z\n      +\t\tEOF\n      +\t) &&\n      +\n      +\t(\n      +\t\tcd sparse-checkout/folder1 &&\n     -+\t\ttest_completion \"git sparse-checkout add 0\" <<-\\EOF\n     -+\t\t0\n     ++\t\ttest_completion \"git sparse-checkout add \" <<-\\EOF\n     ++\t\t./ Z\n     ++\t\t0 Z\n     ++\t\t0/1 Z\n      +\t\tEOF\n      +\t)\n      +'\n     @@ t/t9902-completion.sh: test_expect_success 'git checkout - with --detach, comple\n      +test_expect_success 'non-cone mode sparse-checkout uses bash completion' '\n      +\t# reset sparse-checkout repo to non-cone mode\n      +\tgit -C sparse-checkout sparse-checkout disable &&\n     -+\tgit -C sparse-checkout sparse-checkout set &&\n     ++\tgit -C sparse-checkout sparse-checkout set --no-cone &&\n      +\n     -+\t# test tab completion\n      +\t(\n      +\t\tcd sparse-checkout &&\n      +\t\t# expected to be empty since we have not configured\n     @@ t/t9902-completion.sh: test_expect_success 'git checkout - with --detach, comple\n      +\t\tEOF\n      +\t)\n      +'\n     ++\n     ++test_expect_success 'git sparse-checkout set --cone completes directory names' '\n     ++\tgit -C sparse-checkout sparse-checkout disable &&\n     ++\n     ++\t(\n     ++\t\tcd sparse-checkout &&\n     ++\t\ttest_completion \"git sparse-checkout set --cone f\" <<-\\EOF\n     ++\t\tfolder1 Z\n     ++\t\tfolder1/0 Z\n     ++\t\tfolder1/0/1 Z\n     ++\t\tfolder2 Z\n     ++\t\tfolder2/0 Z\n     ++\t\tfolder3 Z\n     ++\t\tEOF\n     ++\t)\n     ++'\n      +\n       test_expect_success 'git switch - with -d, complete all references' '\n       \ttest_completion \"git switch -d \" <<-\\EOF\n 2:  7d70beb2a6b < -:  ----------- completion: sparse-checkout updates\n 3:  760cae85bd4 ! 2:  5b8d53402ae completion: ensure cone mode completion with multiple <TAB>s\n     @@ Metadata\n      Author: Lessley Dennington <lessleydennington@gmail.com>\n      \n       ## Commit message ##\n     -    completion: ensure cone mode completion with multiple <TAB>s\n     +    completion: improve sparse-checkout cone mode directory completion\n      \n     -    Ensure users in a cone mode sparse checkout can tab-complete to\n     -    directories at multiple levels with multiple <TAB>s. For example, if path\n     -    a/b/c/ exists in the current directory, running a<TAB>b<TAB> will result\n     -    in:\n     +    Use new __gitcomp_directories method to complete directory names in cone\n     +    mode sparse-checkouts. This method addresses the caveat of poor\n     +    performance in monorepos from the previous commit (by completing only one\n     +    level of directories).\n      \n     -            a/b/c/\n     -\n     -    The 'sparse-checkout completes directory names' test has also been\n     -    updated with trailing slashes according to these changes.\n     +    The unusual character caveat from the previous commit will be fixed by the\n     +    final commit in this series.\n      \n          Co-authored-by: Elijah Newren <newren@gmail.com>\n          Co-authored-by: Lessley Dennington <lessleydennington@gmail.com>\n     @@ contrib/completion/git-completion.bash: _git_show_branch ()\n       _git_sparse_checkout ()\n       {\n       \tlocal subcommands=\"list init set disable add reapply\"\n     - \tlocal subcommand=\"$(__git_find_on_cmdline \"$subcommands\")\"\n     --\n     - \tif [ -z \"$subcommand\" ]; then\n     - \t\t__gitcomp \"$subcommands\"\n     - \t\treturn\n      @@ contrib/completion/git-completion.bash: _git_sparse_checkout ()\n     - \t\t;;\n     - \t\tset,*|add,*)\n     - \t\t\tif [ $(__git config core.sparseCheckoutCone) ]; then\n     --\t\t\t\t__git_complete_index_file \"--directory\"\n     -+\t\t\t\t__gitcomp_directories\n     - \t\t\tfi\n     - \t\t;;\n     + \tset,*|add,*)\n     + \t\tif [ $(__git config core.sparseCheckoutCone) ] ||\n     + \t\t[ \"$(__git_find_on_cmdline --cone)\" ]; then\n     +-\t\t\t__gitcomp \"$(git ls-tree -d -r HEAD --name-only)\"\n     ++\t\t\t__gitcomp_directories\n     + \t\tfi\n       \tesac\n     + }\n      \n       ## t/t9902-completion.sh ##\n      @@ t/t9902-completion.sh: test_expect_success 'cone mode sparse-checkout completes directory names' '\n       \t(\n       \t\tcd sparse-checkout &&\n       \t\ttest_completion \"git sparse-checkout set f\" <<-\\EOF\n     --\t\tfolder1\n     --\t\tfolder2\n     --\t\tfolder3\n     +-\t\tfolder1 Z\n     +-\t\tfolder1/0 Z\n     +-\t\tfolder1/0/1 Z\n     +-\t\tfolder2 Z\n     +-\t\tfolder2/0 Z\n     +-\t\tfolder3 Z\n      +\t\tfolder1/\n      +\t\tfolder2/\n      +\t\tfolder3/\n     - \t\tEOF\n     - \t) &&\n     - \n     - \t(\n     - \t\tcd sparse-checkout &&\n     - \t\ttest_completion \"git sparse-checkout set folder1/\" <<-\\EOF\n     --\t\tfolder1/0\n     ++\t\tEOF\n     ++\t) &&\n     ++\n     ++\t(\n     ++\t\tcd sparse-checkout &&\n     ++\t\ttest_completion \"git sparse-checkout set folder1/\" <<-\\EOF\n      +\t\tfolder1/0/\n     - \t\tEOF\n     - \t) &&\n     - \n     - \t(\n     - \t\tcd sparse-checkout &&\n     - \t\ttest_completion \"git sparse-checkout set folder1/0/\" <<-\\EOF\n     --\t\tfolder1/0/1\n     ++\t\tEOF\n     ++\t) &&\n     ++\n     ++\t(\n     ++\t\tcd sparse-checkout &&\n     ++\t\ttest_completion \"git sparse-checkout set folder1/0/\" <<-\\EOF\n      +\t\tfolder1/0/1/\n       \t\tEOF\n       \t) &&\n       \n       \t(\n       \t\tcd sparse-checkout/folder1 &&\n     - \t\ttest_completion \"git sparse-checkout add 0\" <<-\\EOF\n     --\t\t0\n     +-\t\ttest_completion \"git sparse-checkout add \" <<-\\EOF\n     +-\t\t./ Z\n     +-\t\t0 Z\n     +-\t\t0/1 Z\n     ++\t\ttest_completion \"git sparse-checkout add 0\" <<-\\EOF\n      +\t\t0/\n       \t\tEOF\n       \t)\n       '\n     +@@ t/t9902-completion.sh: test_expect_success 'git sparse-checkout set --cone completes directory names' '\n     + \t(\n     + \t\tcd sparse-checkout &&\n     + \t\ttest_completion \"git sparse-checkout set --cone f\" <<-\\EOF\n     +-\t\tfolder1 Z\n     +-\t\tfolder1/0 Z\n     +-\t\tfolder1/0/1 Z\n     +-\t\tfolder2 Z\n     +-\t\tfolder2/0 Z\n     +-\t\tfolder3 Z\n     ++\t\tfolder1/\n     ++\t\tfolder2/\n     ++\t\tfolder3/\n     + \t\tEOF\n     + \t)\n     + '\n -:  ----------- > 3:  ddf5e583dd7 completion: handle unusual characters for sparse-checkout\n\n-- \ngitgitgadget\n"},{"id":"447652","messageId":"5b8d53402ae68e5d66898b3517f3a950e6117765.1643921091.git.gitgitgadget@gmail.com","threadId":"57165","inReplyTo":"pull.1108.v5.git.1643921091.gitgitgadget@gmail.com","subject":"[PATCH v5 2/3] completion: improve sparse-checkout cone mode directory completion","fromName":"Lessley Dennington via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-02-03T20:44:50Z","receivedAt":"2022-02-03T20:47:16Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"From: Lessley Dennington <lessleydennington@gmail.com>\n\nUse new __gitcomp_directories method to complete directory names in cone\nmode sparse-checkouts. This method addresses the caveat of poor\nperformance in monorepos from the previous commit (by completing only one\nlevel of directories).\n\nThe unusual character caveat from the previous commit will be fixed by the\nfinal commit in this series.\n\nCo-authored-by: Elijah Newren <newren@gmail.com>\nCo-authored-by: Lessley Dennington <lessleydennington@gmail.com>\nSigned-off-by: Lessley Dennington <lessleydennington@gmail.com>\n---\n contrib/completion/git-completion.bash | 32 +++++++++++++++++++++-\n t/t9902-completion.sh                  | 38 +++++++++++++++-----------\n 2 files changed, 53 insertions(+), 17 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 2976f63747f..c5c8df6b6e5 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -2986,6 +2986,36 @@ _git_show_branch ()\n \t__git_complete_revlist\n }\n \n+__gitcomp_directories ()\n+{\n+     local _tmp_dir _tmp_completions\n+\n+     # Get the directory of the current token; this differs from dirname\n+     # in that it keeps up to the final trailing slash.  If no slash found\n+     # that's fine too.\n+     [[ \"$cur\" =~ .*/ ]]\n+     _tmp_dir=$BASH_REMATCH\n+\n+     # Find possible directory completions, adding trailing '/' characters\n+     _tmp_completions=\"$(git ls-tree -d --name-only HEAD $_tmp_dir |\n+         sed -e s%$%/%)\"\n+\n+     if [[ -n \"$_tmp_completions\" ]]; then\n+         # There were some directory completions, so find ones that\n+         # start with \"$cur\", the current token, and put those in COMPREPLY\n+         local i=0 c IFS=$' \\t\\n'\n+         for c in $_tmp_completions; do\n+             if [[ $c == \"$cur\"* ]]; then\n+                 COMPREPLY+=(\"$c\")\n+             fi\n+         done\n+     elif [[ \"$cur\" =~ /$ ]]; then\n+         # No possible further completions any deeper, so assume we're at\n+         # a leaf directory and just consider it complete\n+         __gitcomp_direct_append \"$cur \"\n+     fi\n+}\n+\n _git_sparse_checkout ()\n {\n \tlocal subcommands=\"list init set disable add reapply\"\n@@ -3002,7 +3032,7 @@ _git_sparse_checkout ()\n \tset,*|add,*)\n \t\tif [ $(__git config core.sparseCheckoutCone) ] ||\n \t\t[ \"$(__git_find_on_cmdline --cone)\" ]; then\n-\t\t\t__gitcomp \"$(git ls-tree -d -r HEAD --name-only)\"\n+\t\t\t__gitcomp_directories\n \t\tfi\n \tesac\n }\ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex f6eeb9aa035..b38a7302249 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -1480,21 +1480,30 @@ test_expect_success 'cone mode sparse-checkout completes directory names' '\n \t(\n \t\tcd sparse-checkout &&\n \t\ttest_completion \"git sparse-checkout set f\" <<-\\EOF\n-\t\tfolder1 Z\n-\t\tfolder1/0 Z\n-\t\tfolder1/0/1 Z\n-\t\tfolder2 Z\n-\t\tfolder2/0 Z\n-\t\tfolder3 Z\n+\t\tfolder1/\n+\t\tfolder2/\n+\t\tfolder3/\n+\t\tEOF\n+\t) &&\n+\n+\t(\n+\t\tcd sparse-checkout &&\n+\t\ttest_completion \"git sparse-checkout set folder1/\" <<-\\EOF\n+\t\tfolder1/0/\n+\t\tEOF\n+\t) &&\n+\n+\t(\n+\t\tcd sparse-checkout &&\n+\t\ttest_completion \"git sparse-checkout set folder1/0/\" <<-\\EOF\n+\t\tfolder1/0/1/\n \t\tEOF\n \t) &&\n \n \t(\n \t\tcd sparse-checkout/folder1 &&\n-\t\ttest_completion \"git sparse-checkout add \" <<-\\EOF\n-\t\t./ Z\n-\t\t0 Z\n-\t\t0/1 Z\n+\t\ttest_completion \"git sparse-checkout add 0\" <<-\\EOF\n+\t\t0/\n \t\tEOF\n \t)\n '\n@@ -1520,12 +1529,9 @@ test_expect_success 'git sparse-checkout set --cone completes directory names' '\n \t(\n \t\tcd sparse-checkout &&\n \t\ttest_completion \"git sparse-checkout set --cone f\" <<-\\EOF\n-\t\tfolder1 Z\n-\t\tfolder1/0 Z\n-\t\tfolder1/0/1 Z\n-\t\tfolder2 Z\n-\t\tfolder2/0 Z\n-\t\tfolder3 Z\n+\t\tfolder1/\n+\t\tfolder2/\n+\t\tfolder3/\n \t\tEOF\n \t)\n '\n-- \ngitgitgadget\n\n"},{"id":"447653","messageId":"ddf5e583dd71a729d6fb0513aed9fc4eb6ebbdd7.1643921091.git.gitgitgadget@gmail.com","threadId":"57165","inReplyTo":"pull.1108.v5.git.1643921091.gitgitgadget@gmail.com","subject":"[PATCH v5 3/3] completion: handle unusual characters for sparse-checkout","fromName":"Lessley Dennington via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-02-03T20:44:51Z","receivedAt":"2022-02-03T20:47:18Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"From: Lessley Dennington <lessleydennington@gmail.com>\n\nUpdate the __gitcomp_directories method to de-quote and handle unusual\ncharacters in directory names. Although this initially involved an attempt\nto re-use the logic in __git_index_files, this method removed\nsubdirectories (e.g. folder1/0/ became folder1/), so instead new custom\nlogic was placed directly in the __gitcomp_directories method.\n\nCo-authored-by: Johannes Schindelin <johannes.schindelin@gmx.de>\nCo-authored-by: Lessley Dennington <lessleydennington@gmail.com>\nSigned-off-by: Lessley Dennington <lessleydennington@gmail.com>\n---\n contrib/completion/git-completion.bash | 50 +++++++++++++-------------\n t/t9902-completion.sh                  | 28 +++++++++++++++\n 2 files changed, 52 insertions(+), 26 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex c5c8df6b6e5..c47e9ce09b2 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -2988,32 +2988,30 @@ _git_show_branch ()\n \n __gitcomp_directories ()\n {\n-     local _tmp_dir _tmp_completions\n-\n-     # Get the directory of the current token; this differs from dirname\n-     # in that it keeps up to the final trailing slash.  If no slash found\n-     # that's fine too.\n-     [[ \"$cur\" =~ .*/ ]]\n-     _tmp_dir=$BASH_REMATCH\n-\n-     # Find possible directory completions, adding trailing '/' characters\n-     _tmp_completions=\"$(git ls-tree -d --name-only HEAD $_tmp_dir |\n-         sed -e s%$%/%)\"\n-\n-     if [[ -n \"$_tmp_completions\" ]]; then\n-         # There were some directory completions, so find ones that\n-         # start with \"$cur\", the current token, and put those in COMPREPLY\n-         local i=0 c IFS=$' \\t\\n'\n-         for c in $_tmp_completions; do\n-             if [[ $c == \"$cur\"* ]]; then\n-                 COMPREPLY+=(\"$c\")\n-             fi\n-         done\n-     elif [[ \"$cur\" =~ /$ ]]; then\n-         # No possible further completions any deeper, so assume we're at\n-         # a leaf directory and just consider it complete\n-         __gitcomp_direct_append \"$cur \"\n-     fi\n+\tlocal _tmp_dir _tmp_completions _found=0\n+\n+\t# Get the directory of the current token; this differs from dirname\n+\t# in that it keeps up to the final trailing slash.  If no slash found\n+\t# that's fine too.\n+\t[[ \"$cur\" =~ .*/ ]]\n+\t_tmp_dir=$BASH_REMATCH\n+\n+\t# Find possible directory completions, adding trailing '/' characters,\n+\t# de-quoting, and handling unusual characters.\n+\twhile IFS= read -r -d $'\\0' c ; do\n+\t\t# If there are directory completions, find ones that start\n+\t\t# with \"$cur\", the current token, and put those in COMPREPLY\n+\t\tif [[ $c == \"$cur\"* ]]; then\n+\t\t\tCOMPREPLY+=(\"$c/\")\n+\t\t\t_found=1\n+\t\tfi\n+\tdone < <(git ls-tree -z -d --name-only HEAD $_tmp_dir)\n+\n+\tif [[ $_found == 0 ]] && [[ \"$cur\" =~ /$ ]]; then\n+\t\t# No possible further completions any deeper, so assume we're at\n+\t\t# a leaf directory and just consider it complete\n+\t\t__gitcomp_direct_append \"$cur \"\n+\tfi\n }\n \n _git_sparse_checkout ()\ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex b38a7302249..7f63d6057be 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -1508,6 +1508,34 @@ test_expect_success 'cone mode sparse-checkout completes directory names' '\n \t)\n '\n \n+# use FUNNYNAMES to avoid running on Windows, which doesn't permit backslashes in paths\n+test_expect_success FUNNYNAMES 'cone mode sparse-checkout completes directory names with special characters' '\n+\t# reset sparse-checkout\n+\tgit -C sparse-checkout sparse-checkout disable &&\n+\t(\n+\t\tcd sparse-checkout &&\n+\t\tmkdir \"directory with spaces\" &&\n+\t\tmkdir \"$(printf \"directory\\twith\\ttabs\")\" &&\n+\t\tmkdir \"directory\\with\\backslashes\" &&\n+\t\tmkdir \"directory-with-áccent\" &&\n+\t\t>\"directory with spaces/randomfile\" &&\n+\t\t>\"$(printf \"directory\\twith\\ttabs\")/randomfile\" &&\n+\t\t>\"directory\\with\\backslashes/randomfile\" &&\n+\t\t>\"directory-with-áccent/randomfile\" &&\n+\t\tgit add . &&\n+\t\tgit commit -m \"Add directories containing unusual characters\" &&\n+\t\tgit sparse-checkout set --cone \"directory with spaces\" \\\n+\t\t\t\"$(printf \"directory\\twith\\ttabs\")\" \"directory\\with\\backslashes\" \\\n+\t\t\t\"directory-with-áccent\" &&\n+\t\ttest_completion \"git sparse-checkout add dir\" <<-\\EOF\n+\t\tdirectory with spaces/\n+\t\tdirectory\twith\ttabs/\n+\t\tdirectory\\with\\backslashes/\n+\t\tdirectory-with-áccent/\n+\t\tEOF\n+\t)\n+'\n+\n test_expect_success 'non-cone mode sparse-checkout uses bash completion' '\n \t# reset sparse-checkout repo to non-cone mode\n \tgit -C sparse-checkout sparse-checkout disable &&\n-- \ngitgitgadget\n"},{"id":"447670","messageId":"xmqqo83nr59i.fsf@gitster.g","threadId":"57165","inReplyTo":"pull.1108.v5.git.1643921091.gitgitgadget@gmail.com","subject":"Re: [PATCH v5 0/3] completion: sparse-checkout updates","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-02-03T21:48:09Z","receivedAt":"2022-02-03T21:48:12Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Lessley Dennington via GitGitGadget\" <gitgitgadget@gmail.com>\nwrites:\n\n> This series is based on en/sparse-checkout-set.\n\nThis has been a very helpful note, but after the topic was merged to\n'master' on Jan 3rd, it has become a tad stale.  Let me apply the\ntopic directly on v2.35.0 instead.\n\nThanks.\n"},{"id":"447677","messageId":"7033ab1b-7d90-d83c-fc65-33801c6348cc@gmail.com","threadId":"57165","inReplyTo":"xmqqo83nr59i.fsf@gitster.g","subject":"Re: [PATCH v5 0/3] completion: sparse-checkout updates","fromName":"Lessley Dennington","fromEmail":"lessleydennington@gmail.com","sentAt":"2022-02-03T22:17:12Z","receivedAt":"2022-02-03T22:17:16Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"\n\nOn 2/3/22 1:48 PM, Junio C Hamano wrote:\n> \"Lessley Dennington via GitGitGadget\" <gitgitgadget@gmail.com>\n> writes:\n> \n>> This series is based on en/sparse-checkout-set.\n> \n> This has been a very helpful note, but after the topic was merged to\n> 'master' on Jan 3rd, it has become a tad stale.  Let me apply the\n> topic directly on v2.35.0 instead.\n> \n> Thanks.\n\nThank you for the heads up! I will remove from future versions.\n"},{"id":"447682","messageId":"xmqqy22rpm10.fsf@gitster.g","threadId":"57165","inReplyTo":"7033ab1b-7d90-d83c-fc65-33801c6348cc@gmail.com","subject":"Re: [PATCH v5 0/3] completion: sparse-checkout updates","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-02-03T23:28:59Z","receivedAt":"2022-02-03T23:29:02Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Lessley Dennington <lessleydennington@gmail.com> writes:\n\n> On 2/3/22 1:48 PM, Junio C Hamano wrote:\n>> \"Lessley Dennington via GitGitGadget\" <gitgitgadget@gmail.com>\n>> writes:\n>> \n>>> This series is based on en/sparse-checkout-set.\n>> This has been a very helpful note, but after the topic was merged to\n>> 'master' on Jan 3rd, it has become a tad stale.  Let me apply the\n>> topic directly on v2.35.0 instead.\n>> Thanks.\n>\n> Thank you for the heads up! I will remove from future versions.\n\nNo problem.\n\nFWIW, the tip of 'seen' seems to be failing the CI; I haven't looked\ninto the cause of the breakage.\n\n  https://github.com/git/git/actions/runs/1792151138\n\nThere is another CI job running on 'seen', whose only difference from\nthe above version is that this topic has been temporarily ejected:\n\n  https://github.com/git/git/actions/runs/1792296432\n\nWe'll see if that fails the same way (in which this topic may not\nhave anything to do with the breakage) or if it passes.\n\nThanks.\n"},{"id":"447685","messageId":"CABPp-BF0V7SomKSU4QYZGiwSOSpm_=pCrmyuUVGweCEKfV7RwQ@mail.gmail.com","threadId":"57165","inReplyTo":"a1c46c763fd4c832a6784e2a368199efedce17e9.1643921091.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v5 1/3] completion: address sparse-checkout issues","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2022-02-03T23:52:37Z","receivedAt":"2022-02-03T23:52:51Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Thu, Feb 3, 2022 at 12:44 PM Lessley Dennington via GitGitGadget\n<gitgitgadget@gmail.com> wrote:\n>\n> From: Lessley Dennington <lessleydennington@gmail.com>\n>\n> Correct multiple issues with tab completion of the git sparse-checkout\n> command. These issues were:\n>\n> 1. git sparse-checkout <TAB> previously resulted in an incomplete list of\n> subcommands (it was missing reapply and add).\n> 2. Subcommand options were not tab-completable.\n> 3. git sparse-checkout set <TAB> and git sparse-checkout add <TAB> showed\n> both file names and directory names. While this may be a less surprising\n> behavior for non-cone mode, cone mode sparse checkouts should complete\n> only directory names.\n>\n> Note that while the new strategy of just using git ls-tree to complete on\n> directory names is simple and a step in the right direction, it does have\n> some caveats. These are:\n>\n> 1. Likelihood of poor performance in large monorepos (as a result of\n> recursively completing directory names).\n> 2. Inability to handle paths containing unusual characters.\n>\n> These caveats will be fixed by subsequent commits in this series.\n>\n> Signed-off-by: Lessley Dennington <lessleydennington@gmail.com>\n> ---\n>  contrib/completion/git-completion.bash | 16 ++---\n>  t/t9902-completion.sh                  | 83 ++++++++++++++++++++++++++\n>  2 files changed, 91 insertions(+), 8 deletions(-)\n>\n> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\n> index c82ccaebcc7..2976f63747f 100644\n> --- a/contrib/completion/git-completion.bash\n> +++ b/contrib/completion/git-completion.bash\n> @@ -2988,7 +2988,7 @@ _git_show_branch ()\n>\n>  _git_sparse_checkout ()\n>  {\n> -       local subcommands=\"list init set disable\"\n> +       local subcommands=\"list init set disable add reapply\"\n>         local subcommand=\"$(__git_find_on_cmdline \"$subcommands\")\"\n>         if [ -z \"$subcommand\" ]; then\n>                 __gitcomp \"$subcommands\"\n> @@ -2996,14 +2996,14 @@ _git_sparse_checkout ()\n>         fi\n>\n>         case \"$subcommand,$cur\" in\n> -       init,--*)\n> -               __gitcomp \"--cone\"\n> -               ;;\n> -       set,--*)\n> -               __gitcomp \"--stdin\"\n> -               ;;\n> -       *)\n> +       *,--*)\n> +               __gitcomp_builtin sparse-checkout_$subcommand \"\" \"--\"\n>                 ;;\n> +       set,*|add,*)\n> +               if [ $(__git config core.sparseCheckoutCone) ] ||\n\nShouldn't this be\n\n                 if [ \"$(__git config core.sparseCheckoutCone)\" == \"true\" ] ||\n\notherwise I think you'd trigger when it's manually set to false.\n\n> +               [ \"$(__git_find_on_cmdline --cone)\" ]; then\n\nThis might read better as\n\n                [ -n \"$(__git_find_on_cmdline --cone)\" ]; then\n\nbecause otherwise you are relying on\n\n     [ \"--cone\" ]\n\nto evaluate as true which just seems slightly weird.\n\n> +                       __gitcomp \"$(git ls-tree -d -r HEAD --name-only)\"\n> +               fi\n>         esac\n>  }\n>\n> diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\n> index 518203fbe07..f6eeb9aa035 100755\n> --- a/t/t9902-completion.sh\n> +++ b/t/t9902-completion.sh\n> @@ -1447,6 +1447,89 @@ test_expect_success 'git checkout - with --detach, complete only references' '\n>         EOF\n>  '\n>\n> +test_expect_success 'setup sparse-checkout tests' '\n> +       # set up sparse-checkout repo\n> +       git init sparse-checkout &&\n> +       (\n> +               cd sparse-checkout &&\n> +               mkdir -p folder1/0/1 folder2/0 folder3 &&\n> +               touch folder1/0/1/t.txt &&\n> +               touch folder2/0/t.txt &&\n> +               touch folder3/t.txt &&\n> +               git add . &&\n> +               git commit -am \"Initial commit\"\n> +       )\n> +'\n> +\n> +test_expect_success 'sparse-checkout completes subcommands' '\n> +       test_completion \"git sparse-checkout \" <<-\\EOF\n> +       list Z\n> +       init Z\n> +       set Z\n> +       add Z\n> +       reapply Z\n> +       disable Z\n> +       EOF\n> +'\n> +\n> +test_expect_success 'cone mode sparse-checkout completes directory names' '\n> +       # initialize sparse-checkout definitions\n> +       git -C sparse-checkout sparse-checkout set --cone folder1/0 folder3 &&\n> +\n> +       # test tab completion\n> +       (\n> +               cd sparse-checkout &&\n> +               test_completion \"git sparse-checkout set f\" <<-\\EOF\n> +               folder1 Z\n> +               folder1/0 Z\n> +               folder1/0/1 Z\n> +               folder2 Z\n> +               folder2/0 Z\n> +               folder3 Z\n> +               EOF\n> +       ) &&\n> +\n> +       (\n> +               cd sparse-checkout/folder1 &&\n> +               test_completion \"git sparse-checkout add \" <<-\\EOF\n> +               ./ Z\n> +               0 Z\n> +               0/1 Z\n> +               EOF\n> +       )\n> +'\n> +\n> +test_expect_success 'non-cone mode sparse-checkout uses bash completion' '\n> +       # reset sparse-checkout repo to non-cone mode\n> +       git -C sparse-checkout sparse-checkout disable &&\n> +       git -C sparse-checkout sparse-checkout set --no-cone &&\n> +\n> +       (\n> +               cd sparse-checkout &&\n> +               # expected to be empty since we have not configured\n> +               # custom completion for non-cone mode\n> +               test_completion \"git sparse-checkout set f\" <<-\\EOF\n> +\n> +               EOF\n> +       )\n> +'\n> +\n> +test_expect_success 'git sparse-checkout set --cone completes directory names' '\n> +       git -C sparse-checkout sparse-checkout disable &&\n> +\n> +       (\n> +               cd sparse-checkout &&\n> +               test_completion \"git sparse-checkout set --cone f\" <<-\\EOF\n> +               folder1 Z\n> +               folder1/0 Z\n> +               folder1/0/1 Z\n> +               folder2 Z\n> +               folder2/0 Z\n> +               folder3 Z\n> +               EOF\n> +       )\n> +'\n> +\n>  test_expect_success 'git switch - with -d, complete all references' '\n>         test_completion \"git switch -d \" <<-\\EOF\n>         HEAD Z\n\nThe rest looks good to me.\n"},{"id":"447687","messageId":"CABPp-BFD51BTsG7gQFD4BuqVLLBV2iJOKnrnya89otoGonzVvA@mail.gmail.com","threadId":"57165","inReplyTo":"ddf5e583dd71a729d6fb0513aed9fc4eb6ebbdd7.1643921091.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v5 3/3] completion: handle unusual characters for sparse-checkout","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2022-02-03T23:58:12Z","receivedAt":"2022-02-03T23:58:26Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Thu, Feb 3, 2022 at 12:44 PM Lessley Dennington via GitGitGadget\n<gitgitgadget@gmail.com> wrote:\n>\n> From: Lessley Dennington <lessleydennington@gmail.com>\n>\n> Update the __gitcomp_directories method to de-quote and handle unusual\n> characters in directory names. Although this initially involved an attempt\n> to re-use the logic in __git_index_files, this method removed\n> subdirectories (e.g. folder1/0/ became folder1/), so instead new custom\n> logic was placed directly in the __gitcomp_directories method.\n>\n> Co-authored-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> Co-authored-by: Lessley Dennington <lessleydennington@gmail.com>\n> Signed-off-by: Lessley Dennington <lessleydennington@gmail.com>\n> ---\n>  contrib/completion/git-completion.bash | 50 +++++++++++++-------------\n>  t/t9902-completion.sh                  | 28 +++++++++++++++\n>  2 files changed, 52 insertions(+), 26 deletions(-)\n>\n> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\n> index c5c8df6b6e5..c47e9ce09b2 100644\n> --- a/contrib/completion/git-completion.bash\n> +++ b/contrib/completion/git-completion.bash\n> @@ -2988,32 +2988,30 @@ _git_show_branch ()\n>\n>  __gitcomp_directories ()\n>  {\n> -     local _tmp_dir _tmp_completions\n> -\n> -     # Get the directory of the current token; this differs from dirname\n> -     # in that it keeps up to the final trailing slash.  If no slash found\n> -     # that's fine too.\n> -     [[ \"$cur\" =~ .*/ ]]\n> -     _tmp_dir=$BASH_REMATCH\n> -\n> -     # Find possible directory completions, adding trailing '/' characters\n> -     _tmp_completions=\"$(git ls-tree -d --name-only HEAD $_tmp_dir |\n> -         sed -e s%$%/%)\"\n> -\n> -     if [[ -n \"$_tmp_completions\" ]]; then\n> -         # There were some directory completions, so find ones that\n> -         # start with \"$cur\", the current token, and put those in COMPREPLY\n> -         local i=0 c IFS=$' \\t\\n'\n> -         for c in $_tmp_completions; do\n> -             if [[ $c == \"$cur\"* ]]; then\n> -                 COMPREPLY+=(\"$c\")\n> -             fi\n> -         done\n> -     elif [[ \"$cur\" =~ /$ ]]; then\n> -         # No possible further completions any deeper, so assume we're at\n> -         # a leaf directory and just consider it complete\n> -         __gitcomp_direct_append \"$cur \"\n> -     fi\n> +       local _tmp_dir _tmp_completions _found=0\n> +\n> +       # Get the directory of the current token; this differs from dirname\n> +       # in that it keeps up to the final trailing slash.  If no slash found\n> +       # that's fine too.\n> +       [[ \"$cur\" =~ .*/ ]]\n> +       _tmp_dir=$BASH_REMATCH\n> +\n> +       # Find possible directory completions, adding trailing '/' characters,\n> +       # de-quoting, and handling unusual characters.\n> +       while IFS= read -r -d $'\\0' c ; do\n> +               # If there are directory completions, find ones that start\n> +               # with \"$cur\", the current token, and put those in COMPREPLY\n> +               if [[ $c == \"$cur\"* ]]; then\n> +                       COMPREPLY+=(\"$c/\")\n> +                       _found=1\n> +               fi\n> +       done < <(git ls-tree -z -d --name-only HEAD $_tmp_dir)\n> +\n> +       if [[ $_found == 0 ]] && [[ \"$cur\" =~ /$ ]]; then\n> +               # No possible further completions any deeper, so assume we're at\n> +               # a leaf directory and just consider it complete\n> +               __gitcomp_direct_append \"$cur \"\n> +       fi\n\nThe indentation changes are distracting and make the patch harder to\nreview.  Could you either remove those, or apply the indentation\nchanges to patch 2 so that it starts with the right indentation?\n\nI'm slightly surprised that __gitcomp_direct_append handles the\nquoting for us, but the testcases below seem to cover it, so that's\ncool.\n\nAnyway, looks pretty clever to me; I was worried this was going to\nrequire a much bigger change.\n\n>  }\n>\n>  _git_sparse_checkout ()\n> diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\n> index b38a7302249..7f63d6057be 100755\n> --- a/t/t9902-completion.sh\n> +++ b/t/t9902-completion.sh\n> @@ -1508,6 +1508,34 @@ test_expect_success 'cone mode sparse-checkout completes directory names' '\n>         )\n>  '\n>\n> +# use FUNNYNAMES to avoid running on Windows, which doesn't permit backslashes in paths\n> +test_expect_success FUNNYNAMES 'cone mode sparse-checkout completes directory names with special characters' '\n> +       # reset sparse-checkout\n> +       git -C sparse-checkout sparse-checkout disable &&\n> +       (\n> +               cd sparse-checkout &&\n> +               mkdir \"directory with spaces\" &&\n> +               mkdir \"$(printf \"directory\\twith\\ttabs\")\" &&\n> +               mkdir \"directory\\with\\backslashes\" &&\n> +               mkdir \"directory-with-áccent\" &&\n> +               >\"directory with spaces/randomfile\" &&\n> +               >\"$(printf \"directory\\twith\\ttabs\")/randomfile\" &&\n> +               >\"directory\\with\\backslashes/randomfile\" &&\n> +               >\"directory-with-áccent/randomfile\" &&\n> +               git add . &&\n> +               git commit -m \"Add directories containing unusual characters\" &&\n> +               git sparse-checkout set --cone \"directory with spaces\" \\\n> +                       \"$(printf \"directory\\twith\\ttabs\")\" \"directory\\with\\backslashes\" \\\n> +                       \"directory-with-áccent\" &&\n> +               test_completion \"git sparse-checkout add dir\" <<-\\EOF\n> +               directory with spaces/\n> +               directory       with    tabs/\n> +               directory\\with\\backslashes/\n> +               directory-with-áccent/\n> +               EOF\n> +       )\n> +'\n\nI'm glad you tested with lots of special characters -- spaces, tabs,\nbackslashes, and accents.  Newlines might also be nice, but probably\nmakes the test hard.  Anyway, looks good to me, other than the\nindentation change.\n\n> +\n>  test_expect_success 'non-cone mode sparse-checkout uses bash completion' '\n>         # reset sparse-checkout repo to non-cone mode\n>         git -C sparse-checkout sparse-checkout disable &&\n> --\n> gitgitgadget\n"},{"id":"447688","messageId":"eb442213-d369-fdcd-c3a3-05239bccb5bf@gmail.com","threadId":"57165","inReplyTo":"xmqqy22rpm10.fsf@gitster.g","subject":"Re: [PATCH v5 0/3] completion: sparse-checkout updates","fromName":"Lessley Dennington","fromEmail":"lessleydennington@gmail.com","sentAt":"2022-02-03T23:59:33Z","receivedAt":"2022-02-03T23:59:36Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"\n\nOn 2/3/22 3:28 PM, Junio C Hamano wrote:\n> Lessley Dennington <lessleydennington@gmail.com> writes:\n> \n>> On 2/3/22 1:48 PM, Junio C Hamano wrote:\n>>> \"Lessley Dennington via GitGitGadget\" <gitgitgadget@gmail.com>\n>>> writes:\n>>>\n>>>> This series is based on en/sparse-checkout-set.\n>>> This has been a very helpful note, but after the topic was merged to\n>>> 'master' on Jan 3rd, it has become a tad stale.  Let me apply the\n>>> topic directly on v2.35.0 instead.\n>>> Thanks.\n>>\n>> Thank you for the heads up! I will remove from future versions.\n> \n> No problem.\n> \n> FWIW, the tip of 'seen' seems to be failing the CI; I haven't looked\n> into the cause of the breakage.\n> \n>    https://github.com/git/git/actions/runs/1792151138\n> \n> There is another CI job running on 'seen', whose only difference from\n> the above version is that this topic has been temporarily ejected:\n> \n>    https://github.com/git/git/actions/runs/1792296432\n> \n> We'll see if that fails the same way (in which this topic may not\n> have anything to do with the breakage) or if it passes.\n> \n> Thanks.\n\nI just merged seen locally and was able to repro the failure. I will\nsubmit a fix ASAP.\n"},{"id":"447690","messageId":"d7f7a36d-daa1-395b-2df0-2bf135c6ec4a@gmail.com","threadId":"57165","inReplyTo":"CABPp-BF0V7SomKSU4QYZGiwSOSpm_=pCrmyuUVGweCEKfV7RwQ@mail.gmail.com","subject":"Re: [PATCH v5 1/3] completion: address sparse-checkout issues","fromName":"Lessley Dennington","fromEmail":"lessleydennington@gmail.com","sentAt":"2022-02-04T00:34:29Z","receivedAt":"2022-02-04T00:34:36Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"\n\nOn 2/3/22 3:52 PM, Elijah Newren wrote:\n> On Thu, Feb 3, 2022 at 12:44 PM Lessley Dennington via GitGitGadget\n> <gitgitgadget@gmail.com> wrote:\n>>\n>> From: Lessley Dennington <lessleydennington@gmail.com>\n>>\n>> Correct multiple issues with tab completion of the git sparse-checkout\n>> command. These issues were:\n>>\n>> 1. git sparse-checkout <TAB> previously resulted in an incomplete list of\n>> subcommands (it was missing reapply and add).\n>> 2. Subcommand options were not tab-completable.\n>> 3. git sparse-checkout set <TAB> and git sparse-checkout add <TAB> showed\n>> both file names and directory names. While this may be a less surprising\n>> behavior for non-cone mode, cone mode sparse checkouts should complete\n>> only directory names.\n>>\n>> Note that while the new strategy of just using git ls-tree to complete on\n>> directory names is simple and a step in the right direction, it does have\n>> some caveats. These are:\n>>\n>> 1. Likelihood of poor performance in large monorepos (as a result of\n>> recursively completing directory names).\n>> 2. Inability to handle paths containing unusual characters.\n>>\n>> These caveats will be fixed by subsequent commits in this series.\n>>\n>> Signed-off-by: Lessley Dennington <lessleydennington@gmail.com>\n>> ---\n>>   contrib/completion/git-completion.bash | 16 ++---\n>>   t/t9902-completion.sh                  | 83 ++++++++++++++++++++++++++\n>>   2 files changed, 91 insertions(+), 8 deletions(-)\n>>\n>> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\n>> index c82ccaebcc7..2976f63747f 100644\n>> --- a/contrib/completion/git-completion.bash\n>> +++ b/contrib/completion/git-completion.bash\n>> @@ -2988,7 +2988,7 @@ _git_show_branch ()\n>>\n>>   _git_sparse_checkout ()\n>>   {\n>> -       local subcommands=\"list init set disable\"\n>> +       local subcommands=\"list init set disable add reapply\"\n>>          local subcommand=\"$(__git_find_on_cmdline \"$subcommands\")\"\n>>          if [ -z \"$subcommand\" ]; then\n>>                  __gitcomp \"$subcommands\"\n>> @@ -2996,14 +2996,14 @@ _git_sparse_checkout ()\n>>          fi\n>>\n>>          case \"$subcommand,$cur\" in\n>> -       init,--*)\n>> -               __gitcomp \"--cone\"\n>> -               ;;\n>> -       set,--*)\n>> -               __gitcomp \"--stdin\"\n>> -               ;;\n>> -       *)\n>> +       *,--*)\n>> +               __gitcomp_builtin sparse-checkout_$subcommand \"\" \"--\"\n>>                  ;;\n>> +       set,*|add,*)\n>> +               if [ $(__git config core.sparseCheckoutCone) ] ||\n> \n> Shouldn't this be\n> \n>                   if [ \"$(__git config core.sparseCheckoutCone)\" == \"true\" ] ||\n> \n> otherwise I think you'd trigger when it's manually set to false.\n> \n>> +               [ \"$(__git_find_on_cmdline --cone)\" ]; then\n> \n> This might read better as\n> \n>                  [ -n \"$(__git_find_on_cmdline --cone)\" ]; then\n> \n> because otherwise you are relying on\n> \n>       [ \"--cone\" ]\n> \n> to evaluate as true which just seems slightly weird.\n> \nYup, this was causing some problems. Odd that the failure only cropped up\nwhen merged with 'seen' but I have a fix prepared and will submit as soon\nas GGG CI completes.\n>> +                       __gitcomp \"$(git ls-tree -d -r HEAD --name-only)\"\n>> +               fi\n>>          esac\n>>   }\n>>\n>> diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\n>> index 518203fbe07..f6eeb9aa035 100755\n>> --- a/t/t9902-completion.sh\n>> +++ b/t/t9902-completion.sh\n>> @@ -1447,6 +1447,89 @@ test_expect_success 'git checkout - with --detach, complete only references' '\n>>          EOF\n>>   '\n>>\n>> +test_expect_success 'setup sparse-checkout tests' '\n>> +       # set up sparse-checkout repo\n>> +       git init sparse-checkout &&\n>> +       (\n>> +               cd sparse-checkout &&\n>> +               mkdir -p folder1/0/1 folder2/0 folder3 &&\n>> +               touch folder1/0/1/t.txt &&\n>> +               touch folder2/0/t.txt &&\n>> +               touch folder3/t.txt &&\n>> +               git add . &&\n>> +               git commit -am \"Initial commit\"\n>> +       )\n>> +'\n>> +\n>> +test_expect_success 'sparse-checkout completes subcommands' '\n>> +       test_completion \"git sparse-checkout \" <<-\\EOF\n>> +       list Z\n>> +       init Z\n>> +       set Z\n>> +       add Z\n>> +       reapply Z\n>> +       disable Z\n>> +       EOF\n>> +'\n>> +\n>> +test_expect_success 'cone mode sparse-checkout completes directory names' '\n>> +       # initialize sparse-checkout definitions\n>> +       git -C sparse-checkout sparse-checkout set --cone folder1/0 folder3 &&\n>> +\n>> +       # test tab completion\n>> +       (\n>> +               cd sparse-checkout &&\n>> +               test_completion \"git sparse-checkout set f\" <<-\\EOF\n>> +               folder1 Z\n>> +               folder1/0 Z\n>> +               folder1/0/1 Z\n>> +               folder2 Z\n>> +               folder2/0 Z\n>> +               folder3 Z\n>> +               EOF\n>> +       ) &&\n>> +\n>> +       (\n>> +               cd sparse-checkout/folder1 &&\n>> +               test_completion \"git sparse-checkout add \" <<-\\EOF\n>> +               ./ Z\n>> +               0 Z\n>> +               0/1 Z\n>> +               EOF\n>> +       )\n>> +'\n>> +\n>> +test_expect_success 'non-cone mode sparse-checkout uses bash completion' '\n>> +       # reset sparse-checkout repo to non-cone mode\n>> +       git -C sparse-checkout sparse-checkout disable &&\n>> +       git -C sparse-checkout sparse-checkout set --no-cone &&\n>> +\n>> +       (\n>> +               cd sparse-checkout &&\n>> +               # expected to be empty since we have not configured\n>> +               # custom completion for non-cone mode\n>> +               test_completion \"git sparse-checkout set f\" <<-\\EOF\n>> +\n>> +               EOF\n>> +       )\n>> +'\n>> +\n>> +test_expect_success 'git sparse-checkout set --cone completes directory names' '\n>> +       git -C sparse-checkout sparse-checkout disable &&\n>> +\n>> +       (\n>> +               cd sparse-checkout &&\n>> +               test_completion \"git sparse-checkout set --cone f\" <<-\\EOF\n>> +               folder1 Z\n>> +               folder1/0 Z\n>> +               folder1/0/1 Z\n>> +               folder2 Z\n>> +               folder2/0 Z\n>> +               folder3 Z\n>> +               EOF\n>> +       )\n>> +'\n>> +\n>>   test_expect_success 'git switch - with -d, complete all references' '\n>>          test_completion \"git switch -d \" <<-\\EOF\n>>          HEAD Z\n> \n> The rest looks good to me.\n"},{"id":"447691","messageId":"d7e0898f-6a4f-3688-2c55-8da412531edc@gmail.com","threadId":"57165","inReplyTo":"CABPp-BFD51BTsG7gQFD4BuqVLLBV2iJOKnrnya89otoGonzVvA@mail.gmail.com","subject":"Re: [PATCH v5 3/3] completion: handle unusual characters for sparse-checkout","fromName":"Lessley Dennington","fromEmail":"lessleydennington@gmail.com","sentAt":"2022-02-04T00:37:36Z","receivedAt":"2022-02-04T00:37:40Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"\n\nOn 2/3/22 3:58 PM, Elijah Newren wrote:\n> On Thu, Feb 3, 2022 at 12:44 PM Lessley Dennington via GitGitGadget\n> <gitgitgadget@gmail.com> wrote:\n>>\n>> From: Lessley Dennington <lessleydennington@gmail.com>\n>>\n>> Update the __gitcomp_directories method to de-quote and handle unusual\n>> characters in directory names. Although this initially involved an attempt\n>> to re-use the logic in __git_index_files, this method removed\n>> subdirectories (e.g. folder1/0/ became folder1/), so instead new custom\n>> logic was placed directly in the __gitcomp_directories method.\n>>\n>> Co-authored-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n>> Co-authored-by: Lessley Dennington <lessleydennington@gmail.com>\n>> Signed-off-by: Lessley Dennington <lessleydennington@gmail.com>\n>> ---\n>>   contrib/completion/git-completion.bash | 50 +++++++++++++-------------\n>>   t/t9902-completion.sh                  | 28 +++++++++++++++\n>>   2 files changed, 52 insertions(+), 26 deletions(-)\n>>\n>> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\n>> index c5c8df6b6e5..c47e9ce09b2 100644\n>> --- a/contrib/completion/git-completion.bash\n>> +++ b/contrib/completion/git-completion.bash\n>> @@ -2988,32 +2988,30 @@ _git_show_branch ()\n>>\n>>   __gitcomp_directories ()\n>>   {\n>> -     local _tmp_dir _tmp_completions\n>> -\n>> -     # Get the directory of the current token; this differs from dirname\n>> -     # in that it keeps up to the final trailing slash.  If no slash found\n>> -     # that's fine too.\n>> -     [[ \"$cur\" =~ .*/ ]]\n>> -     _tmp_dir=$BASH_REMATCH\n>> -\n>> -     # Find possible directory completions, adding trailing '/' characters\n>> -     _tmp_completions=\"$(git ls-tree -d --name-only HEAD $_tmp_dir |\n>> -         sed -e s%$%/%)\"\n>> -\n>> -     if [[ -n \"$_tmp_completions\" ]]; then\n>> -         # There were some directory completions, so find ones that\n>> -         # start with \"$cur\", the current token, and put those in COMPREPLY\n>> -         local i=0 c IFS=$' \\t\\n'\n>> -         for c in $_tmp_completions; do\n>> -             if [[ $c == \"$cur\"* ]]; then\n>> -                 COMPREPLY+=(\"$c\")\n>> -             fi\n>> -         done\n>> -     elif [[ \"$cur\" =~ /$ ]]; then\n>> -         # No possible further completions any deeper, so assume we're at\n>> -         # a leaf directory and just consider it complete\n>> -         __gitcomp_direct_append \"$cur \"\n>> -     fi\n>> +       local _tmp_dir _tmp_completions _found=0\n>> +\n>> +       # Get the directory of the current token; this differs from dirname\n>> +       # in that it keeps up to the final trailing slash.  If no slash found\n>> +       # that's fine too.\n>> +       [[ \"$cur\" =~ .*/ ]]\n>> +       _tmp_dir=$BASH_REMATCH\n>> +\n>> +       # Find possible directory completions, adding trailing '/' characters,\n>> +       # de-quoting, and handling unusual characters.\n>> +       while IFS= read -r -d $'\\0' c ; do\n>> +               # If there are directory completions, find ones that start\n>> +               # with \"$cur\", the current token, and put those in COMPREPLY\n>> +               if [[ $c == \"$cur\"* ]]; then\n>> +                       COMPREPLY+=(\"$c/\")\n>> +                       _found=1\n>> +               fi\n>> +       done < <(git ls-tree -z -d --name-only HEAD $_tmp_dir)\n>> +\n>> +       if [[ $_found == 0 ]] && [[ \"$cur\" =~ /$ ]]; then\n>> +               # No possible further completions any deeper, so assume we're at\n>> +               # a leaf directory and just consider it complete\n>> +               __gitcomp_direct_append \"$cur \"\n>> +       fi\n> \n> The indentation changes are distracting and make the patch harder to\n> review.  Could you either remove those, or apply the indentation\n> changes to patch 2 so that it starts with the right indentation?\n\nI've also corrected this as part of the fix I'm about to submit.\n> \n> I'm slightly surprised that __gitcomp_direct_append handles the\n> quoting for us, but the testcases below seem to cover it, so that's\n> cool.\n>\n> Anyway, looks pretty clever to me; I was worried this was going to\n> require a much bigger change.\n> \n>>   }\n>>\n>>   _git_sparse_checkout ()\n>> diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\n>> index b38a7302249..7f63d6057be 100755\n>> --- a/t/t9902-completion.sh\n>> +++ b/t/t9902-completion.sh\n>> @@ -1508,6 +1508,34 @@ test_expect_success 'cone mode sparse-checkout completes directory names' '\n>>          )\n>>   '\n>>\n>> +# use FUNNYNAMES to avoid running on Windows, which doesn't permit backslashes in paths\n>> +test_expect_success FUNNYNAMES 'cone mode sparse-checkout completes directory names with special characters' '\n>> +       # reset sparse-checkout\n>> +       git -C sparse-checkout sparse-checkout disable &&\n>> +       (\n>> +               cd sparse-checkout &&\n>> +               mkdir \"directory with spaces\" &&\n>> +               mkdir \"$(printf \"directory\\twith\\ttabs\")\" &&\n>> +               mkdir \"directory\\with\\backslashes\" &&\n>> +               mkdir \"directory-with-áccent\" &&\n>> +               >\"directory with spaces/randomfile\" &&\n>> +               >\"$(printf \"directory\\twith\\ttabs\")/randomfile\" &&\n>> +               >\"directory\\with\\backslashes/randomfile\" &&\n>> +               >\"directory-with-áccent/randomfile\" &&\n>> +               git add . &&\n>> +               git commit -m \"Add directories containing unusual characters\" &&\n>> +               git sparse-checkout set --cone \"directory with spaces\" \\\n>> +                       \"$(printf \"directory\\twith\\ttabs\")\" \"directory\\with\\backslashes\" \\\n>> +                       \"directory-with-áccent\" &&\n>> +               test_completion \"git sparse-checkout add dir\" <<-\\EOF\n>> +               directory with spaces/\n>> +               directory       with    tabs/\n>> +               directory\\with\\backslashes/\n>> +               directory-with-áccent/\n>> +               EOF\n>> +       )\n>> +'\n> \n> I'm glad you tested with lots of special characters -- spaces, tabs,\n> backslashes, and accents.  Newlines might also be nice, but probably\n> makes the test hard.  Anyway, looks good to me, other than the\n> indentation change.\n> \n>> +\n>>   test_expect_success 'non-cone mode sparse-checkout uses bash completion' '\n>>          # reset sparse-checkout repo to non-cone mode\n>>          git -C sparse-checkout sparse-checkout disable &&\n>> --\n>> gitgitgadget\n"},{"id":"447696","messageId":"cb6f65b5-4e02-08af-bea6-141fb6227927@gmail.com","threadId":"57165","inReplyTo":"eb442213-d369-fdcd-c3a3-05239bccb5bf@gmail.com","subject":"Re: [PATCH v5 0/3] completion: sparse-checkout updates","fromName":"Lessley Dennington","fromEmail":"lessleydennington@gmail.com","sentAt":"2022-02-04T02:43:53Z","receivedAt":"2022-02-04T02:43:57Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"\n\nOn 2/3/22 3:59 PM, Lessley Dennington wrote:\n> \n> \n> On 2/3/22 3:28 PM, Junio C Hamano wrote:\n>> Lessley Dennington <lessleydennington@gmail.com> writes:\n>>\n>>> On 2/3/22 1:48 PM, Junio C Hamano wrote:\n>>>> \"Lessley Dennington via GitGitGadget\" <gitgitgadget@gmail.com>\n>>>> writes:\n>>>>\n>>>>> This series is based on en/sparse-checkout-set.\n>>>> This has been a very helpful note, but after the topic was merged to\n>>>> 'master' on Jan 3rd, it has become a tad stale.  Let me apply the\n>>>> topic directly on v2.35.0 instead.\n>>>> Thanks.\n>>>\n>>> Thank you for the heads up! I will remove from future versions.\n>>\n>> No problem.\n>>\n>> FWIW, the tip of 'seen' seems to be failing the CI; I haven't looked\n>> into the cause of the breakage.\n>>\n>>    https://github.com/git/git/actions/runs/1792151138\n>>\n>> There is another CI job running on 'seen', whose only difference from\n>> the above version is that this topic has been temporarily ejected:\n>>\n>>    https://github.com/git/git/actions/runs/1792296432\n>>\n>> We'll see if that fails the same way (in which this topic may not\n>> have anything to do with the breakage) or if it passes.\n>>\n>> Thanks.\n> \n> I just merged seen locally and was able to repro the failure. I will\n> submit a fix ASAP.\n\nGitGitGadget CI has passed with the fix, but it is not responding to the\n/submit command. As a heads up, fix may not be submitted until folks who\nare a bit more knowledgeable about GGG than I are available to help\ntroubleshoot.\n"},{"id":"447697","messageId":"pull.1108.v6.git.1643945198.gitgitgadget@gmail.com","threadId":"57165","inReplyTo":"pull.1108.v5.git.1643921091.gitgitgadget@gmail.com","subject":"[PATCH v6 0/3] completion: sparse-checkout updates","fromName":"Lessley Dennington via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-02-04T03:26:35Z","receivedAt":"2022-02-04T03:26:43Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"This change updates custom tab completion for the sparse-checkout command.\nSpecifically, it corrects the following issues with the current method:\n\n 1. git sparse-checkout <TAB> results in an incomplete list of subcommands\n    (it is missing reapply and add).\n 2. Options for subcommands are not tab-completable.\n 3. git sparse-checkout set <TAB> and git sparse-checkout add <TAB> show\n    both file names and directory names. While this may be a less surprising\n    behavior for non-cone mode, we want to only show directories in cone\n    mode.\n\nThe first commit in this series is an intermediate step that fixes issues 1\nand 2 above and introduces a simple fix for issue 3 with some performance\nand unusual character-related caveats. The next commit adds a new\n__gitcomp_directories method that fixes the performance-related caveat from\nthe first commit by completing just a single level of directories. The final\ncommit modifies __gitcomp_directories to handle unusual characters in\ndirectory names.\n\n\nChanges since V5\n================\n\n * Fix incorrect conditional that was causing failure of non-cone mode test\n   (and causing 'seen' CI to fail).\n * Remove __git_comp_directories indentation changes between the second and\n   third commits.\n\n\nChanges since V4\n================\n\n * Clarify that completing on files and directories is a less-surprising\n   behavior in non-cone mode (rather than definitely the correct behavior)\n   in commit message and cover letter.\n * Add explicit --no-cone to non-cone mode sparse-checkout completion test.\n * Replace use of __git_complete_index_file with a new version of\n   __gitcomp_directories that is able to handle unusual characters.\n * Ensure that users running git sparse-checkout set --cone get cone\n   mode-style completion whether or not they already have the cone mode\n   config set.\n * Refactor creation of sparse-checkout test repo into a sparse-checkout\n   setup test.\n\n\nChanges since V3\n================\n\n * Update commit descriptions to begin with completion instead of\n   sparse-checkout.\n * Remove explicit completion of --help, as this is inconsistent with the\n   rest of the completion script.\n * Use __gitcomp_builtin to auto-complete subcommand options (and remove\n   option completion test from previous iterations, as it is no longer\n   necessary).\n * Use __git_complete_index_file helper function in place of __gitcomp\n   \"$(git ls-tree -d -r HEAD --name-only).\n * If in cone-mode sparse checkout, only show directory completions. If in\n   non-cone mode sparse checkout show both files and directories.\n\n\nChanges since V2\n================\n\n * Change use of $prev to $subcommand in _git_sparse_checkout() method in\n   git-completion.bash.\n * State explicitly that directory completion applies in both cone and\n   non-cone mode in 'sparse-checkout: custom tab completion' commit\n * Add new patch with __gitcomp_directories method to improve performance by\n   only outputting directories at the current level.\n\n\nChanges since V1\n================\n\n * Rebase onto en/sparse-checkout-set.\n * Add subcommand options (including --no-cone) for set and reapply.\n * Extend 'sparse-checkout completes subcommand options' test to validate\n   new set/reapply subcommand options.\n * No longer set index.sparse to false in 'sparse-checkout completes\n   directory names' test.\n * Refactor creation of sparse-checkout repo into a setup test.\n\nThanks, Lessley\n\nLessley Dennington (3):\n  completion: address sparse-checkout issues\n  completion: improve sparse-checkout cone mode directory completion\n  completion: handle unusual characters for sparse-checkout\n\n contrib/completion/git-completion.bash |  44 ++++++++--\n t/t9902-completion.sh                  | 117 +++++++++++++++++++++++++\n 2 files changed, 153 insertions(+), 8 deletions(-)\n\n\nbase-commit: dfac9b609f86cd4f6ce896df9e1172d2a02cde48\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-1108%2Fldennington%2Fsparse-checkout-bash-completion-v6\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1108/ldennington/sparse-checkout-bash-completion-v6\nPull-Request: https://github.com/gitgitgadget/git/pull/1108\n\nRange-diff vs v5:\n\n 1:  a1c46c763fd ! 1:  23390000dd3 completion: address sparse-checkout issues\n     @@ contrib/completion/git-completion.bash: _git_sparse_checkout ()\n      +\t\t__gitcomp_builtin sparse-checkout_$subcommand \"\" \"--\"\n       \t\t;;\n      +\tset,*|add,*)\n     -+\t\tif [ $(__git config core.sparseCheckoutCone) ] ||\n     -+\t\t[ \"$(__git_find_on_cmdline --cone)\" ]; then\n     ++\t\tif [ \"$(__git config core.sparseCheckoutCone)\" == \"true\" ] ||\n     ++\t\t[ -n \"$(__git_find_on_cmdline --cone)\" ]; then\n      +\t\t\t__gitcomp \"$(git ls-tree -d -r HEAD --name-only)\"\n      +\t\tfi\n       \tesac\n 2:  5b8d53402ae ! 2:  10a190ce6a1 completion: improve sparse-checkout cone mode directory completion\n     @@ contrib/completion/git-completion.bash: _git_show_branch ()\n       \n      +__gitcomp_directories ()\n      +{\n     -+     local _tmp_dir _tmp_completions\n     ++\tlocal _tmp_dir _tmp_completions\n      +\n     -+     # Get the directory of the current token; this differs from dirname\n     -+     # in that it keeps up to the final trailing slash.  If no slash found\n     -+     # that's fine too.\n     -+     [[ \"$cur\" =~ .*/ ]]\n     -+     _tmp_dir=$BASH_REMATCH\n     ++\t# Get the directory of the current token; this differs from dirname\n     ++\t# in that it keeps up to the final trailing slash.  If no slash found\n     ++\t# that's fine too.\n     ++\t[[ \"$cur\" =~ .*/ ]]\n     ++\t_tmp_dir=$BASH_REMATCH\n      +\n     -+     # Find possible directory completions, adding trailing '/' characters\n     -+     _tmp_completions=\"$(git ls-tree -d --name-only HEAD $_tmp_dir |\n     -+         sed -e s%$%/%)\"\n     ++\t# Find possible directory completions, adding trailing '/' characters\n     ++\t_tmp_completions=\"$(git ls-tree -d --name-only HEAD $_tmp_dir |\n     ++\t\tsed -e s%$%/%)\"\n      +\n     -+     if [[ -n \"$_tmp_completions\" ]]; then\n     -+         # There were some directory completions, so find ones that\n     -+         # start with \"$cur\", the current token, and put those in COMPREPLY\n     -+         local i=0 c IFS=$' \\t\\n'\n     -+         for c in $_tmp_completions; do\n     -+             if [[ $c == \"$cur\"* ]]; then\n     -+                 COMPREPLY+=(\"$c\")\n     -+             fi\n     -+         done\n     -+     elif [[ \"$cur\" =~ /$ ]]; then\n     -+         # No possible further completions any deeper, so assume we're at\n     -+         # a leaf directory and just consider it complete\n     -+         __gitcomp_direct_append \"$cur \"\n     -+     fi\n     ++\tif [[ -n \"$_tmp_completions\" ]]; then\n     ++\t\t# There were some directory completions, so find ones that\n     ++\t\t# start with \"$cur\", the current token, and put those in COMPREPLY\n     ++\t\tlocal i=0 c IFS=$' \\t\\n'\n     ++\t\tfor c in $_tmp_completions; do\n     ++\t\tif [[ $c == \"$cur\"* ]]; then\n     ++\t\t\tCOMPREPLY+=(\"$c\")\n     ++\t\tfi\n     ++\t\tdone\n     ++\telif [[ \"$cur\" =~ /$ ]]; then\n     ++\t\t# No possible further completions any deeper, so assume we're at\n     ++\t\t# a leaf directory and just consider it complete\n     ++\t\t__gitcomp_direct_append \"$cur \"\n     ++\tfi\n      +}\n      +\n       _git_sparse_checkout ()\n     @@ contrib/completion/git-completion.bash: _git_show_branch ()\n       \tlocal subcommands=\"list init set disable add reapply\"\n      @@ contrib/completion/git-completion.bash: _git_sparse_checkout ()\n       \tset,*|add,*)\n     - \t\tif [ $(__git config core.sparseCheckoutCone) ] ||\n     - \t\t[ \"$(__git_find_on_cmdline --cone)\" ]; then\n     + \t\tif [ \"$(__git config core.sparseCheckoutCone)\" == \"true\" ] ||\n     + \t\t[ -n \"$(__git_find_on_cmdline --cone)\" ]; then\n      -\t\t\t__gitcomp \"$(git ls-tree -d -r HEAD --name-only)\"\n      +\t\t\t__gitcomp_directories\n       \t\tfi\n 3:  ddf5e583dd7 ! 3:  e805dbb58cc completion: handle unusual characters for sparse-checkout\n     @@ contrib/completion/git-completion.bash: _git_show_branch ()\n       \n       __gitcomp_directories ()\n       {\n     --     local _tmp_dir _tmp_completions\n     --\n     --     # Get the directory of the current token; this differs from dirname\n     --     # in that it keeps up to the final trailing slash.  If no slash found\n     --     # that's fine too.\n     --     [[ \"$cur\" =~ .*/ ]]\n     --     _tmp_dir=$BASH_REMATCH\n     --\n     --     # Find possible directory completions, adding trailing '/' characters\n     --     _tmp_completions=\"$(git ls-tree -d --name-only HEAD $_tmp_dir |\n     --         sed -e s%$%/%)\"\n     --\n     --     if [[ -n \"$_tmp_completions\" ]]; then\n     --         # There were some directory completions, so find ones that\n     --         # start with \"$cur\", the current token, and put those in COMPREPLY\n     --         local i=0 c IFS=$' \\t\\n'\n     --         for c in $_tmp_completions; do\n     --             if [[ $c == \"$cur\"* ]]; then\n     --                 COMPREPLY+=(\"$c\")\n     --             fi\n     --         done\n     --     elif [[ \"$cur\" =~ /$ ]]; then\n     --         # No possible further completions any deeper, so assume we're at\n     --         # a leaf directory and just consider it complete\n     --         __gitcomp_direct_append \"$cur \"\n     --     fi\n     +-\tlocal _tmp_dir _tmp_completions\n      +\tlocal _tmp_dir _tmp_completions _found=0\n     -+\n     -+\t# Get the directory of the current token; this differs from dirname\n     -+\t# in that it keeps up to the final trailing slash.  If no slash found\n     -+\t# that's fine too.\n     -+\t[[ \"$cur\" =~ .*/ ]]\n     -+\t_tmp_dir=$BASH_REMATCH\n     -+\n     + \n     + \t# Get the directory of the current token; this differs from dirname\n     + \t# in that it keeps up to the final trailing slash.  If no slash found\n     +@@ contrib/completion/git-completion.bash: __gitcomp_directories ()\n     + \t[[ \"$cur\" =~ .*/ ]]\n     + \t_tmp_dir=$BASH_REMATCH\n     + \n     +-\t# Find possible directory completions, adding trailing '/' characters\n     +-\t_tmp_completions=\"$(git ls-tree -d --name-only HEAD $_tmp_dir |\n     +-\t\tsed -e s%$%/%)\"\n     +-\n     +-\tif [[ -n \"$_tmp_completions\" ]]; then\n     +-\t\t# There were some directory completions, so find ones that\n     +-\t\t# start with \"$cur\", the current token, and put those in COMPREPLY\n     +-\t\tlocal i=0 c IFS=$' \\t\\n'\n     +-\t\tfor c in $_tmp_completions; do\n      +\t# Find possible directory completions, adding trailing '/' characters,\n      +\t# de-quoting, and handling unusual characters.\n      +\twhile IFS= read -r -d $'\\0' c ; do\n      +\t\t# If there are directory completions, find ones that start\n      +\t\t# with \"$cur\", the current token, and put those in COMPREPLY\n     -+\t\tif [[ $c == \"$cur\"* ]]; then\n     + \t\tif [[ $c == \"$cur\"* ]]; then\n     +-\t\t\tCOMPREPLY+=(\"$c\")\n      +\t\t\tCOMPREPLY+=(\"$c/\")\n      +\t\t\t_found=1\n     -+\t\tfi\n     + \t\tfi\n     +-\t\tdone\n     +-\telif [[ \"$cur\" =~ /$ ]]; then\n      +\tdone < <(git ls-tree -z -d --name-only HEAD $_tmp_dir)\n      +\n      +\tif [[ $_found == 0 ]] && [[ \"$cur\" =~ /$ ]]; then\n     -+\t\t# No possible further completions any deeper, so assume we're at\n     -+\t\t# a leaf directory and just consider it complete\n     -+\t\t__gitcomp_direct_append \"$cur \"\n     -+\tfi\n     - }\n     - \n     - _git_sparse_checkout ()\n     + \t\t# No possible further completions any deeper, so assume we're at\n     + \t\t# a leaf directory and just consider it complete\n     + \t\t__gitcomp_direct_append \"$cur \"\n      \n       ## t/t9902-completion.sh ##\n      @@ t/t9902-completion.sh: test_expect_success 'cone mode sparse-checkout completes directory names' '\n\n-- \ngitgitgadget\n"},{"id":"447698","messageId":"23390000dd31b38a8a7711cc300b0f7fc192a824.1643945198.git.gitgitgadget@gmail.com","threadId":"57165","inReplyTo":"pull.1108.v6.git.1643945198.gitgitgadget@gmail.com","subject":"[PATCH v6 1/3] completion: address sparse-checkout issues","fromName":"Lessley Dennington via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-02-04T03:26:36Z","receivedAt":"2022-02-04T03:26:47Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"From: Lessley Dennington <lessleydennington@gmail.com>\n\nCorrect multiple issues with tab completion of the git sparse-checkout\ncommand. These issues were:\n\n1. git sparse-checkout <TAB> previously resulted in an incomplete list of\nsubcommands (it was missing reapply and add).\n2. Subcommand options were not tab-completable.\n3. git sparse-checkout set <TAB> and git sparse-checkout add <TAB> showed\nboth file names and directory names. While this may be a less surprising\nbehavior for non-cone mode, cone mode sparse checkouts should complete\nonly directory names.\n\nNote that while the new strategy of just using git ls-tree to complete on\ndirectory names is simple and a step in the right direction, it does have\nsome caveats. These are:\n\n1. Likelihood of poor performance in large monorepos (as a result of\nrecursively completing directory names).\n2. Inability to handle paths containing unusual characters.\n\nThese caveats will be fixed by subsequent commits in this series.\n\nSigned-off-by: Lessley Dennington <lessleydennington@gmail.com>\n---\n contrib/completion/git-completion.bash | 16 ++---\n t/t9902-completion.sh                  | 83 ++++++++++++++++++++++++++\n 2 files changed, 91 insertions(+), 8 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex c82ccaebcc7..7f6c86dc6c0 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -2988,7 +2988,7 @@ _git_show_branch ()\n \n _git_sparse_checkout ()\n {\n-\tlocal subcommands=\"list init set disable\"\n+\tlocal subcommands=\"list init set disable add reapply\"\n \tlocal subcommand=\"$(__git_find_on_cmdline \"$subcommands\")\"\n \tif [ -z \"$subcommand\" ]; then\n \t\t__gitcomp \"$subcommands\"\n@@ -2996,14 +2996,14 @@ _git_sparse_checkout ()\n \tfi\n \n \tcase \"$subcommand,$cur\" in\n-\tinit,--*)\n-\t\t__gitcomp \"--cone\"\n-\t\t;;\n-\tset,--*)\n-\t\t__gitcomp \"--stdin\"\n-\t\t;;\n-\t*)\n+\t*,--*)\n+\t\t__gitcomp_builtin sparse-checkout_$subcommand \"\" \"--\"\n \t\t;;\n+\tset,*|add,*)\n+\t\tif [ \"$(__git config core.sparseCheckoutCone)\" == \"true\" ] ||\n+\t\t[ -n \"$(__git_find_on_cmdline --cone)\" ]; then\n+\t\t\t__gitcomp \"$(git ls-tree -d -r HEAD --name-only)\"\n+\t\tfi\n \tesac\n }\n \ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex 518203fbe07..f6eeb9aa035 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -1447,6 +1447,89 @@ test_expect_success 'git checkout - with --detach, complete only references' '\n \tEOF\n '\n \n+test_expect_success 'setup sparse-checkout tests' '\n+\t# set up sparse-checkout repo\n+\tgit init sparse-checkout &&\n+\t(\n+\t\tcd sparse-checkout &&\n+\t\tmkdir -p folder1/0/1 folder2/0 folder3 &&\n+\t\ttouch folder1/0/1/t.txt &&\n+\t\ttouch folder2/0/t.txt &&\n+\t\ttouch folder3/t.txt &&\n+\t\tgit add . &&\n+\t\tgit commit -am \"Initial commit\"\n+\t)\n+'\n+\n+test_expect_success 'sparse-checkout completes subcommands' '\n+\ttest_completion \"git sparse-checkout \" <<-\\EOF\n+\tlist Z\n+\tinit Z\n+\tset Z\n+\tadd Z\n+\treapply Z\n+\tdisable Z\n+\tEOF\n+'\n+\n+test_expect_success 'cone mode sparse-checkout completes directory names' '\n+\t# initialize sparse-checkout definitions\n+\tgit -C sparse-checkout sparse-checkout set --cone folder1/0 folder3 &&\n+\n+\t# test tab completion\n+\t(\n+\t\tcd sparse-checkout &&\n+\t\ttest_completion \"git sparse-checkout set f\" <<-\\EOF\n+\t\tfolder1 Z\n+\t\tfolder1/0 Z\n+\t\tfolder1/0/1 Z\n+\t\tfolder2 Z\n+\t\tfolder2/0 Z\n+\t\tfolder3 Z\n+\t\tEOF\n+\t) &&\n+\n+\t(\n+\t\tcd sparse-checkout/folder1 &&\n+\t\ttest_completion \"git sparse-checkout add \" <<-\\EOF\n+\t\t./ Z\n+\t\t0 Z\n+\t\t0/1 Z\n+\t\tEOF\n+\t)\n+'\n+\n+test_expect_success 'non-cone mode sparse-checkout uses bash completion' '\n+\t# reset sparse-checkout repo to non-cone mode\n+\tgit -C sparse-checkout sparse-checkout disable &&\n+\tgit -C sparse-checkout sparse-checkout set --no-cone &&\n+\n+\t(\n+\t\tcd sparse-checkout &&\n+\t\t# expected to be empty since we have not configured\n+\t\t# custom completion for non-cone mode\n+\t\ttest_completion \"git sparse-checkout set f\" <<-\\EOF\n+\n+\t\tEOF\n+\t)\n+'\n+\n+test_expect_success 'git sparse-checkout set --cone completes directory names' '\n+\tgit -C sparse-checkout sparse-checkout disable &&\n+\n+\t(\n+\t\tcd sparse-checkout &&\n+\t\ttest_completion \"git sparse-checkout set --cone f\" <<-\\EOF\n+\t\tfolder1 Z\n+\t\tfolder1/0 Z\n+\t\tfolder1/0/1 Z\n+\t\tfolder2 Z\n+\t\tfolder2/0 Z\n+\t\tfolder3 Z\n+\t\tEOF\n+\t)\n+'\n+\n test_expect_success 'git switch - with -d, complete all references' '\n \ttest_completion \"git switch -d \" <<-\\EOF\n \tHEAD Z\n-- \ngitgitgadget\n\n"},{"id":"447699","messageId":"10a190ce6a19978c69a831736ca2e2bf7f0cb493.1643945198.git.gitgitgadget@gmail.com","threadId":"57165","inReplyTo":"pull.1108.v6.git.1643945198.gitgitgadget@gmail.com","subject":"[PATCH v6 2/3] completion: improve sparse-checkout cone mode directory completion","fromName":"Lessley Dennington via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-02-04T03:26:37Z","receivedAt":"2022-02-04T03:26:47Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"From: Lessley Dennington <lessleydennington@gmail.com>\n\nUse new __gitcomp_directories method to complete directory names in cone\nmode sparse-checkouts. This method addresses the caveat of poor\nperformance in monorepos from the previous commit (by completing only one\nlevel of directories).\n\nThe unusual character caveat from the previous commit will be fixed by the\nfinal commit in this series.\n\nCo-authored-by: Elijah Newren <newren@gmail.com>\nCo-authored-by: Lessley Dennington <lessleydennington@gmail.com>\nSigned-off-by: Lessley Dennington <lessleydennington@gmail.com>\n---\n contrib/completion/git-completion.bash | 32 +++++++++++++++++++++-\n t/t9902-completion.sh                  | 38 +++++++++++++++-----------\n 2 files changed, 53 insertions(+), 17 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 7f6c86dc6c0..eeb80fdc6e4 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -2986,6 +2986,36 @@ _git_show_branch ()\n \t__git_complete_revlist\n }\n \n+__gitcomp_directories ()\n+{\n+\tlocal _tmp_dir _tmp_completions\n+\n+\t# Get the directory of the current token; this differs from dirname\n+\t# in that it keeps up to the final trailing slash.  If no slash found\n+\t# that's fine too.\n+\t[[ \"$cur\" =~ .*/ ]]\n+\t_tmp_dir=$BASH_REMATCH\n+\n+\t# Find possible directory completions, adding trailing '/' characters\n+\t_tmp_completions=\"$(git ls-tree -d --name-only HEAD $_tmp_dir |\n+\t\tsed -e s%$%/%)\"\n+\n+\tif [[ -n \"$_tmp_completions\" ]]; then\n+\t\t# There were some directory completions, so find ones that\n+\t\t# start with \"$cur\", the current token, and put those in COMPREPLY\n+\t\tlocal i=0 c IFS=$' \\t\\n'\n+\t\tfor c in $_tmp_completions; do\n+\t\tif [[ $c == \"$cur\"* ]]; then\n+\t\t\tCOMPREPLY+=(\"$c\")\n+\t\tfi\n+\t\tdone\n+\telif [[ \"$cur\" =~ /$ ]]; then\n+\t\t# No possible further completions any deeper, so assume we're at\n+\t\t# a leaf directory and just consider it complete\n+\t\t__gitcomp_direct_append \"$cur \"\n+\tfi\n+}\n+\n _git_sparse_checkout ()\n {\n \tlocal subcommands=\"list init set disable add reapply\"\n@@ -3002,7 +3032,7 @@ _git_sparse_checkout ()\n \tset,*|add,*)\n \t\tif [ \"$(__git config core.sparseCheckoutCone)\" == \"true\" ] ||\n \t\t[ -n \"$(__git_find_on_cmdline --cone)\" ]; then\n-\t\t\t__gitcomp \"$(git ls-tree -d -r HEAD --name-only)\"\n+\t\t\t__gitcomp_directories\n \t\tfi\n \tesac\n }\ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex f6eeb9aa035..b38a7302249 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -1480,21 +1480,30 @@ test_expect_success 'cone mode sparse-checkout completes directory names' '\n \t(\n \t\tcd sparse-checkout &&\n \t\ttest_completion \"git sparse-checkout set f\" <<-\\EOF\n-\t\tfolder1 Z\n-\t\tfolder1/0 Z\n-\t\tfolder1/0/1 Z\n-\t\tfolder2 Z\n-\t\tfolder2/0 Z\n-\t\tfolder3 Z\n+\t\tfolder1/\n+\t\tfolder2/\n+\t\tfolder3/\n+\t\tEOF\n+\t) &&\n+\n+\t(\n+\t\tcd sparse-checkout &&\n+\t\ttest_completion \"git sparse-checkout set folder1/\" <<-\\EOF\n+\t\tfolder1/0/\n+\t\tEOF\n+\t) &&\n+\n+\t(\n+\t\tcd sparse-checkout &&\n+\t\ttest_completion \"git sparse-checkout set folder1/0/\" <<-\\EOF\n+\t\tfolder1/0/1/\n \t\tEOF\n \t) &&\n \n \t(\n \t\tcd sparse-checkout/folder1 &&\n-\t\ttest_completion \"git sparse-checkout add \" <<-\\EOF\n-\t\t./ Z\n-\t\t0 Z\n-\t\t0/1 Z\n+\t\ttest_completion \"git sparse-checkout add 0\" <<-\\EOF\n+\t\t0/\n \t\tEOF\n \t)\n '\n@@ -1520,12 +1529,9 @@ test_expect_success 'git sparse-checkout set --cone completes directory names' '\n \t(\n \t\tcd sparse-checkout &&\n \t\ttest_completion \"git sparse-checkout set --cone f\" <<-\\EOF\n-\t\tfolder1 Z\n-\t\tfolder1/0 Z\n-\t\tfolder1/0/1 Z\n-\t\tfolder2 Z\n-\t\tfolder2/0 Z\n-\t\tfolder3 Z\n+\t\tfolder1/\n+\t\tfolder2/\n+\t\tfolder3/\n \t\tEOF\n \t)\n '\n-- \ngitgitgadget\n\n"},{"id":"447700","messageId":"e805dbb58ccd24926ebe411022cc9f1408ce8b49.1643945198.git.gitgitgadget@gmail.com","threadId":"57165","inReplyTo":"pull.1108.v6.git.1643945198.gitgitgadget@gmail.com","subject":"[PATCH v6 3/3] completion: handle unusual characters for sparse-checkout","fromName":"Lessley Dennington via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-02-04T03:26:38Z","receivedAt":"2022-02-04T03:26:51Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"From: Lessley Dennington <lessleydennington@gmail.com>\n\nUpdate the __gitcomp_directories method to de-quote and handle unusual\ncharacters in directory names. Although this initially involved an attempt\nto re-use the logic in __git_index_files, this method removed\nsubdirectories (e.g. folder1/0/ became folder1/), so instead new custom\nlogic was placed directly in the __gitcomp_directories method.\n\nCo-authored-by: Johannes Schindelin <johannes.schindelin@gmx.de>\nCo-authored-by: Lessley Dennington <lessleydennington@gmail.com>\nSigned-off-by: Lessley Dennington <lessleydennington@gmail.com>\n---\n contrib/completion/git-completion.bash | 24 ++++++++++------------\n t/t9902-completion.sh                  | 28 ++++++++++++++++++++++++++\n 2 files changed, 39 insertions(+), 13 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex eeb80fdc6e4..6d81f03f291 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -2988,7 +2988,7 @@ _git_show_branch ()\n \n __gitcomp_directories ()\n {\n-\tlocal _tmp_dir _tmp_completions\n+\tlocal _tmp_dir _tmp_completions _found=0\n \n \t# Get the directory of the current token; this differs from dirname\n \t# in that it keeps up to the final trailing slash.  If no slash found\n@@ -2996,20 +2996,18 @@ __gitcomp_directories ()\n \t[[ \"$cur\" =~ .*/ ]]\n \t_tmp_dir=$BASH_REMATCH\n \n-\t# Find possible directory completions, adding trailing '/' characters\n-\t_tmp_completions=\"$(git ls-tree -d --name-only HEAD $_tmp_dir |\n-\t\tsed -e s%$%/%)\"\n-\n-\tif [[ -n \"$_tmp_completions\" ]]; then\n-\t\t# There were some directory completions, so find ones that\n-\t\t# start with \"$cur\", the current token, and put those in COMPREPLY\n-\t\tlocal i=0 c IFS=$' \\t\\n'\n-\t\tfor c in $_tmp_completions; do\n+\t# Find possible directory completions, adding trailing '/' characters,\n+\t# de-quoting, and handling unusual characters.\n+\twhile IFS= read -r -d $'\\0' c ; do\n+\t\t# If there are directory completions, find ones that start\n+\t\t# with \"$cur\", the current token, and put those in COMPREPLY\n \t\tif [[ $c == \"$cur\"* ]]; then\n-\t\t\tCOMPREPLY+=(\"$c\")\n+\t\t\tCOMPREPLY+=(\"$c/\")\n+\t\t\t_found=1\n \t\tfi\n-\t\tdone\n-\telif [[ \"$cur\" =~ /$ ]]; then\n+\tdone < <(git ls-tree -z -d --name-only HEAD $_tmp_dir)\n+\n+\tif [[ $_found == 0 ]] && [[ \"$cur\" =~ /$ ]]; then\n \t\t# No possible further completions any deeper, so assume we're at\n \t\t# a leaf directory and just consider it complete\n \t\t__gitcomp_direct_append \"$cur \"\ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex b38a7302249..7f63d6057be 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -1508,6 +1508,34 @@ test_expect_success 'cone mode sparse-checkout completes directory names' '\n \t)\n '\n \n+# use FUNNYNAMES to avoid running on Windows, which doesn't permit backslashes in paths\n+test_expect_success FUNNYNAMES 'cone mode sparse-checkout completes directory names with special characters' '\n+\t# reset sparse-checkout\n+\tgit -C sparse-checkout sparse-checkout disable &&\n+\t(\n+\t\tcd sparse-checkout &&\n+\t\tmkdir \"directory with spaces\" &&\n+\t\tmkdir \"$(printf \"directory\\twith\\ttabs\")\" &&\n+\t\tmkdir \"directory\\with\\backslashes\" &&\n+\t\tmkdir \"directory-with-áccent\" &&\n+\t\t>\"directory with spaces/randomfile\" &&\n+\t\t>\"$(printf \"directory\\twith\\ttabs\")/randomfile\" &&\n+\t\t>\"directory\\with\\backslashes/randomfile\" &&\n+\t\t>\"directory-with-áccent/randomfile\" &&\n+\t\tgit add . &&\n+\t\tgit commit -m \"Add directories containing unusual characters\" &&\n+\t\tgit sparse-checkout set --cone \"directory with spaces\" \\\n+\t\t\t\"$(printf \"directory\\twith\\ttabs\")\" \"directory\\with\\backslashes\" \\\n+\t\t\t\"directory-with-áccent\" &&\n+\t\ttest_completion \"git sparse-checkout add dir\" <<-\\EOF\n+\t\tdirectory with spaces/\n+\t\tdirectory\twith\ttabs/\n+\t\tdirectory\\with\\backslashes/\n+\t\tdirectory-with-áccent/\n+\t\tEOF\n+\t)\n+'\n+\n test_expect_success 'non-cone mode sparse-checkout uses bash completion' '\n \t# reset sparse-checkout repo to non-cone mode\n \tgit -C sparse-checkout sparse-checkout disable &&\n-- \ngitgitgadget\n"},{"id":"447701","messageId":"7bcd8f30-840e-be53-ff7a-b5ab035fd3b3@gmail.com","threadId":"57165","inReplyTo":"cb6f65b5-4e02-08af-bea6-141fb6227927@gmail.com","subject":"Re: [PATCH v5 0/3] completion: sparse-checkout updates","fromName":"Lessley Dennington","fromEmail":"lessleydennington@gmail.com","sentAt":"2022-02-04T03:28:13Z","receivedAt":"2022-02-04T03:28:17Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"\n\nOn 2/3/22 6:43 PM, Lessley Dennington wrote:\n> \n> \n> On 2/3/22 3:59 PM, Lessley Dennington wrote:\n>>\n>>\n>> On 2/3/22 3:28 PM, Junio C Hamano wrote:\n>>> Lessley Dennington <lessleydennington@gmail.com> writes:\n>>>\n>>>> On 2/3/22 1:48 PM, Junio C Hamano wrote:\n>>>>> \"Lessley Dennington via GitGitGadget\" <gitgitgadget@gmail.com>\n>>>>> writes:\n>>>>>\n>>>>>> This series is based on en/sparse-checkout-set.\n>>>>> This has been a very helpful note, but after the topic was merged to\n>>>>> 'master' on Jan 3rd, it has become a tad stale.  Let me apply the\n>>>>> topic directly on v2.35.0 instead.\n>>>>> Thanks.\n>>>>\n>>>> Thank you for the heads up! I will remove from future versions.\n>>>\n>>> No problem.\n>>>\n>>> FWIW, the tip of 'seen' seems to be failing the CI; I haven't looked\n>>> into the cause of the breakage.\n>>>\n>>>    https://github.com/git/git/actions/runs/1792151138\n>>>\n>>> There is another CI job running on 'seen', whose only difference from\n>>> the above version is that this topic has been temporarily ejected:\n>>>\n>>>    https://github.com/git/git/actions/runs/1792296432\n>>>\n>>> We'll see if that fails the same way (in which this topic may not\n>>> have anything to do with the breakage) or if it passes.\n>>>\n>>> Thanks.\n>>\n>> I just merged seen locally and was able to repro the failure. I will\n>> submit a fix ASAP.\n> \n> GitGitGadget CI has passed with the fix, but it is not responding to the\n> /submit command. As a heads up, fix may not be submitted until folks who\n> are a bit more knowledgeable about GGG than I are available to help\n> troubleshoot.\n\nNvm, I was able to get it to work!\n"},{"id":"447703","messageId":"220204.86leyr45w3.gmgdl@evledraar.gmail.com","threadId":"57165","inReplyTo":"cb6f65b5-4e02-08af-bea6-141fb6227927@gmail.com","subject":"Re: [PATCH v5 0/3] completion: sparse-checkout updates","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-02-04T04:21:26Z","receivedAt":"2022-02-04T04:23:16Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Thu, Feb 03 2022, Lessley Dennington wrote:\n\n> On 2/3/22 3:59 PM, Lessley Dennington wrote:\n>> \n>> On 2/3/22 3:28 PM, Junio C Hamano wrote:\n>>> Lessley Dennington <lessleydennington@gmail.com> writes:\n>>>\n>>>> On 2/3/22 1:48 PM, Junio C Hamano wrote:\n>>>>> \"Lessley Dennington via GitGitGadget\" <gitgitgadget@gmail.com>\n>>>>> writes:\n>>>>>\n>>>>>> This series is based on en/sparse-checkout-set.\n>>>>> This has been a very helpful note, but after the topic was merged to\n>>>>> 'master' on Jan 3rd, it has become a tad stale.  Let me apply the\n>>>>> topic directly on v2.35.0 instead.\n>>>>> Thanks.\n>>>>\n>>>> Thank you for the heads up! I will remove from future versions.\n>>>\n>>> No problem.\n>>>\n>>> FWIW, the tip of 'seen' seems to be failing the CI; I haven't looked\n>>> into the cause of the breakage.\n>>>\n>>>    https://github.com/git/git/actions/runs/1792151138\n>>>\n>>> There is another CI job running on 'seen', whose only difference from\n>>> the above version is that this topic has been temporarily ejected:\n>>>\n>>>    https://github.com/git/git/actions/runs/1792296432\n>>>\n>>> We'll see if that fails the same way (in which this topic may not\n>>> have anything to do with the breakage) or if it passes.\n>>>\n>>> Thanks.\n>> I just merged seen locally and was able to repro the failure. I will\n>> submit a fix ASAP.\n>\n> GitGitGadget CI has passed with the fix, but it is not responding to the\n> /submit command. As a heads up, fix may not be submitted until folks who\n> are a bit more knowledgeable about GGG than I are available to help\n> troubleshoot.\n\nJust an FYI: If you're blocked on GGG it takes 1 minute to click through\nto generate an app password for your GMail account.\n\nThen you can use it with git-send-email with config like e.g. this one\nI've got:\n    \n    $ git config -l|grep -F sendemail.|perl -pe 's/pass=\\K.*/WORD/g'\n    sendemail.smtpserver=smtp.gmail.com\n    sendemail.smtpencryption=ssl\n    sendemail.smtpuser=avarab@gmail.com\n    sendemail.confirm=always\n    sendemail.smtppass=WORD\n    sendemail.xmailer=true\n    sendemail.to=git@vger.kernel.org\n    sendemail.security.to=git-security@googlegroups.com\n    sendemail.test.to=avarab@gmail.com\n\nThen you can submit your patches with git-format-patch + git-send-email.\n"},{"id":"447704","messageId":"220204.86h79f45nf.gmgdl@evledraar.gmail.com","threadId":"57165","inReplyTo":"CABPp-BFD51BTsG7gQFD4BuqVLLBV2iJOKnrnya89otoGonzVvA@mail.gmail.com","subject":"Re: [PATCH v5 3/3] completion: handle unusual characters for sparse-checkout","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-02-04T04:25:38Z","receivedAt":"2022-02-04T04:28:26Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Thu, Feb 03 2022, Elijah Newren wrote:\n\n> On Thu, Feb 3, 2022 at 12:44 PM Lessley Dennington via GitGitGadget\n> <gitgitgadget@gmail.com> wrote:\n>>\n>> From: Lessley Dennington <lessleydennington@gmail.com>\n>> +# use FUNNYNAMES to avoid running on Windows, which doesn't permit backslashes in paths\n>> +test_expect_success FUNNYNAMES 'cone mode sparse-checkout completes directory names with special characters' '\n>> +       # reset sparse-checkout\n>> +       git -C sparse-checkout sparse-checkout disable &&\n>> +       (\n>> +               cd sparse-checkout &&\n>> +               mkdir \"directory with spaces\" &&\n>> +               mkdir \"$(printf \"directory\\twith\\ttabs\")\" &&\n>> +               mkdir \"directory\\with\\backslashes\" &&\n>> +               mkdir \"directory-with-áccent\" &&\n>> +               >\"directory with spaces/randomfile\" &&\n>> +               >\"$(printf \"directory\\twith\\ttabs\")/randomfile\" &&\n>> +               >\"directory\\with\\backslashes/randomfile\" &&\n>> +               >\"directory-with-áccent/randomfile\" &&\n>> +               git add . &&\n>> +               git commit -m \"Add directories containing unusual characters\" &&\n>> +               git sparse-checkout set --cone \"directory with spaces\" \\\n>> +                       \"$(printf \"directory\\twith\\ttabs\")\" \"directory\\with\\backslashes\" \\\n>> +                       \"directory-with-áccent\" &&\n>> +               test_completion \"git sparse-checkout add dir\" <<-\\EOF\n>> +               directory with spaces/\n>> +               directory       with    tabs/\n>> +               directory\\with\\backslashes/\n>> +               directory-with-áccent/\n>> +               EOF\n>> +       )\n>> +'\n>\n> I'm glad you tested with lots of special characters -- spaces, tabs,\n> backslashes, and accents.  Newlines might also be nice, but probably\n> makes the test hard.  Anyway, looks good to me, other than the\n> indentation change.\n\nThis looks like its over-skipping tests, the comment says Windows\ndoesn't like \\ in paths, but there's a lo more being skipped here than\nthat.\n\nShouldn't e.g. \"directory-with-áccent/\" be pulled out into another test,\nleaving the directory\\with\\backslashes/ etc. as non-Windows?\n\nAnother useful method is to just try to create those paths\nunconditionally, but with \"mkdir\" etc., and if that works run the test\nwith git. After all if the OS can create a given path, but we're not\nhandling it that's our bug.\n\nBut if the FS just doesn't support the path we'd catch that in the\n\"mkdir\" (or whatever), which we can assume behaves sanely on that\nplatform (or we're horribly broken anyway...).\n\n"},{"id":"447707","messageId":"CABPp-BGM0xu=Hgd_uKevAbpCtxR9ZY5NX=PWNn2Bqw8SaOJvLQ@mail.gmail.com","threadId":"57165","inReplyTo":"pull.1108.v6.git.1643945198.gitgitgadget@gmail.com","subject":"Re: [PATCH v6 0/3] completion: sparse-checkout updates","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2022-02-04T06:05:36Z","receivedAt":"2022-02-04T06:06:11Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"Hi,\n\nOn Thu, Feb 3, 2022 at 7:26 PM Lessley Dennington via GitGitGadget\n<gitgitgadget@gmail.com> wrote:\n>\n> This change updates custom tab completion for the sparse-checkout command.\n> Specifically, it corrects the following issues with the current method:\n>\n>  1. git sparse-checkout <TAB> results in an incomplete list of subcommands\n>     (it is missing reapply and add).\n>  2. Options for subcommands are not tab-completable.\n>  3. git sparse-checkout set <TAB> and git sparse-checkout add <TAB> show\n>     both file names and directory names. While this may be a less surprising\n>     behavior for non-cone mode, we want to only show directories in cone\n>     mode.\n>\n> The first commit in this series is an intermediate step that fixes issues 1\n> and 2 above and introduces a simple fix for issue 3 with some performance\n> and unusual character-related caveats. The next commit adds a new\n> __gitcomp_directories method that fixes the performance-related caveat from\n> the first commit by completing just a single level of directories. The final\n> commit modifies __gitcomp_directories to handle unusual characters in\n> directory names.\n>\n>\n> Changes since V5\n> ================\n>\n>  * Fix incorrect conditional that was causing failure of non-cone mode test\n>    (and causing 'seen' CI to fail).\n>  * Remove __git_comp_directories indentation changes between the second and\n>    third commits.\n\nThis round looks good to me:\n\nReviewed-by: Elijah Newren <newren@gmail.com>\n\nNice work!\n"},{"id":"447753","messageId":"xmqq1r0io95u.fsf@gitster.g","threadId":"57165","inReplyTo":"CABPp-BGM0xu=Hgd_uKevAbpCtxR9ZY5NX=PWNn2Bqw8SaOJvLQ@mail.gmail.com","subject":"Re: [PATCH v6 0/3] completion: sparse-checkout updates","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-02-04T17:04:29Z","receivedAt":"2022-02-04T17:09:42Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Elijah Newren <newren@gmail.com> writes:\n\n>> Changes since V5\n>> ================\n>>\n>>  * Fix incorrect conditional that was causing failure of non-cone mode test\n>>    (and causing 'seen' CI to fail).\n>>  * Remove __git_comp_directories indentation changes between the second and\n>>    third commits.\n>\n> This round looks good to me:\n>\n> Reviewed-by: Elijah Newren <newren@gmail.com>\n>\n> Nice work!\n\nThanks, both.  Will queue.  Let's mark it to be merged down to\n'next' soonish.\n"},{"id":"447757","messageId":"CABPp-BGN+rErYFmMbUwxcwSOvCQbJMzB43-VRtim7tXtkuKvCQ@mail.gmail.com","threadId":"57165","inReplyTo":"xmqq1r0io95u.fsf@gitster.g","subject":"Re: [PATCH v6 0/3] completion: sparse-checkout updates","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2022-02-04T17:55:57Z","receivedAt":"2022-02-04T17:56:12Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Fri, Feb 4, 2022 at 9:04 AM Junio C Hamano <gitster@pobox.com> wrote:\n>\n> Elijah Newren <newren@gmail.com> writes:\n>\n> >> Changes since V5\n> >> ================\n> >>\n> >>  * Fix incorrect conditional that was causing failure of non-cone mode test\n> >>    (and causing 'seen' CI to fail).\n> >>  * Remove __git_comp_directories indentation changes between the second and\n> >>    third commits.\n> >\n> > This round looks good to me:\n> >\n> > Reviewed-by: Elijah Newren <newren@gmail.com>\n> >\n> > Nice work!\n>\n> Thanks, both.  Will queue.  Let's mark it to be merged down to\n> 'next' soonish.\n\nÆvar had a good comment about code coverage on Windows that we might\nwant to address first[1].  (Namely, splitting one test into two -- one\nthat tests a path with backslashes that can be skipped on windows, and\na separate test that checks paths with spaces, tabs, and non-ascii\nthat can be run on all platforms.)\n\nBut other than that, yeah, this should be ready for 'next'.\n\n[1] https://lore.kernel.org/git/220204.86h79f45nf.gmgdl@evledraar.gmail.com/\n"},{"id":"447764","messageId":"xmqq4k5emmq2.fsf@gitster.g","threadId":"57165","inReplyTo":"CABPp-BGN+rErYFmMbUwxcwSOvCQbJMzB43-VRtim7tXtkuKvCQ@mail.gmail.com","subject":"Re: [PATCH v6 0/3] completion: sparse-checkout updates","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-02-04T19:54:29Z","receivedAt":"2022-02-04T19:54:36Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Elijah Newren <newren@gmail.com> writes:\n\n> Ævar had a good comment about code coverage on Windows that we might\n> want to address first[1].  (Namely, splitting one test into two -- one\n> that tests a path with backslashes that can be skipped on windows, and\n> a separate test that checks paths with spaces, tabs, and non-ascii\n> that can be run on all platforms.)\n\nAccording to the lazy-prereq definition for FUNNYNAMES, we seem to\nskip tab-embedded names on windows, so it may not be used on all\nplatforms, but such a detail aside...\n\nI do not get why funny letters should matter and need to be tested\nspecially in the first place, to be honest, but because we have with\nFUNNYNAMES prereq already, hiding some tests behind it would be a\ngood idea regardless.\n\n> But other than that, yeah, this should be ready for 'next'.\n>\n> [1] https://lore.kernel.org/git/220204.86h79f45nf.gmgdl@evledraar.gmail.com/\n\nThanks.\n"},{"id":"447765","messageId":"CABPp-BHgU3-VVt+OYfY77_ymPdFHbs8x1SMN_V9jfawDZ570Ng@mail.gmail.com","threadId":"57165","inReplyTo":"xmqq4k5emmq2.fsf@gitster.g","subject":"Re: [PATCH v6 0/3] completion: sparse-checkout updates","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2022-02-04T20:01:22Z","receivedAt":"2022-02-04T20:03:44Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Fri, Feb 4, 2022 at 11:54 AM Junio C Hamano <gitster@pobox.com> wrote:\n>\n> Elijah Newren <newren@gmail.com> writes:\n>\n> > Ævar had a good comment about code coverage on Windows that we might\n> > want to address first[1].  (Namely, splitting one test into two -- one\n> > that tests a path with backslashes that can be skipped on windows, and\n> > a separate test that checks paths with spaces, tabs, and non-ascii\n> > that can be run on all platforms.)\n>\n> According to the lazy-prereq definition for FUNNYNAMES, we seem to\n> skip tab-embedded names on windows, so it may not be used on all\n> platforms, but such a detail aside...\n>\n> I do not get why funny letters should matter and need to be tested\n> specially in the first place, to be honest, but because we have with\n> FUNNYNAMES prereq already, hiding some tests behind it would be a\n> good idea regardless.\n\nEarlier versions of the patch series failed to handle paths that\ncontained various special characters; see the second comment at\nhttps://lore.kernel.org/git/CABPp-BEq9pTqsy_R_SR1DSgUK58ubNR1Gk4G1RoL8wkadyo6zw@mail.gmail.com/.\nHandling them was specifically the job of the third patch in the\nseries, and thus it made sense to add some kind of test for them.\n"},{"id":"447780","messageId":"xmqq5ypul2wu.fsf@gitster.g","threadId":"57165","inReplyTo":"CABPp-BHgU3-VVt+OYfY77_ymPdFHbs8x1SMN_V9jfawDZ570Ng@mail.gmail.com","subject":"Re: [PATCH v6 0/3] completion: sparse-checkout updates","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-02-04T21:47:45Z","receivedAt":"2022-02-04T21:47:50Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Elijah Newren <newren@gmail.com> writes:\n\n> Handling them was specifically the job of the third patch in the\n> series, and thus it made sense to add some kind of test for them.\n\nAh, yeah, reading from ls-tree via process substitution to avoid a\npipe that makes the loop a subshell and using \"read -d$'\\0'\" with\nIFS disabled to grok the -z output.  Full of bash-isms of the good\nkind ;-).\n\nNicely done, and it deserves to be showed off in tests.\n\n\n"},{"id":"447781","messageId":"xmqqr18ijnyt.fsf@gitster.g","threadId":"57165","inReplyTo":"ddf5e583dd71a729d6fb0513aed9fc4eb6ebbdd7.1643921091.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v5 3/3] completion: handle unusual characters for sparse-checkout","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-02-04T21:55:54Z","receivedAt":"2022-02-04T21:56:01Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Lessley Dennington via GitGitGadget\" <gitgitgadget@gmail.com>\nwrites:\n\n> +test_expect_success FUNNYNAMES 'cone mode sparse-checkout completes directory names with special characters' '\n> +\t# reset sparse-checkout\n> +\tgit -C sparse-checkout sparse-checkout disable &&\n> +\t(\n> +\t\tcd sparse-checkout &&\n> +\t\tmkdir \"directory with spaces\" &&\n> +\t\tmkdir \"$(printf \"directory\\twith\\ttabs\")\" &&\n> +\t\tmkdir \"directory\\with\\backslashes\" &&\n> +\t\tmkdir \"directory-with-áccent\" &&\n> +\t\t>\"directory with spaces/randomfile\" &&\n> +\t\t>\"$(printf \"directory\\twith\\ttabs\")/randomfile\" &&\n> +\t\t>\"directory\\with\\backslashes/randomfile\" &&\n> +\t\t>\"directory-with-áccent/randomfile\" &&\n> +\t\tgit add . &&\n> +\t\tgit commit -m \"Add directories containing unusual characters\" &&\n> +\t\tgit sparse-checkout set --cone \"directory with spaces\" \\\n> +\t\t\t\"$(printf \"directory\\twith\\ttabs\")\" \"directory\\with\\backslashes\" \\\n> +\t\t\t\"directory-with-áccent\" &&\n> +\t\ttest_completion \"git sparse-checkout add dir\" <<-\\EOF\n> +\t\tdirectory with spaces/\n> +\t\tdirectory\twith\ttabs/\n> +\t\tdirectory\\with\\backslashes/\n> +\t\tdirectory-with-áccent/\n> +\t\tEOF\n> +\t)\n> +'\n\nI wonder if we care about the repetition, which can burden anybody\nwho will later have to change this script.  \"directory with spaces\"\nappears three times in the above (i.e. mkdir uses it, then redirection\nto create a file under it uses it, and \"sparse-checkout set\" uses it,\nand then finally the expected output has it.\n\nAn obvious way to reduce repetition is to add variables for them,\nand because this is in a subshell, we do not have to worry about the\nuse of extra variables contaminating the namespace for later tests.\n\n\tD1=\"directory with spaces\" &&\n\tD2=$(printf \"directory\\t\\with\\ttabs\") &&\n\tD3=\"directory\\with\\backslashes\" &&\n        D4=\"directory-with-áccent\" &&\n\tfor D in \"$D1\" \"$D2\" \"$D3\" \"$D4\"\n\tdo\n\t\t>\"$D/samplefile\" || return 1\n\tdone &&\n\tgit add . &&\n\tgit commit -m \"add many\" &&\n\tgit sparse-checkout set --cone \"$D1\" \"$D2\" \"$D3\" \"$D4\" &&\n\ttest_completion \"git sparse-checkout add dir\" <<-EOF\n\t$D1/\n\t$D2/\n\t$D3/\n\t$D4/\n\tEOF\n\nHaving written it, I am undecided.  It does reduce repetition, and\nit does reduce the chance to make typo, but did I make it easier to\nfollow?  I am not sure about the last part.\n\nThanks.\n"},{"id":"447895","messageId":"pull.1108.v7.git.1644255105.gitgitgadget@gmail.com","threadId":"57165","inReplyTo":"pull.1108.v6.git.1643945198.gitgitgadget@gmail.com","subject":"[PATCH v7 0/3] completion: sparse-checkout updates","fromName":"Lessley Dennington via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-02-07T17:31:42Z","receivedAt":"2022-02-07T17:45:47Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"This change updates custom tab completion for the sparse-checkout command.\nSpecifically, it corrects the following issues with the current method:\n\n 1. git sparse-checkout <TAB> results in an incomplete list of subcommands\n    (it is missing reapply and add).\n 2. Options for subcommands are not tab-completable.\n 3. git sparse-checkout set <TAB> and git sparse-checkout add <TAB> show\n    both file names and directory names. While this may be a less surprising\n    behavior for non-cone mode, we want to only show directories in cone\n    mode.\n\nThe first commit in this series is an intermediate step that fixes issues 1\nand 2 above and introduces a simple fix for issue 3 with some performance\nand unusual character-related caveats. The next commit adds a new\n__gitcomp_directories method that fixes the performance-related caveat from\nthe first commit by completing just a single level of directories. The final\ncommit modifies __gitcomp_directories to handle unusual characters in\ndirectory names.\n\n\nChanges since V6\n================\n\n * Split tests for unusual characters so that spaces and accents are\n   verified on Windows (in addition to macOS and Linux). Tabs and\n   backslashes are still excluded on Windows (details on why are included in\n   the third commit message).\n\n\nChanges since V5\n================\n\n * Fix incorrect conditional that was causing failure of non-cone mode test\n   (and causing 'seen' CI to fail).\n * Remove __git_comp_directories indentation changes between the second and\n   third commits.\n\n\nChanges since V4\n================\n\n * Clarify that completing on files and directories is a less-surprising\n   behavior in non-cone mode (rather than definitely the correct behavior)\n   in commit message and cover letter.\n * Add explicit --no-cone to non-cone mode sparse-checkout completion test.\n * Replace use of __git_complete_index_file with a new version of\n   __gitcomp_directories that is able to handle unusual characters.\n * Ensure that users running git sparse-checkout set --cone get cone\n   mode-style completion whether or not they already have the cone mode\n   config set.\n * Refactor creation of sparse-checkout test repo into a sparse-checkout\n   setup test.\n\n\nChanges since V3\n================\n\n * Update commit descriptions to begin with completion instead of\n   sparse-checkout.\n * Remove explicit completion of --help, as this is inconsistent with the\n   rest of the completion script.\n * Use __gitcomp_builtin to auto-complete subcommand options (and remove\n   option completion test from previous iterations, as it is no longer\n   necessary).\n * Use __git_complete_index_file helper function in place of __gitcomp\n   \"$(git ls-tree -d -r HEAD --name-only).\n * If in cone-mode sparse checkout, only show directory completions. If in\n   non-cone mode sparse checkout show both files and directories.\n\n\nChanges since V2\n================\n\n * Change use of $prev to $subcommand in _git_sparse_checkout() method in\n   git-completion.bash.\n * State explicitly that directory completion applies in both cone and\n   non-cone mode in 'sparse-checkout: custom tab completion' commit\n * Add new patch with __gitcomp_directories method to improve performance by\n   only outputting directories at the current level.\n\n\nChanges since V1\n================\n\n * Rebase onto en/sparse-checkout-set.\n * Add subcommand options (including --no-cone) for set and reapply.\n * Extend 'sparse-checkout completes subcommand options' test to validate\n   new set/reapply subcommand options.\n * No longer set index.sparse to false in 'sparse-checkout completes\n   directory names' test.\n * Refactor creation of sparse-checkout repo into a setup test.\n\nThanks, Lessley\n\nLessley Dennington (3):\n  completion: address sparse-checkout issues\n  completion: improve sparse-checkout cone mode directory completion\n  completion: handle unusual characters for sparse-checkout\n\n contrib/completion/git-completion.bash |  44 ++++++--\n t/t9902-completion.sh                  | 138 +++++++++++++++++++++++++\n 2 files changed, 174 insertions(+), 8 deletions(-)\n\n\nbase-commit: dfac9b609f86cd4f6ce896df9e1172d2a02cde48\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-1108%2Fldennington%2Fsparse-checkout-bash-completion-v7\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1108/ldennington/sparse-checkout-bash-completion-v7\nPull-Request: https://github.com/gitgitgadget/git/pull/1108\n\nRange-diff vs v6:\n\n 1:  23390000dd3 ! 1:  26422c759a0 completion: address sparse-checkout issues\n     @@ Commit message\n          These caveats will be fixed by subsequent commits in this series.\n      \n          Signed-off-by: Lessley Dennington <lessleydennington@gmail.com>\n     +    Reviewed-by: Elijah Newren <newren@gmail.com>\n      \n       ## contrib/completion/git-completion.bash ##\n      @@ contrib/completion/git-completion.bash: _git_show_branch ()\n 2:  10a190ce6a1 ! 2:  2c20830b4ce completion: improve sparse-checkout cone mode directory completion\n     @@ Commit message\n          Co-authored-by: Elijah Newren <newren@gmail.com>\n          Co-authored-by: Lessley Dennington <lessleydennington@gmail.com>\n          Signed-off-by: Lessley Dennington <lessleydennington@gmail.com>\n     +    Reviewed-by: Elijah Newren <newren@gmail.com>\n      \n       ## contrib/completion/git-completion.bash ##\n      @@ contrib/completion/git-completion.bash: _git_show_branch ()\n 3:  e805dbb58cc ! 3:  996cbe7dfb7 completion: handle unusual characters for sparse-checkout\n     @@ Commit message\n          subdirectories (e.g. folder1/0/ became folder1/), so instead new custom\n          logic was placed directly in the __gitcomp_directories method.\n      \n     +    Note there are two tests for this new functionality - one for spaces and\n     +    accents and one for backslashes and tabs. The backslashes and tabs test\n     +    uses FUNNYNAMES to avoid running on Windows. This is because:\n     +\n     +    1. Backslashes are explicitly not allowed in Windows file paths.\n     +    2. Although tabs appear to be allowed when creating a file in a Windows\n     +    bash shell, they actually are not renderable (and appear as empty boxes\n     +    in the shell).\n     +\n          Co-authored-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n          Co-authored-by: Lessley Dennington <lessleydennington@gmail.com>\n     +    Helped-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n          Signed-off-by: Lessley Dennington <lessleydennington@gmail.com>\n     +    Reviewed-by: Elijah Newren <newren@gmail.com>\n      \n       ## contrib/completion/git-completion.bash ##\n      @@ contrib/completion/git-completion.bash: _git_show_branch ()\n     @@ t/t9902-completion.sh: test_expect_success 'cone mode sparse-checkout completes\n       \t)\n       '\n       \n     -+# use FUNNYNAMES to avoid running on Windows, which doesn't permit backslashes in paths\n     -+test_expect_success FUNNYNAMES 'cone mode sparse-checkout completes directory names with special characters' '\n     ++test_expect_success 'cone mode sparse-checkout completes directory names with spaces and accents' '\n      +\t# reset sparse-checkout\n      +\tgit -C sparse-checkout sparse-checkout disable &&\n      +\t(\n      +\t\tcd sparse-checkout &&\n      +\t\tmkdir \"directory with spaces\" &&\n     -+\t\tmkdir \"$(printf \"directory\\twith\\ttabs\")\" &&\n     -+\t\tmkdir \"directory\\with\\backslashes\" &&\n      +\t\tmkdir \"directory-with-áccent\" &&\n      +\t\t>\"directory with spaces/randomfile\" &&\n     -+\t\t>\"$(printf \"directory\\twith\\ttabs\")/randomfile\" &&\n     -+\t\t>\"directory\\with\\backslashes/randomfile\" &&\n      +\t\t>\"directory-with-áccent/randomfile\" &&\n      +\t\tgit add . &&\n     -+\t\tgit commit -m \"Add directories containing unusual characters\" &&\n     ++\t\tgit commit -m \"Add directory with spaces and directory with accent\" &&\n      +\t\tgit sparse-checkout set --cone \"directory with spaces\" \\\n     -+\t\t\t\"$(printf \"directory\\twith\\ttabs\")\" \"directory\\with\\backslashes\" \\\n      +\t\t\t\"directory-with-áccent\" &&\n     -+\t\ttest_completion \"git sparse-checkout add dir\" <<-\\EOF\n     ++\t\ttest_completion \"git sparse-checkout add dir\" <<-\\EOF &&\n      +\t\tdirectory with spaces/\n     -+\t\tdirectory\twith\ttabs/\n     -+\t\tdirectory\\with\\backslashes/\n      +\t\tdirectory-with-áccent/\n      +\t\tEOF\n     ++\t\trm -rf \"directory with spaces\" &&\n     ++\t\trm -rf \"directory-with-áccent\" &&\n     ++\t\tgit add . &&\n     ++\t\tgit commit -m \"Remove directory with spaces and directory with accent\"\n     ++\t)\n     ++'\n     ++\n     ++# use FUNNYNAMES to avoid running on Windows, which doesn't permit backslashes or tabs in paths\n     ++test_expect_success FUNNYNAMES 'cone mode sparse-checkout completes directory names with backslashes and tabs' '\n     ++\t# reset sparse-checkout\n     ++\tgit -C sparse-checkout sparse-checkout disable &&\n     ++\t(\n     ++\t\tcd sparse-checkout &&\n     ++\t\tmkdir \"directory\\with\\backslashes\" &&\n     ++\t\tmkdir \"$(printf \"directory\\twith\\ttabs\")\" &&\n     ++\t\t>\"directory\\with\\backslashes/randomfile\" &&\n     ++\t\t>\"$(printf \"directory\\twith\\ttabs\")/randomfile\" &&\n     ++\t\tgit add . &&\n     ++\t\tgit commit -m \"Add directory with backslashes and directory with tabs\" &&\n     ++\t\tgit sparse-checkout set --cone \"directory\\with\\backslashes\" \\\n     ++\t\t\t\"$(printf \"directory\\twith\\ttabs\")\" &&\n     ++\t\ttest_completion \"git sparse-checkout add dir\" <<-\\EOF &&\n     ++\t\tdirectory\\with\\backslashes/\n     ++\t\tdirectory\twith\ttabs/\n     ++\t\tEOF\n     ++\t\trm -rf \"directory\\with\\backslashes\" &&\n     ++\t\trm -rf \"$(printf \"directory\\twith\\ttabs\")\" &&\n     ++\t\tgit add . &&\n     ++\t\tgit commit -m \"Remove directory with backslashes and directory with tabs\"\n      +\t)\n      +'\n      +\n\n-- \ngitgitgadget\n"},{"id":"447896","messageId":"2c20830b4ce0da0b559f645ba1bf211702cf97c6.1644255105.git.gitgitgadget@gmail.com","threadId":"57165","inReplyTo":"pull.1108.v7.git.1644255105.gitgitgadget@gmail.com","subject":"[PATCH v7 2/3] completion: improve sparse-checkout cone mode directory completion","fromName":"Lessley Dennington via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-02-07T17:31:44Z","receivedAt":"2022-02-07T17:46:27Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"From: Lessley Dennington <lessleydennington@gmail.com>\n\nUse new __gitcomp_directories method to complete directory names in cone\nmode sparse-checkouts. This method addresses the caveat of poor\nperformance in monorepos from the previous commit (by completing only one\nlevel of directories).\n\nThe unusual character caveat from the previous commit will be fixed by the\nfinal commit in this series.\n\nCo-authored-by: Elijah Newren <newren@gmail.com>\nCo-authored-by: Lessley Dennington <lessleydennington@gmail.com>\nSigned-off-by: Lessley Dennington <lessleydennington@gmail.com>\nReviewed-by: Elijah Newren <newren@gmail.com>\n---\n contrib/completion/git-completion.bash | 32 +++++++++++++++++++++-\n t/t9902-completion.sh                  | 38 +++++++++++++++-----------\n 2 files changed, 53 insertions(+), 17 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 7f6c86dc6c0..eeb80fdc6e4 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -2986,6 +2986,36 @@ _git_show_branch ()\n \t__git_complete_revlist\n }\n \n+__gitcomp_directories ()\n+{\n+\tlocal _tmp_dir _tmp_completions\n+\n+\t# Get the directory of the current token; this differs from dirname\n+\t# in that it keeps up to the final trailing slash.  If no slash found\n+\t# that's fine too.\n+\t[[ \"$cur\" =~ .*/ ]]\n+\t_tmp_dir=$BASH_REMATCH\n+\n+\t# Find possible directory completions, adding trailing '/' characters\n+\t_tmp_completions=\"$(git ls-tree -d --name-only HEAD $_tmp_dir |\n+\t\tsed -e s%$%/%)\"\n+\n+\tif [[ -n \"$_tmp_completions\" ]]; then\n+\t\t# There were some directory completions, so find ones that\n+\t\t# start with \"$cur\", the current token, and put those in COMPREPLY\n+\t\tlocal i=0 c IFS=$' \\t\\n'\n+\t\tfor c in $_tmp_completions; do\n+\t\tif [[ $c == \"$cur\"* ]]; then\n+\t\t\tCOMPREPLY+=(\"$c\")\n+\t\tfi\n+\t\tdone\n+\telif [[ \"$cur\" =~ /$ ]]; then\n+\t\t# No possible further completions any deeper, so assume we're at\n+\t\t# a leaf directory and just consider it complete\n+\t\t__gitcomp_direct_append \"$cur \"\n+\tfi\n+}\n+\n _git_sparse_checkout ()\n {\n \tlocal subcommands=\"list init set disable add reapply\"\n@@ -3002,7 +3032,7 @@ _git_sparse_checkout ()\n \tset,*|add,*)\n \t\tif [ \"$(__git config core.sparseCheckoutCone)\" == \"true\" ] ||\n \t\t[ -n \"$(__git_find_on_cmdline --cone)\" ]; then\n-\t\t\t__gitcomp \"$(git ls-tree -d -r HEAD --name-only)\"\n+\t\t\t__gitcomp_directories\n \t\tfi\n \tesac\n }\ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex f6eeb9aa035..b38a7302249 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -1480,21 +1480,30 @@ test_expect_success 'cone mode sparse-checkout completes directory names' '\n \t(\n \t\tcd sparse-checkout &&\n \t\ttest_completion \"git sparse-checkout set f\" <<-\\EOF\n-\t\tfolder1 Z\n-\t\tfolder1/0 Z\n-\t\tfolder1/0/1 Z\n-\t\tfolder2 Z\n-\t\tfolder2/0 Z\n-\t\tfolder3 Z\n+\t\tfolder1/\n+\t\tfolder2/\n+\t\tfolder3/\n+\t\tEOF\n+\t) &&\n+\n+\t(\n+\t\tcd sparse-checkout &&\n+\t\ttest_completion \"git sparse-checkout set folder1/\" <<-\\EOF\n+\t\tfolder1/0/\n+\t\tEOF\n+\t) &&\n+\n+\t(\n+\t\tcd sparse-checkout &&\n+\t\ttest_completion \"git sparse-checkout set folder1/0/\" <<-\\EOF\n+\t\tfolder1/0/1/\n \t\tEOF\n \t) &&\n \n \t(\n \t\tcd sparse-checkout/folder1 &&\n-\t\ttest_completion \"git sparse-checkout add \" <<-\\EOF\n-\t\t./ Z\n-\t\t0 Z\n-\t\t0/1 Z\n+\t\ttest_completion \"git sparse-checkout add 0\" <<-\\EOF\n+\t\t0/\n \t\tEOF\n \t)\n '\n@@ -1520,12 +1529,9 @@ test_expect_success 'git sparse-checkout set --cone completes directory names' '\n \t(\n \t\tcd sparse-checkout &&\n \t\ttest_completion \"git sparse-checkout set --cone f\" <<-\\EOF\n-\t\tfolder1 Z\n-\t\tfolder1/0 Z\n-\t\tfolder1/0/1 Z\n-\t\tfolder2 Z\n-\t\tfolder2/0 Z\n-\t\tfolder3 Z\n+\t\tfolder1/\n+\t\tfolder2/\n+\t\tfolder3/\n \t\tEOF\n \t)\n '\n-- \ngitgitgadget\n\n"},{"id":"447897","messageId":"996cbe7dfb73c211eae012813b352b0d0de3954c.1644255105.git.gitgitgadget@gmail.com","threadId":"57165","inReplyTo":"pull.1108.v7.git.1644255105.gitgitgadget@gmail.com","subject":"[PATCH v7 3/3] completion: handle unusual characters for sparse-checkout","fromName":"Lessley Dennington via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-02-07T17:31:45Z","receivedAt":"2022-02-07T17:47:31Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"From: Lessley Dennington <lessleydennington@gmail.com>\n\nUpdate the __gitcomp_directories method to de-quote and handle unusual\ncharacters in directory names. Although this initially involved an attempt\nto re-use the logic in __git_index_files, this method removed\nsubdirectories (e.g. folder1/0/ became folder1/), so instead new custom\nlogic was placed directly in the __gitcomp_directories method.\n\nNote there are two tests for this new functionality - one for spaces and\naccents and one for backslashes and tabs. The backslashes and tabs test\nuses FUNNYNAMES to avoid running on Windows. This is because:\n\n1. Backslashes are explicitly not allowed in Windows file paths.\n2. Although tabs appear to be allowed when creating a file in a Windows\nbash shell, they actually are not renderable (and appear as empty boxes\nin the shell).\n\nCo-authored-by: Johannes Schindelin <johannes.schindelin@gmx.de>\nCo-authored-by: Lessley Dennington <lessleydennington@gmail.com>\nHelped-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\nSigned-off-by: Lessley Dennington <lessleydennington@gmail.com>\nReviewed-by: Elijah Newren <newren@gmail.com>\n---\n contrib/completion/git-completion.bash | 24 ++++++-------\n t/t9902-completion.sh                  | 49 ++++++++++++++++++++++++++\n 2 files changed, 60 insertions(+), 13 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex eeb80fdc6e4..6d81f03f291 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -2988,7 +2988,7 @@ _git_show_branch ()\n \n __gitcomp_directories ()\n {\n-\tlocal _tmp_dir _tmp_completions\n+\tlocal _tmp_dir _tmp_completions _found=0\n \n \t# Get the directory of the current token; this differs from dirname\n \t# in that it keeps up to the final trailing slash.  If no slash found\n@@ -2996,20 +2996,18 @@ __gitcomp_directories ()\n \t[[ \"$cur\" =~ .*/ ]]\n \t_tmp_dir=$BASH_REMATCH\n \n-\t# Find possible directory completions, adding trailing '/' characters\n-\t_tmp_completions=\"$(git ls-tree -d --name-only HEAD $_tmp_dir |\n-\t\tsed -e s%$%/%)\"\n-\n-\tif [[ -n \"$_tmp_completions\" ]]; then\n-\t\t# There were some directory completions, so find ones that\n-\t\t# start with \"$cur\", the current token, and put those in COMPREPLY\n-\t\tlocal i=0 c IFS=$' \\t\\n'\n-\t\tfor c in $_tmp_completions; do\n+\t# Find possible directory completions, adding trailing '/' characters,\n+\t# de-quoting, and handling unusual characters.\n+\twhile IFS= read -r -d $'\\0' c ; do\n+\t\t# If there are directory completions, find ones that start\n+\t\t# with \"$cur\", the current token, and put those in COMPREPLY\n \t\tif [[ $c == \"$cur\"* ]]; then\n-\t\t\tCOMPREPLY+=(\"$c\")\n+\t\t\tCOMPREPLY+=(\"$c/\")\n+\t\t\t_found=1\n \t\tfi\n-\t\tdone\n-\telif [[ \"$cur\" =~ /$ ]]; then\n+\tdone < <(git ls-tree -z -d --name-only HEAD $_tmp_dir)\n+\n+\tif [[ $_found == 0 ]] && [[ \"$cur\" =~ /$ ]]; then\n \t\t# No possible further completions any deeper, so assume we're at\n \t\t# a leaf directory and just consider it complete\n \t\t__gitcomp_direct_append \"$cur \"\ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex b38a7302249..da6c86c64b3 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -1508,6 +1508,55 @@ test_expect_success 'cone mode sparse-checkout completes directory names' '\n \t)\n '\n \n+test_expect_success 'cone mode sparse-checkout completes directory names with spaces and accents' '\n+\t# reset sparse-checkout\n+\tgit -C sparse-checkout sparse-checkout disable &&\n+\t(\n+\t\tcd sparse-checkout &&\n+\t\tmkdir \"directory with spaces\" &&\n+\t\tmkdir \"directory-with-áccent\" &&\n+\t\t>\"directory with spaces/randomfile\" &&\n+\t\t>\"directory-with-áccent/randomfile\" &&\n+\t\tgit add . &&\n+\t\tgit commit -m \"Add directory with spaces and directory with accent\" &&\n+\t\tgit sparse-checkout set --cone \"directory with spaces\" \\\n+\t\t\t\"directory-with-áccent\" &&\n+\t\ttest_completion \"git sparse-checkout add dir\" <<-\\EOF &&\n+\t\tdirectory with spaces/\n+\t\tdirectory-with-áccent/\n+\t\tEOF\n+\t\trm -rf \"directory with spaces\" &&\n+\t\trm -rf \"directory-with-áccent\" &&\n+\t\tgit add . &&\n+\t\tgit commit -m \"Remove directory with spaces and directory with accent\"\n+\t)\n+'\n+\n+# use FUNNYNAMES to avoid running on Windows, which doesn't permit backslashes or tabs in paths\n+test_expect_success FUNNYNAMES 'cone mode sparse-checkout completes directory names with backslashes and tabs' '\n+\t# reset sparse-checkout\n+\tgit -C sparse-checkout sparse-checkout disable &&\n+\t(\n+\t\tcd sparse-checkout &&\n+\t\tmkdir \"directory\\with\\backslashes\" &&\n+\t\tmkdir \"$(printf \"directory\\twith\\ttabs\")\" &&\n+\t\t>\"directory\\with\\backslashes/randomfile\" &&\n+\t\t>\"$(printf \"directory\\twith\\ttabs\")/randomfile\" &&\n+\t\tgit add . &&\n+\t\tgit commit -m \"Add directory with backslashes and directory with tabs\" &&\n+\t\tgit sparse-checkout set --cone \"directory\\with\\backslashes\" \\\n+\t\t\t\"$(printf \"directory\\twith\\ttabs\")\" &&\n+\t\ttest_completion \"git sparse-checkout add dir\" <<-\\EOF &&\n+\t\tdirectory\\with\\backslashes/\n+\t\tdirectory\twith\ttabs/\n+\t\tEOF\n+\t\trm -rf \"directory\\with\\backslashes\" &&\n+\t\trm -rf \"$(printf \"directory\\twith\\ttabs\")\" &&\n+\t\tgit add . &&\n+\t\tgit commit -m \"Remove directory with backslashes and directory with tabs\"\n+\t)\n+'\n+\n test_expect_success 'non-cone mode sparse-checkout uses bash completion' '\n \t# reset sparse-checkout repo to non-cone mode\n \tgit -C sparse-checkout sparse-checkout disable &&\n-- \ngitgitgadget\n"},{"id":"447898","messageId":"26422c759a018262dd0095817d7d67e1e39908fe.1644255105.git.gitgitgadget@gmail.com","threadId":"57165","inReplyTo":"pull.1108.v7.git.1644255105.gitgitgadget@gmail.com","subject":"[PATCH v7 1/3] completion: address sparse-checkout issues","fromName":"Lessley Dennington via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-02-07T17:31:43Z","receivedAt":"2022-02-07T17:47:31Z","isPatch":true,"sender":{"key":"lessleydennington@gmail.com","avatar":"https://avatars.githubusercontent.com/u/11321782?v=4"},"body":"From: Lessley Dennington <lessleydennington@gmail.com>\n\nCorrect multiple issues with tab completion of the git sparse-checkout\ncommand. These issues were:\n\n1. git sparse-checkout <TAB> previously resulted in an incomplete list of\nsubcommands (it was missing reapply and add).\n2. Subcommand options were not tab-completable.\n3. git sparse-checkout set <TAB> and git sparse-checkout add <TAB> showed\nboth file names and directory names. While this may be a less surprising\nbehavior for non-cone mode, cone mode sparse checkouts should complete\nonly directory names.\n\nNote that while the new strategy of just using git ls-tree to complete on\ndirectory names is simple and a step in the right direction, it does have\nsome caveats. These are:\n\n1. Likelihood of poor performance in large monorepos (as a result of\nrecursively completing directory names).\n2. Inability to handle paths containing unusual characters.\n\nThese caveats will be fixed by subsequent commits in this series.\n\nSigned-off-by: Lessley Dennington <lessleydennington@gmail.com>\nReviewed-by: Elijah Newren <newren@gmail.com>\n---\n contrib/completion/git-completion.bash | 16 ++---\n t/t9902-completion.sh                  | 83 ++++++++++++++++++++++++++\n 2 files changed, 91 insertions(+), 8 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex c82ccaebcc7..7f6c86dc6c0 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -2988,7 +2988,7 @@ _git_show_branch ()\n \n _git_sparse_checkout ()\n {\n-\tlocal subcommands=\"list init set disable\"\n+\tlocal subcommands=\"list init set disable add reapply\"\n \tlocal subcommand=\"$(__git_find_on_cmdline \"$subcommands\")\"\n \tif [ -z \"$subcommand\" ]; then\n \t\t__gitcomp \"$subcommands\"\n@@ -2996,14 +2996,14 @@ _git_sparse_checkout ()\n \tfi\n \n \tcase \"$subcommand,$cur\" in\n-\tinit,--*)\n-\t\t__gitcomp \"--cone\"\n-\t\t;;\n-\tset,--*)\n-\t\t__gitcomp \"--stdin\"\n-\t\t;;\n-\t*)\n+\t*,--*)\n+\t\t__gitcomp_builtin sparse-checkout_$subcommand \"\" \"--\"\n \t\t;;\n+\tset,*|add,*)\n+\t\tif [ \"$(__git config core.sparseCheckoutCone)\" == \"true\" ] ||\n+\t\t[ -n \"$(__git_find_on_cmdline --cone)\" ]; then\n+\t\t\t__gitcomp \"$(git ls-tree -d -r HEAD --name-only)\"\n+\t\tfi\n \tesac\n }\n \ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex 518203fbe07..f6eeb9aa035 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -1447,6 +1447,89 @@ test_expect_success 'git checkout - with --detach, complete only references' '\n \tEOF\n '\n \n+test_expect_success 'setup sparse-checkout tests' '\n+\t# set up sparse-checkout repo\n+\tgit init sparse-checkout &&\n+\t(\n+\t\tcd sparse-checkout &&\n+\t\tmkdir -p folder1/0/1 folder2/0 folder3 &&\n+\t\ttouch folder1/0/1/t.txt &&\n+\t\ttouch folder2/0/t.txt &&\n+\t\ttouch folder3/t.txt &&\n+\t\tgit add . &&\n+\t\tgit commit -am \"Initial commit\"\n+\t)\n+'\n+\n+test_expect_success 'sparse-checkout completes subcommands' '\n+\ttest_completion \"git sparse-checkout \" <<-\\EOF\n+\tlist Z\n+\tinit Z\n+\tset Z\n+\tadd Z\n+\treapply Z\n+\tdisable Z\n+\tEOF\n+'\n+\n+test_expect_success 'cone mode sparse-checkout completes directory names' '\n+\t# initialize sparse-checkout definitions\n+\tgit -C sparse-checkout sparse-checkout set --cone folder1/0 folder3 &&\n+\n+\t# test tab completion\n+\t(\n+\t\tcd sparse-checkout &&\n+\t\ttest_completion \"git sparse-checkout set f\" <<-\\EOF\n+\t\tfolder1 Z\n+\t\tfolder1/0 Z\n+\t\tfolder1/0/1 Z\n+\t\tfolder2 Z\n+\t\tfolder2/0 Z\n+\t\tfolder3 Z\n+\t\tEOF\n+\t) &&\n+\n+\t(\n+\t\tcd sparse-checkout/folder1 &&\n+\t\ttest_completion \"git sparse-checkout add \" <<-\\EOF\n+\t\t./ Z\n+\t\t0 Z\n+\t\t0/1 Z\n+\t\tEOF\n+\t)\n+'\n+\n+test_expect_success 'non-cone mode sparse-checkout uses bash completion' '\n+\t# reset sparse-checkout repo to non-cone mode\n+\tgit -C sparse-checkout sparse-checkout disable &&\n+\tgit -C sparse-checkout sparse-checkout set --no-cone &&\n+\n+\t(\n+\t\tcd sparse-checkout &&\n+\t\t# expected to be empty since we have not configured\n+\t\t# custom completion for non-cone mode\n+\t\ttest_completion \"git sparse-checkout set f\" <<-\\EOF\n+\n+\t\tEOF\n+\t)\n+'\n+\n+test_expect_success 'git sparse-checkout set --cone completes directory names' '\n+\tgit -C sparse-checkout sparse-checkout disable &&\n+\n+\t(\n+\t\tcd sparse-checkout &&\n+\t\ttest_completion \"git sparse-checkout set --cone f\" <<-\\EOF\n+\t\tfolder1 Z\n+\t\tfolder1/0 Z\n+\t\tfolder1/0/1 Z\n+\t\tfolder2 Z\n+\t\tfolder2/0 Z\n+\t\tfolder3 Z\n+\t\tEOF\n+\t)\n+'\n+\n test_expect_success 'git switch - with -d, complete all references' '\n \ttest_completion \"git switch -d \" <<-\\EOF\n \tHEAD Z\n-- \ngitgitgadget\n\n"},{"id":"447940","messageId":"CABPp-BE4w+kdk3sBRUTash4JrMf9w0eWzps=mqEzrW3zBSG4tA@mail.gmail.com","threadId":"57165","inReplyTo":"pull.1108.v7.git.1644255105.gitgitgadget@gmail.com","subject":"Re: [PATCH v7 0/3] completion: sparse-checkout updates","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2022-02-08T04:16:25Z","receivedAt":"2022-02-08T04:16:44Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Mon, Feb 7, 2022 at 9:31 AM Lessley Dennington via GitGitGadget\n<gitgitgadget@gmail.com> wrote:\n>\n> This change updates custom tab completion for the sparse-checkout command.\n> Specifically, it corrects the following issues with the current method:\n>\n>  1. git sparse-checkout <TAB> results in an incomplete list of subcommands\n>     (it is missing reapply and add).\n>  2. Options for subcommands are not tab-completable.\n>  3. git sparse-checkout set <TAB> and git sparse-checkout add <TAB> show\n>     both file names and directory names. While this may be a less surprising\n>     behavior for non-cone mode, we want to only show directories in cone\n>     mode.\n>\n> The first commit in this series is an intermediate step that fixes issues 1\n> and 2 above and introduces a simple fix for issue 3 with some performance\n> and unusual character-related caveats. The next commit adds a new\n> __gitcomp_directories method that fixes the performance-related caveat from\n> the first commit by completing just a single level of directories. The final\n> commit modifies __gitcomp_directories to handle unusual characters in\n> directory names.\n>\n>\n> Changes since V6\n> ================\n>\n>  * Split tests for unusual characters so that spaces and accents are\n>    verified on Windows (in addition to macOS and Linux). Tabs and\n>    backslashes are still excluded on Windows (details on why are included in\n>    the third commit message).\n\nThanks for doing that.  I think this series is ready for next.\n\n(It already has my Reviewed-by, so no need for me to re-give it.)\n"},{"id":"453172","messageId":"20220406094207.h7ru4xdiimywelqg@lucy.dinwoodie.org","threadId":"57165","inReplyTo":"996cbe7dfb73c211eae012813b352b0d0de3954c.1644255105.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v7 3/3] completion: handle unusual characters for sparse-checkout","fromName":"Adam Dinwoodie","fromEmail":"adam@dinwoodie.org","sentAt":"2022-04-06T09:42:07Z","receivedAt":"2022-04-06T14:04:42Z","isPatch":true,"sender":{"key":"adam@dinwoodie.org","avatar":"https://avatars.githubusercontent.com/u/1397507?v=4"},"body":"On Mon, Feb 07, 2022 at 05:31:45PM +0000, Lessley Dennington via GitGitGadget wrote:\n> <snip>\n> \n> Note there are two tests for this new functionality - one for spaces and\n> accents and one for backslashes and tabs. The backslashes and tabs test\n> uses FUNNYNAMES to avoid running on Windows. This is because:\n> \n> 1. Backslashes are explicitly not allowed in Windows file paths.\n> 2. Although tabs appear to be allowed when creating a file in a Windows\n> bash shell, they actually are not renderable (and appear as empty boxes\n> in the shell).\n> \n> <snip>\n> diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\n> index b38a7302249..da6c86c64b3 100755\n> --- a/t/t9902-completion.sh\n> +++ b/t/t9902-completion.sh\n> @@ -1508,6 +1508,55 @@ test_expect_success 'cone mode sparse-checkout completes directory names' '\n> <snip>\n> +# use FUNNYNAMES to avoid running on Windows, which doesn't permit backslashes or tabs in paths\n> +test_expect_success FUNNYNAMES 'cone mode sparse-checkout completes directory names with backslashes and tabs' '\n> +\t# reset sparse-checkout\n> +\tgit -C sparse-checkout sparse-checkout disable &&\n> +\t(\n> +\t\tcd sparse-checkout &&\n> +\t\tmkdir \"directory\\with\\backslashes\" &&\n> +\t\tmkdir \"$(printf \"directory\\twith\\ttabs\")\" &&\n> +\t\t>\"directory\\with\\backslashes/randomfile\" &&\n> +\t\t>\"$(printf \"directory\\twith\\ttabs\")/randomfile\" &&\n> +\t\tgit add . &&\n> +\t\tgit commit -m \"Add directory with backslashes and directory with tabs\" &&\n> +\t\tgit sparse-checkout set --cone \"directory\\with\\backslashes\" \\\n> +\t\t\t\"$(printf \"directory\\twith\\ttabs\")\" &&\n> +\t\ttest_completion \"git sparse-checkout add dir\" <<-\\EOF &&\n> +\t\tdirectory\\with\\backslashes/\n> +\t\tdirectory\twith\ttabs/\n> +\t\tEOF\n> +\t\trm -rf \"directory\\with\\backslashes\" &&\n> +\t\trm -rf \"$(printf \"directory\\twith\\ttabs\")\" &&\n> +\t\tgit add . &&\n> +\t\tgit commit -m \"Remove directory with backslashes and directory with tabs\"\n> +\t)\n> +'\n> +\n>  test_expect_success 'non-cone mode sparse-checkout uses bash completion' '\n>  \t# reset sparse-checkout repo to non-cone mode\n>  \tgit -C sparse-checkout sparse-checkout disable &&\n\nOn Cygwin this test is failing: `FUNNYNAMES` checks (a) the system isn't\nMinGW, and (b) the filesystem supports tabs, quotes and newlines.\nCygwin isn't MinGW, and its interface to the file system supports all\nthose characters, but doesn't support backslashes.\n\nI think the ideal solution here would be to split this test into two:\none part to cover the tab part, which will work on Cygwin, and a\nseparate part that has another prereq (which might be a new variant of\nFUN*NAMES, or might be something more explicit like\nSLASHALLOWEDINPATHCOMPONENTS, or might just be FUNNYNAMES,!CYGWIN).  But\nit might be easier to just gate this test on FUNNYNAMES,!CYGWIN and not\nworry about not being able to test the tab handling on Cygwin systems,\nas the chances of a Cygwin-specific regression that'd only be caught by\nthis test seems pretty low to me.\n"}]}