Add svn:externals support
This will fix #436 (closed) .
Text copied from #436 (closed) comment 2.
I've got some WIP code (I've gotten to the point where I need to write to the new repo).
Basically, SVN externals have one of the following forms:
{RELATIVE DIRECTORY} [-rREVISION] {REPO URL}
[-rREVISION] {REPO URL} {RELATIVE DIRECTORY}
{REPO URL}[@REVISION] {RELATIVE DIRECTORY}
Notably, the svn:externals
property can be set on any arbitrary directory (unlike git submodules; there is one source of truth for those).
What I've done in my WIP code is:
- Parse the externals to a struct
- Store the externals in a map of strings to lists, where the key is the directory where
svn:externals
was set and the value being a list of externals for that directory- This map is currently regenerated on every commit with
svn:externals
.
- This map is currently regenerated on every commit with
- Print out the externals (which can be done on a per-commit basis, if I didn't bork something)
- Search on an external URL/revision/path combo (although I think I need to fix the path -- I was just comparing the relative path) -- this was to make it easier to set the equivalent git URL, revision, and (maybe) a different path if the repo URL was checking out a subdirectory.
Converting from an external to a .gitmodule is something I've done manually (which was a PITA). As an example, svn:externals
on the path applications/editors/josm
is
http://josm.openstreetmap.de/svn/trunk/tools 00_core_tools
http://josm.openstreetmap.de/svn/trunk/test/lib 00_core_test_lib
https://github.com/JOSM/JOSM-areaselector/trunk areaselector
Converting it to git submodules would look like this:
[submodule "applications/editors/josm/core"]
path = applications/editors/josm/core
url = ../josm.git
branch = master
[submodule "applications/editors/josm/plugins/areaselector"]
path = applications/editors/josm/plugins/areaselector
url = ../areaselector.git
branch = master
Notably, since subversion lets us check out a subdirectory instead of the full repository, we need to additionally add symbolic links to the "real" location.
Example (works with reposurgeon 4.18):
blob :4000001 <<EOF
../core/tools
EOF
<30121> add M 120000 :4000001 applications/editors/josm/plugins/00_core_tools
blob :4000002 <<EOF
../core/test/lib
EOF
<30552> add M 120000 :4000002 applications/editors/josm/plugins/00_core_test_lib
So, what I need to do with my WIP code:
- Enable editing of repo information
- Generate the
.gitmodules
file every time the externals change; this should be fairly trivial, I'll just want to make it idempotent (probably sorting by full path). - Set the directory checkout information to a fake blob when no revision information is given; this is where I got stuck on my initial version of the code (I was doing the all of the processing in svnread, and git didn't like the generated hashes)
- Create symbolic links, where necessary
- If a repository is already checked out somewhere and at the same revision, the symbolic link should go there
- Otherwise, the repository should be checked-out to a well-known location (e.g.
.gitmodules-sources
in the root directory)