Whether you are setting up an open source development environment, in which many people across the Internet might develop a project, or establishing a project for internal development within a private group, the mechanics of collaboration are essentially the same. The main difference between the two scenarios is the location of the repository and access to it.
The phrase “commit rights” is really sort of a misnomer in Git. Git doesn’t try to manage access rights, leaving that issue to other tools, such as SSH, more suited to the task. You can always commit in any repository to which you have (Unix) access either via SSH and “cding” to that repository, or through which you have read, write, and execute access.
The concept might better be paraphrased as “Can I update the published repository?” In that expression, you can see the issue is really the question, “Can I push changes to the published repository?”
Earlier, in Referring to Remote Repositories, I cautioned you about
using the remote repository URL form
/path/to/repo.git because it might display problems
inherent in repositories using shared files. On the other hand, setting
up a common depot from which several repositories that are very similar
are offered is a common situation where you would want to use a shared,
underlying object store. In this case, you expect the repositories to be
monotonically increasing in size without objects and refs being removed
from them. This situation can benefit from large-scale sharing of many
the object store by many repositories, thus saving tremendous volumes of
disk space. To achieve this space savings, consider using the
--reference
, or
the repository
--local
or --shared
options during
the initial bare-repository clone-setup step for your published
repositories.
As mentioned earlier in this chapter, it might be sufficient for your project to publish a bare repository in a known location on a filesystem inside your organization that everyone can access.
Naturally, “access” in this context means that all developers can see the filesystem on their machines and have traditional Unix ownership and read-write permissions. In these scenarios, using a filename URL such as /path/to/Depot/project.git or file://path/to/Depot/project.git might suffice. Although the performance might be less than ideal, an NFS-mounted filesystem can provide such sharing support.
Slightly more complex access is called for if multiple development machines are used. Within a corporation, for example, the IT department might provide a central server for the repository depot and keep it backed up. Each developer might then have a desktop machine for development. If direct filesystem access such as NFS is not available, you could use repositories named with SSH URLs, but this still requires each developer to have an account on the central server.
In any situation where you publish a repository, it is strongly advised that you publish a bare one.
In the following example, the same repository published in /tmp/Depot/public_html.git earlier in this chapter is accessed by a developer who has SSH access to the hosting machine:
desktop$desktop$
cd /tmp
git clone ssh://example.com/tmp/Depot/public_html.git
Initialize public_html/.git Initialized empty Git repository in /tmp/public_html/.git/ [email protected]'s password: remote: Counting objects: 27, done. Receiving objects: 100% (27/27), done.objects: 3% (1/27) Resolving deltas: 100% (7/7), done. remote: Compressing objects: 100% (23/23), done. remote: Total 27 (delremote: ta 7), reused 0 (delta 0)
When that clone is made, it records the source repository using the URL ssh://example.com/tmp/Depot/public_html.git.
Similarly, other commands such as git fetch and git push can now be used across the network:
desktop$ git push
[email protected]'s password:
Counting objects: 5, done.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 385 bytes, done.
Total 3 (delta 1), reused 0 (delta 0)
To ssh://example.com/tmp/Depot/public_html.git
55c15c8..451e41c master -> master
In both of these examples, the password requested is the normal Unix login password for the remote hosting machine.
If you need to provide network access with authenticated developers but are not willing to provide login access to the hosting server, check out Tommi Vertanen’s gitosis project at git://eagain.net/gitosis.git.
Again, depending on the desired scope of access, such SSH access to machines may be entirely within a group or corporate setting or may be available across the entire Internet.
If you want to share code, you’ll probably want to set up a hosting server to publish repositories and allow others to clone them. Anonymous, read-only access is all that developers need to clone or fetch from these repositories. A common and easy solution is to export them using git-daemon and also perhaps an HTTP daemon.
Again, the actual realm across which you can publish your repository is as limited or as broad as access to your HTTP pages or your git-daemon. That is, if you host these commands on a public-facing machine, anyone can clone and fetch from your repositories. If you put them behind a corporate firewall, only those people inside the corporation will have access (in the absence of security breaches).
Setting up git-daemon allows you to export your repositories using the Git native protocol.
You must mark repositories as “OK to be exported” in some way. Typically this is done by creating the file git-daemon-export-ok in the top-level directory of the bare repository. This mechanism gives you fine-grained control over which repositories the daemon can export.
Instead of marking each repository individually, you can also
run git-daemon with the
--export-all
option to publish all identifiable (by
having both an objects and a
refs subdirectory) repositories found in its
list of directories
. There are many
git-daemon options that limit and configure which
repositories will be exported.
One common way to set up the git-daemon daemon on a server is to enable it as an inetd service. This involves ensuring that your /etc/services has an entry for Git. The default port is 9418, though you may use any port you like. A typical entry might be:
git 9418/tcp # Git Version Control System
Once you add that line to /etc/services, you must set up an entry in your /etc/inetd.conf to specify how the git-daemon should be invoked.
A typical entry might look like this:
# Place on one long line in /etc/inetd.conf git stream tcp nowait nobody /usr/bin/git-daemon git-daemon --inetd --verbose --export-all --base-path=/pub/git
Using xinetd instead of inetd, place a similar configuration in the file /etc/xinetd.d/git-daemon:
# description: The git server offers access to git repositories service git { disable = no type = UNLISTED port = 9418 socket_type = stream wait = no user = nobody server = /usr/bin/git-daemon server_args = --inetd --export-all --base-path=/pub/git log_on_failure += USERID }
You can make it look as if repositories are located on separate hosts, even though they’re just in separate directories on a single host, through a trick supported by git-daemon. The following example entry allows a server to provide multiple, virtually hosted Git daemons:
# Place on one long line in /etc/inetd.conf git stream tcp nowait nobody /usr/bin/git-daemon git-daemon --inetd --verbose --export-all --interpolated-path=/pub/%H%D
In the command shown, git-daemon will fill
in the %H
with a fully qualified host name and
%D
with the repository’s directory path. Because
%H
can be a logical host name, different sets of
repositories can be offered by one physical server.
Typically, an additional level of directory structure, such as
/software, or /scm, is
used to organize the advertised repositories. If you combine the
--interpolated-path=/pub/%H%D
with a
/software repository directory path, the bare
repositories to be published will be physically present on the
server in directories such as:
/pub/git.example.com/software/ /pub/www.example.org/software/
You would then advertise the availability of your repositories at URLs such as:
git://git.example.com/software/repository.git
git://www.example.org/software/repository.git
Here the %H
is replaced by the host
git.example.com
or
www.example.org
and the %D
is
replaced by full repository names, such as
/software/
.repository.git
The important point of this example is that it shows how a single git-daemon can be used to maintain and publish multiple, separate collections of Git repositories that are physically hosted on one server but presented as logically separate hosts. Those repositories available from one host might be different than those offered by a different host.
Sometimes, an easier way to publish repositories with anonymous read access is to simply make them available through an HTTP daemon. If you also set up gitweb, visitors can load a URL into their web browsers, see an index listing of your repository, and negotiate using familiar clicks and the browser Back button. Visitors needn’t be running Git in order to download files.
You will need to make one configuration adjustment to your bare Git repository before it can be properly served by an HTTP daemon: enable the hooks/post-update option as follows:
$cd /path/to/bare/repo.git
$mv hooks/post-update.sample hooks/post-update
Verify that the post-update script is executable, or use chmod 755 on it just to be sure. Finally, copy that bare Git repository into a directory served by your HTTP daemon. You can now advertise that your project is available using a URL such as:
http://www.example.org/software/repository.git
If you see the error message such as:
... not found: did you run git update-server-info on the server?
or
Perhaps git-update-server-info needs to be run there?
chances are good that you aren’t running the hooks/post-update command properly on the server.
Although using a web server and browser is certainly convenient, think carefully about how much traffic you plan to handle on your server. Development projects can become large, and HTTP is less efficient than the native Git protocol.
You can provide both HTTP and Git daemon access, but it might
take some adjusting and coordination between your Git daemon and
your HTTP daemon. Specifically, it may require a mapping with the
--interpolated-path
option to
git-daemon and an Alias
option
to Apache to provide seamless integration of the two views of the
same data. Further details lie beyond the scope of this
book.
Technically, you may use the Git native protocol URL
forms to allow anonymous write into repositories served by
git-daemon. To do so requires you to enable the
receive-pack
option in the published
repositories:
[daemon] receivepack = true
You might do this on a private LAN where every developer is trusted, but it is not considered best practice. Instead, you should consider tunneling your Git push needs over an SSH connection.
3.15.179.121