Por que você não deve assumir
Durante muito tempo, presumi que a conclusão do git na minha configuração de zsh vinha de /usr/local/share/git-core/contrib/completion/
, especificamente de git-completion.zsh
ou mesmo git-completion.bash
. Eu acho que eu estava assumindo isso porque a maioria das pesquisas irá produzir resultados falando sobre esses arquivos. No entanto, não incluí explicitamente nenhum desses arquivos e, por mais tempo, estava apenas supondo que o oh-my-zsh os estava incluindo.
Mas ...
Não estamos mais no Kansas
Não foi até eu usar o rastreamento do método zsh, ativado via setopt xtrace
, que percebi (pesquisando alguns nomes de método) que o script sendo usado era, de fato, /usr/local/share/zsh/functions/_git
. Eu tinha usado anteriormente XCode Instruments.app para monitorar quais scripts estavam sendo acessados no sistema de arquivos, mas não os identificaram (a saída é bastante tagarela e também mostra acessos de outros aplicativos).
O que está acontecendo?
Os traços mostraram isso (traços parciais à frente!)
git reset HEAD <TAB>
...
+__git_tree_files:17> tree=HEAD
+__git_tree_files:18> tree_files+=+__git_tree_files:18> _call_program tree-files git ls-tree --name-only -z HEAD ./
+__git_tree_files:18> tree_files+=( first second third )
e
git reset HEAD^ <TAB>
...
+__git_tree_files:17> tree=HEAD^
+__git_tree_files:18> tree_files+=+__git_tree_files:18> _call_program tree-files git ls-tree --name-only -z 'HEAD^' ./
+__git_tree_files:18> tree_files+=( )
Esse vazio tree_files
parece suspeito.
Na linha 6058 em /usr/local/share/zsh/functions/_git
, encontramos
tree_files+=(${(ps:tree_files+=(${(ps:git reset HEAD <TAB>
...
+__git_tree_files:17> tree=HEAD
+__git_tree_files:18> tree_files+=+__git_tree_files:18> _call_program tree-files git ls-tree --name-only -z HEAD ./
+__git_tree_files:18> tree_files+=( first second third )
:)"$(_call_program tree-files git ls-tree $extra_args --name-only -z ${(q)tree} $Path 2>/dev/null)"})
:)"$(_call_program tree-files git ls-tree $extra_args --name-only -z $tree $Path 2>/dev/null)"})
Definitivamente precisamos escapar dessa variável $tree
. Dito e feito:
git reset HEAD^ <TAB>
...
+__git_tree_files:17> tree=HEAD^
+__git_tree_files:18> tree_files+=+__git_tree_files:18> _call_program tree-files git ls-tree --name-only -z 'HEAD^' ./
+__git_tree_files:18> tree_files+=( )
Epílogo
Existem mais alguns bugs neste script (por exemplo, a lista de arquivos de git reset <tree-ish>
é baseada no <tree-ish>
, quando deveria ser baseado no HEAD. Agora eu sei onde corrigi-los!
Atualizar
Existe também a possibilidade de executar os scripts de conclusão do git. Você pode fazer isso seguindo esta resposta .