刚碰到类似的东西;希望可以发表我的笔记。关于git
别名和参数,使我感到困惑的一件事可能来自git help config
(我的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/
...或:如果您!
在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 help config
以上引用的上下文中,我推测声明如下内容更为准确:“ ...调用” git new“等同于运行shell命令” gitk --all --not ORIG_HEAD $ @“,其中$ @是在运行时从命令行传递到git命令别名的参数。我认为这也可以解释为什么OP中的“直接”方法不适用于位置参数。
$1
应该可以使用)。