<feed xmlns='http://www.w3.org/2005/Atom'>
<title>git/contrib/completion/git-completion.zsh, branch v2.21.3</title>
<subtitle>Mirror of https://git.kernel.org/pub/scm/git/git.git/
</subtitle>
<id>https://git.shady.money/git/atom?h=v2.21.3</id>
<link rel='self' href='https://git.shady.money/git/atom?h=v2.21.3'/>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/'/>
<updated>2019-01-03T19:48:13Z</updated>
<entry>
<title>zsh: complete unquoted paths with spaces correctly</title>
<updated>2019-01-03T19:48:13Z</updated>
<author>
<name>Chayoung You</name>
<email>yousbe@gmail.com</email>
</author>
<published>2019-01-01T14:05:08Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=7a478b36aa1f202aed207a230def66563227f30e'/>
<id>urn:sha1:7a478b36aa1f202aed207a230def66563227f30e</id>
<content type='text'>
The following is the description of -Q flag of zsh compadd [1]:

    This flag instructs the completion code not to quote any
    metacharacters in the words when inserting them into the command
    line.

Let's say there is a file named 'foo bar.txt' in repository, but it's
not yet added to the repository. Then the following command triggers a
completion:

    git add fo&lt;Tab&gt;
    git add 'fo&lt;Tab&gt;
    git add "fo&lt;Tab&gt;

The completion results in bash:

    git add foo\ bar.txt
    git add 'foo bar.txt'
    git add "foo bar.txt"

While them in zsh:

    git add foo bar.txt
    git add 'foo bar.txt'
    git add "foo bar.txt"

The first one, where the pathname is not enclosed in quotes, should
escape the space with a backslash, just like bash completion does.
Otherwise, this leads git to think there are two files; foo, and
bar.txt.

The main cause of this behavior is __gitcomp_file_direct(). The both
implementions of bash and zsh are called with an argument 'foo bar.txt',
but only bash adds a backslash before a space on command line.

[1]: http://zsh.sourceforge.net/Doc/Release/Completion-Widgets.html

Signed-off-by: Chayoung You &lt;yousbe@gmail.com&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>Merge branch 'sg/completion-zsh-workaround'</title>
<updated>2018-06-13T19:50:45Z</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2018-06-13T19:50:45Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=4d605b0f38775066be0eaed33c52e0b716035498'/>
<id>urn:sha1:4d605b0f38775066be0eaed33c52e0b716035498</id>
<content type='text'>
Work around zsh segfaulting when loading git-completion.zsh

* sg/completion-zsh-workaround:
  completion: correct zsh detection when run from git-completion.zsh
</content>
</entry>
<entry>
<title>completion: correct zsh detection when run from git-completion.zsh</title>
<updated>2018-06-12T17:13:44Z</updated>
<author>
<name>SZEDER Gábor</name>
<email>szeder.dev@gmail.com</email>
</author>
<published>2018-06-11T18:20:53Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=61d48c66ea7ef8acc0dd1114e0f79f4250aead38'/>
<id>urn:sha1:61d48c66ea7ef8acc0dd1114e0f79f4250aead38</id>
<content type='text'>
v2.18.0-rc0~90^2 (completion: reduce overhead of clearing cached
--options, 2018-04-18) worked around a bug in bash's "set" builtin on
MacOS by using compgen instead.  It was careful to avoid breaking zsh
by guarding this workaround with

	if [[ -n ${ZSH_VERSION-}} ]]

Alas, this interacts poorly with git-completion.zsh's bash emulation:

	ZSH_VERSION='' . "$script"

Correct it by instead using a new GIT_SOURCING_ZSH_COMPLETION shell
variable to detect whether git-completion.bash is being sourced from
git-completion.zsh.  This way, the zsh variant is used both when run
from zsh directly and when run via git-completion.zsh.

Reproduction recipe:

 1. cd git/contrib/completion &amp;&amp; cp git-completion.zsh _git
 2. Put the following in a new ~/.zshrc file:

 	autoload -U compinit; compinit
	autoload -U bashcompinit; bashcompinit
	fpath=(~/src/git/contrib/completion $fpath)

 3. Open zsh and "git &lt;TAB&gt;".

With this patch:
Triggers nice git-completion.bash based tab completion

Without:
 contrib/completion/git-completion.bash:354: read-only variable: QISUFFIX
 zsh:12: command not found: ___main
 zsh:15: _default: function definition file not found
 _dispatch:70: bad math expression: operand expected at `/usr/bin/g...'
 Segmentation fault

Reported-by: Rick van Hattem &lt;wolph@wol.ph&gt;
Reported-by: Dave Borowitz &lt;dborowitz@google.com&gt;
Signed-off-by: SZEDER Gábor &lt;szeder.dev@gmail.com&gt;
Signed-off-by: Jonathan Nieder &lt;jrnieder@gmail.com&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>completion: fill COMPREPLY directly when completing paths</title>
<updated>2018-04-17T03:49:37Z</updated>
<author>
<name>SZEDER Gábor</name>
<email>szeder.dev@gmail.com</email>
</author>
<published>2018-04-16T22:42:36Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=7b0034206843c38dc96e700a527e06b88ac35d69'/>
<id>urn:sha1:7b0034206843c38dc96e700a527e06b88ac35d69</id>
<content type='text'>
During git-aware path completion, when a lot of path components have
to be listed, a significant amount of time is spent in
__gitcomp_file(), or more accurately in the shell loop of
__gitcompappend(), iterating over all the path components filtering
path components matching the current word to be completed, adding
prefix path components, and placing the resulting matching paths into
the COMPREPLY array.

Now, a previous patch in this series made 'git ls-files' and 'git
diff-index' list only paths matching the current word to be completed,
so an additional filtering in __gitcomp_file() is not necessary
anymore.  Adding the prefix path components could be done much more
efficiently in __git_index_files()'s 'awk' script while stripping
trailing path components and removing duplicates and quoting.  And
then the resulting paths won't require any more filtering or
processing before being handed over to Bash, so we could fill the
COMPREPLY array directly.

Unfortunately, we can't simply use the __gitcomp_direct() helper
function to do that, because __gitcomp_file() does one additional
thing: it tells Bash that we are doing filename completion, so the
shell will kindly do four important things for us:

  1. Append a trailing space to all filenames.
  2. Append a trailing '/' to all directory names.
  3. Escape any meta, globbing, separator, etc. characters.
  4. List only the current path component when listing possible
     completions (i.e. 'dir/subdir/f&lt;TAB&gt;' will list 'file1', 'file2',
     etc. instead of the whole 'dir/subdir/file1',
     'dir/subdir/file2').

While we could let __git_index_files()'s 'awk' script take care of the
first two points, the third one gets tricky, and we absolutely need
the shell's support for the fourth.

Add the helper function __gitcomp_file_direct(), which, just like
__gitcomp_direct(), fills the COMPREPLY array with prefiltered and
preprocessed paths without any additional processing, without a shell
loop, with just one single compound assignment, and, similar to
__gitcomp_file(), tells Bash and ZSH that we are doing filename
completion.  Extend __git_index_files()'s 'awk' script a bit to
prepend any prefix path components to all listed paths.  Finally,
modify __git_complete_index_file() to feed __git_index_files()'s
output to ___gitcomp_file_direct() instead of __gitcomp_file().

After this patch there is no shell loop left in the path completion
code path.

This speeds up path completion when there are a lot of paths matching
the current word to be completed.  In a pathological repository with
100k files in a single directory, listing all those files:

  Before this patch, best of five, using GNU awk on Linux:

    $ time cur=dir/ __git_complete_index_file

    real    0m0.983s
    user    0m1.004s
    sys     0m0.033s

  After:

    real    0m0.313s
    user    0m0.341s
    sys     0m0.029s

  Difference: -68.2%
  Speedup:      3.1x

  To see the benefits of the whole patch series, the same command with
  v2.17.0:

    real    0m2.736s
    user    0m2.472s
    sys     0m0.610s

  Difference: -88.6%
  Speedup:      8.7x

Note that this patch changes the output of the __git_index_files()
helper function by unconditionally prepending the prefix path
components to every listed path.  This would break users' completion
scriptlets that directly run:

  __gitcomp_file "$(__git_index_files ...)" "$pfx" "$cur_"

because that would add the prefix path components once more.
However, __git_index_files() is kind of a "helper function of a helper
function", and users' completion scriptlets should have been using
__git_complete_index_file() for git-aware path completion in the first
place, so this is likely doesn't worth worrying about.

Signed-off-by: SZEDER Gábor &lt;szeder.dev@gmail.com&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>completion: fill COMPREPLY directly when completing refs</title>
<updated>2017-03-23T18:18:22Z</updated>
<author>
<name>SZEDER Gábor</name>
<email>szeder.dev@gmail.com</email>
</author>
<published>2017-03-23T15:29:22Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=fef56eb0063dcf61796bf812ba980c99ce85f6b0'/>
<id>urn:sha1:fef56eb0063dcf61796bf812ba980c99ce85f6b0</id>
<content type='text'>
__gitcomp_nl() iterates over all the possible completion words it gets
as argument

  - filtering matching words,
  - appending a trailing space to each matching word (in all but two
    cases),
  - prepending a prefix to each matching word (when completing words
    after e.g. '--option=&lt;TAB&gt;' or 'master..&lt;TAB&gt;'), and
  - adding each matching word to the COMPREPLY array.

This takes a while when a lot of refs are passed to __gitcomp_nl().

The previous changes in this series ensure that __git_refs() lists
only refs matching the current word to be completed, making a second
filtering in __gitcomp_nl() redundant.

Adding the necessary prefix and suffix could be done in __git_refs()
as well:

  - When refs come from 'git for-each-ref', then that prefix and
    suffix could be added much more efficiently using a 'git
    for-each-ref' format containing said prefix and suffix.  Care
    should be taken, though, because that prefix might contain
    'for-each-ref' format specifiers as part of the left hand side of
    a '..' range or '...' symmetric difference notation or
    fetch/push/etc. refspec, e.g. 'git log "evil-%(refname)..br&lt;TAB&gt;'.
    Doubling every '%' in the prefix will prevent 'git for-each-ref'
    from interpolating any of those contained specifiers.
  - When refs come from 'git ls-remote', then that prefix and suffix
    can be added in the shell loop that has to process 'git
    ls-remote's output anyway.
  - Finally, the prefix and suffix can be added to that handful of
    potentially matching symbolic and pseudo refs right away in the
    shell loop listing them.

And then all what is still left to do is to assign a bunch of
newline-separated words to a shell array, which can be done without a
shell loop iterating over each word, basically making all of
__gitcomp_nl() unnecessary for refs completion.

Add the helper function __gitcomp_direct() to fill the COMPREPLY array
with prefiltered and preprocessed words without any additional
processing, without a shell loop, with just one single compound
assignment.  Modify __git_refs() to accept prefix and suffix
parameters and add them to each and every listed ref as described
above.  Modify __git_complete_refs() to pass the prefix and suffix
parameters to __git_refs() and to feed __git_refs()'s output to
__gitcomp_direct() instead of __gitcomp_nl().

This speeds up refs completion when there are a lot of refs matching
the current word to be completed.  Listing all branches for completion
in a repo with 100k local branches, all packed, best of five:

  On Linux, near the beginning of this series, for reference:

    $ time __git_complete_refs

    real    0m2.028s
    user    0m1.692s
    sys     0m0.344s

  Before this patch:

    real    0m1.135s
    user    0m1.112s
    sys     0m0.024s

  After:

    real    0m0.367s
    user    0m0.352s
    sys     0m0.020s

  On Windows, near the beginning:

    real    0m13.078s
    user    0m1.609s
    sys     0m0.060s

  Before this patch:

    real    0m2.093s
    user    0m1.641s
    sys     0m0.060s

  After:

    real    0m0.683s
    user    0m0.203s
    sys     0m0.076s

Signed-off-by: SZEDER Gábor &lt;szeder.dev@gmail.com&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>Merge branch 'pd/completion-filenames-fix'</title>
<updated>2015-01-07T21:06:37Z</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2015-01-07T21:06:36Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=e82f629cf40795e7780329f056fc3df2d6adc97b'/>
<id>urn:sha1:e82f629cf40795e7780329f056fc3df2d6adc97b</id>
<content type='text'>
The top-of-the-file instruction for completion scripts (in contrib/)
did not name the files correctly.

* pd/completion-filenames-fix:
  Update documentation occurrences of filename .sh
</content>
</entry>
<entry>
<title>Update documentation occurrences of filename .sh</title>
<updated>2014-12-15T17:37:14Z</updated>
<author>
<name>Peter van der Does</name>
<email>peter@avirtualhome.com</email>
</author>
<published>2014-12-15T14:34:28Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=0e5ed7cca3c51c821c2bb0465617e75d994f432f'/>
<id>urn:sha1:0e5ed7cca3c51c821c2bb0465617e75d994f432f</id>
<content type='text'>
Documentation in the completion scripts for Bash and Zsh state the wrong filenames.

Signed-off-by: Peter van der Does &lt;peter@avirtualhome.com&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>completion: fix completing args of aliased "push", "fetch", etc.</title>
<updated>2014-04-09T21:22:18Z</updated>
<author>
<name>Felipe Contreras</name>
<email>felipe.contreras@gmail.com</email>
</author>
<published>2014-04-09T18:50:04Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=880111c11befaaf070e8ea1021bf11b4fb58c461'/>
<id>urn:sha1:880111c11befaaf070e8ea1021bf11b4fb58c461</id>
<content type='text'>
Some commands need the first word to determine the actual action that is
being executed, however, the command is wrong when we use an alias, for
example 'alias.p=push', if we try to complete 'git p origin ', the
result would be wrong because __git_complete_remote_or_refspec() doesn't
know where it came from.

So let's override words[1], so the alias 'p' is override by the actual
command, 'push'.

Reported-by: Aymeric Beaumet &lt;aymeric.beaumet@gmail.com&gt;
Signed-off-by: Felipe Contreras &lt;felipe.contreras@gmail.com&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>completion: introduce __gitcomp_nl_append ()</title>
<updated>2014-01-06T17:14:48Z</updated>
<author>
<name>Ramkumar Ramachandra</name>
<email>artagnon@gmail.com</email>
</author>
<published>2014-01-05T10:18:03Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=f33c2c0f9e2258a80e6e406af39e9fa3fd6e430e'/>
<id>urn:sha1:f33c2c0f9e2258a80e6e406af39e9fa3fd6e430e</id>
<content type='text'>
There are situations where multiple classes of completions possible. For
example

  branch.&lt;TAB&gt;

should try to complete

  branch.master.
  branch.autosetupmerge
  branch.autosetuprebase

The first candidate has the suffix ".", and the second/ third candidates
have the suffix " ". To facilitate completions of this kind, create a
variation of __gitcomp_nl () that appends to the existing list of
completion candidates, COMPREPLY.

Signed-off-by: Ramkumar Ramachandra &lt;artagnon@gmail.com&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>zsh completion: find matching custom bash completion</title>
<updated>2014-01-06T17:14:29Z</updated>
<author>
<name>Ramkumar Ramachandra</name>
<email>artagnon@gmail.com</email>
</author>
<published>2014-01-05T10:18:02Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=d028b8906afb5b8c24c9449f26e5f930750d8df7'/>
<id>urn:sha1:d028b8906afb5b8c24c9449f26e5f930750d8df7</id>
<content type='text'>
If zsh completion is being read from a location that is different from
system-wide default, it is likely that the user is trying to use a
custom version, perhaps closer to the bleeding edge, installed in her
own directory. We will more likely to find the matching bash completion
script in the same directory than in those system default places.

Signed-off-by: Ramkumar Ramachandra &lt;artagnon@gmail.com&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
</feed>
