I must be missing something obvious... but Git aliases are not working at all. Help me please!
$ 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
As per @torek's suggestion, I tested the same thing with log
, and it also doesn't work:
$ 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
The problem was that git --exec-path
was somehow set to an incorrect directory. In the end, I built and installed from source and now everything works as expected. Thanks to everyone who helped.
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.)
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
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.)
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
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.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With