Reputation: 1277
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:
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?
git format-patch back
to the initial commitgit am
all-the-patches to git_svnHere, however, Git tells me that the patch fail to be applied.
Upvotes: 1
Views: 118
Reputation: 1277
The workflow in chronological order is like:
I was working on this svn repository:
A --- ... --- F
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
Now the intention was to use git-svn to archieve:
A --- ... --- F --- F' --- G --- ... --- K
git svn clone url-of-svn-repo
(svn_repo with svn_branch containing A-F)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