| '\" t |
| .\" Title: gitcvs-migration |
| .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] |
| .\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/> |
| .\" Date: 02/06/2019 |
| .\" Manual: Git Manual |
| .\" Source: Git 2.21.0.rc0 |
| .\" Language: English |
| .\" |
| .TH "GITCVS\-MIGRATION" "7" "02/06/2019" "Git 2\&.21\&.0\&.rc0" "Git Manual" |
| .\" ----------------------------------------------------------------- |
| .\" * Define some portability stuff |
| .\" ----------------------------------------------------------------- |
| .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| .\" http://bugs.debian.org/507673 |
| .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html |
| .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| .ie \n(.g .ds Aq \(aq |
| .el .ds Aq ' |
| .\" ----------------------------------------------------------------- |
| .\" * set default formatting |
| .\" ----------------------------------------------------------------- |
| .\" disable hyphenation |
| .nh |
| .\" disable justification (adjust text to left margin only) |
| .ad l |
| .\" ----------------------------------------------------------------- |
| .\" * MAIN CONTENT STARTS HERE * |
| .\" ----------------------------------------------------------------- |
| .SH "NAME" |
| gitcvs-migration \- Git for CVS users |
| .SH "SYNOPSIS" |
| .sp |
| .nf |
| \fIgit cvsimport\fR * |
| .fi |
| .sp |
| .SH "DESCRIPTION" |
| .sp |
| 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\&. |
| .sp |
| Some basic familiarity with Git is required\&. Having gone through \fBgittutorial\fR(7) and \fBgitglossary\fR(7) should be sufficient\&. |
| .SH "DEVELOPING AGAINST A SHARED REPOSITORY" |
| .sp |
| 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 over ssh with: |
| .sp |
| .if n \{\ |
| .RS 4 |
| .\} |
| .nf |
| $ git clone foo\&.com:/pub/repo\&.git/ my\-project |
| $ cd my\-project |
| .fi |
| .if n \{\ |
| .RE |
| .\} |
| .sp |
| .sp |
| and hack away\&. The equivalent of \fIcvs update\fR is |
| .sp |
| .if n \{\ |
| .RS 4 |
| .\} |
| .nf |
| $ git pull origin |
| .fi |
| .if n \{\ |
| .RE |
| .\} |
| .sp |
| .sp |
| which merges in any work that others might have done since the clone operation\&. If there are uncommitted changes in your working tree, commit them first before running git pull\&. |
| .if n \{\ |
| .sp |
| .\} |
| .RS 4 |
| .it 1 an-trap |
| .nr an-no-space-flag 1 |
| .nr an-break-flag 1 |
| .br |
| .ps +1 |
| \fBNote\fR |
| .ps -1 |
| .br |
| .sp |
| The \fIpull\fR command knows where to get updates from because of certain configuration variables that were set by the first \fIgit clone\fR command; see \fBgit config \-l\fR and the \fBgit-config\fR(1) man page for details\&. |
| .sp .5v |
| .RE |
| .sp |
| You can update the shared repository with your changes by first committing your changes, and then using the \fIgit push\fR command: |
| .sp |
| .if n \{\ |
| .RS 4 |
| .\} |
| .nf |
| $ git push origin master |
| .fi |
| .if n \{\ |
| .RE |
| .\} |
| .sp |
| .sp |
| to "push" those commits to the shared repository\&. If someone else has updated the repository more recently, \fIgit push\fR, like \fIcvs commit\fR, will complain, in which case you must pull any changes before attempting the push again\&. |
| .sp |
| In the \fIgit push\fR command above we specify the name of the remote branch to update (\fBmaster\fR)\&. If we leave that out, \fIgit push\fR tries to update any branches in the remote repository that have the same name as a branch in the local repository\&. So the last \fIpush\fR can be done with either of: |
| .sp |
| .if n \{\ |
| .RS 4 |
| .\} |
| .nf |
| $ git push origin |
| $ git push foo\&.com:/pub/project\&.git/ |
| .fi |
| .if n \{\ |
| .RE |
| .\} |
| .sp |
| .sp |
| as long as the shared repository does not have any branches other than \fBmaster\fR\&. |
| .SH "SETTING UP A SHARED REPOSITORY" |
| .sp |
| We assume you have already created a Git repository for your project, possibly created from scratch or from a tarball (see \fBgittutorial\fR(7)), or imported from an already existing CVS repository (see the next section)\&. |
| .sp |
| Assume your existing repo is at /home/alice/myproject\&. Create a new "bare" repository (a repository without a working tree) and fetch your project into it: |
| .sp |
| .if n \{\ |
| .RS 4 |
| .\} |
| .nf |
| $ mkdir /pub/my\-repo\&.git |
| $ cd /pub/my\-repo\&.git |
| $ git \-\-bare init \-\-shared |
| $ git \-\-bare fetch /home/alice/myproject master:master |
| .fi |
| .if n \{\ |
| .RE |
| .\} |
| .sp |
| .sp |
| 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\(cqt 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 \fBgit-shell\fR(1)\&. |
| .sp |
| Put all the committers in the same group, and make the repository writable by that group: |
| .sp |
| .if n \{\ |
| .RS 4 |
| .\} |
| .nf |
| $ chgrp \-R $group /pub/my\-repo\&.git |
| .fi |
| .if n \{\ |
| .RE |
| .\} |
| .sp |
| .sp |
| Make sure committers have a umask of at most 027, so that the directories they create are writable and searchable by other group members\&. |
| .SH "IMPORTING A CVS ARCHIVE" |
| .if n \{\ |
| .sp |
| .\} |
| .RS 4 |
| .it 1 an-trap |
| .nr an-no-space-flag 1 |
| .nr an-break-flag 1 |
| .br |
| .ps +1 |
| \fBNote\fR |
| .ps -1 |
| .br |
| .sp |
| These instructions use the \fBgit\-cvsimport\fR script which ships with git, but other importers may provide better results\&. See the note in \fBgit-cvsimport\fR(1) for other options\&. |
| .sp .5v |
| .RE |
| .sp |
| First, install version 2\&.1 or higher of cvsps from \m[blue]\fBhttps://github\&.com/andreyvit/cvsps\fR\m[] and make sure it is in your path\&. Then cd to a checked out CVS working directory of the project you are interested in and run \fBgit-cvsimport\fR(1): |
| .sp |
| .if n \{\ |
| .RS 4 |
| .\} |
| .nf |
| $ git cvsimport \-C <destination> <module> |
| .fi |
| .if n \{\ |
| .RE |
| .\} |
| .sp |
| .sp |
| This puts a Git archive of the named CVS module in the directory <destination>, which will be created if necessary\&. |
| .sp |
| 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\&. |
| .sp |
| The main trunk is stored in the Git branch named \fBorigin\fR, 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 \fBmaster\fR branch, so you can start adding your own changes right away\&. |
| .sp |
| 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\&. |
| .sp |
| If you want a shared repository, you will need to make a bare clone of the imported directory, as described above\&. Then treat the imported directory as another development clone for purposes of merging incremental imports\&. |
| .SH "ADVANCED SHARED REPOSITORY MANAGEMENT" |
| .sp |
| 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 \fBgithooks\fR(5)\&. |
| .sp |
| You can enforce finer grained permissions using update hooks\&. See \m[blue]\fBControlling access to branches using update hooks\fR\m[]\&\s-2\u[1]\d\s+2\&. |
| .SH "PROVIDING CVS ACCESS TO A GIT REPOSITORY" |
| .sp |
| It is also possible to provide true CVS access to a Git repository, so that developers can still use CVS; see \fBgit-cvsserver\fR(1) for details\&. |
| .SH "ALTERNATIVE DEVELOPMENT MODELS" |
| .sp |
| CVS users are accustomed to giving a group of developers commit access to a common repository\&. As we\(cqve 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\&. |
| .sp |
| For example, you can choose a single person to maintain the project\(cqs 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\(cqre 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\&. |
| .sp |
| With a small group, developers may just pull changes from each other\(cqs repositories without the need for a central maintainer\&. |
| .SH "SEE ALSO" |
| .sp |
| \fBgittutorial\fR(7), \fBgittutorial-2\fR(7), \fBgitcore-tutorial\fR(7), \fBgitglossary\fR(7), \fBgiteveryday\fR(7), \m[blue]\fBThe Git User\(cqs Manual\fR\m[]\&\s-2\u[2]\d\s+2 |
| .SH "GIT" |
| .sp |
| Part of the \fBgit\fR(1) suite |
| .SH "NOTES" |
| .IP " 1." 4 |
| Controlling access to branches using update hooks |
| .RS 4 |
| \%git-htmldocs/howto/update-hook-example.html |
| .RE |
| .IP " 2." 4 |
| The Git User\(cqs Manual |
| .RS 4 |
| \%git-htmldocs/user-manual.html |
| .RE |