1. Migrating to Git
The section is based on: https://git-scm.com/book/en/v2/Git-and-Other-Systems-Migrating-to-Git
1.1. Prepare author information
However, the import isn’t perfect, and because it will take so long, you may as well do it right. The first problem is the author information. In Subversion, each person committing has a user on the system who is recorded in the commit information. If you want to map this to better Git author data, you need a mapping from the Subversion users to the Git authors. Create a file called users.txt
that has this mapping in a format like this:
schacon = Scott Chacon <schacon@geemail.com> selse = Someo Nelse <selse@geemail.com>
If your users.txt file contains no entries
LOGIN = USERNAME <EMAIL>
the conversion process fails
To get a list of the author names that SVN uses, you can run this:
$ svn log --xml --quiet | grep author | sort -u | perl -pe 's/.*>(.*?)<.*/$1 = /' > users.txt
That generates the log output in XML format, then keeps only the lines with author information, discards duplicates, strips out the XML tags. (Obviously this only works on a machine with grep
, sort
, and perl
installed.) Then, redirect that output into your users.txt
file so you can add the equivalent Git user data next to each entry.
1.2. Create git branches and tags
Remember to load the git module to use the git svn feature
$ module load git
You can provide this file to git svn
to help it map the author data more accurately. You can also tell git svn
not to include the metadata that Subversion normally imports, by passing --no-metadata
to the clone
or init
command (though if you want to keep the synchronisation-metadata, feel free to omit this parameter). This makes your import
command look like this:
$ git svn clone https://gforge-next.eufus.eu/svn/<SVN_PROJECT_NAME>/ \ --authors-file=users.txt --no-metadata --prefix "" -s my_project $ cd my_project
Non-standard SVN layouts
If your SVN repository doesn’t have a standard layout, you need to provide the locations of your trunk, branches, and tags using the --trunk
, --branches
, and --tags
command line options. For example, if you have branches stored in both the /branches
directory and the /bugfixes
directories, you would use the following command:
git svn clone --trunk=/trunk --branches=/branches --branches=/bugfixes --tags=/tags --authors-file=users.txt --no-metadata --prefix "" https://<USERNAME>@gforge-next.eufus.eu/svn/<SVN_PROJECT_NAME> my_project
In case you consider the current layout of your SVN/Git repository more elaborate than usual (convoluted /tags, /trunk and /branches or heavily reliant on externals), please contact the ACH team to get some assistance on the migration.
You should also do a bit of post-import cleanup. For one thing, you should clean up the weird references that git svn
set up. First you’ll move the tags so they’re actual tags rather than strange remote branches, and then you’ll move the rest of the branches so they’re local.
proper shell
The next commands require bash shell.
If you using tcsh or other instead of bash, just type in the console:
$ bash
To move the tags to be proper Git tags, run:
$ for t in $(git for-each-ref --format='%(refname:short)' refs/remotes/tags); do git tag ${t/tags\//} $t && git branch -D -r $t; done
This takes the references that were remote branches that started with refs/remotes/tags/
and makes them real (lightweight) tags.
Next, move the rest of the references under refs/remotes
to be local branches:
$ for b in $(git for-each-ref --format='%(refname:short)' refs/remotes); do git branch $b refs/remotes/$b && git branch -D -r $b; done
It may happen that you’ll see some extra branches which are suffixed by @xxx
(where xxx is a number), while in Subversion you only see one branch. This is actually a Subversion feature called “peg-revisions”, which is something that Git simply has no syntactical counterpart for. Hence, git svn
simply adds the svn version number to the branch name just in the same way as you would have written it in svn to address the peg-revision of that branch. If you do not care anymore about the peg-revisions, simply remove them:
$ for p in $(git for-each-ref --format='%(refname:short)' | grep @); do git branch -D $p; done
Now all the old branches are real Git branches and all the old tags are real Git tags.
There’s one last thing to clean up. Unfortunately, git svn
creates an extra branch named trunk
, which maps to Subversion’s default branch, but the trunk
ref points to the same place as master
. Since master
is more idiomatically Git, here’s how to remove the extra branch:
$ git branch -d trunk
After finishing this section, "hanging" branches may appear (not connected to the main line of code history).
They can be "plugged into" using the git rebase command.
You can easily browse the new repository using gitk command:
$ gitk --all
1.3. Prepare new project
- Log in to https://gitlab.eufus.psnc.eu/dashboard/projects
- Press button "New project"
- Choose "Create blank project"
- Fill in the project form
- Disable option Initialize repository with a README
- Press button "Create project"
1.4. Send changes to new Git repository
The last thing to do is add your new Git server as a remote and push to it. Here is an example of adding your server as a remote:
$ git remote add origin https://gitlab.eufus.psnc.pl/<YOUR_GITLAB_USERNAME>/<GIT_PROJECT_NAME>
Because you want all your branches and tags to go up, you can now run this:
$ git push origin --all $ git push origin --tags
All your branches and tags should be on your new Git server in a nice, clean import.
Password is needed to access remote git repositories.
Git allow to store authentication parameters ( the default location is ~/.git-credentials
):
$ git config --global credential.helper store