Autogenerated HTML docs for v1.1.6-g1a5c3
[git.git] / cvs-migration.html
index 50f4653..0ee0488 100644 (file)
@@ -263,124 +263,185 @@ div.exampleblock-content {
 </div>\r
 <div id="preamble">\r
 <div class="sectionbody">\r
-<p>Ok, so you're a CVS user. That's ok, it's a treatable condition, and the\r
-first step to recovery is admitting you have a problem. The fact that\r
-you are reading this file means that you may be well on that path\r
-already.</p>\r
-<p>The thing about CVS is that it absolutely sucks as a source control\r
-manager, and you'll thus be happy with almost anything else. git,\r
-however, may be a bit <em>too</em> different (read: "good") for your taste, and\r
-does a lot of things differently.</p>\r
-<p>One particular suckage of CVS is very hard to work around: CVS is\r
-basically a tool for tracking <em>file</em> history, while git is a tool for\r
-tracking <em>project</em> history.  This sometimes causes problems if you are\r
-used to doing very strange things in CVS, in particular if you're doing\r
-things like making branches of just a subset of the project.  git can't\r
-track that, since git never tracks things on the level of an individual\r
-file, only on the whole project level.</p>\r
-<p>The good news is that most people don't do that, and in fact most sane\r
-people think it's a bug in CVS that makes it tag (and check in changes)\r
-one file at a time.  So most projects you'll ever see will use CVS\r
-<em>as if</em> it was sane.  In which case you'll find it very easy indeed to\r
-move over to git.</p>\r
-<p>First off: this is not a git tutorial. See\r
-<a href="tutorial.html">Documentation/tutorial.txt</a> for how git\r
-actually works. This is more of a random collection of gotcha's\r
-and notes on converting from CVS to git.</p>\r
-<p>Second: CVS has the notion of a "repository" as opposed to the thing\r
-that you're actually working in (your working directory, or your\r
-"checked out tree").  git does not have that notion at all, and all git\r
-working directories <em>are</em> the repositories.  However, you can easily\r
-emulate the CVS model by having one special "global repository", which\r
-people can synchronize with.  See details later, but in the meantime\r
-just keep in mind that with git, every checked out working tree will\r
-have a full revision control history of its own.</p>\r
-</div>\r
-</div>\r
-<h2>Importing a CVS archive</h2>\r
-<div class="sectionbody">\r
-<p>Ok, you have an old project, and you want to at least give git a chance\r
-to see how it performs. The first thing you want to do (after you've\r
-gone through the git tutorial, and generally familiarized yourself with\r
-how to commit stuff etc in git) is to create a git'ified version of your\r
-CVS archive.</p>\r
-<p>Happily, that's very easy indeed. git will do it for you, although git\r
-will need the help of a program called "cvsps":</p>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>http://www.cobite.com/cvsps/</tt></pre>\r
-</div></div>\r
-<p>which is not actually related to git at all, but which makes CVS usage\r
-look almost sane (ie you almost certainly want to have it even if you\r
-decide to stay with CVS). However, git will want <em>at least</em> version 2.1\r
-of cvsps (available at the address above), and in fact will currently\r
-refuse to work with anything else.</p>\r
-<p>Once you've gotten (and installed) cvsps, you may or may not want to get\r
-any more familiar with it, but make sure it is in your path. After that,\r
-the magic command line is</p>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>git cvsimport -v -d &lt;cvsroot&gt; -C &lt;destination&gt; &lt;module&gt;</tt></pre>\r
-</div></div>\r
-<p>which will do exactly what you'd think it does: it will create a git\r
-archive of the named CVS module. The new archive will be created in the\r
-subdirectory named &lt;destination&gt;; it'll be created if it doesn't exist.\r
-Default is the local directory.</p>\r
-<p>It can take some time to actually do the conversion for a large archive\r
-since it involves checking out from CVS every revision of every file,\r
-and the conversion script is reasonably chatty unless you omit the <em>-v</em>\r
-option, but on some not very scientific tests it averaged about twenty\r
-revisions per second, so a medium-sized project should not take more\r
-than a couple of minutes.  For larger projects or remote repositories,\r
-the process may take longer.</p>\r
-<p>After the (initial) import is done, the CVS archive's current head\r
-revision will be checked out &#8212; thus, you can start adding your own\r
-changes right away.</p>\r
-<p>The import is incremental, i.e. if you call it again next month it'll\r
-fetch any CVS updates that have been happening in the meantime. The\r
-cut-off is date-based, so don't change the branches that were imported\r
-from CVS.</p>\r
-<p>You can merge those updates (or, in fact, a different CVS branch) into\r
-your main branch:</p>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>git resolve HEAD origin "merge with current CVS HEAD"</tt></pre>\r
-</div></div>\r
-<p>The HEAD revision from CVS is named "origin", not "HEAD", because git\r
-already uses "HEAD". (If you don't like <em>origin</em>, use cvsimport's\r
-<em>-o</em> option to change it.)</p>\r
-</div>\r
-<h2>Emulating CVS behaviour</h2>\r
-<div class="sectionbody">\r
-<p>So, by now you are convinced you absolutely want to work with git, but\r
-at the same time you absolutely have to have a central repository.\r
-Step back and think again. Okay, you still need a single central\r
-repository? There are several ways to go about that:</p>\r
-<ol>\r
+<p>So you're a CVS user. That's ok, it's a treatable condition.  The job of\r
+this document is to put you on the road to recovery, by helping you\r
+convert an existing cvs repository to git, and by showing you how to use a\r
+git repository in a cvs-like fashion.</p>\r
+<p>Some basic familiarity with git is required.  This\r
+<a href="tutorial.html">tutorial introduction to git</a> should be sufficient.</p>\r
+<p>First, note some ways that git differs from CVS:</p>\r
+<ul>\r
 <li>\r
 <p>\r
-Designate a person responsible to pull all branches. Make the\r
-repository of this person public, and make every team member\r
-pull regularly from it.\r
+Commits are atomic and project-wide, not per-file as in CVS.\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Set up a public repository with read/write access for every team\r
-member. Use "git pull/push" as you used "cvs update/commit".  Be\r
-sure that your repository is up to date before pushing, just\r
-like you used to do with "cvs commit"; your push will fail if\r
-what you are pushing is not up to date.\r
+Offline work is supported: you can make multiple commits locally,\r
+    then submit them when you're ready.\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Make the repository of every team member public. It is the\r
-responsibility of each single member to pull from every other\r
-team member.\r
+Branching is fast and easy.\r
 </p>\r
 </li>\r
-</ol>\r
+<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 &lt;cvsroot&gt; -C &lt;destination&gt; &lt;module&gt;</tt></pre>\r
+</div></div>\r
+<p>This puts a git archive of the named CVS module in the directory\r
+&lt;destination&gt;, 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
 </div>\r
 <h2>CVS annotate</h2>\r
 <div class="sectionbody">\r
@@ -518,7 +579,7 @@ that contain this changed "if" statement:</p>
 </div>\r
 <div id="footer">\r
 <div id="footer-text">\r
-Last updated 06-Jan-2006 17:12:56 PDT\r
+Last updated 30-Jan-2006 23:10:24 PDT\r
 </div>\r
 </div>\r
 </body>\r