Question

I used subgit to transform an old svn repository to git (including full history, branches, tags). After some initial trouble I got it working and it worked almost perfectly. Except branches doesn't seem to be merged back to the trunk/master branch:

enter image description here

As you can see, git knows that I branched the green master to get the black branch. But it doesn't seem to know that this branch was merged back to the master at commit 73653d1. It just looks like I abandoned that branch and independently implemented all that in one single commit in the master branch.

This isn't how a correct merge is supposed to look like, right? Is there a way to fix this? Note that this is about 50 commits back in history and besides the seemingly missing reference, the code is fine.

Was it helpful?

Solution

So,

r141: copied ^/trunk to ^/branches/restructure
r142: modified ^/branches/restructure
...
r148: modified ^/branches/restructure
r149: merged r142:148 from ^/branches/restructure to ^/trunk

That is, one didn't merge r141 of ^/branches/restructure into ^/trunk at r149.

As you probably know, merge commit in Git includes the whole history of every its parent. That's why SubGit checks whether all the necessary revisions were merged into a corresponding branch when it creates a merge commit.

In your case SubGit detected r141 as a gap in the history of ^/branches/restructure, that's why it didn't add this branch as a merge parent to commit 73653d1.

One may argue:

r141 didn't introduce any file or directory modifications, so why SubGit needs including this revision into svn:mergeinfo?

Well, in common case, a single SVN revision may create a branch and modify any file in it. That's why SubGit still checks every revision in history of the branch.

However, SubGit may be a bit smarter and check whether revision that creates a branch modifies any file in it, so for your case SubGit would create a merge commit automatically. We may implement that in future; here's the issue for that at our tracker.

How to fix the history in Git?

As Subversion doesn't allow any modifications in existing history, you have to create a new revision which adds missing r141 into svn:mergeinfo property of ^/trunk. Consider do the following for that:

$ svn switch ^/trunk .
$ svn merge --record-only ^/branches/restructure@148 .
$ svn commit -m 'Merged r141 of restructure changes into the trunk'

If you keep Subversion and Git repositories synchronized, SubGit should automatically translate this revision into merge commit. Otherwise you can translate the history from scratch or just install SubGit once again into the same SVN repository.

UPDATE:
How to fix history in Git repository if you don't need SVN sync anymore?

You can rewrite the part of Git history starting from 73653d1 commit with the following command:

git filter-branch --parent-filter \
'test $GIT_COMMIT = 73653d1 && echo "-p 2ec9e8c -p 5c237f9" || cat' master

NB: Put full commit IDs instead of abbreviated 73653d1, 2ec9e8c and 5c237f9.

This command should add 5c237f9 commit as a merge parent to 73653d1 commit.

Hope that helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top