Repository | Pro | Con | Controlling Access | Create Repositories |
---|---|---|---|---|
File share | No network access required | Not internet friendly | Using filepermissions | Needs preparation per project on the share |
Git daemon | Fast git protocol | Not internet friendly port | no good permission control. Read by default, Write can be enabled , but only anonymous | per project needs to be blessed |
Plain SSH server | Allows good security | Not internet friendly port, requires account creation per user on server | Uses filepermissions | per project inited |
SSH server git-shell | Enhancement of Plain SSH Server scenario | Not internet friendly port, requires account creation per user on server | Uses filepermissions | per project inited |
Gitosis | Adds good remote management of users and repositories, only requires one system account | Not internet friendly port | Uses gitosis-config file | No server initalisation, only config is needed |
Apache http | Falls back to standard apache config, only requires one system account, internet friendly | Slightly overhead | Uses htpasswd | per project inited |
Apache http + gitweb | Falls back to standard apache config, only requires one system account, internet friendly, adds nice view of repository | Slightly overhead, read-only access | Uses htpasswd | per project inited |
github | Internet accessible, easy to use webinterface | Hosted externally | Managing sshkeys | Web interface |
http://www.kernel.org/pub/software/scm/git/docs/user-manual.html#setting-up-a-public-repository
Preparation:Git enable a simple project-X
Let's say you have project called project-X that you have been working on, on your local machine. It contains one file called README.To enable git on this project you can:
$ cd $HOME/project-X
# git init enables the git repository $ git init
# You add the readme file to the repository $ git add README
# You commit your changed to your local repository $ git commit -a -m 'Added README'
this will give you a .git directory in the project-X directory , ready to use in this tutorial
Share it over a file share
Instead of having people reference your local repository, you can put your repository on a file share.Let's say we have share path /share/git/ where we want to put our project-X
Preparing the repository
# First we navigate to the repository place and will create a new project-X dir $ cd /share/git $ mkdir project-X $ cd project-X
# now we initialize this directory # but instead of using git init, we use git --bare init # "A short aside about what git means by bare: A default git repository assumes that you will be using it as your working directory, # so git stores the actual bare repository files in a .git directory alongside all the project files. Remote repositories don't need # copies of the files on the filesystem unlike working copies, all they need are the deltas and binary what-nots of the repository itself. This is what "bare" means to git. Just the repository itself." $ git --bare init
Pushing your local repository to the shared repository
# First go to your local repository $ cd $HOME/project-X # Then make the link to the shared repository $ git remote add origin file:///share/git/project-X
# We push to the remote repository $ git push origin master
Controlling access
As we are dealing with a fileshare, permissions are handled by filesystem permissions. You could create two groups: project-X-read, project-X-write. To set these different group permissions you could use:
- Using extended permissions on Linux with setfacl - http://articles.techrepublic.com.com/5100-10878_11-6091748.html
- Extended permissions on MacOSX - chmod +a Groking Darwin ACLs - http://www.afp548.com/article.php?story=20050506085817850
Accessing the repository
# Another user can now clone the repository using: $ git clone file:///share/git/project-X # Change something $ .... # Commit the changes $ git commit -a # Push the changes to the central repository $ git push
Share using git-daemon
Installing git-daemonGit includes a simple daemon that you use to share your project using the git protocol.
On Centos,Redhat this seems to required another package:
$ sudo yum install git-daemonMore detail can be found http://www.kernel.org/pub/software/scm/git/docs/git-daemon.html
# Start the git daemon $ git daemonThis creates a network listener on the GIT port. It allows by default read access to git projects.
Prepare the repository
To allow git-daemon to read your project you have to add the file .git/git-daemon-export-ok to your project.
Controlling access
Git daemon has no notion of users. By default is allows read to everybody, if you want to give write access, then you have to enable it to everybody anonymously.
This is what makes is less suitable for controlling access.
If you try to update you receive the following erors:
# On the local side $ git push git://localhost/... Initialized empty Git repository in .... localhost[0: ::1]: errno=Connection refused localhost[0: fe80::1]: errno=Connection refused fatal: The remote end hung up unexpectedly
# On the git daemon side Error on daemon side: [9027] 'receive-pack': service not enabled for git://localhost/... ..
Accessing the repository
$ git clone git:localhost/your-path/project-X
Share using ssh server
Sharing over ssh is similar to sharing it over a filesystem.- http://toolmantim.com/articles/setting_up_a_new_remote_git_repository
- http://blog.bhushangahire.net/2009/02/19/setting-up-a-new-remote-git-repository/
# On the SSH server we assume var/git as the central repository place and will create a new project-X dir $ cd /var/git $ mkdir project-X $ cd project-X
# now we initialize this directory # but instead of using git init, we use git --bare init # "A short aside about what git means by bare: A default git repository assumes that you will be using it as your working directory # , so git stores the actual bare repository files in a .git directory alongside all the project files. Remote repositories don't need copies of the files on the filesystem unlike working copies, all they need are the deltas and binary what-nots of the repository itself. This is what "bare" means to git. Just the repository itself." $ git --bare init
Pushing your local repository to the shared repository
# First go to your local repository $ cd $HOME/project-X # Then make the link to the shared repository $ git remote add origin ssh://user@gitserver/var/git/project-X
# We push to the remote repository $ git push origin master
Controlling access
To have access, all users must have an account on the ssh server. So that means user-add for each user.
Permissions are handled by filesystem permissions. You could create two groups: project-X-read, project-X-write.
To set these different group permissions you could use:
- Using extended permissions on Linux with setfacl - http://articles.techrepublic.com.com/5100-10878_11-6091748.html
- Extended permissions on MacOSX - chmod +a Groking Darwin ACLs - http://www.afp548.com/article.php?story=20050506085817850
Accessing the repository
# Another user can now clone the repository using: $ git clone file:///share/git/project-X # Change something $ .... # Commit the changes $ git commit -a # Push the changes to the central repository $ git push
Share using git-daemon
Starting the daeminGit includes a simple daemon that you use to share your project using the git protocol.
More detail can be found http://www.kernel.org/pub/software/scm/git/docs/git-daemon.html
# Start the git daemon $ git daemonThis creates a network listener on the GIT port. It allows by default read access to git projects.
Prepare the repository
To allow git-daemon to read your project you have to add the file .git/git-daemon-export-ok to your project.
Controlling access
Git daemon has no notion of users. By default is allows read to everybody, if you want to give write access, then you have to enable it to everybody anonymously.
This is what makes is less suitable for controlling access.
If you try to update you receive the following erors:
# On the local side $ git push git://localhost/... Initialized empty Git repository in .... localhost[0: ::1]: errno=Connection refused localhost[0: fe80::1]: errno=Connection refused fatal: The remote end hung up unexpectedly
# On the git daemon side Error on daemon side: [9027] 'receive-pack': service not enabled for git://localhost/... ..
Accessing the repository
$ git clone git:localhost/your-path/project-X
Share using ssh server
Sharing over ssh is similar to sharing it over a filesystem.Preparing the repository
# On the SSH server we assume var/git as the central repository place and will create a new project-X dir $ cd /var/git $ mkdir project-X $ cd project-X
# now we initialize this directory # but instead of using git init, we use git --bare init # "A short aside about what git means by bare: A default git repository assumes that you will be using it as your working directory # , so git stores the actual bare repository files in a .git directory alongside all the project files. Remote repositories don't need copies of the files on the filesystem unlike working copies, all they need are the deltas and binary what-nots of the repository itself. This is what "bare" means to git. Just the repository itself." $ git --bare init
Pushing your local repository to the shared repository
# First go to your local repository $ cd $HOME/project-X # Then make the link to the shared repository $ git remote add origin ssh://user@gitserver/var/git/project-X
# We push to the remote repository $ git push origin master
Controlling access
To have access, all users must have an account on the ssh server. So that means user-add for each user.
Permissions are handled by filesystem permissions. You could create two groups: project-X-read, project-X-write.
To set these different group permissions you would use the set To set these different group permissions you would use the setfacl command on linux or the chmod +a on MacOSX
You could off course have multiple keys to one account, but this would not allow you to differentiate between different rights
Accessing the repository
# Another user can now clone the repository using: $ git clone ssh://user@gitserver/var/git/project-X # Change something $ .... # Commit the changes $ git commit -a # Push the changes to the central repository $ git push
Share using git-shell
Similar to the SSH Repository setup. The only difference is that instead of giving each user a normal shell f.i. '/bin/login', you set '/usr/bin/git-shell' as a more restrictive shell, that only allows the git commands.Access it in any other way will result in fun message:
fatal: What do you think I am? A shell?
Share using gitosis
Gitosis allows you to have on account on the ssh server and have all commits pass through that account.- http://scie.nti.st/2007/11/14/hosting-git-repositories-the-easy-and-secure-way
- http://blog.ardes.com/2008/5/19/git-hosting-with-leopard
- http://eagain.net/gitweb/?p=gitosis.git;a=blob;f=README.rst;hb=master
Installing gitosis
# On Centos,Redhat to install gitosis $ sudo yum install gitosis
# This creates /var/lib/gitosis # This creates a user gitosis with as default homedir /var/lib/gitosis $ grep gitosis /etc/passwd gitosis:x:100:101:git repository hosting:/var/lib/gitosis:/bin/sh
Initialize gitosis
To have gitosis initialize itself, it needs to have public key (id_dsa.pub) of a user that will be the first administrator
# To initialize the gitosis account $ sudo -H -u gitosis gitosis-init < /tmp/id_dsa.pub Initialized empty Git repository in ./ Reinitialized existing Git repository in ./ **
This results in the following structure created under:
. |-- .gitosis.conf - /var/lib/gitosis/repositories/gitosis-admin.git/gitosis.conf |-- .ssh | `-- authorized_keys |-- gitosis | `-- projects.list `-- repositories `-- gitosis-admin.git |-- HEAD |-- branches |-- config |-- description |-- gitosis-export | `-- keydir | `-- myself@my-Portable.local.pub |-- gitosis.conf |-- hooks | |-- applypatch-msg | |-- commit-msg | |-- post-commit | |-- post-receive | |-- post-update | |-- pre-applypatch | |-- pre-commit | |-- pre-rebase | |-- prepare-commit-msg | `-- update |-- index |-- info | `-- exclude |-- objects | |-- info | `-- pack | |-- pack-82e64648d14e24258fa7c569100c6805edfc314c.idx | `-- pack-82e64648d14e24258fa7c569100c6805edfc314c.pack `-- refs |-- heads | `-- master `-- tags 15 directories, 23 files
Apart from this directory structures, gitosis-init also add the key to the authorized_keys of the gitosis user.
It does not allow interactive login, and restricts the commands to the gitosis-server command.
$ sudo -H -u gitosis cat $HOME/.ssh/authorized_keys ### autogenerated by gitosis, DO NOT EDIT command="gitosis-serve myself@my-Portable.local",no-port-forwarding ,no-X11-forwarding,no-agent-forwarding,no-pty ssh-dss AAAAB3NzaC1kc3MAAACBAMAgxc ....
To make gitosis handle updates correctly we have to make the post-update executable
sudo chmod 755 /var/lib/gitosis/repositories/gitosis-admin.git/hooks/post-update
Controlling Access
Before you can push your local repository to gitosis, you have to setup the correct permissions
# Checkout the gitosis-admin repository (using the public key you used to gitosis-init $ mkdir gitosis $ git clone ssh://gitosis@gitosis-server:gitosis-admin.git # And two groups to the gitosis-conf [group project-X-read] members = usera, userb readable = project-XPushing your local repo to to the gitosis server
[group project-X-write] members = userc, userd writable = project-X
# Copy the public keys of usera,userb, userc, userd into the keydir, with the correct names |-- gitosis-export | `-- keydir | `-- myself@my-Portable.local.pub | usersa.pub | usersb.pub | usersc.pub | usersd.pub |-- gitosis.conf # Add the keys $ git add gitosis-export/keydir/*.pub $ git commit -a -m 'Added users' # push them back to the repository $ git push
$ cd project-X $ git remote add origin gitosis@gitosis-server:project-X.git $ git push origin master:refs/heads/masterThis will create a directory project-X under /var/lib/gitosis/repositories/
Accessing the repository Nothing special here. If your key was added to the gitosis-admin repository, then you can acces it with.
$ git clone gitosis@gitosis-server:project-X.git
Share over apache http
Preparing the repository# On the web server we assume var/git as the central repository place and will create a new project-X dir $ cd /var/git $ mkdir project-X $ cd project-XNow that we created the project directory we need to give apache access to it:
# now we initialize this directory # but instead of using git init, we use git --bare init # "A short aside about what git means by bare: A default git repository assumes that you will be using it as your working directory # , so git stores the actual bare repository files in a .git directory alongside all the project files. Remote repositories don't need copies of the files on the filesystem unlike working copies, all they need are the deltas and binary what-nots of the repository itself. This is what "bare" means to git. Just the repository itself." $ git --bare init
- Be sure to set the correct permissions on the /var/git directory so that it can be read by the webuser. chown -R apache:apache /var/git/project-X
- If you have selinux enabled: chcon -R -t httpd_sys_content_t /var/git/project-X
- Enable the post-update hook: chmod +x /var/git/project-X/hooks/post-update
When you did not set the post commithook:
$ git clone http://git.yourdomain.com/project-X Initialized empty Git repository in /Users/mydir/project-X/.git/ fatal: http://git.yourdomain.com/project-X.git/info/refs not found: did you run git update-server-info on the server?Then you can need to run it manually the first time
$ cd /var/git/project-X $ sudo -u apache git update-server-info
Preparing apache
This document assumes you have a basic apache setup. And you have virtual name server working. Most of it is standard acces to the directory.
To allow write access, we need to have Webdav enabled.
http://www.kernel.org/pub/software/scm/git/docs/howto/setup-git-server-over-http.txt
<VirtualHost some-ip:80> Servername git.mydomain.com DocumentRoot /var/git <Directory "/var/git"> DAV On Options +Indexes +FollowSymLinks AllowOverride None Allow from all Order allow,deny </Directory> </VirtualHost>This will add a virtual server that has access to the /var/git directory using simple browsing.
In case you are experiencing trouble:
- Remove the restrictions from welcome.conf: in this default file, it disables the index option. Error: ...
- Note the + before the options, to allow the merge of permissions
We control access to your repository using apache groupfiles and password files
<VirtualHost YOUR-IP:80> ServerName git.yourdomain.com DocumentRoot /var/git <Directory /var/git/> DAV On Options ExecCGI FollowSymLinks Indexes # Deny everyything here Deny from all AuthType Basic AuthName "git repository" AuthUserFile /var/git/htpasswd.git AuthGroupFile /var/git/htgroup.git </Directory>
<Directory /var/git/project-X> Allow from all Order allow,deny <Limit GET> Require group project-X-read </Limit> <Limit GET PUT POST DELETE PROPPATCH MKCOL COPY MOVE LOCK UNLOCK> Require group project-X-write </Limit> </Directory> </VirtualHost>
Accessing the repository
Git uses curl to access http repositories. Because our repository is now protected we need to create an entry in our $HOME/.netrc file
$ cat $HOME/.netrc machine git.yourdomain.com login reader password readerNow you should be able to clone project-X
$ git clone http://git.mydomain.com/project-XPossible Errors
Trying update error: Cannot access URL http://git.yourdomain.com/project-X/, return code 22 error: failed to push some refs to 'http://git.yourdomain.com/project-X'If there's something wrong with the permissions. Maybe you don't have webdav enabled, the user is in the wrong group, or filepermissions are not set correctly. Check your apache error_log
$ git clone http://git.yourdomain.com/project-X $ git push fatal: git-push is not available for http/https repository when not compiled with USE_CURL_MULTIerror: failed to push some refs to 'http://git.yourdomain.com/project-X'Either you compile your git client with the correct curl options. Or you can alternatively mount the remote repository as webdav share and access it via file:// references. See http://wiki.dreamhost.com/Talk:Git
The following happens if your curl library was not compiled with the correct options to post to http://kerneltrap.org/mailarchive/git/2008/1/13/564431 After a bit of research it seems that CURL compilation into GIT was not entirely successful for the Git on Mac OS X. As I was already mounting the git repository via WebDAV you an push and pull to your locally mounted repository by replacing the http URL with the path to your mounted WebDAV (/Volumes//). This worked pretty well for me and works well with Dreamhost with very little configuration.
$ git push Fetching remote heads... refs/ refs/tags/ refs/heads/ No refs in common and none specified; doing nothing.
This happens when you cloned an empty repository: Because you cloned an empty repository , you need to specify the origin and master , after this first push, you can use git push as usual
$ git push origin master
Sharing repository using apache and gitweb
By default, the apache does not provide a friendly view of the repository. To allow a better web interface, you can use git-web. This is a python script.Before you take this option, be sure to setup the simple apache http first. This allows you to better check where the problem lies.
- http://fedora.co.in/content/how-setup-gitweb-fedoracentos
- http://2008.planet-soc.com/?q=node/5770
- http://markmcb.com/2008/09/19/installing-gitweb-on-fedora-linux-and-apache
- http://www.howtoforge.com/how-to-install-a-public-git-repository-on-a-debian-server
# Easy gitweb installation on Centos,Redhat, which installs itself in /var/www/git by default $ yum install gitweb # You have to manually create a /etc/gitweb.conf file $GIT= "/usr/bin/git"; $projectroot = "/var/git/";
Gitweb provides a nice interface but if you would have it take control of your web rendering, git would be confused.
To solve this we allow different ways to access the same repository:
- Using http://git.yourdomain.com/project-X.git : using AliasMatch we can map this to the traditional index rendering
- With http://git.yourdomain.com/project-X : this will show the gitweb interface
<VirtualHost YOUR-IP:80> SetEnv GITWEB_CONFIG /etc/gitweb.conf ServerName git.yourdomain.com DocumentRoot /var/www/git AliasMatch ^(/.*?)(\.git)(/.*)? /var/git$1$3 <Directory /var/git/> DAV On Options ExecCGI FollowSymLinks Indexes # Deny everyything here Deny from all AuthType Basic AuthName "git repository" AuthUserFile /var/git/htpasswd.git AuthGroupFile /var/git/htgroup.git </Directory>
<Directory /var/git/project-X> Allow from all Order allow,deny <Limit GET> Require group project-X-read </Limit> <Limit GET PUT POST DELETE PROPPATCH MKCOL COPY MOVE LOCK UNLOCK> Require group project-X-write </Limit> </Directory>
<Directory /var/www/git> Options ExecCGI FollowSymLinks Indexes Allow from all Order allow,deny AddHandler cgi-script cgi DirectoryIndex gitweb.cgi RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^.* /gitweb.cgi/$0 [L,PT] </Directory> </VirtualHost>
Controlling Access
Similar to the Apache http Repository
Publish your local repository
Similar to the Apache http Repository but now you need to use the .git extension
$ git clone http://git.yourdomain.com/project-X.git
A very common error
$ git push No refs in common and none specified; doing nothing. Perhaps you should specify a branch such as 'master'. fatal: The remote end hung up unexpectedly error: failed to push some refs to 'file:///share/projects/project-X'If you have gone through the steps of git remote add origin ...., you might think that git would be smart enough to now that a git push needs to go to your origin.
The first time after adding this, you can't use the default git push, but you have to specify the full path
$ git push origin masterAnother way to solve this is to add the following lines to your .git/config file
$ vi .git/config [branch "master"] remote = origin merge = refs/heads/masterOr stil another way is to specify the option while you add the remote http://swedishcampground.com/adding-a-remote-to-existing-git-repo
$ git remote add --track master origin file:///share/projects/project-X