Part 1: Version Control - git and gitosis
As soon as you move beyond one developer version control becomes a necessity. Even alone, the advantages of being able to roll back your code, manage releases, and automate deployment are considerable. Version control is the foundation of any software engineering enterprise and so before anything else, we'll start here.
Things have progressed since the days of CVS, and now we have funky new distributed version control systems to play with. These allow developers to have a personal repository on their machines and push out changes to remote repositories for merging and release. Apart from being able to work more easily on the move, and encourage more regular commits of your code, this supposedly makes merges much less painless as well. So I'm going to run you through installing git, which is one of the most recognisable names in this category, and the server component, gitosis.
Before we start a note about environment - I'm working on a mac, but these instructions should be easily translatable to any platform. I'm also assuming that you have a 'management server' which is going to act as a persistant, backed up location for your repository and for other key software in later posts. In my case this is running Ubuntu, for other flavours of linux you will have to change the package install steps. I'm going to refer to these as local and mgt below and I'm assuming you also have an account called dev on mgt which we'll use to set things up.
Start by installing git on both local and mgt and setup your details correctly on local so commits are attributed:
git config --global user.name "John Doe" git config --global user.email "email@example.com"Next on mgt install gitosis, which on ubuntu is conveniently packaged:
sudo apt-get install gitosisIf you want to access your gitosis repository remotely, then ensure that your firewall/router has a rule setup to forward port 9418 to mgt. Next, create a ssh key setup for the dev user on mgt and initialise the repository:
ssh-keygen -t rsa sudo -H -u gitosis gitosis-init <~/.ssh/id_rsa.pubAt this point, you're pretty much up and running, give it a go by checking out the admin repository on mgt:
mkdir ~/repo cd ~/repo git clone -o myco firstname.lastname@example.org:gitosis-admin.git(Replace myco with a tag for your company; this option isn't strictly necessary, but I've found it useful when pushing changes to more than one place to be explicit about pushes to the company repository)
Adding a user
Now to create an account for yourself to access to your new repository. Generate yourself a ssh key if you don't have one already and copy it from local to the gitosis-admin project you just cloned:
ssh-keygen -t rsa scp ~/.ssh/id_rsa.id email@example.com:~/firstname.lastname@example.orgThen edit ~/repo/gitosis-admin/gitosis.conf on mgt to create a new group for your team with your first project and add yourself to the members line. While you're there add yourself to the gitosis-admin team. Something like:
[gitosis] [group gitosis-admin] writeable = gitosis-admin members = email@example.com firstname.lastname@example.org [group teamawesome] writable = myproject members = email@example.comNow for your first commit!
cd ~/repo/gitosis-admin git add firstname.lastname@example.org git commit -am 'Created myproject and added John' git push myco masterThe git add does what it says and marks a file to be added to the repository - git won't add any files you don't tell it to, so you can have versioned and unversioned files in the same directory. The next line commits your changes to the local repository (in ~/repo/gitosis-admin/.git) with -a to tell git to commit all files which have changed. The last command then pushes the local repository to the gitosis server you cloned it from (which is also mgt in this first case).
Now you have access to the gitosis-admin project, let's add another user but this time locally. Get Jane to give you her public key and on local:
mkdir ~/repo cd ~/repo git clone -o myco email@example.com:gitosis-admin.git cd gitosis-admin cp janes-public-key.pub firstname.lastname@example.org git add email@example.comEdit gitosis.conf and add Jane to myproject members, then:
git commit -am 'Added Jane to myproject' git push myco masterNow you've told gitosis-admin about myproject and added some users, lets actually make the project on local and initialise the local repository:
mkdir ~/repo/myproject cd ~/repo/myproject git initAnd push it out to gitosis:
git remote add myco firstname.lastname@example.org:myproject.git git add . git push myco masterAdd a new file:
echo 'A test file' > test.txt git add test.txtCommit it locally (repository in ~/repo/myproject/.git):
git commit -am 'Added test file'Push changes to gitosis for everyone else to grab:
git push myco masterAnd if Jane wants to work on the project from her machine she can do:
cd ~/repo git clone -o myco email@example.com:myproject.gitOne other useful command is if you're coming back to a repository that's already checked out and you want to make sure you have all the latest changes from gitosis:
git pullSo that's the basics, but there's one final thing I like to have setup... I've always liked to have a mailing list running which shows commits into the central repository so all developers can have an eye to what's going on and how projects are evolving. In this case I've setup a google group on our corporate google apps account and added John and Jane as members. Now to integrate gitosis with it. Unfortunately this requires editing a file in the actually repository itself on mgt:
cd /srv/gitosis/repositories/myproject.git cat <<EOF |sudo tee -a config [hooks] mailinglist = firstname.lastname@example.org announcelist = email@example.com envelopesender = firstname.lastname@example.org EOF echo 'A meaningful description of my project' |sudo tee descriptionYou also need to setup a hook. For future projects this will be rolled out by default by us dropping it into the templates directory so that you only have to edit the config file and provide a description as above:
sudo cp /usr/share/doc/git-core/contrib/hooks/post-receive-email /usr/share/git-core/templates/hooks/post-receive sudo chmod +x /usr/share/git-core/templates/hooks/post-receive cd /srv/gitosis/repositories/myproject.git/hooks sudo -u gitosis ln -s sudo chmod +x /usr/share/git-core/templates/hooks/post-receiveThat's it, try making a change and committing in your project - you should get an nice emailing telling you about the changes.
I hope that you've found this a useful, version control is one of the most worthwhile things to push for at any firm even though it seems complicated at first. Stick with it, soon it will seem like second nature. In the next post we'll get our teeth into something more complicated still - automating your infrastructure setup with Chef.
PS. Much of the above I'm typing up after the fact (note to self - document as I go along). So if you find any inaccuracies, missing steps, or the like I apologise and please let me know in the comments so I can fix.
Image courtesy of grendelkhan