git别名:多个命令,可变参数

git别名:多个命令,可变参数,git,git-alias,Git,Git Alias,我经常发现自己在打字: git push remote1 branch1 branch2 tag1 tag2 tag3.. git push remote2 branch1 branch2 tag1 tag2 tag3.. 我更喜欢可以键入以下内容的别名: git pushall branch1 branch2 tag1 tag2 tag3 .. 注意:我知道我可以用多个URL创建一个新的远程“all”。我们不要在这里讨论这个问题,而是关注别名 我可以硬编码远程名称,因为我有许多项目具有相同

我经常发现自己在打字:

git push remote1 branch1 branch2 tag1 tag2 tag3..
git push remote2 branch1 branch2 tag1 tag2 tag3..
我更喜欢可以键入以下内容的别名:

git pushall branch1 branch2 tag1 tag2 tag3 ..
注意:我知道我可以用多个URL创建一个新的远程“all”。我们不要在这里讨论这个问题,而是关注别名

我可以硬编码远程名称,因为我有许多项目具有相同的多个远程名称(通常是“drupal”和“github”)

迄今取得的进展 我已经找到了一个非变量版本:

[alias]
pushall = "!git push github $1; git push drupal $1; #"
这里有两个技巧

  • 使用双引号防止“;”在
    .ini
    文件中具有特殊含义
  • #
    忽略行的其余部分
但这一次只推送一个分支(或标记)。因此,我必须键入以下内容:

git pushall branch1
git pushall branch2
git pushall tag1
git pushall tag2
git pushall tag3
...
我更喜欢可以键入以下内容的别名:

git pushall branch1 branch2 tag1 tag2 tag3 ..
为什么没有一个新的远程“全部”多推URL? 如前所述,让我们关注别名,以便读者找到他们想要的

无论如何,这就是我为什么不创建远程“全部”:

  • 我必须每个项目做一次,但不能在全球范围内做。在我的例子中,在全局别名中硬编码远程名称实际上很好
  • 顺便说一句,我会用像“all/branch1”这样的引用来污染我的历史记录,而不是“remote1/branch1”和“remote2/branch1”或“remote2/branch1”
讨论这个问题的正确地点是这里

另见 以下内容相关,但不涉及可变参数:

以下内容可能会有所帮助,但它解决的是纯shell脚本,而不是git别名:


为了记录在案,下面的“欺骗”确实有效。这并不是一个完整的答案,但对许多人来说可能已经足够好了

[alias]
pushall = "!git push github $1 $2 $3 $4 $5; git push drupal $1 $2 $3 $4 $5; :"
是的,这不是真正的变量,因为它被限制为5个参数(或创建别名时选择的任何数字)。它也不能传递像
--key=value
这样的选项。但正如我所说的,这对你来说可能已经足够好了

在我的特定用例中,大多数时候我只推一个分支和一个发布标签,所以两个参数(
$1$2
)就足够了

请注意,结尾处的
似乎与
#
具有相同的效果。我在stackoverflow上的其他地方学的


我不会“接受”这个答案,因为我想让别人有机会想出更好的办法。

你链接到的其他问题确实回答了这个问题,但为了清楚起见:

[alias]
    pushall = "!git push github \"$@\"; git push drupal \"$@\"; :"
或从命令行进行设置:

git config --global alias.pushall '!git push github "$@"; git push drupal "$@"; :'

通过扩展初始尝试:

[alias]
pushall = "!git push github $@; git push drupal"
这样,
git pushall branch1 branch2 branch3扩展为:

git push github branch1 branch2 branch3; git push drupal branch1 branch2 branch3
#                  |               |                        |               |
#                  +-------+-------+                        +-------+-------+
# these arguments were     |                                        |
# expanded from $@ --------+                                        |
#                                                                   |
#                  these are the arguments of the original command -+
扩展到所有命令行参数。
行末尾不需要
#
;片段
git pushall
被别名的值(参数的其余部分)替换

如果您有一个更大的远程存储库列表,可以这样编写:

[alias]
pushall = "!for repo in github drupal bitbucket; do git push $repo $@; done #"
#                         |               |
#                         +-------+-------+
# put all your repos here         |
# separated by spaces ------------+
这次需要使用
#
标志。它把最初的论点变成评论;否则,该命令有语法错误,无法运行

如果要推送到存储库的所有远程位置,则可以编写更智能的别名:

pushall = "! for repo in $(git remote); do git push $repo $@; done #"
它运行
git remote
查找所有远程设备,并在继续之前使用
git remote
命令的输出替换
$(…)

可以使用以下命令将其定义为全局别名:

$ git config alias.pusha '! for repo in $(git remote); do git push $repo $@; done #'
如果您有一些不想推送到所有远程位置的repo,您可以将其定义为本地别名,并在存储库中使用thi命令自定义每个repo中的远程位置列表:

$ git config --local alias.pusha '! for repo in github drupal; do git push $repo $@; done #'

将任意脚本打包到git别名中的习惯用法是将其放入shell函数中:

pushall = "! f() { git push github \"$@\"; git push drupal \"$@\"; }; f"

我想指出,
$@
的正确用法是将其放在双引号内:
“$@”

请参见@torek。此链接与我前面提到的链接属于同一类别。为了完整起见,我将其添加到“请参见”列表中。我从多个答案中了解到的相关信息是,
$@
在shell脚本中表示可变参数,这也适用于git别名。我没有意识到这一点。现在我不知道我应该接受哪一个答案。。我会明白的。总的技巧是将别名定义为shell函数,然后将传递给别名的所有参数作为其参数。然后使用shell脚本,这是一种真正的(名义上是图灵完整的)语言。在某些特殊情况下,您不需要求助于全功率模式(axiac的答案),但我通常直接使用函数,它们没有那么复杂。我没有看到其他答案中提到的
“$@”
。或者至少不明确。我不知道这个构造。对于记录,我刚刚发现这也将插入像
-l
--version
(对于
ls
)这样的选项。但是,
--help
选项被传递给git命令,它出现了。在一个小的测试运行中,它在
$@
周围没有双引号的情况下工作。如果我省略这些,可能会出现什么问题?在这种情况下,可能不会有太多问题,因为在分词过程中,分支名称不能带有空格或其他可能导致参数列表更改的字符。我想省略
$@#结尾保存了几个字符。但这也让整个事情变得不那么“对称”。所以也许我更喜欢稍长一点的版本;它更通用。您可以在
do
done
之间压缩更多命令(以
终止)。例如,在
push
之后,您可以调用一个程序(比如Ubuntu上的
notify send
)来显示桌面通知。