[英]How can I make tab completion for my Git alias behave like an existing command?
I am writing a shell script to add a "review" sub command to git, to make it easier to do code reviews. 我正在编写一个shell脚本,向git添加“ review”子命令,以使其更容易进行代码审查。 It's basically a fancy wrapper for
git diff
and git difftool
commands, but requires less typing. 从
git difftool
,它是git diff
和git difftool
命令的精美包装器,但所需的键入较少。
Some example usages: 一些示例用法:
# 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
I would like to enable branch auto completion in my shell script, but cannot for the life of me figure out how to do it. 我想在我的shell脚本中启用分支自动完成功能,但是我一生都无法解决如何做到这一点。 Here is what I'm really after:
这是我真正追求的:
git review ma<tab><tab>
And then it should behave like git checkout ma<tab><tab>
. 然后,它的行为应类似于
git checkout ma<tab><tab>
。
My shell script: 我的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."
Really, since I'm in the process of typing the command in, I doubt my shell script will have anything to do with the solution. 确实,由于我正在输入命令,因此我怀疑我的shell脚本是否与解决方案有关。
Some other useful info: 其他一些有用的信息:
Is there a way to add git branch auto completion to a custom git extension command? 有没有一种方法可以将git分支自动完成功能添加到自定义git扩展命令中?
An interesting related question for Linux: custom git command autocompletion . Linux的一个有趣的相关问题: 自定义git命令autocompletion 。
Let's assume a minimal version of your script, something like 让我们假设您的脚本的最低版本,例如
#!/usr/bin/env bash
git diff "$1"
This is executable and somewhere in your $PATH
. 这是可执行文件,位于
$PATH
。 Let's call it gitreview
. 我们称之为
gitreview
。
To get an alias for it, you add it like this in your .gitconfig
: 要为其获取别名,可以在
.gitconfig
像这样添加它:
[alias]
review = "!f() { gitreview \"$@\"; }; f"
This gets you completion for review
when you enter git
. 当您输入
git
时,这将使您完成review
。 Now, to make it behave the same as git checkout
, you can use a null command, like this: 现在,要使其行为与
git checkout
相同,可以使用null命令,如下所示:
review = "!f() { : git checkout ; gitreview \"$@\"; }; f"
and it'll complete the same as git checkout
! 它将完成与
git checkout
相同的操作! Notice that the blank between checkout
and ;
请注意,
checkout
和;
之间的空白;
is required. 是必须的。
This is mentioned in the comments of git-completion.bash
: 这在
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 ; ... '".
Alternatively, you can make your script a proper external command by naming it git-review
and leave it somewhere in your $PATH
. 另外,您可以通过将脚本命名为
git-review
并将其放在$PATH
某个位置,从而使脚本成为适当的外部命令。 To get completion for it (assuming you have both Bash and Git completion), add this to your ~/.bash_completion
file (just create it if it doesn't exist): 要获得完成(假设您同时具有Bash和Git完成),请将其添加到
~/.bash_completion
文件中(如果不存在,请创建它):
_git_review() { _git_checkout; }
Git completion (for Git 2.18 or newer) checks for completion functions that are named _git_$command
, and by doing this, you say "just call _git_checkout
instead". Git完成(对于Git 2.18或更高版本)检查名为
_git_$command
完成功能,然后您说“只调用_git_checkout
”。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.