Skip to content

Commit 105c0ef

Browse files
szedergitster
authored andcommitted
completion: use 'awk' to strip trailing path components
During git-aware path completion we complete one path component at a time, i.e. 'git add <TAB>' offers only 'dir/' at first, not 'dir/subdir/file' right away, just like Bash's own filename completion. However, since both 'git ls-files' and 'git diff-index' dive deep into subdirectories, we have to strip all trailing path components from the listed paths, keeping only the leading path component. This stripping is currently done in a shell loop in __git_index_files(), which can take a significant amount of time when it has to iterate through a large number of paths. Replace this shell loop with a little 'awk' script using '/' as input field separator and printing the first field, which produces the same output much faster. Listing all tracked files (12) and directories (23) at the top of the worktree in linux.git (over 62k files), i.e. what's doing all the hard work behind 'git rm <TAB>': Before this patch, best of five, using GNU awk on Linux: $ time cur= __git_complete_index_file real 0m2.149s user 0m1.307s sys 0m1.086s After: real 0m0.067s user 0m0.089s sys 0m0.023s Difference: -96.9% Speedup: 32.1x Note that this could be done with 'sed', or even with 'cut', just as well, but the upcoming patches require 'awk's scriptability. Note also that this change means one more fork()+exec()ed process during path completion, adding more overhead especially on Windows, but a later patch will more than make up for it by eliminating two other processes in the same function. Signed-off-by: SZEDER Gábor <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent a364e98 commit 105c0ef

File tree

1 file changed

+4
-7
lines changed

1 file changed

+4
-7
lines changed

contrib/completion/git-completion.bash

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -454,15 +454,12 @@ __git_ls_files_helper ()
454454
# 3: List only paths matching this path component (optional).
455455
__git_index_files ()
456456
{
457-
local root="$2" match="$3" file
457+
local root="$2" match="$3"
458458

459459
__git_ls_files_helper "$root" "$1" "$match" |
460-
while read -r file; do
461-
case "$file" in
462-
?*/*) echo "${file%%/*}" ;;
463-
*) echo "$file" ;;
464-
esac
465-
done | sort | uniq
460+
awk -F / '{
461+
print $1
462+
}' | sort | uniq
466463
}
467464

468465
# __git_complete_index_file requires 1 argument:

0 commit comments

Comments
 (0)