Context
I like GIT
Why? Because:
- it’s faster than SVN
- compacts better than SVN — quoting someone, “The Mozilla project’s CVS repository is about 3 GB; it’s about 12 GB in Subversion’s fsfs format. In Git it’s around 300 MB.”
- working with branches takes a whole different meaning with GIT compared with SVN. For me, easier and more intuitive…
- it’s distributed — no need for remote service!!
This said, I wanted to have a central place for keeping my GIT repositories, and where I could create repositories to work with other developers. There are many free GIT repositories, but it’s always funnier to create a GIT “server” by yourself and for yourself
Doing all this, is fairly easy. For example, a shell account, shell access over SSH, and you’re done. But doing it for many projects, for many people, keeping people from messing the others’ repositories and maintaining your server’s security gets bit more complicated.
What I wanted was:
- to have one shell account in my server to access all my repositories
- I wanted also to give access to those repos to other people
- I wanted to give people access to certain repositories only
- Finally, I do not want to give shell access to anyone!
If we think a bit about the “nature” of GIT, and what is needed to give access over ssh to a shell, we’ll come up with the conclusion “this might not be that easy to do…”
Well, at least, with my knowledge (which is very modest indeed), that’s what I concluded
Luckily, there’s a tool which we can use to manage all of this. Gitosis does the job.
How to
First we need to get Gitosis. Let’s grab it from a git repo and install it. (Ensure you have git installed and python setuptools)
sudo apt-get install git-core python-setuptools cd temp/ git clone git://eagain.net/gitosis.git cd gitosis python setup.py install
Gitosis needs a user whose job will be to maintain all repositories inside its home directory and to allow logins over ssh. So, next we’ll create a new system user, with no password and disabled login. We just need to work over ssh with this user.
sudo adduser \ --system \ --shell /bin/sh \ --gecos 'git version control' \ --group \ --disabled-password \ --home /home/git \ git
The above, creates a user named git, with no password and disabled login (we can still use the identity, if you’re a superuser for example…), with sh as its shell and the gecos field with a small description.
Now, we’re ready to configure gitosis. We need to add a public key of the user that you will use to manage all the repositories. This user will be able to create new repositories and allow users to work with specific repositories, along other things. Call it the administrator and I assume this will be you
So you need to take your public key and copy it to your server, where you are installing gitosis. Assuming the key you’ve just copied to the server has the default name, we’ll next initialize gitosis with that same key.
sudo -H -u git gitosis-init < id_rsa.pub
The above will output two lines, hopefully these:
Initialized empty Git repository in ./ Initialized empty Git repository in ./
To finish this we need just to make sure that a certain file is executable.
sudo chmod 755 /home/git/repositories/gitosis-admin.git/hooks/post-update
In the server, this is it for now. Next we want to create and manage repositories.
Managing
Guess how you’ll manage the repos!?
That’s right! You’ll manage them through a git repository as well!
So, the initialization we did before in the server, created a repository only accessible to whom has the private key associated to the public key we used. This should be you and, if so, you’ll be able to clone the repo.
git clone git@YOUR_SERVER_HOSTNAME:gitosis-admin.git
The above will ask for your private key password, and create the repo. Inside you’ll find a file, gitosis.conf, and a directory, keydir.
We manage repositories and users by editing gitosis.conf and adding public keys to the keydir directory.
To create a new Git repo in your server, you just need to open gitosis.conf and create a new group section. For example, to create a repository named bigone:
- open and edit gitosis.conf
[gitosis] [group gitosis-admin] writable = gitosis-admin members = belerophon@belerophon-laptop [group bigone] writable = bigone members = andre john fcporto karmic
- add the user’s public keys to the keydir directory. These files must be the names in the members line ending with .pub
$ ls -al gitosis-admin/keydir/ drwxr-xr-x 2 belerophon belerophon 4096 2009-10-11 23:09 . drwxr-xr-x 4 belerophon belerophon 4096 2009-11-05 03:22 .. -rw-r--r-- 1 belerophon belerophon 395 2009-10-11 23:09 andre.pub -rw-r--r-- 1 belerophon belerophon 750 2009-07-27 16:48 belerophon@belerophon-laptop.pub -rw-r--r-- 1 belerophon belerophon 404 2009-07-27 16:50 john.pub -rw-r--r-- 1 belerophon belerophon 750 2009-07-27 16:48 fcporto.pub -rw-r--r-- 1 belerophon belerophon 406 2009-07-30 22:41 karmic.pub
- commit and push the changes
cd gitosis-admin git add . git commit -a -m"just created new repo called bigone, and associated andre, john, fcporto and karmic users to it." git push origin master
The two steps above just created a new repo, added new users and the corresponding keys. Each user listed in the members’ line, with access to the associated private key, will have commit rights over the repo bigone.
So, if you want to create another repo, you just have to create another group section and add new users, or the users that already exist, in the members’s line. You then commit and push, and you’re repo will be ready to use.
So from, this moment on, any of the users listed in the gitosis.conf file can initialize a repo and push it to your remote repo. Just like this:
mkdir bigone cd bigone git init git remote add origin git@YOUR_SERVER_HOSTNAME:bigone.git ... git add bla.txt git add foo.txt ... git commit -a -m"commit message" ... git add some_more_files.txt ... git commit -a -m"another commit message" ... git push origin master:refs/heads/master
I did not come up with any of this! Credits go to the original post.
In this post you can read about this same process but tweaked for a customized linux installation.
Emailing after push
Something very useful when you’re working in a development team, is emailing the changes whenever a push is made by one of your team members. This can be done with hooks. Hooks are executable files which get called upon specific actions.
In your server, all the repositories are kept inside /home/git/repositories/, and inside each repo, there is a directory hooks with all the hooks.
To email the changes to a group of people, you want to mess with the post-receive hook. This one gets called after a git push in a local repository. So all you need to do, is to write code inside that file capable of emailing the changes, and make the file executable. Fortunately, you don’t need to write the code, because the git installation comes with a script capable of doing this. You just need to make it executable and link it to the hooks directory in your repository folder
cd /home/git/repositories/bigone.git/hooks rm post-receive ln /usr/share/doc/git-core/contrib/hooks/post-receive-email post-receive -s
The above just creates a link to the script that emails the changes. Now you need to specify to whom email the changes. This can be done by editing the config file inside the repo.
cd /home/git/repositories/bigone.git/
vim config
[hooks]
mailinglist = developer@server.com anotheruser@server.com
announcelist = develeoper@server.com
envelopesender = developer@server.com
emailprefix = [GIT]
The mailinglist is an email or more to which emails will be sent. The announcelist is the email or emails to which emails of pushes with annotated tags will be sent. The envelopesender lets you define the sender of the email, and emailprefix will show up in the subject of the emails.
As a note, I’d like to remark that hooks are very useful: imagine that you are involved in a web project and you need a web server always working with the HEAD of your remote GIT repository. One alternative would be you entering the location from where the web server reads the contents and pulling the repository after every push made by the developers. But you can automate all of this process. You just have to write a script that changes the directory to the appropriate location and pulls the repo. Then, you just have to call this same script from a hook of the remote repo. You can choose see when each of the hooks available gets called right here
(PLEASE NOTE that the repositories created by gitosis are bare repositories, hence no original files are kept but only the diffs instead!)
References
- http://git-scm.com/
- http://git.or.cz/gitwiki/GitSvnComparsion
- http://swik.net/gitosis
- http://scie.nti.st/2007/11/14/hosting-git-repositories-the-easy-and-secure-way
- http://www.kernel.org/pub/software/scm/git/docs/githooks.html
- http://www-cs-students.stanford.edu/~blynn/gitmagic/ch07.html
- http://developer.berlios.de/docman/display_doc.php?docid=1813&group_id=2
-rw-r--r-- 1 belerophon belerophon 397 2009-10-08 11:12 belerophon@belerophon-laptop.pub
Post a Comment