带有位置参数的 Git 别名
基本上我试图别名:
git files 9fa3
...来执行命令:
git diff --name-status 9fa3^ 9fa3
但 git 似乎没有将位置参数传递给别名命令。我尝试过:
[alias]
files = "!git diff --name-status $1^ $1"
files = "!git diff --name-status {1}^ {1}"
...以及其他一些尝试,但这些都不起作用。
退化的情况是:
$ git echo_reverse_these_params a b c d e
e d c b a
……我怎样才能做到这一点?
Basically I'm trying to alias:
git files 9fa3
...to execute the command:
git diff --name-status 9fa3^ 9fa3
but git doesn't appear to pass positional parameters to the alias command. I have tried:
[alias]
files = "!git diff --name-status $1^ $1"
files = "!git diff --name-status {1}^ {1}"
...and a few others but those didn't work.
The degenerate case would be:
$ git echo_reverse_these_params a b c d e
e d c b a
...how can I make this work?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
shell 函数可以帮助解决这个问题:
没有
!
的别名被视为 Git 命令;例如commit-all = commit -a
。使用
!
,它在 shell 中作为自己的命令运行,让您可以像这样使用更强大的魔法。UPD
由于命令是在存储库的根目录执行的,因此在命令中引用文件名时可以使用
${GIT_PREFIX}
变量A shell function could help on this:
An alias without
!
is treated as a Git command; e.g.commit-all = commit -a
.With the
!
, it's run as its own command in the shell, letting you use stronger magic like this.UPD
Because commands are executed at the root of repository you may use
${GIT_PREFIX}
variable when referring to the file names in commands您正在寻找的别名是:
带参数验证:
final
#
很重要 - 它阻止 shell 处理所有用户提供的参数(它注释它们)出去)。注意:
git
将所有用户提供的参数放在命令行末尾。要查看此操作的实际效果,请尝试:GIT_TRACE=2 git files abc d
转义(由于嵌套)引号对于包含空格或
" 的文件名很重要;rm -rf --no-preserve-root /;
)The alias you are looking for is:
With argument validation:
The final
#
is important - it prevents all the user-supplied arguments from being processed by the shell (it comments them out).Note:
git
puts all user-supplied arguments at the end of the command line. To see this in action, try:GIT_TRACE=2 git files a b c d
The escaped (due to nesting) quotes are important for filenames containing spaces or
"; rm -rf --no-preserve-root /;
)您还可以直接引用
sh
(而不是创建函数):(请注意行末尾的破折号 - 您将需要它。)
You can also reference
sh
directly (instead of creating a function):(Note the dash at the end of the line -- you'll need that.)
使用 git 手册页上描述的 GIT_TRACE=1 使别名处理透明:
您的原始命令适用于 git 版本 1.8.3.4(Eimantas 注意到这在 1.8.2.1 中发生了变化)。
sh -c '..' --
和f() {..}; f
选项都以不同的方式干净地处理“$@”参数(请参阅 GIT_TRACE)。将“#”附加到别名也将允许位置参数而不留下尾随参数。Use GIT_TRACE=1 described on the git man page to make the alias processing transparent:
Your original commands work with git version 1.8.3.4 (Eimantas noted this changed in 1.8.2.1).
The
sh -c '..' --
andf() {..}; f
options both cleanly handle the "$@" parameters in different ways (see with GIT_TRACE). Appending "#" to an alias would also allow positional parameters without leaving the trailing ones.正如Drealmer上面所述:
GIT_PREFIX
由 git 设置到您所在的子目录,您可以通过首先更改目录来规避此问题:As stated by Drealmer above:
GIT_PREFIX
being set by git to the subdirectory you're in, you can circumvent this by first changing the directory :我想用一个别名来做到这一点:
最后,我创建了一个名为 git-m 的 shell 脚本具有以下内容:
这样做的好处是它更加清晰,因为它位于多行中。另外,我喜欢能够使用
-x
和set -e
调用 bash。您可能可以将整个事情作为别名来完成,但这会非常难看并且难以维护。因为该文件名为
git-m
,所以您可以像这样运行它:git m foo bar
I wanted to do this with an alias that does this:
In the end, I created a shell script named git-m that has this content:
This has the benefit that it's much more legible because it's on multiple lines. Plus I like being able to call bash with
-x
andset -e
. You can probably do this whole thing as an alias, but it would be super ugly and difficult to maintain.Because the file is named
git-m
you can run it like this:git m foo bar
刚刚遇到类似的事情;希望可以发布我的笔记。让我对带有参数的 git 别名感到困惑的一件事可能来自 git help config (我有 git 版本 1.7.9.5):
我的看法 - 如果别名在带有感叹号前缀时“将被视为 shell 命令” - 为什么我需要使用函数或
sh -c
有论据;为什么不直接写我的命令呢?我仍然不知道答案 - 但我认为实际上结果略有不同。这是一个小测试 - 将其放入您的
.git/config
或~/.gitconfig
中:这是我运行这些别名时得到的结果:
...或者:当您在
git
别名中的!
“as-is”之后使用“plain”命令 - 然后git
自动将参数列表附加到那个命令!事实上,避免这种情况的一种方法是将脚本作为函数调用,或者作为sh -c
的参数来调用。这里另一件有趣的事情(对我来说)是,在 shell 脚本中,人们通常期望自动变量
$0
是脚本的文件名。但对于git
别名函数来说,$0
参数基本上是指定该命令的整个字符串的内容(如在配置中输入的)文件)。这就是为什么,我想,如果你碰巧错误引用 - 在下面的情况下,这将转义外部双引号:
... - 那么 git 会失败(至少对我来说)有点神秘的消息:
我认为,由于
git
“看到”整个字符串只是!
的一个参数 - 它试图将其作为可执行文件运行;相应地,它无法找到"echo 'A' 'B'"
作为文件。无论如何,在上面的 git help config 引用的上下文中,我推测更准确的说法是:“ ...调用“git new”是等效的运行 shell 命令“gitk --all --not ORIG_HEAD $@”,其中 $@ 是运行时从命令行传递给 git 命令别名的参数 ... ”。我认为这也可以解释为什么OP中的“直接”方法不适用于位置参数。
Just bumped into something similar; hope it's oK to post my notes. One thing that confuses me about
git
aliases with arguments, probably comes from thegit help config
(I have git version 1.7.9.5):The way I see it - if an alias "will be treated as a shell command" when prefixed with an exclamation point - why would I need to use a function, or
sh -c
with arguments; why not just write my command as-is?I still don't know the answer - but I think actually there is a slight difference in the outcome. Here's a little test - throw this in your
.git/config
or your~/.gitconfig
:Here is what I get running these aliases:
... or: when you're using a "plain" command after the
!
"as-is" in agit
alias - thengit
automatically appends the arguments list to that command! A way to avoid it, is indeed, to call your script as either a function - or as the argument tosh -c
.Another interesting thing here (for me), is that in a shell script, one typically expects the automatic variable
$0
to be the filename of the script. But for agit
alias function, the$0
argument is, basically, the content of the entire string specifying that command (as entered in the config file).Which is why, I guess, if you happen to misquote - in the below case, that would be escaping the outer double quotes:
... - then
git
would fail with (for me, at least) somewhat cryptic message:I think, since
git
"saw" a whole string as only one argument to!
- it tried to run it as an executable file; and correspondingly it failed finding"echo 'A' 'B'"
as a file.In any case, in the context of the
git help config
quote above, I'd speculate that it's more accurate to state something like: " ... the invocation "git new" is equivalent to running the shell command "gitk --all --not ORIG_HEAD $@", where $@ are the arguments passed to the git command alias from the command line at runtime. ... ". I think that would also explain, why the "direct" approach in OP doesn't work with positional parameters.一个对我有用的简单解决方案可能是使用:
结果你得到:
One simple solution, that works for me could be to use:
as a result you get: