Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alias to create aliases

Tags:

git

alias

How can I write a git alias that will let me create more aliases?

For example:

git alias st status

Should create a new alias for git status under st.

like image 890
Anubian Noob Avatar asked May 29 '14 05:05

Anubian Noob


1 Answers

Each alias is simply an entry in the alias section of a git config file. For instance, if zog were an alias, it would be alias.zog

To update a git config file, you can use git config with one of the options to choose which configuration file to update. The most appropriate such options are --global (affecting your personal config file that applies to all repositories) and --local (affecting the current repository only, i.e., an alias that only works in one repo). The default is --local but --global usually makes more sense for aliases.

So let's consider a trivial example, to make git zog mean the same thing as git log:

$ git config --global alias.zog log
$ git zog --oneline
a17003a change f1
9af3861 initial

Now let's change it from meaning log to meaning frog:

$ git config --global alias.zog frog
$ git zog
Expansion of alias 'zog' failed; 'frog' is not a git command

Last, we'll remove it, since this is just for illustration and it's time to clean up:

$ git config --global --unset alias.zog
$ git zog
git: 'zog' is not a git command. See 'git --help'.

Did you mean this?
    log

You say you want an alias that creates more aliases. That means we want the alias alias to run git config. This would almost work:

git config --global alias.alias 'config --global alias.'

except for one very big problem: with this alias in place, running git alias st status results in the equivalent of the command:

git config --global alias. st status

when we want one that has alias.st as the first argument. Also, we'd run into issues with the remaining arguments if there were more than one: git config would get them split up inappropriately.

Thus, we need to resort to invoking the shell. There are many ways to code the remainder. They are hard to type in as shell commands; it's easier to edit the config file and put them in manually (git config --global --edit will do this, or you can just invoke your editor directly).

Here's an example from the git authors (I added some backslash-newline bits to make it fit better on StackOverflow; note that you can write the alias this way in your various config files):

[alias]
    alias = "!sh -c '[ $# = 2 ] && \
        git config --global alias.\"$1\" \"$2\" && exit 0 || \
    echo \"usage: git alias <new alias> <original command>\" >&2 && exit 1' -"

To make this one work I had to add another - right at the end (not shown above); I'm not really sure why, probably some FreeBSD sh variance.

Here's my version of the same thing, using shell functions to handle arguments. If you supply more than two arguments, all the extras are combined:

[alias]
    alias = "!f() { a=\"$1\"; shift; \
        git config --global alias.\"$a\" \"$*\"; }; f"

So now:

$ git alias st status --short
$ GIT_TRACE=1 git st
trace: exec: 'git-st'
trace: run_command: 'git-st'
trace: alias expansion: st => 'status' '--short'
trace: built-in: git 'status' '--short'

(or just look at the config file, with editor or git config --get).

These—both versions—are still slightly defective as they can try to re-alias an existing alias. It might be better to see if alias."$1" is already in the config file, and if so, complain (or require an argument like --overwrite or a different alias like realias or some such). Feel free to experiment with what git does with multiple entries for, e.g., alias.foo, and see the documentation for git config for how git config deals with multiple entries (they are allowed, under various circumstances).

As a general rule, once your git alias starts getting hairy like this, it's probably better to just write a shell script (or shell function) for it.

like image 51
torek Avatar answered Oct 30 '22 18:10

torek