繁体   English   中英

如何使Git别名的制表符完成行为像现有命令一样?

[英]How can I make tab completion for my Git alias behave like an existing command?

我正在编写一个shell脚本,向git添加“ review”子命令,以使其更容易进行代码审查。 git difftool ,它是git diffgit difftool命令的精美包装器,但所需的键入较少。

一些示例用法:

# Lists added, deleted, renamed and modified files between master and current branch
git review master -l

# Opens difftool for files modified between master and current branch
git review -m

我想在我的shell脚本中启用分支自动完成功能,但是我一生都无法解决如何做到这一点。 这是我真正追求的:

git review ma<tab><tab>

然后,它的行为应类似于git checkout ma<tab><tab>

我的shell脚本:

#!/bin/env bash

function print_usage {
    echo "Usage: git review <branch> <-a|-d|-m|-l> [-- paths/to filter/by]"
    echo ""
    echo "    -a: Only review added files"
    echo "    -d: Only review delete files"
    echo "    -m: Only review modified files"
    echo "    -l: List files and and type of modification"
}

if [ -z "$1" ] || [ -z "$2" ]; then
    print_usage
    exit 1
fi

git_branch=$1
review_command=$2
path_filters=""

shift
shift

if [ "$1" = "--" ]; then
    path_filters="$@"
fi

case $review_command in
    "-a")
        echo "Reviewing added files..."

        if [ -z "$path_filters" ]; then
            git difftool $git_branch -- $(git diff --name-status $git_branch | grep -E '^A' | awk '{print $2}')
        else
            git difftool $git_branch -- $(git diff --name-status $git_branch -- $path_filters | grep -E '^A' | awk '{print $2}')
        fi
        ;;
    "-d")
        echo "Reviewing deleted files..."

        if [ -z "$path_filters" ]; then
            git difftool $git_branch -- $(git diff --name-status $git_branch | grep -E '^D' | awk '{print $2}')
        else
            git difftool $git_branch -- $(git diff --name-status $git_branch -- $path_filters | grep -E '^D' | awk '{print $2}')
        fi
        ;;
    "-m")
        echo "Reviewing modified files..."

        if [ -z "$path_filters" ]; then
            git difftool $git_branch -- $(git diff --name-status $git_branch | grep -E '^M' | awk '{print $2}')
        else
            git difftool $git_branch -- $(git diff --name-status $git_branch -- $path_filters | grep -E '^M' | awk '{print $2}')
        fi
        ;;
    "-l")
        echo "Differences between $git_branch and $(git mybranch)..."

        if [ -z "$path_filters" ]; then
            git diff --name-status $git_branch
        else
            git diff --name-status $git_branch -- $path_filters
        fi
        ;;
esac

echo ""
echo "Review finished."

确实,由于我正在输入命令,因此我怀疑我的shell脚本是否与解决方案有关。

其他一些有用的信息:

  • Windows 10
  • Git v2.18.0.windows.1
  • Shell:GNU bash,版本4.4.19(2)-发行版(x86_64-pc-msys)

有没有一种方法可以将git分支自动完成功能添加到自定义git扩展命令中?


Linux的一个有趣的相关问题: 自定义git命令autocompletion

使用别名

让我们假设您的脚本的最低版本,例如

#!/usr/bin/env bash

git diff "$1"

这是可执行文件,位于$PATH 我们称之为gitreview

要为其获取别名,可以在.gitconfig像这样添加它:

[alias]
    review =  "!f() { gitreview \"$@\"; }; f"

当您输入git时,这将使您完成review 现在,要使其行为与git checkout相同,可以使用null命令,如下所示:

review =  "!f() { : git checkout ; gitreview \"$@\"; }; f"

它将完成与git checkout相同的操作! 请注意, checkout;之间的空白; 是必须的。


git-completion.bash 的注释中提到:

# 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 ; ... '".

使用外部命令

另外,您可以通过将脚本命名为git-review并将其放在$PATH某个位置,从而使脚本成为适当的外部命令。 要获得完成(假设您同时具有Bash和Git完成),请将其添加到~/.bash_completion文件中(如果不存在,请创建它):

_git_review() { _git_checkout; }

Git完成(对于Git 2.18或更高版本)检查名为_git_$command完成功能,然后您说“只调用_git_checkout ”。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM