How to alias a tag in Git?

2.4k Views Asked by At

I have a Git command alias to checkout the latest tag from a repository:

~/.gitconfig:

checkout-latest = !git checkout $(git describe --tags `git rev-list --tags --max-count=1`)

So I can use it in properly tagged repositories like this:

$ git checkout-latest

I have command aliases for the checkout command:

~/.gitconfig:

co = checkout

The checkout-latest does not work with the command aliases for checkout:

$ git co-latest
git: 'co-latest' is not a git command. See 'git --help'.

How can I configure Git so that I can use latest as a tag alias that points to the programmatically determined latest tag? I would like to use it like this:

$ git checkout latest

and

$ git co latest

Note that there is no dash between the subcommand and the tag in my desired variants.

3

There are 3 best solutions below

0
On

The only solution to this sort of thing I can think of is a git shell function that does "dispatch" based on arguments.

Something like this:

git() {
    if [ "$1" != checkout ] || [ "$#" -ne 2 ]; then
        git "$@"
        return
    fi

    local lastrev lasttag

    case $2 in
        :latest)
            lastrev=$(git rev-list --tags --max-count=1)
            set -- checkout "$(git describe --tags "$lastrev")"
        ;;
    esac

    git "$@"
}

The tag aliases need to be invalid as normal refs to be safe for hence the use of check-ref-format.

This construct allows for arbitrary tag "aliases" to be added via the case statement.

This function is very limited in terms of what arguments can be used if you want to use the tag "alias". Specifically you cannot pass any. The command must be git checkout <alias>. Parsing all valid git checkout combinations is simply too hard to bother with for this now (though it could probably be done).

1
On

Git aliases cannot reference other aliases.

You can accomplish this with another layer of indirection, however:

co-latest = !git checkout-latest "$@"
0
On

Git can already alias tags in the sense that you can make a new tag which points to the same commit as another tag.

What you seem to want is a macro alias; for Git to recognize a special word like latest and dynamically substitute that with a tag.

Since that probably isn't going to happen without modifying Git, you can make the shell do it, and interpolate via $(...) command substitution:

git checkout $(latest)

latest is just a shell script or function that dynamically computes the tag and prints it on its standard output.

Another idea is to just have an actual latest tag installed as an alias in the repo. When a new change is tagged, latest is pushed forward to that (via git tag -F). Such tagging is a non-fast-forward change, of course, so the upstream repo has to allow that.