0

My SW group is trying to update our source control system from Visual Source Safe, which is no longer supported by Microsoft, to Subversion (because our sister site already uses it). We have a lot of shared code which in VSS can be done directly with internal links. These will need to be moved into shared folders for multiple projects to use. Although externals can be used to bring these in, they are somewhat risky and not naturally integrated into the SVN architecture (although we still intend to use them for third party code and other stuff that doesn't change). Anyway, we came up with a solution that I haven't seen described anywhere but we all think makes sense so I wanted to see what others thought and if there are pitfalls (have not actually tried it live yet).

So I'm calling this "Shared Internal" folders, to contrast with externals. Suppose I have a directory called Common_Code in my repository root containing generic library files for a given language (C++ in this case). Now I create MyProject, with trunk/branches/tags, and want to put the shared folder in a subdirectory of my project. So I create a normal subversion branch that branches from Common_Code to MyProject/trunk/Common_Code. So various team members work on MyProject by branching off the trunk. Bob's branch might look like this: MyProject/branches/Bob_Working and the subfolder would branch to MyProject/branches/Bob_Working/Common_Code. This is effectively a branch of the branch of the shared folder.

When Bob is finished, he merges back to the trunk. This continues without interfering with any other project that might have also created an "internal branch" off the root shared folder. We eventually release our product, but find that we made some generic changes to Common_Code that would benefit other projects. So after some group review, we agree to merge our project's version of Common_Code back to the root version from which is was initially taken. This decouples the need to update shared code for a release from the need to share the changes with the rest of the company.

This seems like a simple yet flexible way to natively share code. I see two possible limitations. First, it won't work across repositories, in which case externals will need to be used. Second, you cannot delete the first branch after merge, so I don't think -reintegrate would be used. I still am not sure if just a normal merge back would be acceptable or if our Tortoise client supports it.

  • 1
    Don't reinvent the wheel!!! SVN Externals are **The Natural Way (tm)** of sharing code and **THEY ARE NATURALLY INTEGATED INTO SVN-ARCHITECTURE**. With your "workflow" you'll get a lot of headache with merging changes back from copy of copy of copy into original location, sure. Just read more about PEG-revisions in externals (and forget about not PEG-ed) and externals in common – Lazy Badger Apr 14 '16 at 04:52
  • Is the nearly inevitable divergence of the shared internals in this scheme, until they are no longer "shared" in truth from project to project, something you want to avoid? Or are you OK with that? – Ben Apr 14 '16 at 04:58
  • Our sister site uses pegged externals (pegged is the way to go yes). But they have very complex method of doing updates. To makes changes, they need to branch the common, point the external to the head revision of the branch. When done, merge the branch into the common trunk and re-peg the external to the new trunk version. Seems like a more complicated version of doing the same thing described above. We are still allowing projects to use an external to point to the shared code if they don't intend to make changes to it. But if they do, this method seems a simpler way. – R. Virzi Apr 14 '16 at 15:57
  • Regarding Bob's comment about divergence, I would discourage making changes to common code that is not generic enough to merge back in. You would have to make a copy of the files in question and put them explicitly into your project code, because they would then be, in fact, project specific files. And there's nothing to stop people from doing that with external code as well by making their own copies of it. In both cases, anyone who doesn't keep their project's shared code common will never benefit from future updates to the shared code. – R. Virzi Apr 14 '16 at 16:06

1 Answers1

0

After more research and much discussion, we have decided to stick with the externals method of sharing code. I am posting the conclusion report so others can benefit from the justifications that we were able to identify. If people think this will benefit other please vote up so that it can be seen.

I went back and reviewed the our sister site policy on externals for and then tried to distill down the major fundamental differences between these two methods. One thing that I did not initially realize, was that they describe a method of updating externals which can be done without the need to have a trunk and branches on the common folders – which was a big negative for me that went away. The differences then just boiled down to these:

Externals method allows you to peg to a common folder revision if desired, but if you want to change common code, you are required to unpeg, update to the latest rev locally, add your own changes, and commit back to the common folder. In other words, everyone works off the trunk in the common areas – but the pegs allow you not to be affected until you wish to make a change. It keeps the common in sync by adding a level of separation between your project specific code and the common it uses.

The double branch allows you to make changes to common code locally in isolation, but requires you to remember to merge it back into the common trunk later. In a sense it goes the other way – it keeps the project specific and common code always in sync at all times and branches, but adds a level of separation between the projects version of common and the shared common.

A practical consequence of this distinction is that for externals, you are forced to merge the common code first (on commit), and then merge into your project trunk second. But other projects are left alone since they are pegged to earlier versions. On the other hand, double branching allows you to merge into your project trunk first, then merge the common code later (second merge). Although you could do it in either order in that case.

We had put forth the idea of letting projects choose either method, but someone rightly pointed out the advantages of sticking to a uniform policy as much as possible. If I had to pick one, given what I know now, I would go with the externals method because it seems to me that shared code should be enforced to remain consistent throughout the repository. By giving it that level of independence from the specific projects, it enforces people to think about making sure the common code remains generic enough to use. If anyone really wanted to tailor it for project use, then they should make a separate copy of the files needed and do it in the project directory. After all, there is no intention in that case to merge back to the original directory, so no need to leave that door open.