只是碰到了类似的东西;希望可以发布我的笔记。有一件事让我对git别名和参数感到困惑,可能来自git帮助配置(我使用的是git 1.7.9.5版本):
如果别名展开以感叹号作为前缀,则它将被视为shell命令。例如,定义“alias”。new = !gitk——all——not ORIG_HEAD”,调用“git new”相当于运行shell命令
“gitk -all -not ORIG_HEAD”。注意,shell命令将从存储库的顶级目录执行,
不一定是当前目录。[…]
我看它的方式-如果一个别名“将被视为一个shell命令”时,加上一个感叹号前缀-为什么我需要使用一个函数,或sh -c参数;为什么不按原样编写我的命令呢?
我仍然不知道答案,但我认为实际上结果会有细微的不同。这里有一个小测试——把它扔到你的.git/config或~/.gitconfig中:
[alias]
# ...
ech = "! echo rem: "
shech = "! sh -c 'echo rem:' "
fech = "! f() { echo rem: ; }; f " # must have ; after echo!
echargs = "! echo 0[[\"$0\"]] 1-\"$1\"/ A-"$@"/ "
fechargs = "! f() { echo 0[[\"$0\"]] 1-\"$1\"/ A-"$@"/ ; }; f "
下面是我运行这些别名得到的结果:
$ git ech word1 word2
rem: word1 word2
$ git shech word1 word2
rem:
$ git fech word1 word2
rem:
$ git echargs word1 word2
0[[ echo 0[["$0"]] 1-"$1"/ A-$@/ ]] 1-word1/ A-word1 word2/ word1 word2
$ git fechargs word1 word2
0[[ f() { echo 0[["$0"]] 1-"$1"/ A-$@/ ; }; f ]] 1-word1/ A-word1 word2/
... 或者,当你在!命令后使用“plain”命令时:“as-is”在git别名中-然后git自动将参数列表追加到该命令!实际上,避免这种情况的一种方法是,以函数-或sh -c参数的形式调用脚本。
这里(对我来说)另一件有趣的事情是,在shell脚本中,人们通常期望自动变量$0是脚本的文件名。但是对于一个git别名函数,$0参数基本上是指定该命令的整个字符串的内容(在配置文件中输入)。
这就是为什么,我猜,如果你碰巧引用错了-在下面的情况下,这将是转义外部双引号:
[alias]
# ...
fail = ! \"echo 'A' 'B'\"
... -然后git会失败(至少对我来说)一些神秘的消息:
$ git fail
"echo 'A' 'B'": 1: echo 'A' 'B': not found
fatal: While expanding alias 'fail': ' "echo 'A' 'B'"': No such file or directory
我想,因为git“看到”整个字符串只有一个参数!-它试图运行它作为一个可执行文件;相应地,它无法找到“echo 'A' 'B'”作为文件。
在任何情况下,在上面引用的git帮助配置的上下文中,我推测更准确的说法是:“……调用“git new”相当于运行shell命令“gitk——all——not ORIG_HEAD $@”,其中$@是从运行时. ...的命令行传递给git命令别名的参数”。我认为这也可以解释,为什么OP中的“直接”方法不适用于位置参数。