Skip to content

Commit eaa4e6e

Browse files
jrngitster
authored andcommitted
Speed up bash completion loading
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>
1 parent 78d553b commit eaa4e6e

File tree

1 file changed

+41
-35
lines changed

1 file changed

+41
-35
lines changed

contrib/completion/git-completion.bash

Lines changed: 41 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,7 @@
2121
# 2) Added the following line to your .bashrc:
2222
# source ~/.git-completion.sh
2323
#
24-
# 3) You may want to make sure the git executable is available
25-
# in your PATH before this script is sourced, as some caching
26-
# is performed while the script loads. If git isn't found
27-
# at source time then all lookups will be done on demand,
28-
# which may be slightly slower.
29-
#
30-
# 4) Consider changing your PS1 to also show the current branch:
24+
# 3) Consider changing your PS1 to also show the current branch:
3125
# PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '
3226
#
3327
# The argument to __git_ps1 will be displayed only if you
@@ -324,12 +318,8 @@ __git_remotes ()
324318
done
325319
}
326320

327-
__git_merge_strategies ()
321+
__git_list_merge_strategies ()
328322
{
329-
if [ -n "${__git_merge_strategylist-}" ]; then
330-
echo "$__git_merge_strategylist"
331-
return
332-
fi
333323
git merge -s help 2>&1 |
334324
sed -n -e '/[Aa]vailable strategies are: /,/^$/{
335325
s/\.$//
@@ -339,8 +329,17 @@ __git_merge_strategies ()
339329
p
340330
}'
341331
}
342-
__git_merge_strategylist=
343-
__git_merge_strategylist=$(__git_merge_strategies 2>/dev/null)
332+
333+
__git_merge_strategies=
334+
# 'git merge -s help' (and thus detection of the merge strategy
335+
# list) fails, unfortunately, if run outside of any git working
336+
# tree. __git_merge_strategies is set to the empty string in
337+
# that case, and the detection will be repeated the next time it
338+
# is needed.
339+
__git_compute_merge_strategies ()
340+
{
341+
: ${__git_merge_strategies:=$(__git_list_merge_strategies)}
342+
}
344343

345344
__git_complete_file ()
346345
{
@@ -474,27 +473,24 @@ __git_complete_remote_or_refspec ()
474473

475474
__git_complete_strategy ()
476475
{
476+
__git_compute_merge_strategies
477477
case "${COMP_WORDS[COMP_CWORD-1]}" in
478478
-s|--strategy)
479-
__gitcomp "$(__git_merge_strategies)"
479+
__gitcomp "$__git_merge_strategies"
480480
return 0
481481
esac
482482
local cur="${COMP_WORDS[COMP_CWORD]}"
483483
case "$cur" in
484484
--strategy=*)
485-
__gitcomp "$(__git_merge_strategies)" "" "${cur##--strategy=}"
485+
__gitcomp "$__git_merge_strategies" "" "${cur##--strategy=}"
486486
return 0
487487
;;
488488
esac
489489
return 1
490490
}
491491

492-
__git_all_commands ()
492+
__git_list_all_commands ()
493493
{
494-
if [ -n "${__git_all_commandlist-}" ]; then
495-
echo "$__git_all_commandlist"
496-
return
497-
fi
498494
local i IFS=" "$'\n'
499495
for i in $(git help -a|egrep '^ [a-zA-Z0-9]')
500496
do
@@ -504,17 +500,18 @@ __git_all_commands ()
504500
esac
505501
done
506502
}
507-
__git_all_commandlist=
508-
__git_all_commandlist="$(__git_all_commands 2>/dev/null)"
509503

510-
__git_porcelain_commands ()
504+
__git_all_commands=
505+
__git_compute_all_commands ()
506+
{
507+
: ${__git_all_commands:=$(__git_list_all_commands)}
508+
}
509+
510+
__git_list_porcelain_commands ()
511511
{
512-
if [ -n "${__git_porcelain_commandlist-}" ]; then
513-
echo "$__git_porcelain_commandlist"
514-
return
515-
fi
516512
local i IFS=" "$'\n'
517-
for i in "help" $(__git_all_commands)
513+
__git_compute_all_commands
514+
for i in "help" $__git_all_commands
518515
do
519516
case $i in
520517
*--*) : helper pattern;;
@@ -595,8 +592,13 @@ __git_porcelain_commands ()
595592
esac
596593
done
597594
}
598-
__git_porcelain_commandlist=
599-
__git_porcelain_commandlist="$(__git_porcelain_commands 2>/dev/null)"
595+
596+
__git_porcelain_commands=
597+
__git_compute_porcelain_commands ()
598+
{
599+
__git_compute_all_commands
600+
: ${__git_porcelain_commands:=$(__git_list_porcelain_commands)}
601+
}
600602

601603
__git_aliases ()
602604
{
@@ -1081,7 +1083,8 @@ _git_help ()
10811083
return
10821084
;;
10831085
esac
1084-
__gitcomp "$(__git_all_commands)
1086+
__git_compute_all_commands
1087+
__gitcomp "$__git_all_commands
10851088
attributes cli core-tutorial cvs-migration
10861089
diffcore gitk glossary hooks ignore modules
10871090
repository-layout tutorial tutorial-2
@@ -1427,7 +1430,8 @@ _git_config ()
14271430
return
14281431
;;
14291432
pull.twohead|pull.octopus)
1430-
__gitcomp "$(__git_merge_strategies)"
1433+
__git_compute_merge_strategies
1434+
__gitcomp "$__git_merge_strategies"
14311435
return
14321436
;;
14331437
color.branch|color.diff|color.interactive|\
@@ -1528,7 +1532,8 @@ _git_config ()
15281532
pager.*)
15291533
local pfx="${cur%.*}."
15301534
cur="${cur#*.}"
1531-
__gitcomp "$(__git_all_commands)" "$pfx" "$cur"
1535+
__git_compute_all_commands
1536+
__gitcomp "$__git_all_commands" "$pfx" "$cur"
15321537
return
15331538
;;
15341539
remote.*.*)
@@ -2125,7 +2130,8 @@ _git ()
21252130
--help
21262131
"
21272132
;;
2128-
*) __gitcomp "$(__git_porcelain_commands) $(__git_aliases)" ;;
2133+
*) __git_compute_porcelain_commands
2134+
__gitcomp "$__git_porcelain_commands $(__git_aliases)" ;;
21292135
esac
21302136
return
21312137
fi

0 commit comments

Comments
 (0)