1

我正在尝试实现我自己的 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 以尝试该代码之后,它工作得很好,但正如我在问题中所说,我想实现我自己的方式,因为我想stable在删除它们之前检查分支是否集成在其中。

由于我不想将我的脚本放在bash_completion.d文件夹中,我创建了这个脚本:

#!/bin/bash

_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]现在输入我的终端,我会得到我的分支。但是,如果我尝试通过键入来限制完成的结果,delete_git_branch 1[TAB][TAB]我会得到与第一个完全相同的结果。

我想我在这里遗漏了一些参数,但我不确定。

你能想到我错过了什么吗?我看不出我的脚本和 git-extras 使用的脚本之间的区别,除了使用bash_completion.d文件夹而不是complete命令。

4

2 回答 2

0

由于我问了多个问题(对不起),我将拆分这个答案:

非工作部分完成

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

Git 完成正在包装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 完成,它会尝试猜测它的函数名称https://github.com/git/git/blob/master/contrib/completion/git-completion.bash# L2606

然后它执行函数。就那么简单 :)

道德

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

于 2015-06-08T10:45:07.807 回答
0

的完成git branch应该更好地使用 Git 2.31(2021 年第一季度):命令行完成(in contrib/)完成了带有分支名称的“”(man),但“ git branch -dmangit branch -D提供标记名,这已得到更正。
" git branch -M" ( man )也有同样的问题。

请参阅Jeff King ( ) 的提交 27dc071提交 bca362c(2021 年 2 月 3 日)和提交 a534cf4(2021 年 2 月 2 日(由Junio C Hamano 合并 -- --006c5f7 提交中,2021 年 2 月 12 日)peff
gitster

completion:处理“branch -m”的其他变体

签字人:杰夫·金

我们没有特例“ branch -M”(大写 M)与“ branch -m”相同,也没有任何“ --copy”变体。
结果,这些提供了任何参考作为下一个候选者,而不仅仅是分支名称。

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

和:

completion: 对待 " branch -D" 和 " branch -d"一样

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

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

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

于 2021-02-14T05:36:02.867 回答