繁体   English   中英

如果在.bash_profile中使用别名,如何启用git命令自动完成功能?

[英]How to enable auto-completion of git commands if you are using aliases in .bash_profile?

我在.bash_profile中具有git别名,并希望在使用这些命令时启用自动完成功能(例如:自动完成分支名称)。 如果我使用完整的git命令,这对我有用,但是当我使用别名时,它不起作用。

我听说,如果您使用通过.gitconfig配置的别名,则可能会自动完成,但是这些别名会强制使用git,而我在.bash_profile中配置的别名将“ git”替换为“ g”,这更加方便。

各种命令的bash bash_completions通常位于bash_completions软件包中,或者随各个命令提供。 安装它们的位置在某种程度上取决于操作系统,在Ubuntu中,它们收集在各个位置,从/etc/bash_completion 该脚本源自全局bash.bashrc ,最终bash.bashrc了各种其他脚本,这些脚本定义了各种命令的完成方式。 最终,它们都调用complete命令来定义何时调用什么完成。

git的完成内容(再次在Ubuntu中,位置可能有所不同)被安装到/usr/share/bash-completion/completions/git 该文件来自git源存储库,并定义了用于完成单个命令的函数,最终定义了一个__git_complete函数,该函数接受一个命令,并使用一个完成函数并安装该命令的完成:

__git_complete git __git_main

上面为git添加了完成功能,以调用__git_main (也在该文件中定义)。 由于所有补全都是源代码,因此使用的函数在您的Shell中都可用,因此您可以使用同一调用将git补全添加到别名中:

__git_complete g __git_main

如果您的别名改用某个git子命令,请使用该文件中定义的各种子命令补全之一。 如果您使用别名ga表示git add ,则可以使用_git_add来代替:

__git_complete ga _git_add

请注意, __git_complete函数(可能是该文件中的所有函数)是私有的,不能直接使用。 该功能带有相应的警告标记:

这不是公共功能。 使用风险自负。

从根本bash_completions ,这意味着更新git和/或bash_completions可能会更改完成文件以及上述函数的命名方式和工作方式,这可能会破坏您的设置。 因此,只有准备好经常重做该设置时,才应使用以上内容。

还要注意,您可能必须从.bashrc.profile显式获取该git完成文件,以使这些功能可用:

source /usr/share/bash-completion/completions/git

特别案例

某些git补全实际上会检查当前命令行以确定下一步要完成什么。 可以完成远程控制或引用规范的任何示例,例如,获取,拉取,远程和推送。 在这种情况下,仅用相应的函数来完成别名是不够的,因为别名将隐藏实际的git命令,因此完成操作将不知道如何进行。 以评论为例:

$ alias gpr='git pull --rebase'
$ __git_complete gpr _git_pull
$ gpr o[TAB]
$ gpr origin m[TAB]
$ gpr origin m

在这种情况下,远程(在这种情况下为原点)仍然可以完成,但是refspec无法完成。 这是由于命令行上缺少“拉”命令。

这种情况无法完全解决,但是可以构建需要额外选项卡的解决方法。 定义了包装器函数,而不是直接钩接到git补全中,它首先使用所需的命令行扩展别名,然后继续进行进一步的补全:

function _gpr {
    if [ $COMP_CWORD = 1 ]
    then
        COMPREPLY=('pull --rebase ')
        return 0
    fi

    __git_func_wrap __git_main
}

包装函数检查当前单词是否为第一个单词,在这种情况下,将COMPREPLY变量设置为所需的命令行扩展(有关详细信息,请参阅文档以了解编程完成信息)。 请注意最后需要的额外空间,因为该功能将使用nospace选项安装,以防止自动插入空格。

然后将包装函数安装为所需别名的完成:

complete -o bashdefault -o default -o nospace -F _gpr gpr

-F _gpr参数指定要调用的包装器函数,最后一个参数( gpr )指定要完成的命令(有关其他选项,请参见完整内置文件的完整文档 )。

完成包装程序后,以上会话现在变为:

$ gpr [TAB]
$ gpr pull --rebase o[TAB]
$ gpr pull --rebase origin m[TAB]
$ gpr pull --rebase origin master

在别名之后需要一个额外的选项卡,以首先扩展到所需的命令行,该命令行先前已完全隐藏在别名中。 从那里开始,完成工作按预期进行。

请注意,由于所需的命令行现在已成为实际命令行的一部分,因此别名应仅指向git而不是git pull --rebase 这也是包装函数始终将完成传递给__git_main而不是单个子命令完成的原因。 别名定义变为:

alias gpr=git

合并的shell和git别名

上述特殊情况的一个不错的替代方法是将shell和git别名组合在一起。 git补全会扩展git别名(即,使用git config alias.<name> '<command>'创建的git config alias.<name> '<command>' ),以用于补全。 为实际命令配置git别名:

$ git config --global alias.pr 'pull --rebase'

然后为git安装一个简写的shell别名:

$ alias g=git

并使用原始方法将其连接到__git_main完成:

$ __git_complete g __git_main

允许此会话:

$ g pr o[TAB]
$ g pr origin m[TAB]
$ g pr origin master

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM