How to prevent yourself from force pushing to master

I am pretty reckless sometimes. I forced pushed to master several days in a row.

What does a real programmer do? - He writes a script that prevents him from doing it ever again, of course..

For the longest time this was a little complicated - you had to
install a hook onto the remote repro. For Git >1.8.2, there's a pre-push hook that was just perfect for my script.

If the hook returns an error the push is not executed.

The script

So this is the git hook i came up with.

#!/usr/bin/env ruby
# Pre-push hook that rejects force pushes to master.
# Requires Git > 1.8.2

class PushRejecter  
  def run
    if pushing_to?(:master) and forced_push?
      reject
    else
      allow
    end
  end

  def pushing_to?(branch)
    `git branch | grep "*" | sed "s/* //"`.match(branch.to_s)
  end

  def forced_push?
    `ps -ocommand= -p #{Process.ppid}`.match(/force|pfush/)
  end

  def reject
    puts "Force push to master rejected."
    exit(1)
  end

  def allow
    exit(0)
  end
end

PushRejecter.new.run  

Ignore the over engineering please..

If the current branch is master and i am force pushing it does return an error and the push is not executed.

How to install it

All my hooks are stored in a folder called ~/.git_template.

It is configured as my template directory for git:

[init]
  templatedir = ~/.git_template

In order to activate the hook you have to go into all your existing repros and execute

git init

This will install the hook for you. As I mentioned you need Git >1.8.2.

Alternatively you could place the hook in the .git/hooks/ directory manually in each of your repros.

Conclusion

I am more confident, that I will not cripple a master branch again. A nice feeling. If you like to have a look at the rest of my setup I recommend a look at
my dotfiles.