bash别名中的Git自动完成?

Posted

技术标签:

【中文标题】bash别名中的Git自动完成?【英文标题】:Git autocomplete in bash aliases? 【发布时间】:2012-04-09 18:51:06 【问题描述】:

我使用go 作为git checkout branchname 的简单bash 别名。我想念的是与完整的git checkout branchna... 命令一起使用但不在别名中的自动完成功能。

有没有办法指示 Bash “继承”另一个命令的自动完成“驱动程序”?

【问题讨论】:

复制:unix.stackexchange.com/questions/4219/… How do I get bash completion to work with aliases?的可能重复 相关:如果别名设置了自定义git-dir,则使用this。 @Claudio,您会考虑重新考虑您选择的已接受答案吗?最受好评的答案对我来说似乎更有用(他遇到了与您完全相同的问题) @Brondahl 嘿,谢谢你的建议。我刚刚做到了。 【参考方案1】:

使用complete -F后:

complete -F _git_checkout go

go 之后的 Tab 可能会导致:

bash: [: 1: unary operator expected

__git_complete代替complete

这是 git bash 完成的内置函数。

声明别名后,将正确的自动完成功能绑定到它:

# Main git completions (prior to git 2.30, you an use _git instead of __git_main)
alias g="git"
__git_complete g __git_main

alias go="git checkout"
__git_complete go _git_checkout

alias gp="git push"
__git_complete gp _git_push

【讨论】:

@LưuVĩnhPhúc 我遇到了同样的问题。这是因为我的 bash-completion 包中有__git_complete 函数(通过带有brew install bash-completion 的自制软件安装),目前我的bash 配置文件中没有该函数。必须将此行添加到 ~/.bash_profile: [ -f /usr/local/etc/bash_completion ] && . /usr/local/etc/bash_completion git checkout 别名下添加 __git_complete 就像魅力一样!!! 应该是__git_main,而不是_git_git 存在的原因只是为了向后兼容,它基本上是 __git_main 包装的。 _git 不再适用于 Git 2.30 如果你也想完成分支名称,请看这里levelup.gitconnected.com/…【参考方案2】:

正如其他人回答的那样,您应该使用__git_complete,否则脚本将失败。

alias g="git"
__git_complete g __git_main

alias g="gl"
__git_complete gl _git_log

但是你不应该使用_git 作为主命令,它是__git_main

不幸的是,很多关于完成的信息都被隐藏了,但你可以在我的 fork 的 README 中找到更多信息:git-completion。

【讨论】:

我使用的是_git,它在 Git 2.30 中被删除,破坏了我的完成。这行得通;谢谢!【参考方案3】:

我知道您是在专门询问 bash 别名,但对于那些来这里寻找复杂 git 别名的自动完成 in bash 的人,请参阅 here。

特别是:

# If you use complex aliases of form '!f()  ... ; f', you can use the null
# command ':' as the first command in the function body to declare the desired
# completion style.  For example '!f()  : git commit ; ... ; f' will
# tell the completion to use commit completion.  This also works with aliases
# of form "!sh -c '...'".  For example, "!sh -c ': git commit ; ... '".

【讨论】:

【参考方案4】:

对于macOS,运行以下命令安装 bash 补全

 brew install bash-completion

然后添加以下内容

[[ -r "/usr/local/etc/profile.d/bash_completion.sh" ]] && . "/usr/local/etc/profile.d/bash_completion.sh" 

到您的 .bashrc 或 .bash_profile

【讨论】:

【参考方案5】:

在 Ubuntu 16.04.3 LTS 中,我需要获取的文件是 /usr/share/bash-completion/completions/git。所以在.bash_custom(或.bashrc,随便):

[ -f /usr/share/bash-completion/completions/git ] && . /usr/share/bash-completion/completions/git
__git_complete g __git_main

【讨论】:

需要手动加载的原因是当前 Bash 动态加载这些文件。到目前为止,它会根据它们的名称加载它们。文件在您点击 Git 完成后才会加载,这在读取 .bashrc 时为时已晚。【参考方案6】:

补充其他出色的答案:通常您有很多 Git 别名,手动转发所有别名的完成可能很乏味。这是自动执行此操作的一个小技巧:

if [ -f "/usr/share/bash-completion/completions/git" ]; then
  # Enable Git completions for aliases
  . /usr/share/bash-completion/completions/git
  for a in $(alias | sed -n 's/^alias \(g[^=]*\)=.git .*/\1/p'); do
    c=$(alias $a | sed 's/^[^=]*=.git \([a-z0-9\-]\+\).*/\1/' | tr '-' '_')
    if set | grep -q "^_git_$c *()"; then
      eval "__git_complete $a _git_$c"
    fi
  done
fi

【讨论】:

【参考方案7】:

在 Ubuntu 18.04(仿生)上,以下工作。将类似 sn-p 的内容(使用您的别名)添加到您首选的 bash 配置文件中,例如.bashrc, .bash_aliases .bash_profile.

# define aliases
alias gc='git checkout'
alias gp='git pull'

# setup autocompletion
if [ -f "/usr/share/bash-completion/completions/git" ]; then
  source /usr/share/bash-completion/completions/git
  __git_complete gc _git_checkout
  __git_complete gp _git_pull
else
  echo "Error loading git completions"
fi

一般__git_complete指令的格式如下:

__git_complete <YOUR ALIAS> _git_<GIT COMMAND NAME>

这将现有答案的智慧结合在一个最新的答案中,谢谢大家。

【讨论】:

我只想为仅 ssh/终端的会话添加它,将所有内容放在 .bashrc 中。我在 .bash_profile 中有完整的 git 内容,在 .bashrc 中有别名,但无法正常工作。直到我添加了一个 echo "profile" / echo "rc" 之后,我才发现了这一点。 在 2021 年 8 月仍可在 Ubuntu 20.04 中使用 为什么这不是第一答案?这是一个完整的例子,展示了 __git_complete 的来源......【参考方案8】:

在 Linux Mint 上,这对我不起作用。我收到bash: [: 1: unary operator expected

我发现以下响应效果很好 - 用户提供的故障排除部分非常有帮助。 https://superuser.com/questions/436314/how-can-i-get-bash-to-perform-tab-completion-for-my-aliases

【讨论】:

【参考方案9】:

如果你能找出原始命令使用的补全函数,你可以使用complete -F将其分配给别名。

例如,在我的ubuntu盒子上,git checkout使用的补全函数是_git_checkout(在/etc/bash_complete.d/git中找到)。

示例

运行前complete -F

[me@home]$ git checkout <TAB><TAB>
HEAD            master          origin/HEAD     origin/master

[me@home]$ alias go="git checkout"

[me@home]$$ go <TAB><TAB>
.git/                precommit_config.py  README.md            SvnSentinel/         
.gitignore           precommit.py         startcommit.py       tests/ 

之后:

[me@home]$$ complete -F _git_checkout go

[me@home]$$ go <TAB><TAB>
HEAD            master          origin/HEAD     origin/master 

【讨论】:

在 ubuntu 12.04 上,补全似乎存在于:/etc/bash_completion.d/git 而不是 /etc/bash_complete.d/git 如果complete -F 不适合您,请参阅下面***.com/a/24665529/3779__git_complete 的答案

以上是关于bash别名中的Git自动完成?的主要内容,如果未能解决你的问题,请参考以下文章

别名 g='git' 并且 bash 完成仍然有效 [重复]

mac OS 中的自动完成 git 不起作用?

.sh 文件的 Git bash 选项卡完成

如何让 bash 完成以在 Windows 10 bash 中使用别名?

别名函数的 Git 完成 [重复]

Emacs shell 模式中的 Bash 自动完成