</div>\r
<div id="preamble">\r
<div class="sectionbody">\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>Git differs from CVS in that every working tree contains a repository with\r
+a full copy of the project history, and no repository is inherently more\r
+important than any other. However, you can emulate the CVS model by\r
+designating a single shared repository which people can synchronize with;\r
+this document explains how to do that.</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
-Commits are atomic and project-wide, not per-file as in CVS.\r
-</p>\r
-</li>\r
-<li>\r
-<p>\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
-Branching is fast and easy.\r
-</p>\r
-</li>\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
-<li>\r
-<p>\r
-Since every working tree contains a repository, a commit in your\r
- private repository will not publish your changes; it will only create\r
- a revision. You have to "push" your changes to a public repository to\r
- make them visible to others.\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>Creating a Shared Repository</h2>\r
+<h2>Developing against a shared repository</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 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
-</div>\r
-<h2>Performing Development on a Shared Repository</h2>\r
-<div class="sectionbody">\r
-<p>Suppose a repository is now set up in /pub/repo.git on the host\r
+<p>Suppose a shared repository is set up in /pub/repo.git on the host\r
foo.com. Then as an individual committer you can clone the shared\r
-repository:</p>\r
+repository over ssh with:</p>\r
<div class="listingblock">\r
<div class="content">\r
<pre><tt>$ git clone foo.com:/pub/repo.git/ my-project\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
+operation. If there are uncommitted changes in your working tree, commit\r
+them first before running git pull.</p>\r
<div class="admonitionblock">\r
<table><tr>\r
<td class="icon">\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
+<pre><tt>URL: foo.com:/pub/project.git/\r
+Pull: refs/heads/master:refs/remotes/origin/master</tt></pre>\r
</div></div>\r
</td>\r
</tr></table>\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
+$ git push foo.com:/pub/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 behavior, 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
+<h2>Setting Up a Shared Repository</h2>\r
+<div class="sectionbody">\r
+<p>We assume you have already created a git repository for your project,\r
+possibly created from scratch or from a tarball (see the\r
+<a href="tutorial.html">tutorial</a>), or imported from an already existing CVS\r
+repository (see the next section).</p>\r
+<p>If your project's working directory is /home/alice/myproject, you can\r
+create a shared repository at /pub/repo.git with:</p>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><tt>$ git clone -bare /home/alice/myproject /pub/repo.git</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 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>$ cd /pub\r
+$ 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
+</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>Advanced Shared Repository Management</h2>\r
<div class="sectionbody">\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
+<h2>Providing CVS Access to a git Repository</h2>\r
<div class="sectionbody">\r
-<p>So, something has gone wrong, and you don't know whom to blame, and\r
-you're an ex-CVS user and used to do "cvs annotate" to see who caused\r
-the breakage. You're looking for the "git annotate", and it's just\r
-claiming not to find such a script. You're annoyed.</p>\r
-<p>Yes, that's right. Core git doesn't do "annotate", although it's\r
-technically possible, and there are at least two specialized scripts out\r
-there that can be used to get equivalent information (see the git\r
-mailing list archives for details).</p>\r
-<p>git has a couple of alternatives, though, that you may find sufficient\r
-or even superior depending on your use. One is called "git-whatchanged"\r
-(for obvious reasons) and the other one is called "pickaxe" ("a tool for\r
-the software archaeologist").</p>\r
-<p>The "git-whatchanged" script is a truly trivial script that can give you\r
-a good overview of what has changed in a file or a directory (or an\r
-arbitrary list of files or directories). The "pickaxe" support is an\r
-additional layer that can be used to further specify exactly what you're\r
-looking for, if you already know the specific area that changed.</p>\r
-<p>Let's step back a bit and think about the reason why you would\r
-want to do "cvs annotate a-file.c" to begin with.</p>\r
-<p>You would use "cvs annotate" on a file when you have trouble\r
-with a function (or even a single "if" statement in a function)\r
-that happens to be defined in the file, which does not do what\r
-you want it to do. And you would want to find out why it was\r
-written that way, because you are about to modify it to suit\r
-your needs, and at the same time you do not want to break its\r
-current callers. For that, you are trying to find out why the\r
-original author did things that way in the original context.</p>\r
-<p>Many times, it may be enough to see the commit log messages of\r
-commits that touch the file in question, possibly along with the\r
-patches themselves, like this:</p>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>$ git-whatchanged -p a-file.c</tt></pre>\r
-</div></div>\r
-<p>This will show log messages and patches for each commit that\r
-touches a-file.</p>\r
-<p>This, however, may not be very useful when this file has many\r
-modifications that are not related to the piece of code you are\r
-interested in. You would see many log messages and patches that\r
-do not have anything to do with the piece of code you are\r
-interested in. As an example, assuming that you have this piece\r
-of code that you are interested in in the HEAD version:</p>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>if (frotz) {\r
- nitfol();\r
-}</tt></pre>\r
-</div></div>\r
-<p>you would use git-rev-list and git-diff-tree like this:</p>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>$ git-rev-list HEAD |\r
- git-diff-tree --stdin -v -p -S'if (frotz) {\r
- nitfol();\r
-}'</tt></pre>\r
-</div></div>\r
-<p>We have already talked about the "--stdin" form of git-diff-tree\r
-command that reads the list of commits and compares each commit\r
-with its parents (otherwise you should go back and read the tutorial).\r
-The git-whatchanged command internally runs\r
-the equivalent of the above command, and can be used like this:</p>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>$ git-whatchanged -p -S'if (frotz) {\r
- nitfol();\r
-}'</tt></pre>\r
-</div></div>\r
-<p>When the -S option is used, git-diff-tree command outputs\r
-differences between two commits only if one tree has the\r
-specified string in a file and the corresponding file in the\r
-other tree does not. The above example looks for a commit that\r
-has the "if" statement in it in a file, but its parent commit\r
-does not have it in the same shape in the corresponding file (or\r
-the other way around, where the parent has it and the commit\r
-does not), and the differences between them are shown, along\r
-with the commit message (thanks to the -v flag). It does not\r
-show anything for commits that do not touch this "if" statement.</p>\r
-<p>Also, in the original context, the same statement might have\r
-appeared at first in a different file and later the file was\r
-renamed to "a-file.c". CVS annotate would not help you to go\r
-back across such a rename, but git would still help you in such\r
-a situation. For that, you can give the -C flag to\r
-git-diff-tree, like this:</p>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>$ git-whatchanged -p -C -S'if (frotz) {\r
- nitfol();\r
-}'</tt></pre>\r
-</div></div>\r
-<p>When the -C flag is used, file renames and copies are followed.\r
-So if the "if" statement in question happens to be in "a-file.c"\r
-in the current HEAD commit, even if the file was originally\r
-called "o-file.c" and then renamed in an earlier commit, or if\r
-the file was created by copying an existing "o-file.c" in an\r
-earlier commit, you will not lose track. If the "if" statement\r
-did not change across such a rename or copy, then the commit that\r
-does rename or copy would not show in the output, and if the\r
-"if" statement was modified while the file was still called\r
-"o-file.c", it would find the commit that changed the statement\r
-when it was in "o-file.c".</p>\r
-<div class="admonitionblock">\r
-<table><tr>\r
-<td class="icon">\r
-<div class="title">Note</div>\r
-</td>\r
-<td class="content">The current version of "git-diff-tree -C" is not eager\r
- enough to find copies, and it will miss the fact that a-file.c\r
- was created by copying o-file.c unless o-file.c was somehow\r
- changed in the same commit.</td>\r
-</tr></table>\r
-</div>\r
-<p>You can use the —pickaxe-all flag in addition to the -S flag.\r
-This causes the differences from all the files contained in\r
-those two commits, not just the differences between the files\r
-that contain this changed "if" statement:</p>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>$ git-whatchanged -p -C -S'if (frotz) {\r
- nitfol();\r
-}' --pickaxe-all</tt></pre>\r
-</div></div>\r
-<div class="admonitionblock">\r
-<table><tr>\r
-<td class="icon">\r
-<div class="title">Note</div>\r
-</td>\r
-<td class="content">This option is called "—pickaxe-all" because -S\r
- option is internally called "pickaxe", a tool for software\r
- archaeologists.</td>\r
-</tr></table>\r
+<p>It is also possible to provide true CVS access to a git repository, so\r
+that developers can still use CVS; see <a href="git-cvsserver.html">git-cvsserver(1)</a> for\r
+details.</p>\r
</div>\r
+<h2>Alternative 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. As we've seen, this is also possible with git.\r
+However, the distributed nature of git allows other development models,\r
+and you may want to first consider whether one of them might be a better\r
+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
<div id="footer">\r
<div id="footer-text">\r
-Last updated 06-Dec-2006 21:11:42 UTC\r
+Last updated 08-Dec-2006 07:23:38 UTC\r
</div>\r
</div>\r
</body>\r
git for CVS users
=================
-So you're a CVS user. That's OK, it's a treatable condition. The job of
-this document is to put you on the road to recovery, by helping you
-convert an existing cvs repository to git, and by showing you how to use a
-git repository in a cvs-like fashion.
+Git differs from CVS in that every working tree contains a repository with
+a full copy of the project history, and no repository is inherently more
+important than any other. However, you can emulate the CVS model by
+designating a single shared repository which people can synchronize with;
+this document explains how to do that.
Some basic familiarity with git is required. This
link:tutorial.html[tutorial introduction to git] should be sufficient.
-First, note some ways that git differs from CVS:
+Developing against a shared repository
+--------------------------------------
- * Commits are atomic and project-wide, not per-file as in CVS.
-
- * Offline work is supported: you can make multiple commits locally,
- then submit them when you're ready.
-
- * Branching is fast and easy.
-
- * Every working tree contains a repository with a full copy of the
- project history, and no repository is inherently more important than
- any other. However, you can emulate the CVS model by designating a
- single shared repository which people can synchronize with; see below
- for details.
-
- * Since every working tree contains a repository, a commit in your
- private repository will not publish your changes; it will only create
- a revision. You have to "push" your changes to a public repository to
- make them visible to others.
-
-Importing a CVS archive
------------------------
-
-First, install version 2.1 or higher of cvsps from
-link:http://www.cobite.com/cvsps/[http://www.cobite.com/cvsps/] and make
-sure it is in your path. The magic command line is then
-
--------------------------------------------
-$ git cvsimport -v -d <cvsroot> -C <destination> <module>
--------------------------------------------
-
-This puts a git archive of the named CVS module in the directory
-<destination>, which will be created if necessary. The -v option makes
-the conversion script very chatty.
-
-The import checks out from CVS every revision of every file. Reportedly
-cvsimport can average some twenty revisions per second, so for a
-medium-sized project this should not take more than a couple of minutes.
-Larger projects or remote repositories may take longer.
-
-The main trunk is stored in the git branch named `origin`, and additional
-CVS branches are stored in git branches with the same names. The most
-recent version of the main trunk is also left checked out on the `master`
-branch, so you can start adding your own changes right away.
-
-The import is incremental, so if you call it again next month it will
-fetch any CVS updates that have been made in the meantime. For this to
-work, you must not modify the imported branches; instead, create new
-branches for your own changes, and merge in the imported branches as
-necessary.
-
-Development Models
-------------------
-
-CVS users are accustomed to giving a group of developers commit access to
-a common repository. In the next section we'll explain how to do this
-with git. However, the distributed nature of git allows other development
-models, and you may want to first consider whether one of them might be a
-better fit for your project.
-
-For example, you can choose a single person to maintain the project's
-primary public repository. Other developers then clone this repository
-and each work in their own clone. When they have a series of changes that
-they're happy with, they ask the maintainer to pull from the branch
-containing the changes. The maintainer reviews their changes and pulls
-them into the primary repository, which other developers pull from as
-necessary to stay coordinated. The Linux kernel and other projects use
-variants of this model.
-
-With a small group, developers may just pull changes from each other's
-repositories without the need for a central maintainer.
-
-Creating a Shared Repository
-----------------------------
-
-Start with an ordinary git working directory containing the project, and
-remove the checked-out files, keeping just the bare .git directory:
-
-------------------------------------------------
-$ mv project/.git /pub/repo.git
-$ rm -r project/
-------------------------------------------------
-
-Next, give every team member read/write access to this repository. One
-easy way to do this is to give all the team members ssh access to the
-machine where the repository is hosted. If you don't want to give them a
-full shell on the machine, there is a restricted shell which only allows
-users to do git pushes and pulls; see gitlink:git-shell[1].
-
-Put all the committers in the same group, and make the repository
-writable by that group:
-
-------------------------------------------------
-$ chgrp -R $group repo.git
-$ find repo.git -mindepth 1 -type d |xargs chmod ug+rwx,g+s
-$ GIT_DIR=repo.git git repo-config core.sharedrepository true
-------------------------------------------------
-
-Make sure committers have a umask of at most 027, so that the directories
-they create are writable and searchable by other group members.
-
-Performing Development on a Shared Repository
----------------------------------------------
-
-Suppose a repository is now set up in /pub/repo.git on the host
+Suppose a shared repository is set up in /pub/repo.git on the host
foo.com. Then as an individual committer you can clone the shared
-repository:
+repository over ssh with:
------------------------------------------------
$ git clone foo.com:/pub/repo.git/ my-project
------------------------------------------------
which merges in any work that others might have done since the clone
-operation.
+operation. If there are uncommitted changes in your working tree, commit
+them first before running git pull.
[NOTE]
================================
`my-project/.git/remotes/origin` file, and that's why the previous step
and the next step both work.
------------
-URL: foo.com:/pub/project.git/ my-project
-Pull: master:origin
+URL: foo.com:/pub/project.git/
+Pull: refs/heads/master:refs/remotes/origin/master
------------
================================
------------
$ git push origin
-$ git push repo.shared.xz:/pub/scm/project.git/
+$ git push foo.com:/pub/project.git/
------------
as long as the shared repository does not have any branches
other than `master`.
-[NOTE]
-============
-Because of this behavior, if the shared repository and the developer's
-repository both have branches named `origin`, then a push like the above
-attempts to update the `origin` branch in the shared repository from the
-developer's `origin` branch. The results may be unexpected, so it's
-usually best to remove any branch named `origin` from the shared
-repository.
-============
+Setting Up a Shared Repository
+------------------------------
+
+We assume you have already created a git repository for your project,
+possibly created from scratch or from a tarball (see the
+link:tutorial.html[tutorial]), or imported from an already existing CVS
+repository (see the next section).
+
+If your project's working directory is /home/alice/myproject, you can
+create a shared repository at /pub/repo.git with:
+
+------------------------------------------------
+$ git clone -bare /home/alice/myproject /pub/repo.git
+------------------------------------------------
+
+Next, give every team member read/write access to this repository. One
+easy way to do this is to give all the team members ssh access to the
+machine where the repository is hosted. If you don't want to give them a
+full shell on the machine, there is a restricted shell which only allows
+users to do git pushes and pulls; see gitlink:git-shell[1].
+
+Put all the committers in the same group, and make the repository
+writable by that group:
+
+------------------------------------------------
+$ cd /pub
+$ chgrp -R $group repo.git
+$ find repo.git -mindepth 1 -type d |xargs chmod ug+rwx,g+s
+$ GIT_DIR=repo.git git repo-config core.sharedrepository true
+------------------------------------------------
+
+Make sure committers have a umask of at most 027, so that the directories
+they create are writable and searchable by other group members.
+
+Importing a CVS archive
+-----------------------
+
+First, install version 2.1 or higher of cvsps from
+link:http://www.cobite.com/cvsps/[http://www.cobite.com/cvsps/] and make
+sure it is in your path. The magic command line is then
+
+-------------------------------------------
+$ git cvsimport -v -d <cvsroot> -C <destination> <module>
+-------------------------------------------
+
+This puts a git archive of the named CVS module in the directory
+<destination>, which will be created if necessary. The -v option makes
+the conversion script very chatty.
+
+The import checks out from CVS every revision of every file. Reportedly
+cvsimport can average some twenty revisions per second, so for a
+medium-sized project this should not take more than a couple of minutes.
+Larger projects or remote repositories may take longer.
+
+The main trunk is stored in the git branch named `origin`, and additional
+CVS branches are stored in git branches with the same names. The most
+recent version of the main trunk is also left checked out on the `master`
+branch, so you can start adding your own changes right away.
+
+The import is incremental, so if you call it again next month it will
+fetch any CVS updates that have been made in the meantime. For this to
+work, you must not modify the imported branches; instead, create new
+branches for your own changes, and merge in the imported branches as
+necessary.
Advanced Shared Repository Management
-------------------------------------
link:howto/update-hook-example.txt[Controlling access to branches using
update hooks].
-CVS annotate
-------------
+Providing CVS Access to a git Repository
+----------------------------------------
+
+It is also possible to provide true CVS access to a git repository, so
+that developers can still use CVS; see gitlink:git-cvsserver[1] for
+details.
+
+Alternative Development Models
+------------------------------
+
+CVS users are accustomed to giving a group of developers commit access to
+a common repository. As we've seen, this is also possible with git.
+However, the distributed nature of git allows other development models,
+and you may want to first consider whether one of them might be a better
+fit for your project.
+
+For example, you can choose a single person to maintain the project's
+primary public repository. Other developers then clone this repository
+and each work in their own clone. When they have a series of changes that
+they're happy with, they ask the maintainer to pull from the branch
+containing the changes. The maintainer reviews their changes and pulls
+them into the primary repository, which other developers pull from as
+necessary to stay coordinated. The Linux kernel and other projects use
+variants of this model.
-So, something has gone wrong, and you don't know whom to blame, and
-you're an ex-CVS user and used to do "cvs annotate" to see who caused
-the breakage. You're looking for the "git annotate", and it's just
-claiming not to find such a script. You're annoyed.
-
-Yes, that's right. Core git doesn't do "annotate", although it's
-technically possible, and there are at least two specialized scripts out
-there that can be used to get equivalent information (see the git
-mailing list archives for details).
-
-git has a couple of alternatives, though, that you may find sufficient
-or even superior depending on your use. One is called "git-whatchanged"
-(for obvious reasons) and the other one is called "pickaxe" ("a tool for
-the software archaeologist").
-
-The "git-whatchanged" script is a truly trivial script that can give you
-a good overview of what has changed in a file or a directory (or an
-arbitrary list of files or directories). The "pickaxe" support is an
-additional layer that can be used to further specify exactly what you're
-looking for, if you already know the specific area that changed.
-
-Let's step back a bit and think about the reason why you would
-want to do "cvs annotate a-file.c" to begin with.
-
-You would use "cvs annotate" on a file when you have trouble
-with a function (or even a single "if" statement in a function)
-that happens to be defined in the file, which does not do what
-you want it to do. And you would want to find out why it was
-written that way, because you are about to modify it to suit
-your needs, and at the same time you do not want to break its
-current callers. For that, you are trying to find out why the
-original author did things that way in the original context.
-
-Many times, it may be enough to see the commit log messages of
-commits that touch the file in question, possibly along with the
-patches themselves, like this:
-
- $ git-whatchanged -p a-file.c
-
-This will show log messages and patches for each commit that
-touches a-file.
-
-This, however, may not be very useful when this file has many
-modifications that are not related to the piece of code you are
-interested in. You would see many log messages and patches that
-do not have anything to do with the piece of code you are
-interested in. As an example, assuming that you have this piece
-of code that you are interested in in the HEAD version:
-
- if (frotz) {
- nitfol();
- }
-
-you would use git-rev-list and git-diff-tree like this:
-
- $ git-rev-list HEAD |
- git-diff-tree --stdin -v -p -S'if (frotz) {
- nitfol();
- }'
-
-We have already talked about the "\--stdin" form of git-diff-tree
-command that reads the list of commits and compares each commit
-with its parents (otherwise you should go back and read the tutorial).
-The git-whatchanged command internally runs
-the equivalent of the above command, and can be used like this:
-
- $ git-whatchanged -p -S'if (frotz) {
- nitfol();
- }'
-
-When the -S option is used, git-diff-tree command outputs
-differences between two commits only if one tree has the
-specified string in a file and the corresponding file in the
-other tree does not. The above example looks for a commit that
-has the "if" statement in it in a file, but its parent commit
-does not have it in the same shape in the corresponding file (or
-the other way around, where the parent has it and the commit
-does not), and the differences between them are shown, along
-with the commit message (thanks to the -v flag). It does not
-show anything for commits that do not touch this "if" statement.
-
-Also, in the original context, the same statement might have
-appeared at first in a different file and later the file was
-renamed to "a-file.c". CVS annotate would not help you to go
-back across such a rename, but git would still help you in such
-a situation. For that, you can give the -C flag to
-git-diff-tree, like this:
-
- $ git-whatchanged -p -C -S'if (frotz) {
- nitfol();
- }'
-
-When the -C flag is used, file renames and copies are followed.
-So if the "if" statement in question happens to be in "a-file.c"
-in the current HEAD commit, even if the file was originally
-called "o-file.c" and then renamed in an earlier commit, or if
-the file was created by copying an existing "o-file.c" in an
-earlier commit, you will not lose track. If the "if" statement
-did not change across such a rename or copy, then the commit that
-does rename or copy would not show in the output, and if the
-"if" statement was modified while the file was still called
-"o-file.c", it would find the commit that changed the statement
-when it was in "o-file.c".
-
-NOTE: The current version of "git-diff-tree -C" is not eager
- enough to find copies, and it will miss the fact that a-file.c
- was created by copying o-file.c unless o-file.c was somehow
- changed in the same commit.
-
-You can use the --pickaxe-all flag in addition to the -S flag.
-This causes the differences from all the files contained in
-those two commits, not just the differences between the files
-that contain this changed "if" statement:
-
- $ git-whatchanged -p -C -S'if (frotz) {
- nitfol();
- }' --pickaxe-all
-
-NOTE: This option is called "--pickaxe-all" because -S
- option is internally called "pickaxe", a tool for software
- archaeologists.
+With a small group, developers may just pull changes from each other's
+repositories without the need for a central maintainer.
</div>\r
<h2>DESCRIPTION</h2>\r
<div class="sectionbody">\r
-<p>Clones a repository into a newly created directory. All remote\r
-branch heads are copied under <tt>$GIT_DIR/refs/heads/</tt>, except\r
-that the remote <tt>master</tt> is also copied to <tt>origin</tt> branch.</p>\r
-<p>In addition, <tt>$GIT_DIR/remotes/origin</tt> file is set up to have\r
-this line:</p>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>Pull: master:origin</tt></pre>\r
-</div></div>\r
-<p>This is to help the typical workflow of working off of the\r
-remote <tt>master</tt> branch. Every time <tt>git pull</tt> without argument\r
-is run, the progress on the remote <tt>master</tt> branch is tracked by\r
-copying it into the local <tt>origin</tt> branch, and merged into the\r
-branch you are currently working on. Remote branches other than\r
-<tt>master</tt> are also added there to be tracked.</p>\r
+<p>Clones a repository into a newly created directory, creates\r
+remote-tracking branches for each branch in the cloned repository\r
+(visible using <tt>git branch -r</tt>), and creates and checks out a master\r
+branch equal to the cloned repository's master branch.</p>\r
+<p>After the clone, a plain <tt>git fetch</tt> without arguments will update\r
+all the remote-tracking branches, and a <tt>git pull</tt> without\r
+arguments will in addition merge the remote master branch into the\r
+current branch.</p>\r
+<p>This default configuration is achieved by creating references to\r
+the remote branch heads under <tt>$GIT_DIR/refs/remotes/origin</tt> and\r
+by initializing <tt>remote.origin.url</tt> and <tt>remote.origin.fetch</tt>\r
+configuration variables.</p>\r
</div>\r
<h2>OPTIONS</h2>\r
<div class="sectionbody">\r
</div>\r
<div id="footer">\r
<div id="footer-text">\r
-Last updated 05-Dec-2006 01:11:37 UTC\r
+Last updated 08-Dec-2006 07:23:38 UTC\r
</div>\r
</div>\r
</body>\r
DESCRIPTION
-----------
-Clones a repository into a newly created directory. All remote
-branch heads are copied under `$GIT_DIR/refs/heads/`, except
-that the remote `master` is also copied to `origin` branch.
-In addition, `$GIT_DIR/remotes/origin` file is set up to have
-this line:
+Clones a repository into a newly created directory, creates
+remote-tracking branches for each branch in the cloned repository
+(visible using `git branch -r`), and creates and checks out a master
+branch equal to the cloned repository's master branch.
- Pull: master:origin
-
-This is to help the typical workflow of working off of the
-remote `master` branch. Every time `git pull` without argument
-is run, the progress on the remote `master` branch is tracked by
-copying it into the local `origin` branch, and merged into the
-branch you are currently working on. Remote branches other than
-`master` are also added there to be tracked.
+After the clone, a plain `git fetch` without arguments will update
+all the remote-tracking branches, and a `git pull` without
+arguments will in addition merge the remote master branch into the
+current branch.
+This default configuration is achieved by creating references to
+the remote branch heads under `$GIT_DIR/refs/remotes/origin` and
+by initializing `remote.origin.url` and `remote.origin.fetch`
+configuration variables.
OPTIONS
-------