luisgo
luisgo

Reputation: 2465

git-svn single svn server, multiple svn directories as multiple git remotes

Is it possible to have a single subversion server with multiple directories for branches that are each mapped as remotes in a git repository created using git-svn?

Existing Setup

This is legacy and in the process of being migrated to git BUT I am trying to prove we can use git-svn and have:

Note that I don't mind it if my remote's names have to be personal/branches, personal/tags, scrum/branches, scrum/tags, company/branches and company/tags respectively.

Ultimately I want to be able to create a branch off of trunk (aka company/master) that is not only local but pushed to personal/branches/some-feature-branch and later can be pushed to a different remote (say scrum/branches/some-feature-branch for collaboration and finally pushed to company/some-feature-branch for release. Note that I understand tagging but intentionally omitting that for the purposes of this discussion.

I thought this would work:

[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
    ignorecase = true
    precomposeunicode = false
    warnambiguousrefs = false
[svn-remote "svn"]
    url = https://svn.example.com
    fetch = trunk:refs/remotes/trunk
    branches = developers/luisgo/branches/*:refs/remotes/svn/personal/branches/*
    tags = developers/luisgo/tags/*:refs/remotes/svn/personal/tags/*
    branches = teams/scrum-01/branches/*:refs/remotes/svn/scrum/branches/*
    tags = teams/scrum-01/tags/*:refs/remotes/svn/scrum/tags/*
    branches = branches/*:refs/remotes/svn/company/branches/*
    tags = releases/*:refs/remotes/svn/company/tags/*

But it doesn't.

EDIT ===========================================

I think I explained myself wrong. Technically that example above works. What I am trying to achieve is to have one "remote" create per branching directory so:

git push personal feature-branch

Results in:

https://svn.example.com/developers/luisgo/branches/feature-branch

And...

git push scrum feature-branch

Results in:

https://svn.example.com/teams/scrum-01/branches/feature-branch

And...

git push company feature-branch

Results in:

https://svn.example.com/branches/feature-branch

In essence personal, scrum and company are remotes with different branches/* in the same svn server.

When I try to do this:

[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
    ignorecase = true
    precomposeunicode = false
    warnambiguousrefs = false
[svn-remote "company"]
    url = https://svn.example.com
    fetch = trunk:refs/remotes/trunk
    branches = branches/*:refs/remotes/svn/company/branches/*
    tags = releases/*:refs/remotes/svn/company/tags/*
[svn-remote "personal"]
    url = https://svn.example.com
    fetch = trunk:refs/remotes/trunk
    branches = developers/luisgo/branches/*:refs/remotes/svn/personal/branches/*
    tags = developers/luisgo/tags/*:refs/remotes/svn/personal/tags/*
[svn-remote "scrum"]
    url = https://svn.example.com
    fetch = trunk:refs/remotes/trunk
    branches = teams/scrum-01/branches/*:refs/remotes/svn/scrum/branches/*
    tags = teams/scrum-01/tags/*:refs/remotes/svn/scrum/tags/*

It tells me I need to resolve an ambiguous setting where I have the same url specified for more than one remote. I get that it is but these do share one trunk.

END EDIT ===========================================

Any ideas? Is this even possible?

Thank you,

Luis

PS: My apologies if this is not being posted in the right place. I am happy to move it. No need to flame.

Upvotes: 3

Views: 1516

Answers (1)

me_and
me_and

Reputation: 15634

Git will be quite happy with you having multiple Subversion repositories with the same base URL (the svn-remote.{name}.url setting). The problem is, from Git's point of view, you have multiple "repositories" trying to pull into refs/remotes/trunk, and pulling from one will overwrite another. The fact that at the end of the day they'll be identical is irrelevant, since there's no real way for Git to be certain of that.

(I'm going to keep referring to separate "repositories", since from Git's point of view these are entirely separate repositories; the fact that they're really the same Subversion repository makes no difference to Git.)

There's two possible solutions I can see based off your current workflow:

  • Delete all the fetch = trunk:refs/remotes/trunk lines from the config, so you only have one repository trying to pull into the trunk.

    If you want to keep things very clean, you could set up an entirely new repository just for the trunk, something like the below:

    [svn-remote "svn"]
            url = http://svn.example.com
            fetch = trunk:refs/remotes/trunk
    

    and then delete that fetch from the three other repositories.

  • Fetch the trunk separately for each repository, so the "company" remote would have the line fetch = trunk:refs/remotes/company/trunk, for example.

    That means you'll be repeating some fetch operations for each repository, but will mean you get the best chance at having the correct merge and branch history, since Git will know about the trunk (and hence branches from/merges to the trunk) in all of your repositories.

    Git still won't be able to track merges and branches between your different repositories, though, so a merge from a scrum branch into a company branch, for example, won't be detected as such.

That said, the commands you're after (git push scrum feature-branch to push to teams/scrum-01/branches/feature-branch, for example) will never work – you need to use git svn commands, such as git svn branch -R scrum feature-branch, then git svn dcommit while feature-branch is checked out.

I'd personally recommend your original configuration, though: it's the simplest option, it means you'll never fetch a commit multiple times, and Git will be able to do the best job it can for tracking branching and merging operations.

With your original config, you'd need to specify -d instead of -R to git svn branch, such as git svn branch -d teams/scrum-01/branches feature-branch, and I'll grant that's a little more complicated, but once the branch is created, pushing to it is exactly the same: git svn dcommit. The added configuration simplicity, and the ability for Git to track full merge and branch history, more than makes up for the increased complexity when creating a branch on the Subversion server.

Upvotes: 1

Related Questions