From: Nikolai Weibull <now@bitwi.se>
To: Zsh Workers <zsh-workers@zsh.org>
Subject: Speed improvement patch for __git_files and __git_files_relative
Date: Fri, 6 May 2011 15:03:49 +0200 [thread overview]
Message-ID: <BANLkTimkmU0ExT8duptV2V6_7NHSwANGOQ@mail.gmail.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 477 bytes --]
Hi!
I’ve now put together a patch for __git_files and
__git_files_relative. __git_files is a lot faster than previous
versions and __git_files_relative should be a lot faster too, now that
it only uses substitutions. (Well, there’s a for loop that iterates
over the file names to determine the common path prefix, but I see no
way of avoiding it.)
It would be great if this could make it into the 4.3.12 release, so
please give it a try as soon as possible.
[-- Attachment #2: __git_files.patch --]
[-- Type: application/octet-stream, Size: 4144 bytes --]
diff --git a/Completion/Unix/Command/_git b/Completion/Unix/Command/_git
index 4664cfa..70992de 100644
--- a/Completion/Unix/Command/_git
+++ b/Completion/Unix/Command/_git
@@ -623,7 +623,11 @@ _git-diff () {
case $CURRENT in
(1)
if [[ -n ${opt_args[(I)--]} ]]; then
- __git_changed-in-working-tree_files && ret=0
+ if [[ -n ${opt_args[(I)--cached|--staged]} ]]; then
+ __git_changed-in-index_files && ret=0
+ else
+ __git_changed-in-working-tree_files && ret=0
+ fi
else
local files_alt='files::__git_changed-in-working-tree_files'
@@ -5146,45 +5150,32 @@ __git_notes_refs () {
(( $+functions[__git_files_relative] )) ||
__git_files_relative () {
- local rawfiles files file f_parts prefix p_parts tmp
+ local files file f_parts prefix p_parts tmp
prefix=$(_call_program gitprefix git rev-parse --show-prefix 2>/dev/null)
__git_command_successful $pipestatus || return
- # Empty prefix, no modifications
if (( $#prefix == 0 )); then
print $1
return
fi
- rawfiles=(${(0)1})
files=()
- # Now we assume that we've given "absolute" paths list with "root"
- # being repository top directory. $prefix is also "absolute" path.
- for file in $rawfiles; do
- # Collapse "/./" and "//", strip "/." and "/" from tail (I know,
- # this is a bit paranoid).
- f_parts=(${(s:/:)"${${${${file//\/\///}//\/.\///}%%/.}%%/}"})
- p_parts=(${(s:/:)"${${${${prefix//\/\///}//\/.\///}%%/.}%%/}"})
- tmp=()
-
- # Strip common path prefix.
- while (( $#f_parts > 0 )) && (( $#p_parts > 0 )) && [[ $f_parts[1] == $p_parts[1] ]]; do
- f_parts[1]=()
- p_parts[1]=()
- done
-
- # If prefix still not empty, ascend up.
- while (( $#p_parts > 0 )); do
- tmp+=..
- p_parts[1]=()
+ # Collapse “//” and “/./” into “/”. Strip any remaining “/.” and “/”.
+ for file in ${${${${${(0)1}//\/\///}//\/.\///}%/.}%/}; do
+ integer i n
+ (( n = $#file > $#prefix ? $#file : $#prefix ))
+ for (( i = 1; i <= n; i++ )); do
+ if [[ $file[i] != $prefix[i] ]]; then
+ while (( i > 0 )) && [[ $file[i-1] != / ]]; do
+ (( i-- ))
+ done
+ break
+ fi
done
- # Add remaining path.
- tmp+=($f_parts)
-
- files+=${(j:/:)tmp}
+ files+=${(l@${#prefix[i,-1]//[^\/]}*3@@../@)}${file[i,-1]}
done
print ${(pj:\0:)files}
@@ -5192,27 +5183,25 @@ __git_files_relative () {
(( $+functions[__git_files] )) ||
__git_files () {
- local compadd_opts opts tag description gitdir gitcdup files expl
+ local compadd_opts opts tag description gitcdup gitprefix files expl
zparseopts -D -E -a compadd_opts V: J: 1 2 n f X: M: P: S: r: R: q F:
zparseopts -D -E -a opts -- -cached -deleted -modified -others -ignored -unmerged -killed x+: --exclude+:
tag=$1 description=$2; shift 2
- gitdir=$(_call_program gitdir git rev-parse --git-dir 2>/dev/null)
+ gitcdup=$(_call_program gitcdup git rev-parse --show-cdup 2>/dev/null)
__git_command_successful $pipestatus || return
- gitcdup=$(_call_program gitcdup git rev-parse --show-cdup 2>/dev/null)
+ gitprefix=$(_call_program gitprefix git rev-parse --show-prefix 2>/dev/null)
__git_command_successful $pipestatus || return
- opts+='--exclude-per-directory=.gitignore'
- [[ -f "$gitdir/info/exclude" ]] && opts+="--exclude-from=$gitdir/info/exclude"
+ # TODO: --directory should probably be added to $opts when --others is given.
- files=$(_call_program files git ls-files -z --full-name $opts -- $gitcdup 2>/dev/null)
- __git_command_successful $pipestatus || return
- files=(${(0)"$(__git_files_relative $files)"})
+ local pref=$gitcdup$gitprefix$PREFIX
+ files=(${(0)"$(_call_program files git ls-files -z --exclude-standard $opts -- ${pref:+$pref\*} 2>/dev/null)"})
__git_command_successful $pipestatus || return
- _wanted $tag expl $description _multi_parts $compadd_opts - / files
+ _wanted $tag expl $description _multi_parts -f $compadd_opts - / files
}
(( $+functions[__git_cached_files] )) ||
next reply other threads:[~2011-05-06 13:59 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-05-06 13:03 Nikolai Weibull [this message]
2011-05-11 13:27 ` Frank Terbeck
2011-05-11 13:44 ` Mikael Magnusson
2011-05-11 14:09 ` Completion crash owing to bad allocation Peter Stephenson
2011-05-13 23:26 ` Peter Stephenson
2011-05-14 2:56 ` Bart Schaefer
2011-05-17 12:55 ` Speed improvement patch for __git_files and __git_files_relative Nikolai Weibull
2011-05-17 13:01 ` Frank Terbeck
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=BANLkTimkmU0ExT8duptV2V6_7NHSwANGOQ@mail.gmail.com \
--to=now@bitwi.se \
--cc=zsh-workers@zsh.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/zsh/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).