migrating from SVN to Git
Matthew Fluet <[email protected]> Sat, 2 Mar 2013 22:14:36 -0500
| Newsgroups | gmane.comp.lang.ml.mlton.devel |
|---|---|
| Message-ID | <CAMrhFL5LjRnzoTigXCgyRw6kg+S_sNKXJWhE3-fgRAuUE++k=Q@mail.gmail.com> |
At various times, the idea of migrating the MLton project sources from
Subversion to a DVCS has been raised. I've been using "git svn" for a
while and have had positive experiences with it, so I'd like to
migrate to Git. One particular reason for migrating now is that I'm
working with a few students on MLton related projects, and I would
like to support a more modern workflow and encourage
commits/reviews/revisions before merging into the public repository.
For a while, I've been working on migrating the SVN repository to a
Git repository. While using "git svn clone" yields a reasonable
conversion, there are some definite "anomalies" in the resulting Git
repository. The major issue with a simple "git svn clone" conversion
is that the original CVS to SVN conversion seems to have had some
issues. See, for instance, the set of SVN branches that existing
immediately after the conversion:
https://sourceforge.net/p/mlton/code/3925/tree/mlton/branches/
Another minor issue is that the resulting Git repository doesn't
reflect merges of branches into trunk. That is, the resulting Git
repository doesn't "feel" like a Git repository.
So, I've developed a Makefile and a number of (ad-hoc) scripts to
handle the conversion, which are available from:
http://mlton.org/misc/mlton-vcs-conversion.tgz
Here are some of the high points:
* The SVN repository is really comprised of four distinct lines of
development: "mlton" corresponds to the compiler-project proper;
"mltonlib" corresponds to the library project (see
http://mlton.org/MLtonLibraryProject); "talks" holds the
sources/slides from the 2006 ML Workshop talk; "tools" holds the
'wiki' tool (which was used for command-line interaction with the
old MoinMoin wiki). I feel that it makes the most sense to split
the distinct lines of development into distinct Git repositories.
The following primarily concerns the SVN "mlton" directory, but
I've also converted the SVN "mltonlib" directory.
* Went back to the original CVS repository to convert history from
before the CVS to SVN conversion. Although the CVS repo was taken
down on 20060809, a backup snapshot of the repository has been kept
around.
* Use "cvs2ps" to generate an initial set of patches from the CVS
repository. The "cvs2ps" tool is used by "git cvsimport" for a
one-time import of a CVS repository. But, it is also possible to
direct "git cvsimport" to use the output of a run of "cvs2ps". I do
this in order to fix a few of the "issues" that arise in the
conversion of the CVS repo; presumably, some of these were what led
to the broken history in the CVS to SVN conversion (but, I also
believe that some of the CVS conversion tools have improved since
the time of the CVS to SVN conversion). Mainly, force the correct
branch on patches for which "cvs2ps" could not identify a branch.
* Use "git svn clone" to import the SVN repository since r3924, which
corresponds to the last commit to the CVS repository.
* Use the ".git/info/grafts" feature of "git"
(https://git.wiki.kernel.org/index.php/GraftPoint) to combine the
CVS and the partial-SVN histories. Also use ".git/info/grafts" to
introduce the various branch-to-trunk merges (and, for the
x86_64-branch, the various trunk-to-branch merges).
* Regularize the naming convention of branches; this seems an
acceptable revision of history and lends some order to an
alphabetical listing of branches. In any cases, since there are no
extant active branches, all branches are moved to a
"refs/archived/heads/" namespace (which isn't copied by default in
a "git clone").
* Turn the various CVS and SVN tags for public releases into git
annotated tags. The "git cvsimport" turned CVS tags into git
lightweight tags, while the "git svn clone" turned SVN tags into
git branches (with a single, empty-diff commit).
* Drop the remaining CVS and SVN tags. Most of these from CVS
corresponded to many fine-grained experimental releases (which were
purged from the SVN repository, see:
https://sourceforge.net/p/mlton/code/4256/). The remaining from
CVS and SVN corresponded to branch and merge points, which are
fairly easily recovered in git, so explicit tags seem unnecessary.
* Use "git filter-branch" to make the ".git/info/grafts" parentages
permanent. Also, rewrite the "git-svn-id: ..." metadata appended
to every SVN commit by "git svn clone" to a simple "SVN rNNNN"
message. This makes it fairly easy to find the git commit
corresponding to a SVN commit via a "git log --grep='SVN rNNNN'" or
"git rev-list --grep='SVN rNNNN'".
I've pushed the resulting Git repositories to (temporary) Git
repositories on SourceForge:
https://sourceforge.net/p/mlton/on-20130302-svn2git-mlton
https://sourceforge.net/p/mlton/on-20130302-svn2git-mltonlib
which can be cloned with:
git clone git://git.code.sf.net/p/mlton/on-20130302-svn2git-mlton mlton
git clone git://git.code.sf.net/p/mlton/on-20130302-svn2git-mltonlib mltonlib
After ironing out any remaining issues with the conversion, I'll
delete these temporary Git repositories and push to permanent Git
repositories on SourceForge (with more concise mount points).
Ultimately, I intend to mirror the final Git repositories from
SourceForge to GitHub (and BitBucket?).
There are a small number of known limitations with the conversion.
* Each distinct username in the CVS and SVN repositories is converted
to a single git user.name and user.email; for the e-mail address, I
used a person's current or last known e-mail address. That is, the
e-mail address that appears in the Git repository may not
correspond to the e-mail address that the author was using at that
point in history. Given date ranges for authors, it wouldn't be
difficult to set e-mail addresses during the "git filter-branch"
step, but I'm not sure that it is worth the trouble. (And, I
suspect that I am the author who has transitioned through the most
e-mail addresses and I'm fine with using my current e-mail
throughout the Git repository.)
* As is well known, SVN can track empty directories while Git does
not track empty directories.
* For the mlton Git repository, looking at the tagged public
releases, this only affects the "package/freebsd/files"
directory, and for trunk/master, this also affects the
"mlton/cm", "mlton/codegen/bytecode", and "runtime/bytecode"
directories. But, these three directories were intended to be
deleted; they weren't because I emptied the directories on a
"git svn clone".
* For the mltonlib Git repository, looking at trunk/master, this
doesn't affect any directories. But, it was common practice in
this development to commit a directory hierarchy without files,
so there are a number of empty-diff commits in the Git
repository. I experimented with using "git svn"'s features for
tracking directories, but the resulting history looked a bit
"noisy" with placeholder files.
Anyways, I'm looking for feedback on the decision to migrate to Git
and on the conversion.
------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_d2d_feb