I\'ve read a great deal of \"go from svn to git\" and other \"git-svn workflow\" articles on the web, and still I think they often deal with overly simple situations. They a
The problem is step 4 of course. A dcommit tries to replay your local history to the server. Dcommit pretends that you're a SVN client. Now, if the code you're dcommitting isn't only from you, that's something that is hard to dcommit to SVN.
Here's what the guru writes on the matter:
- For the sake of simplicity and interoperating with SVN, it is recommended that all git-svn users clone, fetch and dcommit directly from the SVN server (the remote SVN repository that is), and avoid all git-clone/pull/merge/push operations between git repositories and branches which are either retrieved via git svn clone and which are also used to push back changesets into the remote SVN repository.
- The recommended method of exchanging code between git branches and users is git format-patch and git am, or just git svn dcommit to the SVN repository.
- Since git svn dcommit uses git svn rebase internally, any git branches we git push to before git svn dcommit on them will require forcing an overwrite of the existing ref on the remote repository. This is generally considered bad practice, see the git-push documentation for details.
- Running git merge or git pull is not recommended on a branch we plan to git svn dcommit from. SVN does not represent merges in any reasonable or useful fashion so users using SVN cannot see any merges we have made. Furthermore, if we git merge or git pull from a git branch that is a mirror of an SVN branch, git svn dcommit may commit to the wrong branch.
- git clone does not clone branches under the refs/remotes/ hierarchy or any git-svn metadata, or config. So repositories created and managed with using git-svn should use rsync for cloning, if cloning is to be done at all.
- We should not use the --amend option of git commit on a change we have already dcommitted. It is considered bad practice to --amend commits we have already pushed to a remote repository for other users, and dcommit with SVN is analogous to that. More information on this can be found at Modifying a single commit and Problems with rewriting history.
I found this blog post that suggests keeping a separate branch for syncing with the Subversion repository, such that it will still be possible to do push/pull in the master branch.
What I used to do, is create an initial git svn clone, then shared he .git among the developpers using git, so we had exactly the same references.
It seemed to work correctly as we were able to use "specific git features" between git users, as long as we stayed in a linear tree (ie rebasing instead of merging).
As soon as you step in "distributed" issue, you are better off with one bare git repo cloned amongst developers.
Regarding the export-import phase to the public SVN repo, for other to use, the scripts
git2svn and svn2git can help encapsulate the magic.
Other considerations when working in Git and SVN repos are found in the question "Workflow and help with git, 2 svn projects and a single “workcopy”"
One of the problems I perceive with git-svn is that it stores the git-svn-id in the commit comment ; because this rewrites that commit, it changes it's SHA1, so you can't push it anywhere people will be sharing it.
I actually prefer bzr-svn because instead it stores the bzr revid in the remote SVN revision using the SVN revision properties feature instead which means no local revision rewrite. It also has the property desired, that two independent pulls of the same SVN branch will result in identical and interoperable bzr branches.
There's a tool that solves the problem of sharing Git repository synchronized with Subversion repository.
SubGit is a Git-SVN bi-directional server-side mirror.
One may install SubGit into Subversion repository and get Git repository automatically synchronized with SVN:
$ subgit configure $SVN_REPOS
# Adjust $SVN_REPOS/conf/subgit.conf to specify branches, tags and other options;
# Adjust $SVN_REPOS/conf/authors.txt to specify git & svn authors mapping
$ subgit install $SVN_REPOS
...
$ INSTALLATION SUCCESSFUL
SubGit installs pre-commit and post-commit hooks into Subversion repository, pre-receive and post-receive hooks into Git repository. As result it immediately translates incoming modifications from SVN and Git sides. After SubGit installation developers may use any Git client to clone and work with Git repository.
SubGit does not rely on git-svn, it uses its own translation engine our team has developed. More details on this you may find at SubGit vs. git-svn comparison. General documentation on SubGit is available here.
Version 1.0 of SubGit needs local access to Subversion repository, i.e. SVN and Git repositories have to reside on the same host. But with version 2.0 we're going to introduce Git proxy mode, when Subversion and Git repositories can be located anywhere and only Git repositories have SubGit installed into them, i.e. Subversion repositories remain untouched.
SubGit is a commercial product. It is free for open-source, academic project and also for projects with up to 10 committers.
Disclaimer: I'm one of SubGit developers.