views:

48

answers:

2

I have a project in SVN that I'm migrating to Git. The project consists of a "core" product (under trunk), which is then branched within the same repository and used as a starting point to customize for each individual client that we roll the product out to.

It seems to me that these aren't real branches as they will never be merged back into the trunk, and they would be better off living in their own repositories with their history linking them back to the "trunk" repository and the ability to pull in changes from the trunk when required (easily accomplished with git of course).

What makes things slightly more complicated is that one client has a branch of their own project, which is a "real" branch in the sense that it will be merged back onto that clients main branch at some point in time.

To hopefully make things clearer, the SVN structure is as follows:

  • "Project" Repository
    • Trunk
    • Branches
      • Client1 (branched from Trunk v100)
      • Client2 (branched from Trunk v150)
      • Client2-Branch (branched from Client2 v200)
      • Client3 (branched from Trunk v150)

And the structure I'd like to get to is

  • "Project" Repository

  • Client1 Repository (Forked from SHA123)

  • Client2 Repository (Forked from SHA456)

    • Client2-Branch (branched from SHA456789)
  • Client3 Repository (Forked from SHA789)

Can anyone recommend a good way to do this - I'm not a Git newbie and I'm aware of filter-branch, I'm just not sure what method I should take to get this structure and keep as much history as possible.

Thanks

+2  A: 

If you really want to do this, clone the repo, and delete the extraneous branches in each.

But the current situation seems just fine. Are you sure you'll never want to cherry-pick patches from one repo to another?

wnoise
Pretty sure - we would always be going through what is now trunk
spmason
@Steve: I don't think you exactly answered wnoise there. If all work is always going through what you've labeled trunk, then you definitely want at least one repo where these branches all exist, so you can do things like merging common work from trunk into all clients. By all means, create separate clones to work in for each, but there's no reason that each client shouldn't at least be aware of the "trunk", and no reason the trunk shouldn't be aware of all clients. But wnoise is right: all you're asking how to do is clone, and delete a few branches.
Jefromi
But I need the branches I've made to be the master/trunk of the new repositories.. I guess that's just a merge and delete the original branch though?
spmason
`master` is not synonymous with `trunk`. There is nothing special about `master` except that it is the default branch in a new clone. If you want a different `master`, delete the current and create a new one. If you want multiple `master`-type branches, create `client1-master`, `client2-master`, ...
Jonathan
spmason
@spmason: you don't need to merge, even. Just delete all branches but the one you want to keep, and then `git branch -M oldname master`. But I really, truly, see no need to split these into separate repositories. You really should want to have each of the clients interacting with the trunk.
wnoise
+1  A: 

You can use svn2git to clone the branches into their own repos, something like

svn2git svn://project/branches/client1 --rootistrunk

for each branch that you want to make into a forked repo, and then

svn2git svn://project/trunk --rootistrunk

for the trunk.

I did something similar for a very large svn->git conversion.

ebneter