4

As another attempt, I'm trying to convert a CVS repository to GIT. cvs-fast-export was recommended. The only problem is, I have no idea how to actually do so. I have it built, but how do I call it? There's tons of flags explained here but that's more confusing than it is helping.

Is there a short explanation somewhere of the actual process of conversion?

The repository is remote, and I normally go in via SSH. I'm not sure if the folder structure of this project is normal. Here's roughly what it looks like:

  • (on the remote server)/somefolder/cvs/anotherfolder/

  • Contains: CVSROOT repo-I-want-to-clone-name

  • repo-I-want-to-clone-name contains an Attic, and all the source code files with ,v after them. (No CVSROOT)

  • CVSROOT contains an Attic, cleanlog.sh, cvsignore, checkoutlist, checkoutlist,v, editinfo, editinfo,v, commmitinfo, loginfo, taginfo, etc. (No source-code like files here)

Tyler Shellberg
  • 225
  • 1
  • 3
  • 12

3 Answers3

6

You need to have a local copy of the CVS repository directory (containing all the RCS ,v files with history logs). If you have SSH access, use it to download the files via sftp/rsync/tar. If you only have a pserver URL, you need to use something like cvssuck to generate a local repository. In case the repository is hosted at Source­Forge, you can download the whole thing using rsync.

Once you have the RCS files, feed a list of the filenames to cvs-fast-export, and it will output a repository in the intermediate "Git fast-export" format

cd ~/cvsfiles
find . -name '*,v' | cvs-fast-export [some options] > ~/converted.fe

Note: Make sure to include any Attic directories, as they contain files which existed in old commits but were eventually "deleted".

(Besides that, however, there are no additional metadata files needed – each ,v file is completely self-contained, as it uses the same single-file history format as RCS does. The job of cvs-fast-export is to mingle those individual file histories into multi-file commits somehow.)

You can then make edits to the dump using reposurgeon (e.g. assign authors, squash split commits), and finally import it into Git using:

git init ~/result
cd ~/result
git fast-import < ~/converted.fe

The import will generate branches and commits, and will update the working-tree index, but apparently doesn't extract the working-tree files themselves: use git reset --hard or git checkout -f to do that.

(In theory, the same "fast-export" dump can also be imported by various other SCMs such as Mercurial, Plastic, or Bzr.)

Ken Williams
  • 371
  • 2
  • 11
u1686_grawity
  • 426,297
  • 64
  • 894
  • 966
  • Added what the structure of the repository roughly is on the remote server on the original post. Just wanted to clarify so I know for sure that I'll be correct in just copying ```CVSROOT```. – Tyler Shellberg Jun 21 '19 at 21:12
  • Whoops, forgot to add a mention so you get notified. – Tyler Shellberg Jun 21 '19 at 21:25
  • Ah, I think I used the wrong term – I didn't mean the "CVSROOT" directory actually, but rather the one that contains your repository's files specifically (or even the root directory that contains all repositories). – u1686_grawity Jun 21 '19 at 21:39
  • So the folder that has all the source files with ```,v``` after them is the correct one to copy? The ```CVSROOT``` folder with stuff like ```checkoutlist,v``` and ```editinfo,v``` can be safely ignored? Or should I grab both? – Tyler Shellberg Jun 21 '19 at 21:47
  • When I try this, I get ```cvs-fast-export: no commitids before 2019-06-21T16:39:24Z.``` (Which is actually about a half hour from now?) – Tyler Shellberg Jun 21 '19 at 22:12
  • You only need those files you want to see in Git, as each `,v` file is completely self-contained. Commit IDs are a relatively new addition to CVS; many repos have long histories without them. Mostly it just means cvs-fast-export will be forced to guess which check-ins to different files actually correspond to one `cvs` command. – u1686_grawity Jun 21 '19 at 22:19
  • Alright. I just tested with the one that has the source code files. However, once I ran git fast-import on the file, it reported all the source code files as "deleted" and only ```converted.fe``` as untracked. The folder I did this in is empty, except converted.fe. – Tyler Shellberg Jun 21 '19 at 22:25
  • If the import succeeded, you should now have commits in the `master` branch. The working tree can be built using something like `git checkout -f` or `git reset --hard`, if the import doesn't do that automatically. – u1686_grawity Jun 21 '19 at 22:27
3

Here is how I converted and verified my CVS repository named repos to using cvs-fast-export on Ubuntu 18.04.

Perform the conversion

First, create a "fast export" file from CVS:

sudo apt install cvs-fast-export

cd repos/    # The CVS repository
find . | cvs-fast-export -kb > ../repos.fe

Import the fast export file to Git:

cd ..
git init repos.git
cd repos.git
git fast-import < ../repos.fe

git fast-import creates a bare Git repo, so check out the working files:

git checkout -f

Verify the conversion

Create a CVS working copy with keywords not expanded:

cd ..    # Directory in which you started
export CVSROOT=$PWD/repos
mkdir checkout-cvs
cd checkout-cvs
cvs co -kb `(cd ../repos; ls | grep -v CVSROOT)`

Recursively prune empty directories, which do not appear in the Git version:

find . -type d | sort -r | xargs rmdir

The above gives an error for every non-empty directory, but that's fine.

Compare the CVS latest version to the Git latest version:

cd ..
diff -r  checkout-cvs repos.git
John McGehee
  • 373
  • 1
  • 2
  • 11
0

Here is an effective tool I just used for a long delayed migration:

https://github.com/rcls/crap

chqrlie
  • 101
  • 4