The ace-svn-to-git.sh
script will use git-svn to convert ACE's Subversion
repository to Git with the --stdlayout
flag so the trunk, tags, and branches
are handled mostly as expected (more below). The --prefix=svn/
option puts
all of those tags and branches under the svn
reference namespace, and the
--authors-file
option maps the Subversion author names to the current GitHub
profiles of the three authors in ACE's history.
Just run:
./ace-svn-to-git.sh
Note that it will create an authors.txt
file in the current directory
(overwriting any existing file with the same name) and it will create the
repository in an ace/
subdirectory.
The conversion works mostly as expected, but Subversion's tags are not tags in Git but remote branches. This is because tags in Subversion are just like branches and can be modified. Here we assume that the tags will never be modified and the script converts them to Git tags, then deletes the remote (tag) branches.
The trunk
remote branch is then created as a regular Git branch so it can be
checked out.
Finally, the master
branch is renamed to main
, following the current
convention.
Once everything looks good, it can be pushed to GitHub by setting the remote
and pushing all branches. Note that git push --all
does not push remote
(svn/
) branches that have not been converted to Git branches, nor does it
push tags, which is then accomplished with git push --tags
.
git remote add origin https://github.com/delph-in/ace.git
git push -u origin --all
git push -u origin --tags
The trunk
branch should never be committed to directly. Instead, it should
be kept up-to-date with the Subversion repository as follows:
git checkout trunk
git svn rebase
git checkout main # don't remain on trunk to avoid accidental commits
The main
branch can then merge in commits from trunk
, e.g., when a new
release is ready.
Note that the above steps only work if the local repository has the relevant
SVN metadata (e.g., if it was the one that originally cloned from SVN). If not,
the update.sh
script in this gist will attempt to reconfigure Git to know
about the SVN repo and rebuild the metadata. This should also work from a fresh
clone from GitHub.
The GitHub Importer tool does a great job at converting a subversion
repository to a conventional-looking Git repository. It does not, however, keep
the relevant metadata necessary for syncing the Git repo with subsequent
changes to the Subversion repo. Part of this metadata includes lines appended
to every commit message imported from Subversion, and another part exists
within the .git/svn/
subdirectory.
When someone does
svn tag
it creates a commit that adds the newtags/...
subdirectory. In Git, we don't need that commit, because what we want is merely the commit that one is based on. If you want to have those commits, then by all means do so. I removed them because I wanted the repo to follow Git conventions, where a tag is simply a pointer to the commit we want tagged and not a commit itself. This was explained in the link in the comment above: https://stackoverflow.com/a/14800155/1441112The clone creates a lot of branches that aren't necessary in a regular Git repo. E.g., if the SVN repo has 10 branches, you might have 20+ branches created in the Git repo converted from SVN, with some just for tracking the upstream SVN repo, I think. The git-svn docs will explain it better: https://git-scm.com/docs/git-svn.