views:

131

answers:

1

My company has a large Subversion (SVN) repository, and for various reasons, we are considering migrating to Mercurial (HG). I'm hoping to learn the "best practice" ideas for our situation.

Our SVN repository is fairly monolithic, and looks something like this:

  • trunk
    • Python_Project_1
    • Python_Project_2
    • Python_Shared_Code
    • Flex_Code
    • ObjC_Code
    • ...
  • branches
    • Python_Project_1_Release_1.0.x
    • ...
  • tags
    • Python_Project_1_Release_1.0.0
    • ...

Currently, we are the only consumers of any of our code & other resources in the repository but part of the reason for the switch is that we may/will be sharing some portions of our code with other consumers. So, our projects will be divided into the following categories of accessibility:

  • Private Code (available only to us)
  • Shared Code (shared with non-public partners)
  • Public Code (shared via an open source license)

Also, to highlight the point, some code (e.g., the Python_Shared_Code folder in the SVN repository example above) is shared across projects, and so should be easily available to any Python projects (Private Code), and may need to be available for external consumers (Shared Code or Public Code).

I have some ideas of how I think I would lay this out, but I'd like to get outside ideas before continuing with the migration.

Update: I'm not sure it was clear from the above, but in particular, I'm looking for suggestions regarding the layout of HG repositories and how they interact.

Update: This question is similar -- but not identical -- to a few other questions that have been previously asked:

The major difference from the previous questions is the idea of "accessibility" and shared code. Some of the projects are inter-related (e.g., Python_Project_1 and Python_Shared_Code), and some may need to be shared with external entities (i.e., Shared Code and Public Code). The concept of splitting a single monolithic SVN repository into multiple HG repositories has been discussed, but I haven't found any concept of either type of sharing previously discussed.

+1  A: 

I'd say this answer does a great job suggesting separate repos per module.

And in this answer I suggest using either subrepos (which are ready) or (my preference) a build system that pulls in dependencies from a local build box such as ivy.

Ry4an
A few thoughts: The first linked answer only addresses part of the problem (have a repository for each project). It says nothing about inter-related projects. The second answer (using subrepos) seems close, but it doesn't quite do it. For example, consider the following: let `nested` be a subrepo for `main`. When I update and commit (and if necessary, push) to `nested`, I need `main` to be able to update and get the changes as well (without the user knowing about the subrepo relationship). However, some testing shows that this isn't the case.
Chris Phillips
As a follow up on that comment: Specifically, I need changes to the `nested` repository to automatically be made available in the `main` repository. It seems that subrepos only work in the opposite direction (i.e, changes to the subrepo in `main` get promoted/pushed back to the original `nested` repository).
Chris Phillips
subrepos can go both ways. With subrepos you have a pointer to a specific revision of a subrepo, and you can update that pointer to the tip of the subrepo by just updating in that repo space from within main. It's very much like svn:externals.As a matter of process though, I'd suggest having the subrepo pointer in main track some stable tag in the subrepo, not just the bleeding edge. Even internally having semi-formal product releases is nice, so you can make statement like "outer-project X work with inner-project Y version Z, and if it won't compile with Z+1, just built it against Z".
Ry4an
Unfortunately, at least for us, I think the "just updating in that repo space from within main" part of that is a deal breaker. I need to be able to be in the top level of a project, update, and get all necessary dependencies.
Chris Phillips
for therepo in $(find . -type d -name .hg | xargs -l dirname) ; do hg update -R $therepo ; done
Ry4an
There's probably an official way to do that, but that one liner certainly will. Again, though, I urge you to consider a build process where you're not tracking the 'tip' of your subrepos. Internal versioned releases is way more durable. Just because you wrote your utilities module doesn't mean you can run against any version of it, and tracking which versions of it your project requires / was build against is good policy and a lifesaver down the line.
Ry4an