Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GIT SVN: fetching a recreated SVN branch without the wrong merge parent

Tags:

git

svn

git-svn

I have the following situation with my upstream svn repository:

I created an svn branch and did some work on it which led to a really convoluted history. So I deleted it again, retaining the git commits, which allowed me to clean up the history quite nicely.

Once I had my patch series ready, I recloned my branch using svn copy, followed by a git svn fetch. The idea was, that I would then rebase the cleaned up history onto the new svn branch, so that I could easily publish it with git svn dcommit.

However, git svn fetch did not do what I expected. This is what I expected (fake git log --oneline --decorate --graph output):

* xxxxxxx (svn-branch)
* xxxxxxx (svn-parent-branch)
...
somewhere further down, unrelated to the above
* xxxxxxx (old-svn-branch-head)

But this is what I got:

* xxxxxxx (svn-branch)
|\
| * xxxxxxx (svn-parent-branch)
|
* xxxxxxx (old-svn-branch-head)

As you see, git svn fetch completely ignored the fact that the svn branch was deleted, mapping the recreating svn commit to a merge commit in git. Now, I wouldn't fuss about this, if this were of no consequence, but unfortunately, the wrong connection confuses git's merge algorithms, creating bogus merge conflicts when rebasing across the new branch base commit.

So my question is: How can I entice git svn fetch to not link up the new branch base commit with the wrong parent, or somehow fix my git repo in a way that I retain the ability to publish my stuff with git svn dcommit? Of course, I can always delete the whole thing again, and create a new svn branch with a different name, but I was wondering whether a better solution exists.

like image 747
cmaster - reinstate monica Avatar asked Oct 30 '22 14:10

cmaster - reinstate monica


1 Answers

I encountered a similar situation and still couldn't find a way to turn off this behavior (--no-follow-parent turns off the whole branch tracking, which is not what I want).

I ended up fixing history with git replace --graft. It creates a replacement commit and keeps its children unchanged. After the replace (ex. git replace --graft svn-branch svn-parent-branch) this is what you see:

* svn-branch
|
* svn-parent-branch
...
* old-svn-branch-head

You can still see the original commit with gitk --all option.

* svn-branch (replacement)
| 
| * svn-branch (original)
|/|
* |  svn-parent-branch
| |
| * old-svn-branch-head
...
like image 172
snipsnipsnip Avatar answered Nov 15 '22 04:11

snipsnipsnip