如何使我的 Git 别名的制表符补全功能像现有命令一样?
How can I make tab completion for my Git alias behave like an existing command?
我正在编写一个 shell 脚本来向 git 添加一个 "review" 子命令,以便更容易地进行代码审查。它基本上是 git diff
和 git 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 "" ] || [ -z "" ]; then
print_usage
exit 1
fi
git_branch=
review_command=
path_filters=""
shift
shift
if [ "" = "--" ]; 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 }')
else
git difftool $git_branch -- $(git diff --name-status $git_branch -- $path_filters | grep -E '^A' | awk '{print }')
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 }')
else
git difftool $git_branch -- $(git diff --name-status $git_branch -- $path_filters | grep -E '^D' | awk '{print }')
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 }')
else
git difftool $git_branch -- $(git diff --name-status $git_branch -- $path_filters | grep -E '^M' | awk '{print }')
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)-release (x86_64-pc-msys)
有没有办法将 git 分支自动完成添加到自定义 git 扩展命令?
Linux 的一个有趣的相关问题:。
使用别名
让我们假设您的脚本的最小版本,例如
#!/usr/bin/env bash
git diff "$@"
这是可执行文件,位于您的 $PATH
中。我们称它为 gitreview
.
要为它取一个别名,你可以像这样在你的.gitconfig
中添加它:
[alias]
review = "!f() { gitreview \"$@\"; }; f"
当您输入 git
时,这会让您完成 review
。现在,要使其行为与 git checkout
相同,您可以使用空命令,如下所示:
review = "!f() { : git checkout ; gitreview \"$@\"; }; f"
它会像 git checkout
一样完成!请注意 checkout
和 ;
之间的空格是必需的。
这是git-completion.bash
的in the comments提到的:
# 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
相反。
我正在编写一个 shell 脚本来向 git 添加一个 "review" 子命令,以便更容易地进行代码审查。它基本上是 git diff
和 git 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 "" ] || [ -z "" ]; then
print_usage
exit 1
fi
git_branch=
review_command=
path_filters=""
shift
shift
if [ "" = "--" ]; 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 }')
else
git difftool $git_branch -- $(git diff --name-status $git_branch -- $path_filters | grep -E '^A' | awk '{print }')
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 }')
else
git difftool $git_branch -- $(git diff --name-status $git_branch -- $path_filters | grep -E '^D' | awk '{print }')
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 }')
else
git difftool $git_branch -- $(git diff --name-status $git_branch -- $path_filters | grep -E '^M' | awk '{print }')
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)-release (x86_64-pc-msys)
有没有办法将 git 分支自动完成添加到自定义 git 扩展命令?
Linux 的一个有趣的相关问题:
使用别名
让我们假设您的脚本的最小版本,例如
#!/usr/bin/env bash
git diff "$@"
这是可执行文件,位于您的 $PATH
中。我们称它为 gitreview
.
要为它取一个别名,你可以像这样在你的.gitconfig
中添加它:
[alias]
review = "!f() { gitreview \"$@\"; }; f"
当您输入 git
时,这会让您完成 review
。现在,要使其行为与 git checkout
相同,您可以使用空命令,如下所示:
review = "!f() { : git checkout ; gitreview \"$@\"; }; f"
它会像 git checkout
一样完成!请注意 checkout
和 ;
之间的空格是必需的。
这是git-completion.bash
的in the comments提到的:
# 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
相反。