From 83b0ecf333e518867935f6b12c18294a8a7f5017 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Wed, 20 Mar 2019 14:03:26 -0400 Subject: [PATCH 1/4] git: read local config in --list-cmds Normally code that is checking config before we've decided to do setup_git_directory() would use read_early_config(), which uses discover_git_directory() to tentatively see if we're in a repo, and if so to add it to the config sequence. But list_cmds() uses the caching configset mechanism which rightly does not use read_early_config(), because it has no idea if it's being called early. Call setup_git_directory_gently() so we can pick up repo-level config (like completion.commands). Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- git.c | 7 +++++++ help.c | 7 ------- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/git.c b/git.c index 2014aab6b8..181785ec47 100644 --- a/git.c +++ b/git.c @@ -62,6 +62,13 @@ static int list_cmds(const char *spec) { struct string_list list = STRING_LIST_INIT_DUP; int i; + int nongit; + + /* + * Set up the repository so we can pick up any repo-level config (like + * completion.commands). + */ + setup_git_directory_gently(&nongit); while (*spec) { const char *sep = strchrnul(spec, ','); diff --git a/help.c b/help.c index 520c9080e8..fac7e421d0 100644 --- a/help.c +++ b/help.c @@ -375,13 +375,6 @@ void list_cmds_by_config(struct string_list *list) { const char *cmd_list; - /* - * There's no actual repository setup at this point (and even - * if there is, we don't really care; only global config - * matters). If we accidentally set up a repository, it's ok - * too since the caller (git --list-cmds=) should exit shortly - * anyway. - */ if (git_config_get_string_const("completion.commands", &cmd_list)) return; From 402e3e1500b3bce5cee9f903f8aa691a8010e76a Mon Sep 17 00:00:00 2001 From: Todd Zullinger Date: Wed, 20 Mar 2019 14:03:27 -0400 Subject: [PATCH 2/4] t9902: test multiple removals via completion.commands 6532f3740b ("completion: allow to customize the completable command list", 2018-05-20) added the completion.commands config variable. Multiple commands may be added or removed, separated by a space. Demonstrate the failure of multiple removals. Signed-off-by: Todd Zullinger Signed-off-by: Junio C Hamano --- t/t9902-completion.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh index f5e21bf970..3d1859f303 100755 --- a/t/t9902-completion.sh +++ b/t/t9902-completion.sh @@ -1484,6 +1484,12 @@ test_expect_success 'git --help completion' ' test_completion "git --help core" "core-tutorial " ' +test_expect_failure 'completion.commands removes multiple commands' ' + test_config completion.commands "-cherry -mergetool" && + git --list-cmds=list-mainporcelain,list-complete,config >out && + ! grep -E "^(cherry|mergetool)$" out +' + test_expect_success 'setup for integration tests' ' echo content >file1 && echo more >file2 && From 057ab54b6646fbdabc8c953299f218081ff67456 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Wed, 20 Mar 2019 14:03:28 -0400 Subject: [PATCH 3/4] completion: fix multiple command removals Commit 6532f3740b ("completion: allow to customize the completable command list", 2018-05-20) tried to allow multiple space-separated entries in completion.commands. To do this, it copies each parsed token into a strbuf so that the result is NUL-terminated. However, for tokens starting with "-", it accidentally passes the original non-terminated string, meaning that only the final one worked. Switch to using the strbuf. Reported-by: Todd Zullinger Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- help.c | 4 ++-- t/t9902-completion.sh | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/help.c b/help.c index fac7e421d0..a9e451f2ee 100644 --- a/help.c +++ b/help.c @@ -386,8 +386,8 @@ void list_cmds_by_config(struct string_list *list) const char *p = strchrnul(cmd_list, ' '); strbuf_add(&sb, cmd_list, p - cmd_list); - if (*cmd_list == '-') - string_list_remove(list, cmd_list + 1, 0); + if (sb.buf[0] == '-') + string_list_remove(list, sb.buf + 1, 0); else string_list_insert(list, sb.buf); strbuf_release(&sb); diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh index 3d1859f303..43cf313a1c 100755 --- a/t/t9902-completion.sh +++ b/t/t9902-completion.sh @@ -1484,7 +1484,7 @@ test_expect_success 'git --help completion' ' test_completion "git --help core" "core-tutorial " ' -test_expect_failure 'completion.commands removes multiple commands' ' +test_expect_success 'completion.commands removes multiple commands' ' test_config completion.commands "-cherry -mergetool" && git --list-cmds=list-mainporcelain,list-complete,config >out && ! grep -E "^(cherry|mergetool)$" out From 2eb6f09f7d9c02266f7e6ac8b1591abc8b10278d Mon Sep 17 00:00:00 2001 From: Todd Zullinger Date: Wed, 20 Mar 2019 14:03:29 -0400 Subject: [PATCH 4/4] completion: use __git when calling --list-cmds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As we made --list-cmds read the local configuration file in an earlier step, the completion.commands variable respects repo-level configuration. Use __git which ensures that the proper repo config is consulted if the command line contains 'git -C /some/other/repo'. Suggested-by: SZEDER Gábor Signed-off-by: Todd Zullinger Signed-off-by: Junio C Hamano --- contrib/completion/git-completion.bash | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 976e4a6548..93b5e972cb 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -1024,7 +1024,7 @@ __git_all_commands= __git_compute_all_commands () { test -n "$__git_all_commands" || - __git_all_commands=$(git --list-cmds=main,others,alias,nohelpers) + __git_all_commands=$(__git --list-cmds=main,others,alias,nohelpers) } # Lists all set config variables starting with the given section prefix, @@ -1652,9 +1652,9 @@ _git_help () esac if test -n "$GIT_TESTING_ALL_COMMAND_LIST" then - __gitcomp "$GIT_TESTING_ALL_COMMAND_LIST $(git --list-cmds=alias,list-guide) gitk" + __gitcomp "$GIT_TESTING_ALL_COMMAND_LIST $(__git --list-cmds=alias,list-guide) gitk" else - __gitcomp "$(git --list-cmds=main,nohelpers,alias,list-guide) gitk" + __gitcomp "$(__git --list-cmds=main,nohelpers,alias,list-guide) gitk" fi } @@ -2925,7 +2925,7 @@ __git_main () then __gitcomp "$GIT_TESTING_PORCELAIN_COMMAND_LIST" else - __gitcomp "$(git --list-cmds=list-mainporcelain,others,nohelpers,alias,list-complete,config)" + __gitcomp "$(__git --list-cmds=list-mainporcelain,others,nohelpers,alias,list-complete,config)" fi ;; esac