From 637cbbbbbcb90a4c656c78b1ac858b2dc69bf59b Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Tue, 24 Oct 2023 00:08:48 -0400 Subject: [PATCH] bash completion: add support for git 2.30 and on The _git backwards compat wrapper was dropped upstream: https://github.com/git/git/commit/441ecdab37fefdacf32575a60aa523b2367c46f7 Instead, we rely on __git_complete to detect loaded bash completions, since we will use it later on to set up completions -- it is now public API. There is a gap between git 2.30 and 2.31 where _git does not exist, but there is no public API to create completions. Starting 2.31, we are formally permitted to copy/imitate the upstream completions with: ``` __git_complete mycmd git_cmd ``` For 2.30 specifically, we have to pass the internal completion function used instead of "git_cmd", but it's difficult to detect this necessity in a forwards-compatible way. Try it that way first, in the assumption that if the internal completion function still exists it does the same thing. --- etc/hub.bash_completion.sh | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/etc/hub.bash_completion.sh b/etc/hub.bash_completion.sh index 8a4cd4ff3..89b3f942a 100644 --- a/etc/hub.bash_completion.sh +++ b/etc/hub.bash_completion.sh @@ -2,12 +2,12 @@ # This script complements the completion script that ships with git. # If there is no git tab completion, but we have the _completion loader try to load it -if ! declare -F _git > /dev/null && declare -F _completion_loader > /dev/null; then +if ! declare -F __git_complete > /dev/null && declare -F _completion_loader > /dev/null; then _completion_loader git fi # Check that git tab completion is available and we haven't already set up completion -if declare -F _git > /dev/null && ! declare -F __git_list_all_commands_without_hub > /dev/null; then +if declare -F __git_complete > /dev/null && ! declare -F __git_list_all_commands_without_hub > /dev/null; then # Duplicate and rename the 'list_all_commands' function eval "$(declare -f __git_list_all_commands | \ sed 's/__git_list_all_commands/__git_list_all_commands_without_hub/')" @@ -382,6 +382,15 @@ EOF } # Enable completion for hub even when not using the alias - complete -o bashdefault -o default -o nospace -F _git hub 2>/dev/null \ - || complete -o default -o nospace -F _git hub + if declare -F _git >/dev/null; then + # git < 2.30 + complete -o bashdefault -o default -o nospace -F _git hub 2>/dev/null \ + || complete -o default -o nospace -F _git hub + elif declare -F __git_main >/dev/null; then + # in git 2.30 both __git_complete and __git_main are private + __git_complete hub __git_main + else + # git > 2.31 if __git_main is removed + __git_complete hub git + fi fi