为什么我的git完成分支不起作用?

时间:2015-06-08 09:59:02

标签: git bash completion

我正在尝试实现我自己的git-extras版本' git delete-branch

#!/usr/bin/env bash

# Assert there is at least one branch provided
test -z $1 && echo "branch required." 1>&2 && exit 1

for branch in "$@"
do
  remote=$(git config branch.$branch.remote)
  test -z $remote && remote="origin"
  ref=$(git config branch.$branch.merge)
  test -z $ref && ref="refs/heads/$branch"

  git branch -D $branch
  git branch -d -r $remote/$branch
  git push $remote :$ref
done

从这里开始:https://github.com/tj/git-extras/blob/master/bin/git-delete-branch

当然,如果我们不能用它来完成分支,那就没那么有意义了,这个代码用这个代码表示:

_git_delete_branch(){
    __gitcomp "$(__git_heads)"
}

从这里开始:https://github.com/tj/git-extras/blob/master#L_51/etc/bash_completion.sh

安装git-extras以尝试该代码后,它工作得很好,但正如我在问题中所述,我想实现自己的方式,因为我想检查分支是否集成在{{1删除之前。

由于我不想将我的脚本放在stable文件夹中,所以我创建了这个脚本:

#!/斌/庆典

bash_completion.d

_delete_git_branch(){ __gitcomp "$(__git_heads)" } complete -o bashdefault -o default -o nospace -F _delete_git_branch delete_git_branch 中的source包含了哪些内容。 如果我现在在终端中输入~/.bash_profile,我会得到我的分支机构。 但如果我尝试通过键入delete_git_branch [TAB][TAB]来限制完成结果,我会得到与第一个完全相同的结果。

我想我错过了一些参数传递,但我不确定。

你能想到我错过的任何事吗? 我看不出我的脚本和git-extras使用的脚本之间的区别,除了使用delete_git_branch 1[TAB][TAB]文件夹而不是bash_completion.d命令。

2 个答案:

答案 0 :(得分:0)

由于我问过多个问题(抱歉),我将分开这个答案:

非工作部分完成

好吧,我似乎找到了为什么这不能按预期工作的答案。

Git completion正在包装git命令。 这个包装调用__git_func_wrap,它有以下代码行:

_get_comp_words_by_ref -n =: cur words cword prev

此行将参数分配给其命名对应项。 据我所知,$cur变量是整个git完成脚本中用来确定要完成的字符串的变量。 如果没有调用该赋值函数,我们将始终为空$cur,但没有有限的完成。

所以这就是我的完成文件现在的样子:

#!/bin/bash

_delete_git_branch(){
    _get_comp_words_by_ref -n =: cur words cword prev
  __gitcomp "$(__git_heads)"
}

complete -o bashdefault -o default -o nospace -F _delete_git_branch delete_git_branch

这当然很脏,但是调用示例_git会导致重复的调用导致与之前相同的问题(顺便说一下,我不知道为什么)。

我知道这很糟糕,但我很乐意接受你对我的解决方案的反馈。

完成实施的差异

关于为什么完成git-extras开箱即用而不使用complete的部分: 如果没有complete,它当然不会完全奏效。但由于它只是一个git子命令,它也被git完成包装。

似乎如果您正在为子命令运行git completion,它会尝试猜测它的函数名称https://github.com/git/git/blob/master/contrib/completion/git-completion.bash#L2606

然后它执行该功能。很简单:)

道德

是的,我忘记了道德: 如果你真的,真的,真的需要在git子命令之外创建一个带git完成的命令,你可以这样做(或者更好地结合这个和我得到的答案的评论)。但在任何其他情况下,您应该尽可能贴近git子命令实现。只是为了避免这样的麻烦;)

答案 1 :(得分:0)

git branch 的补全应该与 Git 2.31(2021 年第一季度)配合得更好:命令行补全(在 contrib/ 中)已完成“git branch -d({{3} }) 带有分支名称,但 "man"(git branch -D) 还提供了标记名,已更正。
"man"(git branch -M) 遇到了同样的问题。

请参阅 mancommit 27dc071commit bca362c(2021 年 2 月 3 日)和 commit a534cf4(2021 年 2 月 2 日)。
(2021 年 2 月 12 日在 Jeff King (peff)Junio C Hamano -- gitster -- 合并)

<块引用>

commit 006c5f7:处理“branch -m”的其他变体

签字人:Jeff King

<块引用>

我们没有将“branch -M”(大写 M)与“branch -m”或任何“--copy”变体相同。
因此,这些提供了任何 ref 作为下一个候选者,而不仅仅是分支名称。

请注意,我重新包装了 case-arm 线,因为它现在很长,为了保持一致性,下面的线也是如此。
我还对现有的“-D”进行了重新排序,以使案例组合在一起的方式更加明显。

还有:

<块引用>

completion:以与“branch -D”相同的方式对待“branch -d

报告人:Paul Jolly
签字人:Jeff King

<块引用>

前者不仅提供分支,还提供标签作为完成候选。

模仿“branch -d”如何将其建议限制为分支名称。