Disable specific git commands in a particular repository

git

Three times recently, I've done really stupid things while using git. Twice I've run git reset --hard on my home-directory repository. The first time I fat-fingered a reverse-history search in my shell (didn't mean to run it at all), and the second time I was in the wrong terminal window (meant to reset a different repo). The other mistake was running git push --mirror ssh://remote-machine/ from the wrong repository.

git help config informs me that "To avoid confusion and troubles with script usage, aliases that hide existing git commands are ignored.", so my .git/config aliases

[alias]
reset = "!echo no"
push = "!echo wrong repo"

are ignored. Is there a way to do this simply? I'll likely write a wrapper script of some sort and alias git=wrapped-git in my shell, but I was hoping there'd be a simpler way to do it.

Update: using the following, based on grawity's answer, but taking advantage of git's built-in configuration system. This avoids grep'ing an ad-hoc file, and it allows for "cascading" (~/.gitconfig disables 'reset' globally, but per-repo .git/config enables it). In my .zshrc:

git () {
    local disabled=$(command git config --bool disabled.$1 2>/dev/null)
    if ${disabled:-false} ; then
        echo "The $1 command is intentionally disabled" >&2
        return 1
    fi
    command git "$@"
}

Best Answer

Not exactly a wrapper script – you can create a shell function:

git() {
    local gitdir=$(git rev-parse --git-dir 2>/dev/null)
    if [[ $gitdir && -f $gitdir/disabled-commands ]]; then
        # "disabled-commands" should contain "push", "reset", etc
        if grep -Fwqse "$1" "$gitdir/disabled-commands"; then
            echo "You have disabled this command." >&2
            return 1
        else
            command git "$@"
        fi
    else
        command git "$@"
    fi
}

There isn't a simpler way than that.

Edit: Added -e to grep: without it, grep interfered with calls like git --version, which became grep -Fwqs --version, and also with tab completion features.

Related Question