当普通命令成功时,Git别名失败 [英] git alias fails when plain command succeeds
问题描述
我在~/.gitconfig文件中存储了以下别名
reset-master = reset $(git merge-base master $(git rev-parse --abbrev-ref HEAD))
但当我运行git reset-master
时,它失败并显示
$ git reset-master
error: unknown option `abbrev-ref'
usage: git reset [--mixed | --soft | --hard | --merge | --keep] [-q]
[<commit>]
or: git reset [-q] [<tree-ish>] [--] <paths>...
or: git reset --patch [<tree-ish>] [--] [<paths>...]
-q, --quiet be quiet, only report errors
--mixed reset HEAD and index
--soft reset only HEAD
--hard reset HEAD, index and working tree
--merge reset HEAD, index and working tree
--keep reset HEAD but keep local changes
--recurse-submodules[=<reset>]
control recursive updating of submodules
-p, --patch select hunks interactively
-N, --intent-to-add record only the fact that removed paths will be added later
并运行
git reset $(git merge-base master $(git rev-parse --abbrev-ref HEAD))
运行得非常好。我做错了什么?
推荐答案
TL;DR
您需要使用Git别名的!
形式:!git reset $(...)
,而不是较短的形式!reset $(...)
。
长音
要了解此问题,我们需要了解:
cmd1 $(cmd2 arg ...)
实际上是由外壳处理的,它首先运行cmd2
及其参数。cmd2
的输出--更准确地说,是标准输出流--返回到外壳,外壳读取该输出并将其分解为单词,然后将这些单词传递给cmd1
。因此:
wc $(seq -f f%g 1 3)
第一次运行seq -f f%g 1 3
:
$ seq -f f%g 1 3
f1
f2
f3
外壳读取这些单词,将它们转换为三个参数传递给wc
:
wc f1 f2 f3
(此示例有点傻,因为我们知道seq -f f%g 1 3
将始终打印这三个名称,因此我们只需使用这三个名称运行wc
,但可以用于演示。)
默认情况下,Git的别名不是在外壳中运行:
reset-master = reset $(git merge-base master $(git rev-parse --abbrev-ref HEAD))
表示Git尝试将文字字符串$(git
作为第一个参数传递给git reset
。第二个参数是merge-base
,依此类推。其中一个参数是--abbrev-ref
,这是git reset
首先查看的参数-它在试图理解该行的其余部分之前,先扫描所有参数以寻找选项-所以这就是它抱怨的那个参数。
但是,如果我们将整个字符串提供给外壳,我们会让外壳展开每个$(...)
事件。第一个命令运行git rev-parse --abbrev-ref HEAD
,它打印当前分支的名称(如果有,或者HEAD
如果有分离的头部)。此输出被反馈到外部git merge-base
命令中,以查找master
和命名分支(或再一次为HEAD
)之间的合并基本提交。如果幸运的话,git merge-base
打印一个提交散列ID,外壳用它替换最后一个命令:
git reset <hash-id>
我们可以通过以下方式让Git执行此操作:
reset-master = !git reset $(git merge-base master $(git rev-parse --abbrev-ref HEAD))
作为以!
开头的Git别名表示在外壳中运行剩余文本。
注意,如果没有合并基本提交,这将运行git reset
,这相当于git reset --mixed HEAD
,它将重新设置索引以匹配HEAD
提交。如果有多个合并基础--这很少见,但也不是不可能--Git会随机挑选一个。最好编写一个外壳函数或外壳脚本,使用git merge-base --all
来验证是否恰好存在一个合并基,但更简单的别名将适用于几乎所有实际情况。
这篇关于当普通命令成功时,Git别名失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!