The instructions on this page make use of git's native "git-svn" functionality. 

Step 1: Create an "authors-transform.txt" file for the repository you will be converting

svn log -q https://svn-wrf-model.cgd.ucar.edu/ | awk -F '|' '/^r/ {sub("^ ", "", $2); sub(" $", "", $2); print $2" = "$2" <"$2">"}' | sort -u > authors-transform.txt

Make sure you use the base URL for the repository, not just the trunk!

This step creates a text file that allows you to translate the information about SVN commit authors into git for each commit.

Step 2: Edit the "authors-transform.txt" file so that old SVN usernames can be transformed into names/emails.

Follow the format that the above command already generated:

svn_username = Firstname Lastname <email@example.com>

For example:

mkavulich = Michael Kavulich, Jr. <kavulich@ucar.edu>

If you are migrating to Github, try to ensure the email you use for each author is the email address associated with their Github account. This step is optional but highly recommended for keeping your SVN history properly attributed.

Step 3: Clone the SVN repository into a git repository using the command "git svn clone".

This is the major time-consuming step: it may take up to a few hours depending on the size of your repository and the number of revisions. It will convert the old SVN repository into a new local one stored on your machine.

git svn clone --authors-file=authors-transform.txt --stdlayout --prefix=svn/ https://svn-wrf-model.cgd.ucar.edu/ WRF_NEW_REPO

Including "--prefix=svn/" in the above command is highly recommended. You'll see why in the next step. 

Include "--stdlayout" in the above command to specify that your SVN repository has the standard trunk/branches/tags layout. If your SVN repository has no branches or tags, this is unnecessary. If your SVN repository is more complicated you may have to get fancy.

You should enter the new directory that was just created by the "git svn clone" command, the rest of these steps need to be done from that directory.

Step 4: Convert SVN branches/tags to git branches/tags

Initially, all of your original SVN tags and branches are still "remote" tags and branches, and so before pushing to Github you must convert these to local tags and branches. Unfortunately there is no built-in command to do all of these at once. Fortunately, you can use the script attached to this page (git_svn_branch_tag_convert.pl) to do this in one step. Assuming you included "--prefix=svn/" in the previous command as recommended, just download that script into your new git repository and run it. All of your branches and tags should now be local branches and tags to your git repository! You can run the commands "git branch" and "git tag" to see your branches and tags, respectively.

Step 5: Push your new git repository to Github!

Before this step, you'll have to have a Github account and create an empty repository there first; this is easy though.

git remote add github https://wrf-model@github.com/wrf-model/WRF_TEST.git

git push --all github

git push --tags github

Replace "wrf-model" with your github username, and "WRF_TEST" with your repository name.

What happened in those three commands is that you added your empty repository hosted on Github as a "remote" repository named "github", then pushed your entire local repository (that you just created) to that location. For some reason, "git push --all" only pushes branches, not tags, which is why the last command is needed.

If everything went well, you're now done! If you go to your account on Github, you should now see your repository there in its entirety.

 

Merging two (or more) old SVN repositories to a single Git repository

NOTE: The following procedures are not as well tested as the above.

If you would like to merge one or more SVN repositories into a Git repository, this is not only possible, but fairly easy.

There are many ways you can achieve a single Git repository from multiple SVN repositories, but two of the best (my opinion) are described below.

Merged repositories are branches of the main repository

These instructions describe a merged repository where one main SVN repository is created as the master Git repository, and the others are imported as branches. This is not the only way to do this, but it is probably the simplest for future use.

Step 1: Convert your "parent" repository from SVN to Git and move it to github, as described in the first section.

Step 2: Convert your second SVN repository to Git on your local machine, following steps 1-4 in the first section. Do not push this repository to github.

Step 3: Set the repository you wish to merge as a "remote" of your main repository

git remote add -f REPO2 full_path_to_next_import_repo

An example from when I did this for my "REGTEST" repository, merging it into the WRFDA repository (which is the directory I am currently in, with the master branch checked out)

git remote add -f REGTEST /loblolly2/kavulich/GIT/WRFDA_REPO_SETUP/staging/REGTEST

"/loblolly2/kavulich/GIT/WRFDA_REPO_SETUP/staging/REGTEST" was the full path where I had imported the "REGTEST" subversion repository

Step 4:

git branch master-REGTEST remotes/REGTEST/master

git push -u origin master-REGTEST

Merged repositories are "subtrees" of the main repository

These instructions describe a merged repository where the original SVN repositories are in subdirectories of the new main Git repository. These will not be regular subdirectories: they take advantage of the "git subtree" functionality. There is a catch to this method: Only one of these repositories can have branches/tags.

Step 1: Move all of your SVN repositories into local Git repositories (steps 1–4 above).

Step 2: If you have not yet done so, commit the "parent" repository (if one of your repositories has branches/tags, it should be this one) to Github

Step 3: In the "parent" repository (if one of your repositories has branches/tags, it should be this one),  make a directory that you will move its current contents into

mkdir _tmp

git mv [A-Z]* [a-z]* _tmp/ (You might have to change the regular expressions here depending on your repository's contents)

git mv _tmp new_repo_name

Step 4: Commit your changes (remember: "committing" means something different in Git; you haven't pushed anything to Github yet!)

git commit -m 'Moving old trunk to subdirectory "new_repo_name"'

Step 5: Add the repository you're importing as a "remote" repository. In the below example, "REPO2" is the subdirectory you will import the new repository to.

git remote add -f REPO2 full_path_to_next_import_repo
git merge -s ours --no-commit REPO2/master
git read-tree --prefix=REPO2/ -u REPO2/master

Step 6: Commit changes

git commit -m "Subtree merge: REPO2 from repo2_old_location"

Step 7: Repeat Steps 5 and 6 as many times as necessary to merge other repositories

Step 8: Push everything to github.

 

 

  • No labels