在Git Bash中禁用远程分支的自动完成?

时间:2011-07-08 11:15:01

标签: windows git

我正在开发一个相当大的git repo,有几千个(远程)分支。我习惯在控制台中使用自动完成(使用[TAB])(在这种情况下使用Git Bash),所以我也无意识地为git命令执行此操作。

e.g。我打字

git checkout task[TAB]

效果是控制台经常停顿几分钟。有没有办法只限制自动完成到本地分支?

9 个答案:

答案 0 :(得分:25)

我假设您使用的是git-completion.bash脚本,并且关心git checkout

为实现这一目标,我只更改了_git_checkout ()git-completion.bash函数定义中的一行:

<       __gitcomp_nl "$(__git_refs '' $track)"
---
>       __gitcomp_nl "$(__git_heads '' $track)"

我的理解是,这只会影响制表符完成操作(因为它位于switch-case语句的*内)。

答案 1 :(得分:17)

使用Git 2.13(2017年第二季度),您可以禁用(部分)分支完成。

git checkout --no-guess ...
# or:
export GIT_COMPLETION_CHECKOUT_NO_GUESS=1

commit 60e71bbJeff King (peff)(2017年4月21日) Junio C Hamano -- gitster --于2017年5月1日commit b439747合并)

正如contrib/completion/git-completion.bash中记载的那样:

  

您可以设置以下环境变量来影响完成例程的行为:

GIT_COMPLETION_CHECKOUT_NO_GUESS
     

设置为&#34; 1&#34;时,不要包含&#34; DWIM&#34; git-checkout中的建议    完成(例如,完成&#34; foo&#34;当&#34; origin / foo&#34;存在时)。

注意:DWIM is short for Do What I Mean,系统试图预测用户打算做什么,自动纠正琐碎错误,而不是盲目地执行用户&#39;明确但可能不正确的输入。

  

completion:可选择禁用结帐DWIM

     

当我们完成&#34; git checkout&#34;的分支名称时,我们还会完成可能触发DWIM行为的远程分支名称。根据您的工作流程和项目,这可能既方便又烦人。

     

例如,我的gitster.git克隆包含74个本地&#34; jk/*&#34;分支,但原产地包含另一个147.   当我想要签出本地分支但不能完全记住名称时,选项卡完成显示251个条目。更糟糕的是,对于已经为pu获取的主题,上游分支名称可能与我的相似,导致我选择错误的并且意外地创建新分支的概率很高。

注意:&#34;选择了pu&#34;:看到What's cooking in git.git:它始于:

  

提交前缀为&#39; -&#39;仅限于&#39; pu&#39; (建议更新),同时提交前缀为&#39; +&#39;在&#39; next&#39;。

这是Git Workflow Graduation process

的一部分
  

pu(建议的更新)是一个集成分支,用于尚未准备好包含的内容

  

此补丁为用户添加了一种告知完成的方法   代码不包括用于结帐的DWIM建议   这可以通过键入:

来完成
git checkout --no-guess jk/<TAB>
     

但这很麻烦。

     

当然,缺点是当 想要调用DWIM行为时,您不再获得完成支持。
  但是根据你的工作流程,这可能不是一个很大的损失(例如,在git.git中我更有可能想要分离,所以我输入&#34; git checkout origin/jk/<TAB>&#34 ;无论如何)。

答案 2 :(得分:10)

你可以破解/etc/bash_completion.d/git

您需要修改__git_refs ()

请注意,行为的更改将适用于所有位置(即使使用git push / pull,您也可能不希望这样做)。你当然可以复制一下这个函数或传递一个额外的参数,但我把它留给你

答案 3 :(得分:8)

如果您通过自制程序安装了git-completion,它位于: /usr/local/etc/bash_completion.d/git-completion.bash

在上面erik.weathers' answer之后,我做了以下更改,因此自动完成功能可以根据当前前缀为本地和远程工作。默认情况下,它只会搜索本地,但如果我指定origin/…,它就会知道我也想搜索远程分支。

_git_checkout ()方法中,更改

    __gitcomp_nl "$(__git_refs '' $track)"

为:

    # only search local branches instead of remote branches if origin isn't specified
    if [[ $cur == "origin/"* ]]; then
        __gitcomp_nl "$(__git_refs '' $track)"
    else
        __gitcomp_nl "$(__git_heads '' $track)"
    fi

当然,您可以将origin更改为其他内容,或者如果您的远程前缀超过1,则可以通过远程前缀列表进行搜索。

答案 4 :(得分:4)

您可以认为只有具有别名co的本地分支以及具有完整命令checkout的所有分支。

您可以执行以下操作。在.bashrc中,重新定义_git_checkout()函数。除了结束之外,你让这个函数保持不变:

if [ $command -eq "co" ]; then
  __gitcomp "$(__git_refs_local '' $track)"
else
  __gitcomp "$(__git_refs '' $track)"
fi

然后,您只需要定义一个新函数__git_refs_local,删除远程资料。

答案 5 :(得分:3)

Carey Metcalfe撰写了a blog post,其中包含一个解决方案,该解决方案还可以编辑自动完成功能,但是其代码比其他答案要新一些。他还定义了一个别名checkoutr,可以保留旧的自动完成行为,以备不时之需。

简而言之,首先使用以下命令创建checkoutr别名:

git config --global alias.checkoutr checkout

然后找到git-completion.bash,将_git_checkout函数复制到您的Shell的RC文件中,以便对其进行重新定义,然后在该函数中替换以下行:

__git_complete_refs $track_opt

包含以下几行:

if [ "$command" = "checkoutr" ]; then
    __git_complete_refs $track_opt
else
    __gitcomp_direct "$(__git_heads "" "$cur" " ")"
fi

有关更多详细信息和可能的代码更新,请参见the blog post

答案 6 :(得分:2)

修改# SAFE: Quotes only the expansion echo name="$name" 并不是一个好主意,因为每次通过Homebrew更新Git时都会覆盖它。

结合所有答案,我在获取完成文件后,仅在# BUGGY: Runs expansion unquoted; can remove characters in IFS, expand globs, etc echo "name="$name 的完成文件中覆盖$(brew --prefix)/etc/bash_completion.d/git-completion.bash函数:

_git_checkout

答案 7 :(得分:0)

我自己没有使用Git Bash,但如果这与上面提到的相同 http://tekrat.com/2008/04/30/bash-autocompletion-git-super-lazy-goodness/,你应该能够用

中的普通 git branch 替换git branch -a
_complete_git() {
  if [ -d .git ]; then
    branches=`git branch -a | cut -c 3-`
    tags=`git tag`
    cur="${COMP_WORDS[COMP_CWORD]}"
    COMPREPLY=( $(compgen -W "${branches} ${tags}" -- ${cur}) )
  fi
}
complete -F _complete_git git checkout

(在你的.profile或类似内容中)得到你想要的东西。

答案 8 :(得分:0)

FWW是__git_complete_refs的一个技巧,

__git_complete_refs ()

{     本地远程跟踪pfx cur _ =“ $ cur” sfx =“”

while test $# != 0; do
    case "$1" in
    --remote=*) remote="${1##--remote=}" ;;
    --track)    track="yes" ;;
    --pfx=*)    pfx="${1##--pfx=}" ;;
    --cur=*)    cur_="${1##--cur=}" ;;
    --sfx=*)    sfx="${1##--sfx=}" ;;
    *)      return 1 ;;
    esac
    shift
done
echo cur_ $cur_ > a
 if [[  $GIT_COMPLETION_CHECKOUT_NO_GUESS != 1 || $cur_ == "origin"* ]]; then
    __gitcomp_direct "$(__git_refs "$remote" "$track" "$pfx" "$cur_" "$sfx")"
  else
    __gitcomp_direct "$(__git_heads  "" "$cur_")"
  fi

}