在我的.gitconfig
中,我有一个别名设置为lol
以运行以下命令:
git --no-pager log --graph --pretty=oneline --abbrev-commit --decorate --all $*
我在另一篇文章中读到我不应该使用no-pager,所以我使用了如下所示将pager设置为cat
的方法。
我期望别名的输出与上面命令的输出相匹配,如下所示,但是什么也没有发生。知道为什么吗?
命令历史记录:
➜ ~/w/t/some-dir master ✓ git log
commit 4f6dc31e12fb6b39c8d44f293b7561f132c4d9ad
Author: Max Bigras <mbigras22@gmail.com>
Date: Sun Oct 30 20:43:40 2016 -0700
Add readme
➜ ~/w/t/some-dir master ✓ git lg
* 4f6dc31 - (HEAD -> master) Add readme (5 minutes ago) <Max Bigras>
➜ ~/w/t/some-dir master ✓ git --no-pager log --graph --pretty=oneline --abbrev-commit --decorate --all $*
* 4f6dc31 (HEAD -> master) Add readme
➜ ~/w/t/some-dir master ✓ git lol
➜ ~/w/t/some-dir master ✓
.gitconfig
:
[user]
name = Max Bigras
email = mbigras22@gmail.com
[core]
editor = vim
autocrlf = input
excludesfile = /Users/max/.gitignore_global
[push]
default = simple
[alias]
co = checkout
br = branch
ci = commit
s = status
unstage = reset HEAD --
quickcommit-m= "!git add -A; git commit -m"
alias = config --get-regexp ^alias\.
lg = log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit
lol = log --graph --pretty=oneline --abbrev-commit --decorate --all $*
[pager]
lol = cat
.
.
.
这里的问题是末尾的$*
。你应该直接省略它。
在shell脚本中,$*
(或者更好,"$@"
-注意周围的双引号1)展开为"所有附加参数",这在这里是可取的。但是Git别名本身并不是shell脚本,所以不应该这样对待。
相反,Git会在末尾添加任何额外的参数,而不考虑别名的扩展。例如,使用:
[alias]
echo = !echo
我:
$ git echo several additional arguments
several additional arguments
因此,要将剩余的参数传递给扩展的命令(在本例中为echo
,但在本例中为git log
),您只需什么都不做。您可以使某些参数重复:
[alias]
echo = !echo $1
收益率:
$ git echo several additional arguments
several several additional arguments
,但这不是这里的目标,$*
只是展开为文字$*
。
因为这个命令以!
为前缀,因此传递给shell,导致shell扩展$*
,所以很难演示:我们需要一个Git命令来打印它的参数。rev-parse
命令工作得很好:
[alias]
rp = rev-parse $*
后:
$ git rp
$*
$ git rp master
$*
master
fatal: master: no such path in the working tree.
Use 'git <command> -- <path>...' to specify paths that do not exist locally.
或者更好:
$ GIT_TRACE=1 git rp master
22:16:01.828980 git.c:563 trace: exec: 'git-rp' 'master'
22:16:01.831942 run-command.c:336 trace: run_command: 'git-rp' 'master'
22:16:01.850163 git.c:286 trace: alias expansion: rp => 'rev-parse' '$*'
22:16:01.850581 git.c:563 trace: exec: 'git-rev-parse' '$*' 'master'
22:16:01.850678 run-command.c:336 trace: run_command: 'git-rev-parse' '$*' 'master'
22:16:01.883257 git.c:350 trace: built-in: git 'rev-parse' '$*' 'master'
$*
master
fatal: master: no such path in the working tree.
Use 'git <command> -- <path>...' to specify paths that do not exist locally.
(在环境中设置GIT_TRACE=1
是一个方便的调试技巧。)
1双引号防止shell分割包含空格的参数(实际上是$IFS
值)。
在过去糟糕的日子里,当$#
为零时,"$@"
会失败,因为内部展开最终会产生一个空参数。所以我们必须拼写这个${1+"$@"}
,也就是说,如果$1
存在,就使用"$@"
,否则什么都不用。