Mercurial subrepository from a non-nested / siblin

2020-03-31 01:58发布

问题:

Is it possible to create a subrepository using a sibling path?

Subversion is our "chosen" VCS here, but I've already had quite a few issues with out of date commits. It's much more convenient for me to dual version my files under Hg and SVN, and I have had great success with it. However, I've got a few other co-workers using Hg, and we've had no problems there except for one they probably haven't noticed.

Our SVN layout looks like this

Area/
    trunk/
        Program1/
        Program2/
        ...
        Services/
            Program1ServiceA/
            Program1ServiceB/                

    branches/
        Program/
        Program/
        ...
        Services/
            Program1ServiceA/
            Program1ServiceB/                

    tags/
        Program1/
        Program2/
        ...
        Services/
            Program1ServiceA/
            Program1ServiceB/                

Which makes it kind of stupid when you're working on a project, because if your main project is comprised of Program1 and Program2, and a few more services... I can't get all of the changesets in one go, because we've got a repository that matches the directories. So I have to make sure 4 or 5 repos are in sync, especially with some service references.

I've had some good luck using subrepos beneath a single directory:

MainRepo/
    Subrepo1/
    Subrepo2/

But what I would like to do is specify a relative path so I can use sibling directories to the subrepository, so I could have something like this:

Area/
    Project1/
        Program1/ (points to ../trunk/Program1)
        Program2/ (points to ../trunk/Program2)
        Service1/ (... You get the idea)
        Service2/

    trunk/
        Program1/
        Program2/
        Services/
            Service1/
            Service2/

But so far it hasn't worked like I expected it to. trunk/Program1 is an Hg repo, and my Project1/.hgsub file contains

Program1 = ../trunk/Program1

I've also tried ../../trunk/Program1

But the result of either of those is that a new directory is created: Area/Program1/Project1 that is empty.

So far, the only search results I've been able to find use http based repositories for subrepos, so I'm not sure where to go from here. Our dev env is Windows 7, so the "easy" answer is to create junctions, but my primary concern is to make things like this easy to do, so the barrier to entry is as low as possible, and even something as easy as mklink /J Program1 ..\trunk\Program1 from an administrator cmd window is one more thing that would prevent people from migrating to a better workflow.

Is it possible to add a subrepository like I want, or is there a better way to do what we're doing?

回答1:

Subrepositories are always inside another repository. In other words, subrepositories lets you version a collection of repositories where some repositories are nested inside other repositories. Subrepositories can thus not be siblings without creating an outer repository.

The relative paths you're talking about are used when Mercurial needs to figure out where to get a new subrepository from. That is, when you run hg update (or when it's run for you as part of hg clone) and Mercurial notices a .hgsub file, then it needs to create the subrepositories mentioned there. To create the subrepo, Mercurial uses the path on right-hand side:

sub-A = relative/path
sub-B = C:/absolute/path

Here sub-A will be checked out in the root of your working copy using the command

hg clone <default path for main repo>/relative/path sub-A

and sub-B is checked out using the command

hg clone C:/absolute/path sub-B

That's all — it's a very simple mechanism. I've tried to describe this in my subrepository guide and it's also explained in the wiki.

For your case, you can make a thin shell repository for the parts that belong together. This repo will be like Project1 above and have Program1, Program2, Service1, etc as subrepos. The .hgsub will look like this:

Program1 = Program1
Program2 = Program2
Service1 = Service1
Service2 = Service2

By using "trivial subrepo paths" you make things easy: a clone looks just like the clone source and everything is kept together.

A final note: unless you use Program1 or Service1 in other projects, then you should just put everything into a single repository.