I wanted to import a repository that was built in Git into Svn. The project was originally a Svn project, but new developers ported it to Git. I wanted to be able to modify it from either Git or Svn. I knew that I would not be able to create a seamless integration with the first Svn version, but I would be happy with a new one that could work with both from now on.
I found an excellent reference on Stack Overflow. Of course, it did not work with my repository. After many hours, I got it to work.
From Stack Overflow:
1. cd /path/to/git/localrepo
2. svn mkdir --parents protocol:///path/to/repo/PROJECT/trunk -m "Importing git repo"
3. git svn init protocol:///path/to/repo/PROJECT -s
4. git svn fetch
5. git rebase trunk
5.1. git status
5.2. git add (conflicted-files)
5.3. git rebase --continue
5.4. (repeat 5.1.)
6. git svn dcommit
When I reached the git rebase trunk line, I was faced with so many conflicts, it was impossible to continue. I still do not understand why the replay of the previous commits was causing so many (add/add) conflicts.
I then tried another sequence from later in the post:
git svn fetch
git rev-list --parents master | grep '^.\{40\}$'
git rev-parse svn/trunk
echo >> .git/info/grafts
git filter-branch -- ^svn/trunk --all
rm .git/info/grafts
More voodoo. In this sequence, I was introduced to rev-list, rev-parse and filter-branch. I am still a little vague on how these work. I was able to get this to work, and was introduced to a nice GUI for a git repository, gitk.
The next statement was git svn rebase. Again, too many (add/add) conflicts.
I then learned that git rebase has the -s for defining a strategy. With the recursive strategy, it is possible to set an option for always accepting the new revision into the current one.
git rebase -s recursive -Xtheirs svn/trunk
This worked, but then I received an error about a commit that did not have a message. Apparently, some commits were added without messages and this was preventing the rebase.
I found another stack overflow post that explained how to add messages for commits that are missing messages. The technique I picked only works for single line messages:
git filter-branch -f --msg-filter '
read msg
if [ -n "$msg" ] ; then
echo "$msg"
else
echo "The commit message was empty"
fi'
I then aborted the rebase and reran it. I received a bad format error. Filter-branch rehashes all the data, so I had to restart the sequence again, starting with git svn fetch.
Once that was done, I was able to complete the sequence:
git rebase -s recursive -Xtheirs svn/trunk
git svn dcommit
It worked. I can now do as the post suggested:
You can now sync from svn to git, using the following commands:
git svn fetch
git rebase trunk
And to sync from git to svn, use:git svn dcommit
No comments:
Post a Comment