views:

188

answers:

1

I have a situation where I have an elderly CVS repository which we would like to convert to git once and for all while keeping full history etc.

All folders at the root of the repository contains Eclipse projects (either plain or dynamic web projects) including .classpath and .project. We use Team ProjectSets to check out the projects we need for a given task (where the project set is located in the project containing the main, and the rest are library projects).

When the Team ProjectSet is checked out, the workspace is fully populated.

This approach has worked pretty well for many years (except the project set part which came with 3.5), and we would like to work in a similar way with git if possible, but we are uncertain how.

I've played somewhat with git cvs import but it failed - probably due to us not using modules.

How would you suggest we do this, and how should we work with git to allow our current usage of shared library projects? Would we HAVE to introduce maven and create maven modules for our library projects? Or just ant ivy?


EDIT: I've now managed to convert our CVS repository to Subversion with a suitable cvs2svn invocation and found that Eclipse recognizes the resulting Subversion repository nicely. Unfortunately after cloning http://github.com/iteman/svn2git` and trying to run bin/svn2git I get

tra@Sandbox:~/cvsgit/svn2git/svn2git$ bin/svn2git
bin/svn2git:35:in `initialize': wrong number of arguments (2 for 1) (ArgumentError)
        from bin/svn2git:35:in `new'
        from bin/svn2git:35

This is with Ubuntu 10.04.1 LTS Server and I've tried various sudo things with Ruby and its gems without fully understanding what I did as I am not a Ruby programmer so I may have messed up things a bit. I'd appreciate advice - if the easiest is to install another Linux variant to do the conversion, that is fine.


EDIT:

https://help.ubuntu.com/community/Git http://css.dzone.com/articles/subversion-git-morning


Edit: My first try with the default svn2git completed successfully (after a while), and I get a nice repository where git branch -a reports roughly

tra@Sandbox:~/gitroot/svnroot$ git branch -a
* master
  remotes/XX64_DEPLOYED_CODE
  remotes/Beta1
  remotes/Beta2
  remotes/SV46
  ... lots more

We are interested in being able to check out the SV46 branch and work with it (we basically do not care about the tags, just actual branches). I have set up gitosis and pushed this repository to gitosis, and cloned it to another computer to find out how to do the "work with SV46" bit with Eclipse. THAT repository does not know of all the branches:

tra@TRA ~/git/git00 (master)
$ git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/master

Do I need to massage the original result from svn2git to get the information into the gitosis repository? Do I need to clone with an argument? Should I redo the svn2git step with the suggested version instead of the one shipping with Ubuntu?

EDIT: It turned out that publishing the svn2git generated repository with "git push --mirror" made things shown up in the gitosis repository. I now see the following inside gitosis (trimmed):

tra@Sandbox:/srv/gitosis/repositories/git01.git$ git branch -a
* master
  remotes/XX64_DEPLOYED_CODE
  remotes/Basic_Beta1
  remotes/Beta1
  remotes/Beta2
  remotes/SV46
  ... lots more
tra@Sandbox:/srv/gitosis/repositories/git01.git$ git branch
* master
tra@Sandbox:/srv/gitosis/repositories/git01.git$ git tag -l
tra@Sandbox:/srv/gitosis/repositories/git01.git$

Trying to clone this repository with git clone gitosis@sandbox:git01 -b remotes/SV46 or git clone gitosis@sandbox:git01 -b SV46 both tell me that the remote branch is not found upstream origin, using HEAD instead.

Am I barking up the wrong tree?

+5  A: 

First of all, using submodules for independent parts of your Central VCS repository (i.e. your CVS repo) is always good (see "What are the Git limits?").
That mean you will end up with many independent Git repo, that is "set of files evolving independently one from another", which is why submodules exist.

So multiple Git import (in multiple repo) are required.

But since git cvs import is not always up to the task, I would recommend:

  • cvs2svn in order to get an SVN repo first (just one repo)
  • svn2git in order to properly convert your SVN repo to a git one (i.e. transforming SVN branches into Git branch and SVN tags into Git tags)
VonC
Thanks. I will have a look at the Git limits in the coming days and give the "via SVN" a go after my vacation.
Thorbjørn Ravn Andersen
cvs2svn went nicely, but I have problems with svn2git. Please see my edit to the question.
Thorbjørn Ravn Andersen
@Thorbjørn: `svn2git` line 35 is `migration = Svn2Git::Migration.new(url, options)`, so you shouldn't just run `svn2git`, but run `svn2git url <option>`: you must at least provide an url. `$ svn2git http://svn.example.com/path/to/repo --trunk dev --tags rel --nobranches`. Also make sure to see again http://stackoverflow.com/questions/572893/cloning-a-non-standard-svn-repository-with-git-svn/572898#572898: I have updated the svn2git repo address: pick the nirvdrum's repo, not the iteman.
VonC
I managed to get a conversion with the default svn2git installed in Ubuntu with -s. Would you recommend redoing it with the nirvdrum version, or would this be fine? This is a one-time conversion, so no need to backsynchronizing to svn or cvs.
Thorbjørn Ravn Andersen
@Thorbjørn: I don't think you need to redo the conversion if you explorer first the resulting git repo (`gitk --all`) and see if nothing is missing.
VonC
@VonC, it looks right for HEAD, but I cannot locate how to get to a given CVS-branch (they appear to be in the SVN repository). Given a branch named e.g. SV48 how would I get the corresponding checkout with git?
Thorbjørn Ravn Andersen
@Thorbjørn: if the conversion went well, the *directory* `SVN48` should have been converted as a Git branch `SVN48`, meaning you can checkout that branch directly: `git checkout SVN48` and see (with a `gitk --all`, or a `git branch --all`) if you are at the `HEAD` of `SVN48` branch, and if its content is similar to the SVN48 original directory of the SVN repo.
VonC
@VonC. Just to be certain - I have e.g. three projects A, B, C. Project A and B were branched a long time ago in CVS on a branch named SV48, but not project C. Now I need to do work on this on my ported repository. How would I get to the SV48 branch/version of A and B?
Thorbjørn Ravn Andersen
@Thorbjørn: if get from one giant SVN repo, you end up with one giant Git repo (that you may then want to divide). But if `ProjectA` and `B` weren't a branch (`SVNRepo/branches/ProjectA` would be a branch) but a subdirectory within the branch SVN48 (as in `SVNRepo/branches/SVN48/Projectx`), then a `git checkout SVN48` should be enough for you to access the `SVN48` branch version of `ProjectA` or `B`.
VonC
I don't understand your explanation. In CVS a given file may exist in several branches, and you choose which branch you want to work in. It is the easiest for all files to belong to the same branch. It sounds to me that I need to play more with this to understand it better.
Thorbjørn Ravn Andersen
@Thorbjørn: the difference between CVS/SVN and Git is that branches are first-class citizen in Git (and not a simple directory). A same file can also exist in several branches. If you `git checkout SVN48`, you will get all files from that branch.
VonC
@Thorbjørn: thank you for the bounty, but please, do tell me if you managed to find your projects `A`, `B` and `C` in the branch `SVN48`. If so, I will update this answer with precisions extracted from those comments, for other to see.
VonC
@VonC, I have edited my question to reflect that I cannot locate our branches in my clone, so I may have done something wrong. Do you have a suggestion?
Thorbjørn Ravn Andersen
Note: `git checkout SV46` works in the original svn2git repository, but not in the gitosis clone
Thorbjørn Ravn Andersen
@Thorbjørn: I find strange that you list SV46 within the remotes namespaces, like if it was a remote repo (as in 'remotes/origin'). If you re-read the description of svn2giot, the goal is really to transform `branches/1.x` (2 directories within SVN) into a Git branch `1.x`. You should make *a new question* where you detail the initial structure of your SVN repo and the end result in the Git repo, for other (and me) to analyze.
VonC
@Thorbjørn: if `git checkout SV46` works in the first repo, then it may be a simple matter to track that branch in the second repo.
VonC
@Thorbjørn: may be try a `git pull refs/heads/*:refs/remotes/SV46/*` in your clone repo and see if `git branch -a` is more complete. See http://stackoverflow.com/questions/2471879/git-pull-currently-tracked-branch/2472588#2472588 and http://stackoverflow.com/questions/379081/track-all-remote-git-branches-as-local-branches
VonC
@VonC, I've decided to rerun the svn->git conversion with the svn2git you recommend.
Thorbjørn Ravn Andersen
@Thorbjørn: ok but I really would have liked to know if `git pull refs/heads/*:refs/remotes/SV46/*` gave any result.
VonC
I tried and it failed. I didn't save the message, and I think I removed the repository as I work on a disk starved machine.
Thorbjørn Ravn Andersen