我在〜/ .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))
完全正常。我在做什么错了?
答案 0 :(得分:2)
要将PetSerAl's comment(正确)扩展为答案,我们需要知道:
cmd1 $(cmd2 arg ...)
实际上是由 shell 处理的,方法是运行cmd2
及其参数 first 。 cmd2
的输出(更准确地说是标准输出流)返回到外壳程序,该外壳程序将其读取并将其分解为单词,然后将这些单词传递给cmd1
。因此:
wc $(seq -f f%g 1 3)
首先运行seq -f f%g 1 3
:
$ seq -f f%g 1 3
f1
f2
f3
shell读取这些单词,将它们变成三个参数传递给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
所使用的参数-在试图弄清该行的其余部分之前,它会扫描所有参数中的选项,因此它抱怨。
但是,如果我们将整个字符串输入到 shell ,我们将获得shell来扩展每个$(...)
事件。第一个运行git rev-parse --abbrev-ref HEAD
,它打印当前分支的名称(如果有的话,或者如果我们有分离的HEAD,则打印HEAD
)。此输出将反馈到外部git merge-base
命令中,以找到master
与命名分支(或再次为HEAD
)之间的合并基础提交。运气好的话,git merge-base
会打印一个提交哈希ID,shell会用它代替最终命令:
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
,它将重新设置索引以匹配{ {1}}提交。如果存在多个合并基础(这是罕见的但并非不可能),Git会选择随机的基础。编写一个使用HEAD
来验证是否存在一个合并基础的shell函数或shell脚本可能会很好,但是更简单的别名将适用于几乎所有实际情况