别名扩展失败;不是git命令。

5

我一定是忽略了什么很明显的东西...但是Git别名根本不起作用。请帮助我!

$ git config --global alias.v version
$ git config --global --list
alias.v=version
$ git config --global alias.v
version
$ git v
Expansion of alias 'v' failed; 'version' is not a git command
$ git version
git version 2.9.0
$ cat ~/.gitconfig
[alias]
        v = version

更新 1

根据 @torek 的建议,我使用 log 进行了相同的测试,但结果仍然不起作用:

$ git config --global alias.l log
$ git config --global --list
alias.v=version
alias.l=log
$ git config --global alias.l
log
$ git l
Expansion of alias 'l' failed; 'log' is not a git command
$ cat ~/.gitconfig
[alias]
        v = version
        l = log

更新 2:问题已解决

问题在于git --exec-path被设置为错误的目录。最终,我从源代码中构建并安装了Git,现在一切都按预期工作。感谢所有帮忙的人。

4个回答

10
使用除version之外的命令。例如,尝试将l别名为log。(或者,正如VonC所指出的那样,升级 - 它实际上在现代Git中有效。别名处理似乎在2.17.3和2.18.0之间已被重写。)
为什么l = log可以工作,但v = version不行呢?
这有点棘手!
大多数Git命令是单独的程序,它们安装到一个目录(或文件夹)中,而该目录/文件夹包含“您可以运行的Git命令”。例如,git log实际上是由一个名为git-log的命令实现的,该命令安装在特殊的目录/文件夹中。
但是,您通常不会从此目录/文件夹中运行命令。
在遥远的过去,这些Git命令 - git-loggit-commitgit-addgit-diff等 - 都是直接安装的,并且您可以通过键入git-something来直接运行它们。这对bash的自动补全功能运行良好,因为您可以键入git-comTAB以获取提交命令,或者键入git-chTAB以获取检出命令。但是随着时间的推移,Git命令的数量增长(git-cherrygit-cherry-pick),并且不断增长,甚至输入完整的命令git-add也不足够了,因为还有例如git-add--interactive,因此TAB补全基本上完全停止工作。
做出了一个决定:Git不会停止提供57个不同的命令 - 实际上现在已经超过150个了 - 但是,所有这些各种的实现命令将被塞到一个地方,那里它们将不会总是出现在您的面前。单个前端命令git可以让您将命令作为参数键入到前端git命令中:git com然后TAB:bash现在有一个允许的完成列表,并且只选择commit,因为那是您要使用的唯一com,而不是只有脚本经常使用的git-commit-treegit-commit-graph后端程序。
所以:前端git命令知道如何查找和运行所有各种后端实现。按照惯例,大多数后端实现都在git-core目录中:运行
git --exec-path
前端打印出所有后端程序实际存在的位置的名称。(如果您喜欢,可以在那里查看它们,甚至直接从那里运行它们,尽管现在前端的git命令会设置后端命令可能需要的信息。)但是`git version`呢?既然您现在知道Git命令实际上存在于系统中的`git-core`文件夹中,无论该文件夹位于何处,我建议您在其中查找`git-version`程序。你会发现在里面有`git-checkout`,`git-log`,`git-commit`,`git-diff`和许多其他命令,但你不会找到`git-version`。根本没有。 `version`命令直接内置在前端中。别名仅在调用后端命令时才起作用。因此是没有办法使用别名来执行`version`命令的。(显然,在2.9版本之后和2.24版本之前的某个时候,别名处理代码变得更加智能化,也考虑到了前端内置的命令。)
还有一件重要的事情需要知道。前端git命令知道一些常见的后端命令,但它并没有完整的后端命令列表。当您键入`git asdf`或`git rumplestiltskin`或`git helloworld`时,(这些都不是实际的Git命令),它会像往常一样设置一切,然后尝试运行`git-asdf`或`git-rumplestiltskin`或`git-helloworld`,同时告诉系统查找`git-core`目录。它没有告诉系统不要在其他目录中查找。
这意味着您可以编写自己的Git命令。如果您想要一个`git asdf`,您可以编写自己的`git-asdf`程序,并将其放在任何位置,以便运行`git-asdf`成功。现在您可以使用`git asdf`来运行它了。
您可能想知道为什么要这样做?如果您在个人bin或scripts文件夹中安装`git-asdf`,则可以直接运行`git-asdf`。事实上,您确实可以这样做。但是当您让前端运行它时,您将得到提供特殊Git设置信息的能力。主要的助手称为`git-sh-setup`,您可以通过“sourcing”它来调用它,使用`.`(POSIX)或`source`(bash):
#! /bin/sh
. git-sh-setup

这将添加shell函数diesaygit_pagerrequire_clean_work_tree等等。如果在源代码中导入git-sh-setup之前设置了shell变量OPTIONS_SPEC,它将为您解析参数。查看脚本,就在git-core目录中,了解如何使用它。

(请注意,像Git的所有事物一样,它随着时间的推移而增长。例如,在Git 1.7时代,它的功能比现在少。如果您想要向旧版Git进行回溯兼容,请克隆Git存储库,选择一个兼容级别,并使用git checkout命令查看旧版本以确定可以依赖的内容。)


非常感谢您有趣且富有启发性的回答。不幸的是,使用别名log也不起作用。请参见我上面更新的问题中的“更新1”。 - Will Hains
git --exec-path 显示什么?显示的目录中包含什么内容?(您可能安装了错误版本的 Git。) - torek
啊哈!那就是问题所在。git --exec-path 报告的目录与安装目录不同。我尝试在 .bashrc 中设置 GIT_EXEC_PATH,但没有解决问题,最后我按照这些说明从源代码构建并安装到 $HOME/bin 中。现在一切都正常了。你的回答主体实际上没有解决问题,但是你上面的最后一条评论解决了问题,所以我会将此答案标记为已接受。再次感谢,@torek! - Will Hains

7
你可以尝试在你的别名前面加上一个 !
git config --global alias.git '!git'

完成这些操作后,您将不再遇到访问“外部”脚本的问题...
这在git关于别名的页面底部有记录: https://git-scm.com/book/zh/v2/Git-基础-Git-别名

4
你也可以使用以下方法:
$ git config --global alias.v "!git version"
$ git v
git version 2.20.1

现在这个方法还可以,谢谢。(但我仍然想找出为什么它不能正常工作。) - Will Hains

0

我刚刚使用Git 2.24和2.25.1进行了测试:它完全可以正常工作。

C:\>git config --global alias.v version

C:\>git v
git version 2.25.1.windows.1

首先,尝试从旧版本2.9.0更新到当前版本2.25.1,看看问题是否仍然存在。
(如果您使用Linux,请使用ppa upgrade命令进行更新)

我怀疑Git v2.14.0-rc0(2017年第三季度)中的commit 50ad856有所帮助。


但是,从完全相同的tarball安装的这个版本在另一台机器上运行良好。因此,似乎不太可能是git版本的原因?
然后,您需要比较这两台机器帐户之间的.bashrc/.profile以及env的输出。
执行环境的差异可能会解释这种差异。

感谢您的建议。由于对此计算机的管理员存在限制,我无法轻松升级git版本。(我将寻求系统管理员的帮助。)但是,从完全相同的tarball安装的这个确切版本在另一台计算机上运行良好。因此,似乎不太可能是git版本的原因? - Will Hains
谢谢。最后,git --exec-path 是错误的(请参见我上面对@torek答案的最后一条评论)。我尝试使用环境变量来修复它,但无法使其工作,所以最终我选择了从源代码构建并安装的方式。 - Will Hains

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接