Skip to content

Instantly share code, notes, and snippets.

@textarcana
Forked from ScotterC/pre-push.sh
Last active January 10, 2016 11:19
Show Gist options
  • Save textarcana/744d9d6b8cac52cb6cf4 to your computer and use it in GitHub Desktop.
Save textarcana/744d9d6b8cac52cb6cf4 to your computer and use it in GitHub Desktop.

Revisions

  1. Scott Carleton created this gist Sep 2, 2015.
    66 changes: 66 additions & 0 deletions pre-push.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,66 @@
    #!/bin/sh

    # Called by "git push" after it has checked the remote status,
    # but before anything has been pushed.
    #
    # If this script exits with a non-zero status nothing will be pushed.
    #
    # Steps to install, from the root directory of your repo...
    # 1. git config --global init.templatedir '~/.git-templates'
    # 2. mkdir -p ~/.git-templates/hooks
    # 3. Copy this file into your repo at `~/.git-templates/hooks/pre-push`
    # 4. Set executable, run `chmod a+x ~/.git-templates/hooks/pre-push`
    # 5. Reinitialize repo `git init` (already defined hooks won't be overwrriten)
    #
    # Try a force push to master, you should get a message `*** [Policy] never force push...`
    #
    # The commands below will not be allowed...
    # `git push --force origin master`
    # `git push --delete origin master`
    # `git push origin :master`
    #
    # Nor will a force push while on the master branch be allowed...
    # `git co master`
    # `git push --force origin`
    #
    # Requires git 1.8.2 or newer
    #
    # Git 1.8.2 release notes cover the new pre-push hook:
    # <https://github.com/git/git/blob/master/Documentation/RelNotes/1.8.2.txt>
    #
    # See Sample pre-push script:
    # <https://github.com/git/git/blob/87c86dd14abe8db7d00b0df5661ef8cf147a72a3/templates/hooks--pre-push.sample>


    protected_branch='master'

    policy='[Policy] Never force push or delete the '$protected_branch' branch! (Prevented with pre-push hook.)'

    current_branch=$(git symbolic-ref HEAD | sed -e 's,.*/\(.*\),\1,')

    push_command=$(ps -ocommand= -p $PPID)

    is_destructive='force|delete|\-f'

    will_remove_protected_branch=':'$protected_branch

    do_exit(){
    echo $policy
    exit 1
    }

    if [[ $push_command =~ $is_destructive ]] && [ $current_branch = $protected_branch ]; then
    do_exit
    fi

    if [[ $push_command =~ $is_destructive ]] && [[ $push_command =~ $protected_branch ]]; then
    do_exit
    fi

    if [[ $push_command =~ $will_remove_protected_branch ]]; then
    do_exit
    fi

    unset do_exit

    exit 0