如何为 git 命令编写包装函数

Dar*_*eam 4 linux bash git

我想为 git log 创建一个特殊的别名,这样当我使用它时,它会使用自定义的漂亮格式--graph并进行标记。--pretty

我知道我可以使用 git 别名,但是,我不想这样做,因为我想让它动态化,这样它也可以接受额外的参数/标志。另外,我想了解 bash 中的包装是如何工作的,所以我想尝试一下。

这就是我想要它做的事情;

当我使用

git log spc
         ^_______(custom argument)
Run Code Online (Sandbox Code Playgroud)

它运行如下

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
Run Code Online (Sandbox Code Playgroud)

因此,为此,我在我的中添加了此命令(来自此答案~/.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
}
Run Code Online (Sandbox Code Playgroud)

但它不起作用,这是我得到的错误

+ 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'
Run Code Online (Sandbox Code Playgroud)

Bod*_*odo 6

长话短说

\n

使用shift 2代替shift并删除log分支中的else

\n
\n

在你的包装函数中

\n
## git wrapper\ngit()\n{\n  if [ $# -gt 0 ] && [ "$1" == "log" ] && [ "$2" == "spc" ]; then\n     shift    # **********************************************************\n     set -x  \n     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 "$@"\n  else\n     command git log "$@"\n  fi\n}\n
Run Code Online (Sandbox Code Playgroud)\n

shift如果前两个命令行参数匹配log和 ,则使用spc。这将删除第一个参数log,但不会删除第二个参数spc。将spc作为 的一部分附加到您的命令行"@"。这会导致错误的命令

\n
git log --graph  ...  --date=relative spc\n
Run Code Online (Sandbox Code Playgroud)\n

最后git抱怨的地方。spc

\n

正如Saaru Lindest\xc3\xb8kke\ 的回答中所写,您可以使用"${@:2}"而不是"@"从列表中删除另一个参数。

\n

shift对我来说,使用两种不同的方法(和"${@:2}")来删除第一个和第二个参数是没有意义的。我建议与原始行结合使用shift 2(或两次) 。shiftcommand git ...

\n

log此外,我假设当命令行参数不是log和时,您不想插入额外的参数spc。这就是我删除log分支中的原因else

\n

修改后的代码:

\n
## git wrapper\ngit()\n{\n  if [ $# -gt 0 ] && [ "$1" == "log" ] && [ "$2" == "spc" ]; then\n     shift 2\n     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 "$@"\n  else\n     command git "$@"\n  fi\n}\n
Run Code Online (Sandbox Code Playgroud)\n

请注意,它shift适用于每个 POSIX 兼容 shell。您bash可以选择使用"${@:3}"或省略shift.

\n