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

时间:2012-07-13 08:41:25

标签: linux git autocomplete alias

如果我运行常规git命令,例如git checkout,我会在点击Tab键时自动完成分支名称。

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

修改

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

ci = commit
co = checkout

它涉及的更多,并使用$1作为参数,例如:

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

2 个答案:

答案 0 :(得分: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 

要获得更持久的解决方案,只需将函数定义添加到bashrc文件即可。例如:

_git_tagarchive() 
{
    _git_branch
}

请注意,我只是重用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

}

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

答案 1 :(得分:4)

2015年7月更新(Git 2.5):在contrib/completion/git-completion.bash中获取git别名更容易。

commit 12bdc88commit e8f9e42SZEDER Gábor (szeder)(2015年5月10日) Junio C Hamano -- gitster --在2015年5月22日commit 935d937合并)

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

Git 2.1中的复杂别名(2014年8月)可以更好地完成Git 请commit 56f24e8

查看Steffen Prohaska (sprohaska)

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

  

'!f() { ... }; f'和“!sh -c '....' -”是用于声明更复杂别名的推荐模式(请参阅git wiki)。
  这个提交教会完成处理它们。

     

当确定用于别名的完成时,现在跳过左括号或单引号,并继续搜索git命令。
  例如,别名“!f() { git commit ... }”或“!sh -c 'git commit ...'”现在会触发提交完成   以前,搜索停止在开头括号或引号上,并尝试完成   它决定了如何完成,这显然是没用的。

     

现在跳过null命令“:”,以便可以将其用作声明所需完成样式的变通方法。

     

例如,别名:

!f() { : git commit ; if ... } f
!sh -c ': git commit; if ...' -
  

现在触发提交完成。

     

Shell函数声明现在可以在parens之前使用或不使用空格,即“!f() ...”和“!f () ...”都可以正常工作。