How to maintain stable/default configuration with master repository and subrepos in remote hosting environment?

335 views Asked by At

I have an application "myapp" that uses two modules common with other applications "common" and "common-www".

These are arranged as a thin-shell within a master repository

myapp-master
    myapp
    common
    common-www

Each subrepo is setup as a stable/default configuration with "production" and "trunk" repositories.

The .hgsub file for the thin-shell master on stable ("production") is:

myapp = https://myhostingprovider/repos/myapp/grp/production
common = https://myhostingprovider/repos/common/grp/production
common-www = https://myhostingprovider/repos/common-www/grp/production

The master repository itself is at:

https://myhostingprovider/repos/myapp/master/production

This is great - I have a single master repository with consistent versioning across the application and sub-modules.

The problem is being able to maintain a stable/default view of the master repository as the .hgsub file needs to point to different repositories:

myapp = https://myhostingprovider/repos/myapp/grp/trunk
common = https://myhostingprovider/repos/common/grp/trunk
common-www = https://myhostingprovider/repos/common-www/grp/trunk

Since I have to put absolute paths in the .hgsub file, I end up with two entirely independent thin-shell master repositories - one for development and one for production - and no ability to push changes from development to production during a release cycle.

Is this master repository approach for remote hosting typical for shared libraries? Can you recommend an alternative way of working (with regard to remote hosting where hgsub paths are absolute)?

Any thoughts much appreciated?

2

There are 2 answers

4
shadowspawn On

1) Your setup is perfectly usable as is. When you want to merge code changes between development and production you merge the affected subrepos individually, so from trunk to production for myapp. And common. And common-www. This approach is low-tech and the merging is between plain repos, so straight forward Mercurial.

The two master repos still provide the consistent versioning across the application and modules within the development/production branch, but are not used directly in doing merges.

I use this approach myself. You do three merges instead of one uber merge, but the upside is each merge is simple to perform and understand.

2) The .hgsub references do not have to be absolute just because you are using repo hosting. In fact a recommendation for shell master repos is that all of the hgsub references are trivial like foo=foo.

https://www.mercurial-scm.org/wiki/Subrepository#Use_.27trivial.27_subrepo_paths_where_possible

The relative reference is always relative to the master repo, so trivial references require that the layout on the remote server match the layout on your local sandpit.

For example you could have on server:

myapp-production-master
    myapp
    common
    common-www
myapp-trunk-master
    myapp
    common
    common-www

3) As an alternative, I use a slightly different layout which results in non-trivial .hgsub references but makes it easy to mix and match subrepos between master projects.

On the server I group things by branch. Making a new branch is effectively just duplicating the folder. I have the (multiple) master projects sitting beside the source repos. For example on the server the production branch folder might look like:

production
    myapp
    common
    common-www
    specific-mac
    specific-win
    myapp-mac-master
    myapp-win-master

The .hgsub for myapp-mac-master looks like

myapp = ../myapp
common = ../common
common-www = ../common-www
specific-mac = ../specific-mac

When I clone out production/myapp-mac-master I get on the local disk:

myapp-mac-master
    myapp
    common
    common-www
    specific-mac
0
Nick Pierpoint On

Another option I'm considering is to ignore the advice on thin-shell repositories and have the default URL for each dependent module referenced directly from the master project stable repository.

myapp ('stable' repository)

myapp (stable)
    contrib
        common (default)
        common-www (default)
        module x (default)
        module y (default)
        ...
    src
        myapp-specific source (stable version)

myapp ('default' repository)

myapp (default)
    contrib
        common (default)
        common-www (default)
        module x (default)
        module y (default)
        ...
    src
        myapp-specific source (default version)

So - these would be directly related repositories and we could push/pull between development and production.

There is obviously an issue in that the 'stable' application has subrepos pointing to the 'default' repositories. However, since the master repository doesn't automatically update subrepos to the latest version this could be handled manually. Following an update to the stable version of "common" the subrepo in would be updated manually to the correct revision.