+<li>\r
+<p>\r
+Every working tree contains a repository with a full copy of the\r
+ project history, and no repository is inherently more important than\r
+ any other. However, you can emulate the CVS model by designating a\r
+ single shared repository which people can synchronize with; see below\r
+ for details.\r
+</p>\r
+</li>\r
+</ul>\r
+</div>\r
+</div>\r
+<h2>Importing a CVS archive</h2>\r
+<div class="sectionbody">\r
+<p>First, install version 2.1 or higher of cvsps from\r
+<a href="http://www.cobite.com/cvsps/">http://www.cobite.com/cvsps/</a> and make\r
+sure it is in your path. The magic command line is then</p>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><tt>$ git cvsimport -v -d <cvsroot> -C <destination> <module></tt></pre>\r
+</div></div>\r
+<p>This puts a git archive of the named CVS module in the directory\r
+<destination>, which will be created if necessary. The -v option makes\r
+the conversion script very chatty.</p>\r
+<p>The import checks out from CVS every revision of every file. Reportedly\r
+cvsimport can average some twenty revisions per second, so for a\r
+medium-sized project this should not take more than a couple of minutes.\r
+Larger projects or remote repositories may take longer.</p>\r
+<p>The main trunk is stored in the git branch named <tt>origin</tt>, and additional\r
+CVS branches are stored in git branches with the same names. The most\r
+recent version of the main trunk is also left checked out on the <tt>master</tt>\r
+branch, so you can start adding your own changes right away.</p>\r
+<p>The import is incremental, so if you call it again next month it will\r
+fetch any CVS updates that have been made in the meantime. For this to\r
+work, you must not modify the imported branches; instead, create new\r
+branches for your own changes, and merge in the imported branches as\r
+necessary.</p>\r
+</div>\r
+<h2>Development Models</h2>\r
+<div class="sectionbody">\r
+<p>CVS users are accustomed to giving a group of developers commit access to\r
+a common repository. In the next section we'll explain how to do this\r
+with git. However, the distributed nature of git allows other development\r
+models, and you may want to first consider whether one of them might be a\r
+better fit for your project.</p>\r
+<p>For example, you can choose a single person to maintain the project's\r
+primary public repository. Other developers then clone this repository\r
+and each work in their own clone. When they have a series of changes that\r
+they're happy with, they ask the maintainer to pull from the branch\r
+containing the changes. The maintainer reviews their changes and pulls\r
+them into the primary repository, which other developers pull from as\r
+necessary to stay coordinated. The Linux kernel and other projects use\r
+variants of this model.</p>\r
+<p>With a small group, developers may just pull changes from each other's\r
+repositories without the need for a central maintainer.</p>\r
+</div>\r
+<h2>Emulating the CVS Development Model</h2>\r
+<div class="sectionbody">\r
+<p>Start with an ordinary git working directory containing the project, and\r
+remove the checked-out files, keeping just the bare .git directory:</p>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><tt>$ mv project/.git /pub/repo.git\r
+$ rm -r project/</tt></pre>\r
+</div></div>\r
+<p>Next, give every team member read/write access to this repository. One\r
+easy way to do this is to give all the team members ssh access to the\r
+machine where the repository is hosted. If you don't want to give them a\r
+full shell on the machine, there is a restricted shell which only allows\r
+users to do git pushes and pulls; see <a href="git-shell.html">git-shell(1)</a>.</p>\r
+<p>Put all the committers should in the same group, and make the repository\r
+writable by that group:</p>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><tt>$ chgrp -R $group repo.git\r
+$ find repo.git -mindepth 1 -type d |xargs chmod ug+rwx,g+s\r
+$ GIT_DIR=repo.git git repo-config core.sharedrepository true</tt></pre>\r
+</div></div>\r
+<p>Make sure committers have a umask of at most 027, so that the directories\r
+they create are writable and searchable by other group members.</p>\r
+<p>Suppose this repository is now set up in /pub/repo.git on the host\r
+foo.com. Then as an individual commiter you can clone the shared\r
+repository:</p>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><tt>$ git clone foo.com:/pub/repo.git/ my-project\r
+$ cd my-project</tt></pre>\r
+</div></div>\r
+<p>and hack away. The equivalent of <tt>cvs update</tt> is</p>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><tt>$ git pull origin</tt></pre>\r
+</div></div>\r
+<p>which merges in any work that others might have done since the clone\r
+operation.</p>\r
+<div class="admonitionblock">\r
+<table><tr>\r
+<td class="icon">\r
+<div class="title">Note</div>\r
+</td>\r
+<td class="content">\r
+<p>The first <tt>git clone</tt> places the following in the\r
+<tt>my-project/.git/remotes/origin</tt> file, and that's why the previous step\r
+and the next step both work.</p>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><tt>URL: foo.com:/pub/project.git/ my-project\r
+Pull: master:origin</tt></pre>\r
+</div></div>\r
+</td>\r
+</tr></table>\r
+</div>\r
+<p>You can update the shared repository with your changes using:</p>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><tt>$ git push origin master</tt></pre>\r
+</div></div>\r
+<p>If someone else has updated the repository more recently, <tt>git push</tt>, like\r
+<tt>cvs commit</tt>, will complain, in which case you must pull any changes\r
+before attempting the push again.</p>\r
+<p>In the <tt>git push</tt> command above we specify the name of the remote branch\r
+to update (<tt>master</tt>). If we leave that out, <tt>git push</tt> tries to update\r
+any branches in the remote repository that have the same name as a branch\r
+in the local repository. So the last <tt>push</tt> can be done with either of:</p>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><tt>$ git push origin\r
+$ git push repo.shared.xz:/pub/scm/project.git/</tt></pre>\r
+</div></div>\r
+<p>as long as the shared repository does not have any branches\r
+other than <tt>master</tt>.</p>\r
+<div class="admonitionblock">\r
+<table><tr>\r
+<td class="icon">\r
+<div class="title">Note</div>\r
+</td>\r
+<td class="content">\r
+<p>Because of this behaviour, if the shared repository and the developer's\r
+repository both have branches named <tt>origin</tt>, then a push like the above\r
+attempts to update the <tt>origin</tt> branch in the shared repository from the\r
+developer's <tt>origin</tt> branch. The results may be unexpected, so it's\r
+usually best to remove any branch named <tt>origin</tt> from the shared\r
+repository.</p>\r
+</td>\r
+</tr></table>\r
+</div>\r
+</div>\r
+<h2>Advanced Shared Repository Management</h2>\r
+<div class="sectionbody">\r
+<p>Git allows you to specify scripts called "hooks" to be run at certain\r
+points. You can use these, for example, to send all commits to the shared\r
+repository to a mailing list. See <a href="hooks.txt">Hooks used by git</a>.</p>\r
+<p>You can enforce finer grained permissions using update hooks. See\r
+<a href="howto/update-hook-example.txt">Controlling access to branches using\r
+update hooks</a>.</p>\r