cvs-migration documentation update

Here's some changes to the cvs-migration.txt.  As usual, in my attempt
to make things clearer someone may have found I've made them less so, or
I may have just gotten something wrong; so any review is welcomed.

I can break up this sort of thing into smaller steps if preferred, the
monolothic patch is just a bit simpler for me for this sort of
thing.

I moved the material describing shared repository management from
core-tutorial.txt to cvs-migration.txt, where it seems more appropriate,
and combined two sections to eliminate some redundancy.

I also revised the earlier sections of cvs-migration.txt, mainly trying
to make it more concise.

I've left the last section of cvs-migration.txt (on CVS annotate
alternatives) alone for now.

Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
J. Bruce Fields 2006-01-28 23:31:47 -05:00 committed by Junio C Hamano
parent 1506fc34f7
commit b8bc67cef3
2 changed files with 147 additions and 207 deletions

View File

@ -1623,123 +1623,7 @@ suggested in the previous section may be new to you. You do not
have to worry. git supports "shared public repository" style of have to worry. git supports "shared public repository" style of
cooperation you are probably more familiar with as well. cooperation you are probably more familiar with as well.
For this, set up a public repository on a machine that is See link:cvs-migration.txt[git for CVS users] for the details.
reachable via SSH by people with "commit privileges". Put the
committers in the same user group and make the repository
writable by that group. Make sure their umasks are set up to
allow group members to write into directories other members
have created.
You, as an individual committer, then:
- First clone the shared repository to a local repository:
------------------------------------------------
$ git clone repo.shared.xz:/pub/scm/project.git/ my-project
$ cd my-project
$ hack away
------------------------------------------------
- Merge the work others might have done while you were hacking
away:
------------------------------------------------
$ git pull origin
$ test the merge result
------------------------------------------------
[NOTE]
================================
The first `git clone` would have placed the following in
`my-project/.git/remotes/origin` file, and that's why this and
the next step work.
------------
URL: repo.shared.xz:/pub/scm/project.git/ my-project
Pull: master:origin
------------
================================
- push your work as the new head of the shared
repository.
------------------------------------------------
$ git push origin master
------------------------------------------------
If somebody else pushed into the same shared repository while
you were working locally, `git push` in the last step would
complain, telling you that the remote `master` head does not
fast forward. You need to pull and merge those other changes
back before you push your work when it happens.
The `git push` command without any explicit refspec parameter
pushes the refs that exist both in the local repository and the
remote repository. So the last `push` can be done with either
one of these:
------------
$ git push origin
$ git push repo.shared.xz:/pub/scm/project.git/
------------
as long as the shared repository does not have any branches
other than `master`.
[NOTE]
============
If you created your shared repository by cloning from somewhere
else, you may have the `origin` branch. Your developers
typically do not use that branch; remove it. Otherwise, that
would be pushed back by the `git push origin` because your
developers' repository would surely have `origin` branch to keep
track of the shared repository, and would be counted as "exist
on both ends".
============
Advanced Shared Repository Management
-------------------------------------
Being able to push into a shared repository means being able to
write into it. If your developers are coming over the network,
this means you, as the repository administrator, need to give
each of them an SSH access to the shared repository machine.
In some cases, though, you may not want to give a normal shell
account to them, but want to restrict them to be able to only
do `git push` into the repository and nothing else.
You can achieve this by setting the login shell of your
developers on the shared repository host to `git-shell` program.
[NOTE]
Most likely you would also need to list `git-shell` program in
`/etc/shells` file.
This restricts the set of commands that can be run from incoming
SSH connection for these users to only `receive-pack` and
`upload-pack`, so the only thing they can do are `git fetch` and
`git push`.
You still need to create UNIX user accounts for each developer,
and put them in the same group. Make sure that the repository
shared among these developers is writable by that group.
. Initializing the shared repository with `git-init-db --shared`
helps somewhat.
. Run the following in the shared repository:
+
------------
$ chgrp -R $group repo.git
$ find repo.git -type d -print | xargs chmod ug+rwx,g+s
$ GIT_DIR=repo.git git repo-config core.sharedrepository true
------------
The above measures make sure that directories lazily created in
`$GIT_DIR` are writable by group members. You, as the
repository administrator, are still responsible to make sure
your developers belong to that shared repository group and set
their umask to a value no stricter than 027 (i.e. at least allow
reading and searching by group members).
You can implement finer grained branch policies using update
hooks. There is a document ("control access to branches") in
Documentation/howto by Carl Baldwin and JC outlining how to (1)
limit access to branch per user, (2) forbid overwriting existing
tags.
Bundling your work together Bundling your work together
--------------------------- ---------------------------

View File

@ -1,126 +1,182 @@
git for CVS users git for CVS users
================= =================
Ok, so you're a CVS user. That's ok, it's a treatable condition, and the So you're a CVS user. That's ok, it's a treatable condition. The job of
first step to recovery is admitting you have a problem. The fact that this document is to put you on the road to recovery, by helping you
you are reading this file means that you may be well on that path convert an existing cvs repository to git, and by showing you how to use a
already. git repository in a cvs-like fashion.
The thing about CVS is that it absolutely sucks as a source control Some basic familiarity with git is required. This
manager, and you'll thus be happy with almost anything else. git, link:tutorial.html[tutorial introduction to git] should be sufficient.
however, may be a bit 'too' different (read: "good") for your taste, and
does a lot of things differently.
One particular suckage of CVS is very hard to work around: CVS is First, note some ways that git differs from CVS:
basically a tool for tracking 'file' history, while git is a tool for
tracking 'project' history. This sometimes causes problems if you are
used to doing very strange things in CVS, in particular if you're doing
things like making branches of just a subset of the project. git can't
track that, since git never tracks things on the level of an individual
file, only on the whole project level.
The good news is that most people don't do that, and in fact most sane * Commits are atomic and project-wide, not per-file as in CVS.
people think it's a bug in CVS that makes it tag (and check in changes)
one file at a time. So most projects you'll ever see will use CVS
'as if' it was sane. In which case you'll find it very easy indeed to
move over to git.
First off: this is not a git tutorial. See * Offline work is supported: you can make multiple commits locally,
link:tutorial.html[Documentation/tutorial.txt] for how git then submit them when you're ready.
actually works. This is more of a random collection of gotcha's
and notes on converting from CVS to git.
Second: CVS has the notion of a "repository" as opposed to the thing * Branching is fast and easy.
that you're actually working in (your working directory, or your
"checked out tree"). git does not have that notion at all, and all git
working directories 'are' the repositories. However, you can easily
emulate the CVS model by having one special "global repository", which
people can synchronize with. See details later, but in the meantime
just keep in mind that with git, every checked out working tree will
have a full revision control history of its own.
* 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.
Importing a CVS archive Importing a CVS archive
----------------------- -----------------------
Ok, you have an old project, and you want to at least give git a chance First, install version 2.1 or higher of cvsps from
to see how it performs. The first thing you want to do (after you've link:http://www.cobite.com/cvsps/[http://www.cobite.com/cvsps/] and make
gone through the git tutorial, and generally familiarized yourself with sure it is in your path. The magic command line is then
how to commit stuff etc in git) is to create a git'ified version of your
CVS archive.
Happily, that's very easy indeed. git will do it for you, although git -------------------------------------------
will need the help of a program called "cvsps": $ git cvsimport -v -d <cvsroot> -C <destination> <module>
-------------------------------------------
http://www.cobite.com/cvsps/ 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.
which is not actually related to git at all, but which makes CVS usage The import checks out from CVS every revision of every file. Reportedly
look almost sane (ie you almost certainly want to have it even if you cvsimport can average some twenty revisions per second, so for a
decide to stay with CVS). However, git will want 'at least' version 2.1 medium-sized project this should not take more than a couple of minutes.
of cvsps (available at the address above), and in fact will currently Larger projects or remote repositories may take longer.
refuse to work with anything else.
Once you've gotten (and installed) cvsps, you may or may not want to get The main trunk is stored in the git branch named `origin`, and additional
any more familiar with it, but make sure it is in your path. After that, CVS branches are stored in git branches with the same names. The most
the magic command line is 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.
git cvsimport -v -d <cvsroot> -C <destination> <module> 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.
which will do exactly what you'd think it does: it will create a git Development Models
archive of the named CVS module. The new archive will be created in the ------------------
subdirectory named <destination>; it'll be created if it doesn't exist.
Default is the local directory.
It can take some time to actually do the conversion for a large archive CVS users are accustomed to giving a group of developers commit access to
since it involves checking out from CVS every revision of every file, a common repository. In the next section we'll explain how to do this
and the conversion script is reasonably chatty unless you omit the '-v' with git. However, the distributed nature of git allows other development
option, but on some not very scientific tests it averaged about twenty models, and you may want to first consider whether one of them might be a
revisions per second, so a medium-sized project should not take more better fit for your project.
than a couple of minutes. For larger projects or remote repositories,
the process may take longer.
After the (initial) import is done, the CVS archive's current head For example, you can choose a single person to maintain the project's
revision will be checked out -- thus, you can start adding your own primary public repository. Other developers then clone this repository
changes right away. 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.
The import is incremental, i.e. if you call it again next month it'll With a small group, developers may just pull changes from each other's
fetch any CVS updates that have been happening in the meantime. The repositories without the need for a central maintainer.
cut-off is date-based, so don't change the branches that were imported
from CVS.
You can merge those updates (or, in fact, a different CVS branch) into Emulating the CVS Development Model
your main branch: -----------------------------------
git resolve HEAD origin "merge with current CVS HEAD" Start with an ordinary git working directory containing the project, and
remove the checked-out files, keeping just the bare .git directory:
The HEAD revision from CVS is named "origin", not "HEAD", because git ------------------------------------------------
already uses "HEAD". (If you don't like 'origin', use cvsimport's $ mv project/.git /pub/repo.git
'-o' option to change it.) $ 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].
Emulating CVS behaviour Put all the committers should 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
------------------------------------------------
So, by now you are convinced you absolutely want to work with git, but Make sure committers have a umask of at most 027, so that the directories
at the same time you absolutely have to have a central repository. they create are writable and searchable by other group members.
Step back and think again. Okay, you still need a single central
repository? There are several ways to go about that:
1. Designate a person responsible to pull all branches. Make the Suppose this repository is now set up in /pub/repo.git on the host
repository of this person public, and make every team member foo.com. Then as an individual commiter you can clone the shared
pull regularly from it. repository:
2. Set up a public repository with read/write access for every team ------------------------------------------------
member. Use "git pull/push" as you used "cvs update/commit". Be $ git clone foo.com:/pub/repo.git/ my-project
sure that your repository is up to date before pushing, just $ cd my-project
like you used to do with "cvs commit"; your push will fail if ------------------------------------------------
what you are pushing is not up to date.
3. Make the repository of every team member public. It is the and hack away. The equivalent of `cvs update` is
responsibility of each single member to pull from every other
team member.
------------------------------------------------
$ git pull origin
------------------------------------------------
which merges in any work that others might have done since the clone
operation.
[NOTE]
================================
The first `git clone` places the following in the
`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
------------
================================
You can update the shared repository with your changes using:
------------------------------------------------
$ git push origin master
------------------------------------------------
If some else has updated the repository more recently, `git push`, like
`cvs commit`, will complain, in which case you must pull any changes
before attempting the push again.
In the `git push` command above we specify the name of the remote branch
to update (`master`). If we leave that out, `git push` tries to update
any branches in the remote repository that have the same name as a branch
in the local repository. So the last `push` can be done with either of:
------------
$ git push origin
$ git push repo.shared.xz:/pub/scm/project.git/
------------
as long as the shared repository does not have any branches
other than `master`.
[NOTE]
============
Because of this behaviour, 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.
============
Advanced Shared Repository Management
-------------------------------------
Git allows you to specify scripts called "hooks" to be run at certain
points. You can use these, for example, to send all commits to the shared
repository to a mailing list. See link:hooks.txt[Hooks used by git].
You can enforce finer grained permissions using update hooks. See
link:howto/update-hook-example.txt[Controlling access to branches using
update hooks].
CVS annotate CVS annotate
------------ ------------