Last Updated: April 29, 2019
·
23.89K
· jeffremer

Extend Git with Custom Commands

You can extend and customize git through command aliases. You can also add entirely new commands.

Place any executable with a name like git-squash in your PATH and git will automatically make it available as a subcommand.

You can then call it just like any other git command.

$ git squash 3

The git executable places precedence with it's own commands in ls $(git --exec-path), the GITEXECPATH environment variable, and the $(gitexecdir) from the git Makefile during build/install time, so make your command name is unique. That's how projects like git-flow extend git.

Turns out git provides a library of shell functions expressly for this purpose, at $(git --exec-path)/git-sh-setup. Use it in your own shell scripts like:

source "$(git --exec-path)/git-sh-setup"

After that you'll have access to a handful of shell functions that perform useful actions and sanity checks or give you access to git information such as handy usage and die methods.

For example:

git-squash

#!/bin/sh

source "$(git --exec-path)/git-sh-setup"

USAGE="COMMITS"
function _squash() {
    if [[ $# == 1 ]]; then
        if [[ -n $(git rev-parse --verify --quiet HEAD~$1) ]]; then
            git rebase -i HEAD~$1
        else
            die "HEAD~$1 does not exist"
        fi
    else
        usage
    fi  
}

_squash $1

In fact many of the executables that ship with git are just shell scripts, such as git bisect and even git rebase.

3 Responses
Add your response

Thanks! it was useful. Git's approach seems really smart. I am wondering if that's some common pattern for unix programs since never saw it before

over 1 year ago ·

how to make this new command auto complete in zsh?

over 1 year ago ·

This is how git-secret works. It has a bash script that does gpg encryption and decryption of files when you run commands like git secret hide and git secret reveal. You first git secret tell someone@example.com to add them to a keyring in a hidden folder .gitsecret. Then you add a load of secret files to .gitignore and with git secret add file1 file2. Now when you git secret hide it calls git-secret hide which runs the hide function. That gpg encrypts the hidden file with all the keys in the keyring. Now only collaborators can get at the secrets that are encrypted on github. We created keys for our deployment webhooks which pull the latest config in git, decrypt it, then install it into our kubernetes cluster.

over 1 year ago ·