I want to convert a Subversion repository sub-directory (denoted by module
here) into a git repository with full history. There are many svn copy
operations (Subversion people call them branches) in the history of my Subversion repository. The release policy has been that after each release or other branches created, the old URL is left unused and the new URL replaces the old one for containing the work.
Optimally, by my reading, it seems like this should do the trick:
$ git svn clone --username=mysvnusername --authors-file=authors.txt \ --follow-parent \ http://svnserver/svn/src/branches/x/y/apps/module module
(where branches/x/y/
depicts the newest branch). But I got an error, which looks something like this:
W: Ignoring error from SVN, path probably does not exist: (160013): Filesystem has no item: '/svn/src/!svn/bc/100/branches/x/y/apps/module' path not found W: Do not be alarmed at the above message git-svn is just searching aggressively for old history.
(Update: Adding option --no-minimize-url
to the above does not remove the error message.)
The directory module
get created and populated, but the Subversion history past the newest svn copy
commit is not imported (the git repository created ends up having just two commits when I expected hundreds).
The question is, how to export the full Subversion history in the presence of this situation?
Searching for the error message, I found this: git-svn anonymous checkout fails with -s which linked to this Subversion issue: http://subversion.tigris.org/issues/show_bug.cgi?id=3242
What I understand by my reading, something in Subversion 1.5 changed about how the client accesses the repository. With newer Subversion, if there is no read access to some super directory of the URL path (true for me, svn ls http://svnserver/svn
fails with 403 Forbidden
), then we fail with some Subversion operations.
Jeff Fairley in his answer points out that spaces in the Subversion URL might also cause this error message (confirmed by user Owen). Have a look at his solution to see how he solved the case if your git svn clone
is failing for the same resson.
Dejay Clayton in his answer reveals that if the deepest subdirectory components in branch and tag svn urls are equally named (e.g. .../tags/release/1.0.0
and .../branches/release-candidates/1.0.0
) then this error could occur.
What are SVN's disadvantages? SVN's approach does come with some drawbacks that users should be aware of. Due to its centralized design, most operations dealing with state or history will require a direct connection to the central server.
SVN has one central repository – which makes it easier for managers to have more of a top down approach to control, security, permissions, mirrors and dumps. Additionally, many say SVN is easier to use than Git.
# Clone a repo with standard SVN directory layout (like git clone): git svn clone http://svn.example.com/project --stdlayout --prefix svn/ # Or, if the repo uses a non-standard directory layout: git svn clone http://svn.example.com/project -T tr -b branch -t tag --prefix svn/ # View all branches and tags you have ...
I ran into this problem when I had identically-named subdirectories within branches or tags.
For example, I had tags candidates/1.0.0
and releases/1.0.0
, and this caused the documented error because subdirectory 1.0.0
appears within both candidates
and releases
.
Per git-svn docs:
When using multiple --branches or --tags, git svn does not automatically handle name collisions (for example, if two branches from different paths have the same name, or if a branch and a tag have the same name). In these cases, use init to set up your Git repository then, before your first fetch, edit the $GIT_DIR/config file so that the branches and tags are associated with different name spaces.
So while the following command failed due to similarly named candidates
and releases
tags:
git svn clone --authors-file=../authors.txt --no-metadata \ --trunk=/trunk --branches=/branches --tags=/candidates \ --tags=/releases --tags=/tags -r 100:HEAD \ --prefix=origin/ \ svn://example.com:3692/my-repos/path/to/project/
the following sequence of commands did work:
git svn init --no-metadata \ --trunk=/trunk --branches=/branches --tags=/tags \ --prefix=origin/ \ 'svn://example.com:3692/my-repos/path/to/project/' git config --add svn-remote.svn.tags \ 'path/to/project/candidates/*:refs/remotes/origin/tags/Candidates/*' git config --add svn-remote.svn.tags \ 'path/to/project/releases/*:refs/remotes/origin/tags/Releases/*' git svn fetch --authors-file=../authors.txt -r100:HEAD
Note that this only worked because there were no other conflicts within branches
and tags
. If there were, I would have had to resolve them similarly.
After successfully cloning the SVN repository, I then executed the following steps in order to: turn SVN tags into GIT tags; turn trunk
into master
; turn other references into branches; and relocate remote paths:
# Make tags into true tags cp -Rf .git/refs/remotes/origin/tags/* .git/refs/tags/ rm -Rf .git/refs/remotes/origin/tags # Make other references into branches cp -Rf .git/refs/remotes/origin/* .git/refs/heads/ rm -Rf .git/refs/remotes/origin cp -Rf .git/refs/remotes/* .git/refs/heads/ # May be missing; that's okay rm -Rf .git/refs/remotes # Change 'trunk' to 'master' git checkout trunk git branch -d master git branch -m trunk master
Not a full answer, but perhaps the snippet you are missing (I am interested in migrating as well, so I have found that part of the puzzle).
When you look at the documentation of git-svn, you will find the following option:
--no-minimize-url
When tracking multiple directories (using --stdlayout, --branches, or --tags options), git svn will attempt to connect to the root (or highest allowed level) of the Subversion repository. This default allows better tracking of history if entire projects are moved within a repository, but may cause issues on repositories where read access restrictions are in place. Passing --no-minimize-url will allow git svn to accept URLs as-is without attempting to connect to a higher level directory. This option is off by default when only one URL/branch is tracked (it would do little good).
This fits to the situation you have, so that git svn
does not try to read a higher level of the directory tree (which will be blocked).
At least you could give it a try ...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With