@matheusbsbs / matheus-bagliano / commits / eaa4e6ee2a
Fork 0

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>

Jonathan Nieder committed Nov 17, 2009 at 18:49 UTC eaa4e6ee2a1df289e6900ee908751463b22a3a54
1 file changed +41 -35
contrib/completion/git-completion.bash
+41 -35
@@ -21,13 +21,7 @@
21 # 2) Added the following line to your .bashrc:
22 # source ~/.git-completion.sh
23 #
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:
25 # PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '
26 #
27 # The argument to __git_ps1 will be displayed only if you
@@ -324,12 +318,8 @@ __git_remotes ()
318 done
319 }
320
327 -__git_merge_strategies ()
321 +__git_list_merge_strategies ()
322 {
329 - if [ -n "${__git_merge_strategylist-}" ]; then
330 - echo "$__git_merge_strategylist"
331 - return
332 - fi
323 git merge -s help 2>&1 |
324 sed -n -e '/[Aa]vailable strategies are: /,/^$/{
325 s/\.$//
@@ -339,8 +329,17 @@ __git_merge_strategies ()
329 p
330 }'
331 }
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 +}
343
344 __git_complete_file ()
345 {
@@ -474,27 +473,24 @@ __git_complete_remote_or_refspec ()
473
474 __git_complete_strategy ()
475 {
476 + __git_compute_merge_strategies
477 case "${COMP_WORDS[COMP_CWORD-1]}" in
478 -s|--strategy)
479 - __gitcomp "$(__git_merge_strategies)"
479 + __gitcomp "$__git_merge_strategies"
480 return 0
481 esac
482 local cur="${COMP_WORDS[COMP_CWORD]}"
483 case "$cur" in
484 --strategy=*)
485 - __gitcomp "$(__git_merge_strategies)" "" "${cur##--strategy=}"
485 + __gitcomp "$__git_merge_strategies" "" "${cur##--strategy=}"
486 return 0
487 ;;
488 esac
489 return 1
490 }
491
492 -__git_all_commands ()
492 +__git_list_all_commands ()
493 {
494 - if [ -n "${__git_all_commandlist-}" ]; then
495 - echo "$__git_all_commandlist"
496 - return
497 - fi
494 local i IFS=" "$'\n'
495 for i in $(git help -a|egrep '^ [a-zA-Z0-9]')
496 do
@@ -504,17 +500,18 @@ __git_all_commands ()
500 esac
501 done
502 }
507 -__git_all_commandlist=
508 -__git_all_commandlist="$(__git_all_commands 2>/dev/null)"
503
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 ()
511 {
512 - if [ -n "${__git_porcelain_commandlist-}" ]; then
513 - echo "$__git_porcelain_commandlist"
514 - return
515 - fi
512 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
515 do
516 case $i in
517 *--*) : helper pattern;;
@@ -595,8 +592,13 @@ __git_porcelain_commands ()
592 esac
593 done
594 }
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 +}
602
603 __git_aliases ()
604 {
@@ -1081,7 +1083,8 @@ _git_help ()
1083 return
1084 ;;
1085 esac
1084 - __gitcomp "$(__git_all_commands)
1086 + __git_compute_all_commands
1087 + __gitcomp "$__git_all_commands
1088 attributes cli core-tutorial cvs-migration
1089 diffcore gitk glossary hooks ignore modules
1090 repository-layout tutorial tutorial-2
@@ -1427,7 +1430,8 @@ _git_config ()
1430 return
1431 ;;
1432 pull.twohead|pull.octopus)
1430 - __gitcomp "$(__git_merge_strategies)"
1433 + __git_compute_merge_strategies
1434 + __gitcomp "$__git_merge_strategies"
1435 return
1436 ;;
1437 color.branch|color.diff|color.interactive|\
@@ -1528,7 +1532,8 @@ _git_config ()
1532 pager.*)
1533 local pfx="${cur%.*}."
1534 cur="${cur#*.}"
1531 - __gitcomp "$(__git_all_commands)" "$pfx" "$cur"
1535 + __git_compute_all_commands
1536 + __gitcomp "$__git_all_commands" "$pfx" "$cur"
1537 return
1538 ;;
1539 remote.*.*)
@@ -2125,7 +2130,8 @@ _git ()
2130 --help
2131 "
2132 ;;
2128 - *) __gitcomp "$(__git_porcelain_commands) $(__git_aliases)" ;;
2133 + *) __git_compute_porcelain_commands
2134 + __gitcomp "$__git_porcelain_commands $(__git_aliases)" ;;
2135 esac
2136 return
2137 fi