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

Wil*_*ins 3 git

我一定遗漏了一些明显的东西……但是 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
Run Code Online (Sandbox Code Playgroud)

更新 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
Run Code Online (Sandbox Code Playgroud)

更新 2:已解决

问题是git --exec-path不知何故设置为不正确的目录。最后,我从源代码构建和安装,现在一切都按预期工作。感谢所有帮助过的人。

小智 8

您可以尝试!在别名前面加上一个:

git config --global alias.git '!git'
Run Code Online (Sandbox Code Playgroud)

这样做之后,访问“外部”脚本就不再有问题......

这记录在 git 关于别名的页面底部: https://git-scm.com/book/en/v2/Git-Basics-Git-Aliases


tor*_*rek 6

Use a command other than version. Try aliasing l to log, for instance. (Or, as VonC notes, upgrade—it actually does work in modern Git. The alias handling seems to have been rewritten between 2.17.3 and 2.18.0.)

Why does l = log work, and yet v = version not?

This is a little tricky!

Most Git commands are—and at one point, all Git commands were—separate programs that are installed separately into a directory (or folder, if you prefer the term) full of "Git commands you can run". For instance, git log is actually implemented by a command spelled git-log, which is installed in a special directory / folder.

This directory / folder is not one you normally run commands from, though.

Back in the distant past, these Git commands—git-log, git-commit, git-add, git-diff, and so on—were all installed directly, and you ran them directly, by typing in git-something. This worked OK with bash's autocompletion, in that you could type git-comTAB to get the commit command, or git-chTAB to get the checkout command. But over time, the number of Git commands grew (git-cherry and git-cherry-pick), and grew, and grew; and eventually even typing in the full command git-add wasn't enough because there's also git-add--interactive for instance, so the TAB completion basically completely stopped working.

A decision was made: Git wasn't going to stop coming with 57 different commands—actually, it's over 150 now—but instead, all these various implementation commands would be stuffed away into a place where they would not be all up in your face all the time. A single front end command, spelled git, would let you type in the command as an argument to the front-end git command: git com, then TAB: bash now has a list of allowed completions, and will only pick commit since that's the only com that you would use, not the git-commit-tree or git-commit-graph back end programs that only scripts regularly use.

So: the front end git command knows how to find and run all the various back end implementations. By convention, most of them are in the git-core directory: run

git --exec-path
Run Code Online (Sandbox Code Playgroud)

and the front end prints out the name of the place where all the back-end programs actually live. (You can look in there, and even run them out of there directly if you like, although these days the front end git command now sets up information that the back end commands may want.)

But what about git version? Well, now that you know that Git commands actually live in the git-core folder, wherever that may be on your system, I suggest you look in there. Where is the git-version program? You will find git-checkout in there, and git-log, and git-commit, and git-diff and many others, but you won't find a git-version. There isn't one.

The version command is built directly in to the front end. The aliases only work when invoking a back end command. So there is—or was, anyway—no way to alias version. (At some point, obviously post 2.9 and pre 2.24, the alias handling code was smartened up to check the front-end built-ins as well.)

There's one more important thing to know

The front end git command does know about some common back end commands, but it doesn't have a complete list of back end commands. Instead, when you type in git asdf or git rumplestiltskin or git helloworld—none of which are actual Git commands—it just sets things up as usual and then attempts to run git-asdf or git-rumplestiltskin or git-helloworld, while telling the system to look in the git-core directory. It doesn't tell the system not to look in other directories.

This means you can write your own Git commands. If you want a git asdf, you can write your own git-asdf program, and put it anywhere so that running git-asdf succeeds. You can now run it using git asdf.

Why, you might wonder, would you want to do this? If you install git-asdf in your own personal bin or scripts folder, you can just run git-asdf. And indeed, you can do that. But when you have the front end run it, you're run with special Git setup information provided. This gives you the ability to write your program as an sh (or bash) script and get direct access to various Git helpers. The main helper is called git-sh-setup and you invoke it by "sourcing" it, with . (POSIX) or source (bash):

#! /bin/sh
. git-sh-setup
Run Code Online (Sandbox Code Playgroud)

This adds shell functions die and say and git_pager and require_clean_work_tree and more. If you set the shell variable OPTIONS_SPEC before sourcing git-sh-setup, it will parse arguments for you. Look at the script—it's right there in the git-core directory—to see how to use it.

(Note that, like all things Git, it has grown over time. It has more functions now than it did in the days of Git 1.7, for instance. If you want something that backports to older versions of Git, clone the Git repository for Git, pick a compatibility level, and git checkout the old one to see what you can rely on.)