Git别名 - 分支名称的命令行自动完成

bcm*_*cfc 32 linux git alias autocomplete

如果我运行常规git命令,例如git checkout我在按Tab键时获得有用的分支名称自动完成功能.

我有一些git别名,它们将分支名称作为参数,我想知道是否有办法让分支名称自动完成与它们一起工作?

编辑:

只是为了从评论中的讨论中提供一些澄清,具有直接映射的别名工作正常,即:

ci = commit
co = checkout
Run Code Online (Sandbox Code Playgroud)

它涉及的更多,并且$1用作不参与的参数,例如:

tagarchive = !f() { git tag archive/$1 origin/$1 && git push origin :$1 && git push origin archive/$1 && git branch -d $1; }; f
Run Code Online (Sandbox Code Playgroud)

Sha*_*hin 32

对于git别名,git命令(__git())的自动完成功能使用调用git config --get "alias.$1"来确定等效的自动完成功能.这适用于简单的映射,但会阻塞更复杂的别名.

要解决此问题,请定义一个名称与您的别名匹配的自动完成功能,即_git_tagarchive().git的自动完成功能应该选择它并将其用于自动完成.

例如:

[me@home]$ git tagarchive <TAB><TAB>
AUTHORS             gentleSelect/       .gitignore          LICENSE             test_multiple.html  
cron/               .git/               index.html          README.md  
[me@home]$ _git_tagarchive() {
> _git_branch  # reuse that of git branch
> }
[me@home]$ git tagarchive  <TAB><TAB>
enable_multiple          master                   origin/gh-pages          v0.1                     v0.1.3 
FETCH_HEAD               ORIG_HEAD                origin/HEAD              v0.1.1                   v0.1.3.1 
HEAD                     origin/enable_multiple   origin/master            v0.1.2 
Run Code Online (Sandbox Code Playgroud)

要获得更永久的解决方案,只需将函数定义添加到您的bashrc文件中.例如:

_git_tagarchive() 
{
    _git_branch
}
Run Code Online (Sandbox Code Playgroud)

请注意,我只是重复使用自动完成功能git branch; 您可能希望将其更改为更合适的内容或编写自己的内容.

更多信息

该解决方案是基于对的探索而确定的/etc/bash_completion.d/git.

通常,别名git命令由__git_aliased_commands()解析输出的函数处理,git config --get "alias.$1"以决定要使用的自动完成函数.使用更复杂的shell命令作为别名目标可以理解地阻止这种方法.

进一步看,_git()在子命令的自动完成功能中,git()链的自动完成功能通过简单的前置函数_git_(-在命令中使用短划线()替换为下划线).这是在__git_aliased_command()检查之前完成的,所以这是我们可以使用的.

_git ()
{ 
   # .....
   local completion_func="_git_${command//-/_}"
   declare -f $completion_func >/dev/null && $completion_func && return

   local expansion=$(__git_aliased_command "$command")
   if [ -n "$expansion" ]; then
       completion_func="_git_${expansion//-/_}"
       declare -f $completion_func >/dev/null && $completion_func
   fi

}
Run Code Online (Sandbox Code Playgroud)

因此,我所采用的方法是确保存在与您的别名匹配的函数,即_git_tagarchive().


Von*_*onC 5

2015 年 7 月更新(Git 2.5):在contrib/completion/git-completion.bash.

\n\n

请参阅提交 12bdc88提交 e8f9e42(2015 年 5 月 10 日),作者:SZEDER G\xc3\xa1bor ( szeder)
\n (由Junio C Hamano 合并 -- gitster--提交 935d937中,2015 年 5 月 22 日)

\n\n

~~~~~~~~~~~~~~~

\n\n

Git 补全应该可以更好地处理 Git 2.1(2014 年 8 月)中的复杂别名。
\n请参阅Steffen Prohaska提交 56f24e8 ( )sprohaska

\n\n

完成:处理 \' !f() { ... }; f\' 和 " !sh -c \'...\' -" 别名

\n\n
\n

\' !f() { ... }; f\' 和 " !sh -c \'....\' -" 是声明更复杂别名的推荐模式(请参阅git wiki)。
\n 此提交教导完成处理它们。

\n\n

当确定别名使用哪个补全时,现在会跳过左大括号或单引号,并继续搜索 git 命令。
\n 例如,别名 \' !f() { git commit ... }\' 或 " !sh -c \'git commit ...\'" 现在会触发提交完成。
\n 以前,搜索在左大括号或引号处停止,补全尝试\n 确定如何补全,这显然是无用的。

\n\n

命令null\' :\' 现在已被跳过,因此可以将其用作声明所需完成样式的解决方法。

\n\n

例如,别名:

\n
\n\n
!f() { : git commit ; if ... } f\n!sh -c \': git commit; if ...\' -\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n

现在触发提交完成。

\n\n

Shell 函数声明现在可以在括号前使用或不使用空格,即 \' !f() ...\' 和 \' !f () ...\' 都可以使用。

\n
\n