First of all, since your specifications are rather unclear, I'm not sure how much of this really applies. But I'll give it a shot...
If your project has one single release cycle, you only need one repository. If your three teams need to release new version independently, it gets a lot messier. But for that I'd need more specific input. At the moment, it sounds to me like you need to stabilize your API, develop the library and manage your back-end development. If that's part of one project, go ahead and use one repository.
As for the branching, I'd recommend to always have one branch that simply represents the latest released and working version. This branch will probably mostly have merge commits. I like the idea of release branches independent of development branches as a release manager could then easily review everything (after feature freeze if you want so), scratch the last few itches, set the version properly, and merge into your production branch. (You could even bind hooks or deployment strategies to that merge in order to automatically push release onto your build system or something).
As I said above, I'd recommend having one release cycle within one repository. If you can have that, only one production branch will be necessary. If the teams really need to release new versions of the same project independently, it feels like there's something wrong with the project management. But that's again without knowing much about the team and project in general.
A style that I like much is the git flow as described by Atlassian. It suggests having one master (production) and one development branch. On development the actual work happens but, that usually splits up into feature branches. What I like is that a development manager (someone with deep technical insight) can manage the development branch. They decide whether to merge new features or not. At some point they will tell a project/release manager that the team's done and that project/release manager can then (together with the development manager) work out the last few glitches on a release branch before it'll be merged into master (and back into development, of course). It's just an interesting separation of concerns that developers are so keen on regarding different aspects of the very same projects. :)
Hope this helps a bit.
Imagine your code not as a monolithic system, but rather as a series of packages. Some packages depend on others. Some, such as jQuery, are external to your company; others are developed by your company and made public; others, developed by your company, are eventually made private.
For instance, if you develop a web application in Python, you may have a dependency to Flask—a popular Python web framework—and to a bunch of other packages, both external and internal.
What happens to your CI when developers of Flask release a new version? Right, nothing. It's up to you to go and edit your project file which says that from now on, you are not using the version x of Flask, but rather the version y. Once you do that, CI considers that your project changed, and launches all the tests which ensure that the application still works with the new version of Flask. If it doesn't, well, you'll probably fix your application, except in very rare cases where you actually reveal a bug in Flask itself.
The same logic can be applied to any code produced within your company. A shared library becomes a Python package, either shared through pypi
—the repository of public packages for Python, or stored on a private pip
server which can be used within your company only.
It then makes it particularly clear what broke the build. When you publish the new version of a package A, CI runs the corresponding tests and indicates whether the version contains regressions or not. Then, if a problem is encountered at the stage when you ask a package B to use the new version of the package A, it's the package B which broke the build by being incompatible with the new version of the package A: in the same way, your app may not be compatible with a newer version of Flask or jQuery.
Notice that you don't have to really manage dependencies yourself: the packaging system does it for you. The only problem which requires your intervention is the updating of the references, that is the action of telling that a given package will use a different version of another package: if you modified a package which is used a lot in your code base, it may take a while to track and modify all the projects which use it.
As for the version control, it really doesn't matter. You may have a team working with Git, and another one working with SVN. As soon as the two teams agree on using pypi
and choosing specific pip
server(s)¹ for internal packages, everything will be all right. Similarly, you shouldn't care whether developers of Flask or jQuery use Git, SVN, SourceSafe or TFS.
Note: I've used an example from Python world, but the same logic can be applied to other languages as well. There is npm
for Node.js, NuGet
for .NET Framework languages, etc. You can setup private package managers as well.
Further reading: Packages, dependencies and interaction between teams, my article based on this question.
¹ Nothing forces you to have a single package server in your company. Different teams can deploy their own servers; the only constraint is that other teams should know the location of the server in order to use the packages.
Best Answer
Create a new branch called legacy from the current master.
Then merge your international branch into master and go from there.
Be sure to push your changes to any remote repositories you need to.
You can always merge changes from master to legacy, or from legacy to master as needed.