codingdave
codingdave

Reputation: 1277

How to rebase Git commits to SVN after having initialized the Git repository in an SVN directory?

When my SVN server was down I created a Git repository in my SVN repository. After some commits on the master branch I want to rebase the changes back to the SVN server (this is logically possible since the masters initial commit is the SVN revision at the time the SVN server went down plus some minor changes). So I added the SVN as a branch to Git using git-svn like described in SO How do I tell git-svn about a remote branch created after I fetched the repo.

Basically I now have two branches:

  1. git_svn (the SVN revision at the time my SVN server broke down)
  2. master (the branch which was started from 1 and conains all the changes since)

Since they are not connected in the Git tree Git isnt aware of the fact that 1 + 2 are a linear branch.

How can I apply all the changes including their commit messages from the master branch back to SVN?

What I already tried

Here, however, Git tells me that the patch fail to be applied.

Upvotes: 1

Views: 118

Answers (1)

codingdave
codingdave

Reputation: 1277

The workflow in chronological order is like:

  1. I was working on this svn repository:

    A --- ... --- F

  2. The svn server was down but I was working on some feature F' based on F. So I initiated a git repository in the exact same directory and started to commit to git from then (hoping to rebase on the svn branch using git-svn).

    F' --- G --- ... --- K

  3. Now the intention was to use git-svn to archieve:

    A --- ... --- F --- F' --- G --- ... --- K

How to do that?

  • have the svn repository checked out using git svn clone url-of-svn-repo (svn_repo with svn_branch containing A-F)
  • have the git feature branch ready (git_repo containing the feature branch F'-K)

Now we can checkout F' in git_repo to be able to create a patch from F to F'. The idea is to apply the patch to the svn_branch to make the svn_branch HEAD F and the feature branchs initial commit F' identical. With both repositories in one directory:

cd svn_repo
git reset --hard (warning: dont apply if you dont understand the implications)
git clean -rfx   (warning: dont apply if you dont understand the implications)
cd ../git_repo
git checkout F'
git reset --hard (warning: dont apply if you dont understand the implications)
git clean -rfx   (warning: dont apply if you dont understand the implications)
diff -wru3 svn_repo git_repo | grep -i only

Now remove everything that is only in the svn_repo, then were ready for creating and applying the patch:

diff -wrNu3 svn_repo git_repo > svnToGit.patch
cd svn_repo
patch -p1 < ../svnToGit.patch

The patch should run through flawlessly! If not, start over new. If the patch succeeded we commit the changes from F to F' onto the svn_branch:

git commit -a -m"patch applied"

Now we have in svn_branch

A --- ... --- F -- F'

And in git_repo

F' --- G --- ... --- K

For rebasing we now add the feature branch as a remote to svn_repo

git remote add featurebranch path/To/git_repo
git checkout featurebranch

Remeber we now have svn_branch at F' and the feature branch starting at F'. That means git rebase is able to apply commit per commit of our feature branch to our svn_repos svn_branch. We can do this by calling:

git rebase -s recursive -Xours -Xignore-space-at-eol --onto svn_branch G K

Selecting the recursive merge strategy and passing the options ignore-space-at-eol and ours, that effectively tells the recursive strategy to always use the code from the feature branch instead of the svn_branch when there is a conflict.

I only had conflicts of deleted and new files. git mergetool always tells whether the change is local or remote and I decided for remote throughout the rebase, that means for the feature branch. After a conflict you continue the rebase with git rebase --continue. When rebase is done you should check for correctness, watch the log, and in case everything is looking good you can apply the final svn_branch with git svn dcommit.

Upvotes: 1

Related Questions