我想为 git log 创建一个特殊的别名,以便当我使用它时,它会使用--graph
并--pretty
标记自定义的漂亮格式。
我知道我可以使用 git 别名,但我不想这样做,因为我想让它动态化,这样它也可以接受额外的参数/标志。另外,我想了解 bash 中的包装工作原理,所以我想尝试一下。
所以这就是我想要它做的事情;
当我使用
git log spc
^_______(custom argument)
它运行如下
git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %C(bold blue)<%an>%Creset %C(grey)(%cr) ' --abbrev-commit --date=relative
因此为此,我添加了此命令(从这个答案) 在我的~/.bash_profile
## git wrapper
git()
{
if [ $# -gt 0 ] && [ "$1" == "log" ] && [ "$2" == "spc" ]; then
shift
set -x
command git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %C(bold blue)<%an>%Creset %Cgreen(%cr) ' --abbrev-commit --date=relative "$@"
else
command git log "$@"
fi
}
但它不起作用,这是我得到的错误
+ git log spc
+ '[' 2 -gt 0 ']'
+ '[' log == log ']'
+ '[' spc == spc ']'
+ shift
+ command git log --graph '--pretty=format:%Cred%h%Creset -%C(yellow)%d%Creset %s %C(bold blue)<%an>%Creset %Cgreen(%cr) ' --abbrev-commit --date=relative spc
+ git log --graph '--pretty=format:%Cred%h%Creset -%C(yellow)%d%Creset %s %C(bold blue)<%an>%Creset %Cgreen(%cr) ' --abbrev-commit --date=relative spc
fatal: ambiguous argument 'spc': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
++ printf '\033]0;%s@%s:%s\007' aman ip-xx-x-xx-xx '~/one-xx-aws'
答案1
它附加spc
到命令:您可以在错误输出中的第 6 行和第 7 行看到它写入... --abbrev-commit --date=relative spc
。
我认为这是由于"@"
你的函数块中的部分if
。也许你可以跳过第一个参数(spc
)和仅包含第二个及以后的参数通过使用"${@:2}"
而不是"@"
:
command git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %C(bold blue)<%an>%Creset %Cgreen(%cr) ' --abbrev-commit --date=relative "${@:2}"
答案2
总结
使用shift 2
代替shift
并删除分支log
中的else
。
在你的包装函数中
## git wrapper
git()
{
if [ $# -gt 0 ] && [ "$1" == "log" ] && [ "$2" == "spc" ]; then
shift # **********************************************************
set -x
command git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %C(bold blue)<%an>%Creset %Cgreen(%cr) ' --abbrev-commit --date=relative "$@"
else
command git log "$@"
fi
}
shift
如果前两个命令行参数匹配log
,则使用spc
。这将删除第一个参数log
,但不会删除第二个参数spc
。将spc
作为 的一部分附加到命令行中"@"
。这会导致错误的命令
git log --graph ... --date=relative spc
最后git
抱怨的是什么。spc
正如所写Saaru Lindestøkke 的回答,您可以使用"${@:2}"
而不是"@"
从列表中删除一个参数。
shift
对我来说,使用两种不同的方法(和"${@:2}"
)删除第一个和第二个参数是没有意义的。我建议将shift 2
(或两次shift
)与原始行结合使用command git ...
。
log
此外,我假设当命令行参数不是log
和时,您不想插入额外的参数spc
。这就是为什么我删除了分支log
中的else
。
修改后的代码:
## git wrapper
git()
{
if [ $# -gt 0 ] && [ "$1" == "log" ] && [ "$2" == "spc" ]; then
shift 2
command git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %C(bold blue)<%an>%Creset %Cgreen(%cr) ' --abbrev-commit --date=relative "$@"
else
command git "$@"
fi
}
请注意shift
适用于每个 POSIX 兼容 shell。bash
您也可以使用"${@:3}"
并省略shift
。
答案3
考虑到它的作用,您的方法太复杂了。我认为自定义 Bash 函数或自定义脚本对于完全适合 Git 别名的用例来说有点太多了。但包装git
不止于此。
我知道我可以使用 git 别名,但是我不想这样做,因为我想使它动态化,以便它也可以接受额外的参数/标志。
您的包装器传递了"$@"
,这意味着您可以传递额外的git log
标志/开关。但 git 别名允许您做同样的事情。
git config --add --global alias.logcustom "log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %C(bold blue)<%an>%Creset %Cgreen(%cr) ' --abbrev-commit --date=relative"
现在你可以将它与其他开关一起使用。例如限制为五次提交:
git logcustom -5
或者打印差异:
git logcustom -p