Stop yourself from committing to master with git hooks

This is based on the excellent work of Aaron Hoffman which he’s written up here.

This process adds two git hooks to your repositories which prevent you from committing or pushing to a branch named master.

Add directories

Git hooks live in each of your git repositories rather than in a global location, and so the first thing to do is create the files which will be copied into each repository when you do a git clone (or a git init in an existing local repository).

mkdir -p ~/.git-templates/hooks

Add git hooks

Create a file called pre-commit and give it this content:

!/bin/sh
prevent commit to local master branch
branch=git symbolic-ref HEAD
if [ "$branch" = "refs/heads/master" ]; then
echo "pre-commit hook: Can not commit to the local master branch."
exit 1
fi
exit

Create a file called pre-push and give it this content:

!/bin/sh
Prevent push to remote master branch
while read local_ref local_sha remote_ref remote_sha
do
if [ "$remote_ref" = "refs/heads/master" ]; then
echo "pre-push hook: Can not push to remote master branch."
exit 1
fi
done
exit 0

Mark them as executable

chmod a+x .git-templates/hooks/*

Set the git init.templateDir configuration variable

git config --global init.templateDir '~/.git-templates'

Add the hooks to an existing local repository clone

Run git init while in your local clone directory. This is a non-destructive command which will copy the new hooks into your REPO/.git/hooks directory

You can double-check the git-init docs if you’re nervous before doing this!

Add the hooks when you clone a repository

Just clone the repo and your hooks will be in the .git/hooks directory!

Downsides

You will no longer get the sample git hooks copied into REPO/.git/hooks, nor the sample excludes file but they will continue to exist in /usr/share/git-core/templates and can be copied into your ~/.git-templates directory if you want to keep them.

Configuring get_iplayer

There are lots of ways of setting up get_iplayer. Here’s mine.

It means that filenames work across Windows and Linux, removes underscores from names, never deletes old episodes and downloads episodes into a directory named after the series and names the files with the series’ episode number.

Your own options file is in ~/.get_iplayer or c:usersusername.get_iplayer depending on your operating system.

How to push to two servers at once with git

As I said this time last year, I dislike the idea of people using a decentralised version control system to centralise their code.

This means that some of my code sits in Bazaar on my server, some in Git on my server, and some in github. I’m not keen on this situation, and given that github does have a large amount of mindshare, and that launchpad is really quite horrible to use, I want to be able to “git push” to both my server and github at the same time.

It turns out this is quite easy; and everything below (with a few very minor modifications) comes from “Setting up a new remote git repository” by Tim Lucas and Aristotle Pagaltzis‘ answer on this Stackoverflow question.

So, given that I have a working github repo, and a local checkout:

Set up the new bare repo on the server:

$ ssh myserver.com
$ mkdir /var/git/myapp.git
$ cd /var/git/myapp.git
$ git --bare init
Initialized empty Git repository in /var/git/myapp.git
$ exit

Add the remote repository to your existing local git repo and push:

$ cd ~/code/myapp
$ git remote add myserver ssh://myserver.com/var/git/myapp.git
$ git push myserver master

You have now associated the remote repo with your local repo under the name “myserver”. Now open up ~/code/myapp/.git/config and:

put something like this:

[remote "public"]
    url = git@github.com:username/myapp.git
    url = ssh://myserver.com/var/git/myapp.git

Now you can say “git push public” to push to both repos at once.

and that’s it! Every time you push you will be making sure that your code lives on both your server and on github. Adds links to both in your README and the job is complete.

Github worries me

I’m not that keen on git (for mostly aesthetic reasons although I suspect I’ll have to get over this soon), and github makes me jump through a couple of hoops too many to get up and running for the first time, but those aren’t things that worry me.

I’m worried about github going away.

Specifically I’m worried about it going away because so many people I actually know use it. Of course, github reminds me of this every time I log in because the social network features that allow you to follow people, as well as projects, has a constantly updating stream of their activity; something that, as far as I know, Sourceforge and Google Code have never allowed you to do. For me, this changes the dynamic of a hosted version control system quite drastically, because you’re suddenly being shown, very clearly, all the changes your friends are making, and how much they’re investing in this system.

What I really want to know is – where else are they hosting their code? I mean, this is the kind of thing a distributed version control system makes easy, right? But as far as I know, none of these people are hosting their code themselves so that if github went away I’d have no way of  keeping track of what’s going on nor of accessing their code at all.

This kind of thing never seemed like an obvious concern on the centralised code-hosting services, and if it was then it was localised to “me and the projects I’m interested in”. By spreading that more obviously to my network it seems like a much more important problem.

Bazaar and Git

I’ve had cause to use both Bazaar and Git recently, which are very similar to one another and both of which I quite like.

Git seems slightly slicker, and gives me nicely colourised output, which I’m a sucker for. Then of course there’s GitHub, which is a very appealing way of easily publishing your code, forking and so on. All of these mean I’ll probably use it in the future.

The command set of Bazaar feels more natural to me, which I miss a lot in Git. Its parameters for seemingly simple tasks are comparatively obscure, and to this newbie, poorly explained by the command-line help, a consequence of which is that I have found the GitHub guides invaluable. Also, I always forget that in Ubuntu running sudo apt-get install git will not actually install git, but “GNU Interactive Tools, a file browser/viewer and process viewer/killer” (it’s sudo apt-get install git-core, for reference!).

There’s some interesting commentary on revision control systems as a whole, and the git command set in particular on Revision Control Systems suck and the series of posts he links to.

Disable system bell in msys

I am using Git on the command line in Windows via msysgit.

As with all msys installs whenever you press backspace and there is no more text to delete or you press TAB for auto-complete when there are multiple options, your speaker utters an horrendous, ugly beep.

To disable this, load msys and find out where your home directory is:

echo $HOME

Go to that directory (either in Windows or through msys) and create a new file called .inputrc

Put one line in that file:

set bell-style none

Save it and restart msys. You should now have no system bell! I’ve also seen it advised that you can disable your system bell by disabling the hardware emulation for this device in Device Manager, but this didn’t seem to work for me in Vista.