Skip to content

Commit

Permalink
Speed up bash completion loading
Browse files Browse the repository at this point in the history
Since git is not used in each and every interactive xterm, it
seems best to load completion support with cold caches and then
load each needed thing lazily.  This has most of the speed
advantage of pre-generating everything at build time, without the
complication of figuring out at build time what commands will be
available at run time.

On this slow laptop, this decreases the time to load
git-completion.bash from about 500 ms to about 175 ms.

Suggested-by: Kirill Smelkov <kirr@mns.spb.ru>
Acked-by: Shawn O. Pearce <spearce@spearce.org>
Cc: Stephen Boyd <bebarino@gmail.com>
Cc: SZEDER Gábor <szeder@ira.uka.de>
Cc: Sverre Rabbelier <srabbelier@gmail.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Jonathan Nieder authored and Junio C Hamano committed Nov 18, 2009
1 parent 78d553b commit eaa4e6e
Showing 1 changed file with 41 additions and 35 deletions.
76 changes: 41 additions & 35 deletions contrib/completion/git-completion.bash
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,7 @@
# 2) Added the following line to your .bashrc:
# source ~/.git-completion.sh
#
# 3) You may want to make sure the git executable is available
# in your PATH before this script is sourced, as some caching
# is performed while the script loads. If git isn't found
# at source time then all lookups will be done on demand,
# which may be slightly slower.
#
# 4) Consider changing your PS1 to also show the current branch:
# 3) Consider changing your PS1 to also show the current branch:
# PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '
#
# The argument to __git_ps1 will be displayed only if you
Expand Down Expand Up @@ -324,12 +318,8 @@ __git_remotes ()
done
}

__git_merge_strategies ()
__git_list_merge_strategies ()
{
if [ -n "${__git_merge_strategylist-}" ]; then
echo "$__git_merge_strategylist"
return
fi
git merge -s help 2>&1 |
sed -n -e '/[Aa]vailable strategies are: /,/^$/{
s/\.$//
Expand All @@ -339,8 +329,17 @@ __git_merge_strategies ()
p
}'
}
__git_merge_strategylist=
__git_merge_strategylist=$(__git_merge_strategies 2>/dev/null)

__git_merge_strategies=
# 'git merge -s help' (and thus detection of the merge strategy
# list) fails, unfortunately, if run outside of any git working
# tree. __git_merge_strategies is set to the empty string in
# that case, and the detection will be repeated the next time it
# is needed.
__git_compute_merge_strategies ()
{
: ${__git_merge_strategies:=$(__git_list_merge_strategies)}
}

__git_complete_file ()
{
Expand Down Expand Up @@ -474,27 +473,24 @@ __git_complete_remote_or_refspec ()

__git_complete_strategy ()
{
__git_compute_merge_strategies
case "${COMP_WORDS[COMP_CWORD-1]}" in
-s|--strategy)
__gitcomp "$(__git_merge_strategies)"
__gitcomp "$__git_merge_strategies"
return 0
esac
local cur="${COMP_WORDS[COMP_CWORD]}"
case "$cur" in
--strategy=*)
__gitcomp "$(__git_merge_strategies)" "" "${cur##--strategy=}"
__gitcomp "$__git_merge_strategies" "" "${cur##--strategy=}"
return 0
;;
esac
return 1
}

__git_all_commands ()
__git_list_all_commands ()
{
if [ -n "${__git_all_commandlist-}" ]; then
echo "$__git_all_commandlist"
return
fi
local i IFS=" "$'\n'
for i in $(git help -a|egrep '^ [a-zA-Z0-9]')
do
Expand All @@ -504,17 +500,18 @@ __git_all_commands ()
esac
done
}
__git_all_commandlist=
__git_all_commandlist="$(__git_all_commands 2>/dev/null)"

__git_porcelain_commands ()
__git_all_commands=
__git_compute_all_commands ()
{
: ${__git_all_commands:=$(__git_list_all_commands)}
}

__git_list_porcelain_commands ()
{
if [ -n "${__git_porcelain_commandlist-}" ]; then
echo "$__git_porcelain_commandlist"
return
fi
local i IFS=" "$'\n'
for i in "help" $(__git_all_commands)
__git_compute_all_commands
for i in "help" $__git_all_commands
do
case $i in
*--*) : helper pattern;;
Expand Down Expand Up @@ -595,8 +592,13 @@ __git_porcelain_commands ()
esac
done
}
__git_porcelain_commandlist=
__git_porcelain_commandlist="$(__git_porcelain_commands 2>/dev/null)"

__git_porcelain_commands=
__git_compute_porcelain_commands ()
{
__git_compute_all_commands
: ${__git_porcelain_commands:=$(__git_list_porcelain_commands)}
}

__git_aliases ()
{
Expand Down Expand Up @@ -1081,7 +1083,8 @@ _git_help ()
return
;;
esac
__gitcomp "$(__git_all_commands)
__git_compute_all_commands
__gitcomp "$__git_all_commands
attributes cli core-tutorial cvs-migration
diffcore gitk glossary hooks ignore modules
repository-layout tutorial tutorial-2
Expand Down Expand Up @@ -1427,7 +1430,8 @@ _git_config ()
return
;;
pull.twohead|pull.octopus)
__gitcomp "$(__git_merge_strategies)"
__git_compute_merge_strategies
__gitcomp "$__git_merge_strategies"
return
;;
color.branch|color.diff|color.interactive|\
Expand Down Expand Up @@ -1528,7 +1532,8 @@ _git_config ()
pager.*)
local pfx="${cur%.*}."
cur="${cur#*.}"
__gitcomp "$(__git_all_commands)" "$pfx" "$cur"
__git_compute_all_commands
__gitcomp "$__git_all_commands" "$pfx" "$cur"
return
;;
remote.*.*)
Expand Down Expand Up @@ -2125,7 +2130,8 @@ _git ()
--help
"
;;
*) __gitcomp "$(__git_porcelain_commands) $(__git_aliases)" ;;
*) __git_compute_porcelain_commands
__gitcomp "$__git_porcelain_commands $(__git_aliases)" ;;
esac
return
fi
Expand Down

0 comments on commit eaa4e6e

Please sign in to comment.