{"thread":{"id":"3170","subject":"[PATCH] cvs-migration documentation update","startedAt":"2006-01-29T04:31:47Z","lastAt":"2006-01-31T03:40:37Z","messageCount":3,"participants":["J. Bruce Fields","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"15187","messageId":"20060129043147.GA9581@fieldses.org","threadId":"3170","inReplyTo":null,"subject":"[PATCH] cvs-migration documentation update","fromName":"J. Bruce Fields","fromEmail":"bfields@fieldses.org","sentAt":"2006-01-29T04:31:47Z","receivedAt":"2006-01-29T04:31:47Z","isPatch":true,"sender":{"key":"bfields@citi.umich.edu","avatar":null},"body":"Here's some changes to the cvs-migration.txt.  As usual, in my attempt\nto make things clearer someone may have found I've made them less so, or\nI may have just gotten something wrong; so any review is welcomed.\n\nI can break up this sort of thing into smaller steps if preferred, the\nmonolothic patch is just a bit simpler for me for this sort of\nthing.\n\nI moved the material describing shared repository management from\ncore-tutorial.txt to cvs-migration.txt, where it seems more appropriate,\nand combined two sections to eliminate some redundancy.\n\nI also revised the earlier sections of cvs-migration.txt, mainly trying\nto make it more concise.\n\nI've left the last section of cvs-migration.txt (on CVS annotate\nalternatives) alone for now.\n\nSigned-off-by: J. Bruce Fields <bfields@citi.umich.edu>\n\n---\n\n Documentation/core-tutorial.txt |  118 -----------------\n Documentation/cvs-migration.txt |  276 +++++++++++++++++++++++----------------\n 2 files changed, 167 insertions(+), 227 deletions(-)\n\nbfa569527ebfa0388103c0619f15a2ee71ef3624\ndiff --git a/Documentation/core-tutorial.txt b/Documentation/core-tutorial.txt\nindex 35579cc..4513ad6 100644\n--- a/Documentation/core-tutorial.txt\n+++ b/Documentation/core-tutorial.txt\n@@ -1623,123 +1623,7 @@ suggested in the previous section may be\n have to worry. git supports \"shared public repository\" style of\n cooperation you are probably more familiar with as well.\n \n-For this, set up a public repository on a machine that is\n-reachable via SSH by people with \"commit privileges\".  Put the\n-committers in the same user group and make the repository\n-writable by that group.  Make sure their umasks are set up to\n-allow group members to write into directories other members\n-have created.\n-\n-You, as an individual committer, then:\n-\n-- First clone the shared repository to a local repository:\n-------------------------------------------------\n-$ git clone repo.shared.xz:/pub/scm/project.git/ my-project\n-$ cd my-project\n-$ hack away\n-------------------------------------------------\n-\n-- Merge the work others might have done while you were hacking\n-  away:\n-------------------------------------------------\n-$ git pull origin\n-$ test the merge result\n-------------------------------------------------\n-[NOTE]\n-================================\n-The first `git clone` would have placed the following in\n-`my-project/.git/remotes/origin` file, and that's why this and\n-the next step work.\n-------------\n-URL: repo.shared.xz:/pub/scm/project.git/ my-project\n-Pull: master:origin\n-------------\n-================================\n-\n-- push your work as the new head of the shared\n-  repository.\n-------------------------------------------------\n-$ git push origin master\n-------------------------------------------------\n-If somebody else pushed into the same shared repository while\n-you were working locally, `git push` in the last step would\n-complain, telling you that the remote `master` head does not\n-fast forward.  You need to pull and merge those other changes\n-back before you push your work when it happens.\n-\n-The `git push` command without any explicit refspec parameter\n-pushes the refs that exist both in the local repository and the\n-remote repository.  So the last `push` can be done with either\n-one of these:\n-------------\n-$ git push origin\n-$ git push repo.shared.xz:/pub/scm/project.git/\n-------------\n-as long as the shared repository does not have any branches\n-other than `master`.\n-[NOTE]\n-============\n-If you created your shared repository by cloning from somewhere\n-else, you may have the `origin` branch.  Your developers\n-typically do not use that branch; remove it.  Otherwise, that\n-would be pushed back by the `git push origin` because your\n-developers' repository would surely have `origin` branch to keep\n-track of the shared repository, and would be counted as \"exist\n-on both ends\".\n-============\n-\n-Advanced Shared Repository Management\n--------------------------------------\n-\n-Being able to push into a shared repository means being able to\n-write into it.  If your developers are coming over the network,\n-this means you, as the repository administrator, need to give\n-each of them an SSH access to the shared repository machine.\n-\n-In some cases, though, you may not want to give a normal shell\n-account to them, but want to restrict them to be able to only\n-do `git push` into the repository and nothing else.\n-\n-You can achieve this by setting the login shell of your\n-developers on the shared repository host to `git-shell` program.\n-\n-[NOTE]\n-Most likely you would also need to list `git-shell` program in\n-`/etc/shells` file.\n-\n-This restricts the set of commands that can be run from incoming\n-SSH connection for these users to only `receive-pack` and\n-`upload-pack`, so the only thing they can do are `git fetch` and\n-`git push`.\n-\n-You still need to create UNIX user accounts for each developer,\n-and put them in the same group.  Make sure that the repository\n-shared among these developers is writable by that group.\n-\n-. Initializing the shared repository with `git-init-db --shared`\n-helps somewhat.\n-\n-. Run the following in the shared repository:\n-+\n-------------\n-$ chgrp -R $group repo.git\n-$ find repo.git -type d -print | xargs chmod ug+rwx,g+s\n-$ GIT_DIR=repo.git git repo-config core.sharedrepository true\n-------------\n-\n-The above measures make sure that directories lazily created in\n-`$GIT_DIR` are writable by group members.  You, as the\n-repository administrator, are still responsible to make sure\n-your developers belong to that shared repository group and set\n-their umask to a value no stricter than 027 (i.e. at least allow\n-reading and searching by group members).\n-\n-You can implement finer grained branch policies using update\n-hooks.  There is a document (\"control access to branches\") in\n-Documentation/howto by Carl Baldwin and JC outlining how to (1)\n-limit access to branch per user, (2) forbid overwriting existing\n-tags.\n-\n+See link:cvs-migration.txt[git for CVS users] for the details.\n \n Bundling your work together\n ---------------------------\ndiff --git a/Documentation/cvs-migration.txt b/Documentation/cvs-migration.txt\nindex 8fd1a33..2bd58d3 100644\n--- a/Documentation/cvs-migration.txt\n+++ b/Documentation/cvs-migration.txt\n@@ -1,126 +1,182 @@\n git for CVS users\n =================\n \n-Ok, so you're a CVS user. That's ok, it's a treatable condition, and the\n-first step to recovery is admitting you have a problem. The fact that\n-you are reading this file means that you may be well on that path\n-already.\n-\n-The thing about CVS is that it absolutely sucks as a source control\n-manager, and you'll thus be happy with almost anything else. git,\n-however, may be a bit 'too' different (read: \"good\") for your taste, and\n-does a lot of things differently. \n-\n-One particular suckage of CVS is very hard to work around: CVS is\n-basically a tool for tracking 'file' history, while git is a tool for\n-tracking 'project' history.  This sometimes causes problems if you are\n-used to doing very strange things in CVS, in particular if you're doing\n-things like making branches of just a subset of the project.  git can't\n-track that, since git never tracks things on the level of an individual\n-file, only on the whole project level. \n-\n-The good news is that most people don't do that, and in fact most sane\n-people think it's a bug in CVS that makes it tag (and check in changes)\n-one file at a time.  So most projects you'll ever see will use CVS\n-'as if' it was sane.  In which case you'll find it very easy indeed to\n-move over to git. \n-\n-First off: this is not a git tutorial. See\n-link:tutorial.html[Documentation/tutorial.txt] for how git\n-actually works. This is more of a random collection of gotcha's\n-and notes on converting from CVS to git.\n-\n-Second: CVS has the notion of a \"repository\" as opposed to the thing\n-that you're actually working in (your working directory, or your\n-\"checked out tree\").  git does not have that notion at all, and all git\n-working directories 'are' the repositories.  However, you can easily\n-emulate the CVS model by having one special \"global repository\", which\n-people can synchronize with.  See details later, but in the meantime\n-just keep in mind that with git, every checked out working tree will\n-have a full revision control history of its own.\n+So you're a CVS user. That's ok, it's a treatable condition.  The job of\n+this document is to put you on the road to recovery, by helping you\n+convert an existing cvs repository to git, and by showing you how to use a\n+git repository in a cvs-like fashion.\n \n+Some basic familiarity with git is required.  This\n+link:tutorial.html[tutorial introduction to git] should be sufficient.\n+\n+First, note some ways that git differs from CVS:\n+\n+  * Commits are atomic and project-wide, not per-file as in CVS.\n+\n+  * Offline work is supported: you can make multiple commits locally,\n+    then submit them when you're ready.\n+\n+  * Branching is fast and easy.\n+\n+  * Every working tree contains a repository with a full copy of the\n+    project history, and no repository is inherently more important than\n+    any other.  However, you can emulate the CVS model by designating a\n+    single shared repository which people can synchronize with; see below\n+    for details.\n \n Importing a CVS archive\n -----------------------\n \n-Ok, you have an old project, and you want to at least give git a chance\n-to see how it performs. The first thing you want to do (after you've\n-gone through the git tutorial, and generally familiarized yourself with\n-how to commit stuff etc in git) is to create a git'ified version of your\n-CVS archive.\n-\n-Happily, that's very easy indeed. git will do it for you, although git\n-will need the help of a program called \"cvsps\":\n-\n-\thttp://www.cobite.com/cvsps/\n-\n-which is not actually related to git at all, but which makes CVS usage\n-look almost sane (ie you almost certainly want to have it even if you\n-decide to stay with CVS). However, git will want 'at least' version 2.1\n-of cvsps (available at the address above), and in fact will currently\n-refuse to work with anything else.\n-\n-Once you've gotten (and installed) cvsps, you may or may not want to get\n-any more familiar with it, but make sure it is in your path. After that,\n-the magic command line is\n-\n-\tgit cvsimport -v -d <cvsroot> -C <destination> <module>\n-\n-which will do exactly what you'd think it does: it will create a git\n-archive of the named CVS module. The new archive will be created in the\n-subdirectory named <destination>; it'll be created if it doesn't exist.\n-Default is the local directory.\n-\n-It can take some time to actually do the conversion for a large archive\n-since it involves checking out from CVS every revision of every file,\n-and the conversion script is reasonably chatty unless you omit the '-v'\n-option, but on some not very scientific tests it averaged about twenty\n-revisions per second, so a medium-sized project should not take more\n-than a couple of minutes.  For larger projects or remote repositories,\n-the process may take longer.\n-\n-After the (initial) import is done, the CVS archive's current head\n-revision will be checked out -- thus, you can start adding your own\n-changes right away.\n-\n-The import is incremental, i.e. if you call it again next month it'll\n-fetch any CVS updates that have been happening in the meantime. The\n-cut-off is date-based, so don't change the branches that were imported\n-from CVS.\n-\n-You can merge those updates (or, in fact, a different CVS branch) into\n-your main branch:\n-\n-\tgit resolve HEAD origin \"merge with current CVS HEAD\"\n-\n-The HEAD revision from CVS is named \"origin\", not \"HEAD\", because git\n-already uses \"HEAD\". (If you don't like 'origin', use cvsimport's\n-'-o' option to change it.)\n+First, install version 2.1 or higher of cvsps from\n+link:http://www.cobite.com/cvsps/[http://www.cobite.com/cvsps/] and make\n+sure it is in your path.  The magic command line is then\n+\n+-------------------------------------------\n+$ git cvsimport -v -d <cvsroot> -C <destination> <module>\n+-------------------------------------------\n+\n+This puts a git archive of the named CVS module in the directory\n+<destination>, which will be created if necessary.  The -v option makes\n+the conversion script very chatty.\n+\n+The import checks out from CVS every revision of every file.  Reportedly\n+cvsimport can average some twenty revisions per second, so for a\n+medium-sized project this should not take more than a couple of minutes.\n+Larger projects or remote repositories may take longer.\n+\n+The main trunk is stored in the git branch named `origin`, and additional\n+CVS branches are stored in git branches with the same names.  The most\n+recent version of the main trunk is also left checked out on the `master`\n+branch, so you can start adding your own changes right away.\n+\n+The import is incremental, so if you call it again next month it will\n+fetch any CVS updates that have been made in the meantime.  For this to\n+work, you must not modify the imported branches; instead, create new\n+branches for your own changes, and merge in the imported branches as\n+necessary.\n+\n+Development Models\n+------------------\n+\n+CVS users are accustomed to giving a group of developers commit access to\n+a common repository.  In the next section we'll explain how to do this\n+with git.  However, the distributed nature of git allows other development\n+models, and you may want to first consider whether one of them might be a\n+better fit for your project.\n+\n+For example, you can choose a single person to maintain the project's\n+primary public repository.  Other developers then clone this repository\n+and each work in their own clone.  When they have a series of changes that\n+they're happy with, they ask the maintainer to pull from the branch\n+containing the changes.  The maintainer reviews their changes and pulls\n+them into the primary repository, which other developers pull from as\n+necessary to stay coordinated.  The Linux kernel and other projects use\n+variants of this model.\n+\n+With a small group, developers may just pull changes from each other's\n+repositories without the need for a central maintainer.\n+\n+Emulating the CVS Development Model\n+-----------------------------------\n+\n+Start with an ordinary git working directory containing the project, and\n+remove the checked-out files, keeping just the bare .git directory:\n+\n+------------------------------------------------\n+$ mv project/.git /pub/repo.git\n+$ rm -r project/\n+------------------------------------------------\n+\n+Next, give every team member read/write access to this repository.  One\n+easy way to do this is to give all the team members ssh access to the\n+machine where the repository is hosted.  If you don't want to give them a\n+full shell on the machine, there is a restricted shell which only allows\n+users to do git pushes and pulls; see gitlink:git-shell[1].\n+\n+Put all the committers should in the same group, and make the repository\n+writable by that group:\n+\n+------------------------------------------------\n+$ chgrp -R $group repo.git\n+$ find repo.git -mindepth 1 -type d |xargs chmod ug+rwx,g+s\n+$ GIT_DIR=repo.git git repo-config core.sharedrepository true\n+------------------------------------------------\n+\n+Make sure committers have a umask of at most 027, so that the directories\n+they create are writable and searchable by other group members.\n+\n+Suppose this repository is now set up in /pub/repo.git on the host\n+foo.com.  Then as an individual commiter you can clone the shared\n+repository:\n+\n+------------------------------------------------\n+$ git clone foo.com:/pub/repo.git/ my-project\n+$ cd my-project\n+------------------------------------------------\n+\n+and hack away.  The equivalent of `cvs update` is\n+\n+------------------------------------------------\n+$ git pull origin\n+------------------------------------------------\n+\n+which merges in any work that others might have done since the clone\n+operation.\n+\n+[NOTE]\n+================================\n+The first `git clone` places the following in the\n+`my-project/.git/remotes/origin` file, and that's why the previous step\n+and the next step both work.\n+------------\n+URL: foo.com:/pub/project.git/ my-project\n+Pull: master:origin\n+------------\n+================================\n \n+You can update the shared repository with your changes using:\n \n-Emulating CVS behaviour\n------------------------\n+------------------------------------------------\n+$ git push origin master\n+------------------------------------------------\n+\n+If some else has updated the repository more recently, `git push`, like\n+`cvs commit`, will complain, in which case you must pull any changes\n+before attempting the push again.\n+\n+In the `git push` command above we specify the name of the remote branch\n+to update (`master`).  If we leave that out, `git push` tries to update\n+any branches in the remote repository that have the same name as a branch\n+in the local repository.  So the last `push` can be done with either of:\n \n+------------\n+$ git push origin\n+$ git push repo.shared.xz:/pub/scm/project.git/\n+------------\n \n-So, by now you are convinced you absolutely want to work with git, but\n-at the same time you absolutely have to have a central repository.\n-Step back and think again. Okay, you still need a single central\n-repository? There are several ways to go about that:\n-\n-1. Designate a person responsible to pull all branches. Make the\n-repository of this person public, and make every team member\n-pull regularly from it.\n-\n-2. Set up a public repository with read/write access for every team\n-member. Use \"git pull/push\" as you used \"cvs update/commit\".  Be\n-sure that your repository is up to date before pushing, just\n-like you used to do with \"cvs commit\"; your push will fail if\n-what you are pushing is not up to date.\n-\n-3. Make the repository of every team member public. It is the\n-responsibility of each single member to pull from every other\n-team member.\n+as long as the shared repository does not have any branches\n+other than `master`.\n \n+[NOTE]\n+============\n+Because of this behaviour, if the shared repository and the developer's\n+repository both have branches named `origin`, then a push like the above\n+attempts to update the `origin` branch in the shared repository from the\n+developer's `origin` branch.  The results may be unexpected, so it's\n+usually best to remove any branch named `origin` from the shared\n+repository.\n+============\n+\n+Advanced Shared Repository Management\n+-------------------------------------\n+\n+Git allows you to specify scripts called \"hooks\" to be run at certain\n+points.  You can use these, for example, to send all commits to the shared\n+repository to a mailing list.  See link:hooks.txt[Hooks used by git].\n+\n+You can enforce finer grained permissions using update hooks.  See\n+link:howto/update-hook-example.txt[Controlling access to branches using\n+update hooks].\n \n CVS annotate\n ------------\n-- \n0.99.8b.g3480-dirty\n"},{"id":"15280","messageId":"7virs13x1i.fsf@assigned-by-dhcp.cox.net","threadId":"3170","inReplyTo":"20060129043147.GA9581@fieldses.org","subject":"Re: [PATCH] cvs-migration documentation update","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-01-31T03:18:17Z","receivedAt":"2006-01-31T03:18:17Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"J. Bruce Fields\" <bfields@fieldses.org> writes:\n\n> Here's some changes to the cvs-migration.txt.  As usual, in my attempt\n> to make things clearer someone may have found I've made them less so, or\n> I may have just gotten something wrong; so any review is welcomed.\n\nAgain, thanks for doing this.\n\n> I moved the material describing shared repository management from\n> core-tutorial.txt to cvs-migration.txt, where it seems more appropriate,\n> and combined two sections to eliminate some redundancy.\n\nSeems sensible.\n\n> diff --git a/Documentation/cvs-migration.txt...\n> index 8fd1a33..2bd58d3 100644\n> --- a/Documentation/cvs-migration.txt\n> +++ b/Documentation/cvs-migration.txt\n> @@ -1,126 +1,182 @@\n>  git for CVS users\n>  =================\n>  \n> -..., and the\n> -first step to recovery is admitting you have a problem. The fact that\n> -you are reading this file means that you may be well on that path\n> -already.\n> -\n> -The thing about CVS is that it absolutely sucks...\n> -\n> -One particular suckage of CVS is very hard to work around: CVS is...\n\nSomehow I miss the above two paragraphs and a half ;-).\nBut listing the differences as bullet points as you did makes\nthings much clearer.  I like it.\n\n> +------------------------------------------------\n> +$ git push origin master\n> +------------------------------------------------\n> +\n> +If some else has updated the repository more recently, `git push`, like\n\nsome else?\n"},{"id":"15281","messageId":"20060131034036.GA17585@fieldses.org","threadId":"3170","inReplyTo":"7virs13x1i.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] cvs-migration documentation update","fromName":"J. Bruce Fields","fromEmail":"bfields@fieldses.org","sentAt":"2006-01-31T03:40:37Z","receivedAt":"2006-01-31T03:40:37Z","isPatch":true,"sender":{"key":"bfields@citi.umich.edu","avatar":null},"body":"On Mon, Jan 30, 2006 at 07:18:17PM -0800, Junio C Hamano wrote:\n> \"J. Bruce Fields\" <bfields@fieldses.org> writes:\n> \n> > Here's some changes to the cvs-migration.txt.  As usual, in my attempt\n> > to make things clearer someone may have found I've made them less so, or\n> > I may have just gotten something wrong; so any review is welcomed.\n> \n> Again, thanks for doing this.\n\nHey, it's fun.\n\n> > -..., and the\n> > -first step to recovery is admitting you have a problem. The fact that\n> > -you are reading this file means that you may be well on that path\n> > -already.\n> > -\n> > -The thing about CVS is that it absolutely sucks...\n> > -\n> > -One particular suckage of CVS is very hard to work around: CVS is...\n> \n> Somehow I miss the above two paragraphs and a half ;-).\n\nHah.  Yes, understood.  But I figured a reader trying to migrate away\nfrom CVS is more painfully aware of the above than anyone, so better to\njust get out of their way and let them get on with it....\n\n> But listing the differences as bullet points as you did makes\n> things much clearer.  I like it.\n\nOK!  Good.\n\n> > +If some else has updated the repository more recently, `git push`, like\n> \n> some else?\n\nWhoops, thanks for noticing, should be \"someone\", obviously.\n\nLet me know if you'd like a revised patch.--b.\n"}]}