Issue #32 new

Multiple trunks in a single repo

John Peacock
created an issue

We have a codebase that is scheduled to undergo major refactoring, but we need to still have sustaining engineering (bugfix releases) and interim feature releases from the legacy code base. Since the refactored new code may or may not have any direct relation to the legacy code, even though it is ultimately derived from it, it makes no sense to have a single trunk. And in particular, the fact that releases are tagged off the trunk, not the develop branch, means that we are going to be including the wrong code if we we have interleved releases from each code base.

What I've come up with is this (after already initializing the repo for hgflow use):

hg up develop
hg branch legacy

<edit .hgflow and change "master = default" to "master = legacy" and "develop = develop" to "develop = develop-legacy">

hg ci -m 'Create legacy master branch'
hg branch develop-legacy
hg ci -m 'Create legacy develop branch'
hg up develop
hg merge legacy

<undo the changes to .hgflow but leave it marked as merged>

hg ci -m 'Null merge to preserve .hgflow later'
hg up default
hg merge develop
hg ci -m 'Null merge to preserve .hgflow later'

Now, I can switch between the two trunks using

hg up develop


hg up develop-legacy

And I can use any hg flow commands in each flow without doing anything special. Releases from develop-legacy ultimately get merged down to legacy and tags are created from there. Releases from develop ultimately get merged down to default and those tags are created from there. I can manually merge from legacy to develop after a legacy release to get the changes that are appropriate for the new codebase.


Comments (5)

  1. Yujie Wu repo owner

    The legacy branch feels quite like a branch in the <support> stream. A <support> branch is created from <master>, but normally it never merges into other branches. It just goes forward by itself until it's closed one day, but certainly you can create sub-branches from it if that's needed. Example:

    # Update the workspace dir to <master> trunk.
    hg flow master
    # Create a <support> branched: support/legacy.
    hg flow support start legacy
    # Add some commits.
    # Create a sub-branch if needed.
    hg flow support/legacy start fix_difficult_bug
    # The workspace dir is based on the tip of the
    # "support/legacy/fix_difficult_bug" branch
    # Add some commits.
    # Now finish the fix_difficult_bug branch, which will close
    # "support/legacy/fix_difficult_bug" and merge it to the "support/legacy" branch.
    hg flow support/legacy finish
    hg tag

    I think that is in essence the same as what you are trying to do with "multiple trunks". What do you think?

  2. Ralph Lange

    I think we have a similar need as John does, so let me take up this thread.

    We are actively developing multiple major versions of the codebase: The older version, which John called "legacy" (and we might call "stable"), and the main development version (we might call "next"). Both need a development trunk (with feature branches) and a release trunk (possibly with support branches for every release).

    Here's our usual workflow, mapped on hgflow:

    • For a new proposed feature it is decided if this should go into the stable or into the next release.
    • If targeted to stable: Development is done in a feature branch off development-stable, then released on release-stable. The feature branch is eventually merged into development-next.
    • If targeted to next: Development is done in a feature branch off development-next, and released on release-next.
    • Any released version (on both release-stable and release-next) might have a standard support branch for backported bugfixes.

    How would you handle this in hgflow? Keep it in two completely separate repositories? How would the (regular) merge of new features from stable into next work in that case?

  3. Yujie Wu repo owner

    In this situation, I would use a <develop> branch and call it "stable". The <develop> stream's trunk is used as what you called "next", but we don't need to rename it so. One can start <feature> or <release> branches from "stable" in the similar way to that for the <develop> trunk. Anything merged into "stable" will be automatically merged further into <develop> trunk by hgflow. For syntax and workflow details, see the corresponding section in the WIKI: Branches in develop stream.

    Let me know if this fits your problem and/or if you have any questions.

  4. Ralph Lange

    Thanks for your quick reply!

    I can see your idea working for development. Merging a closing "stable" feature branch into "next" (<develop> trunk) will always be immediate, correct? That's probably fine, but one will have to consider that the merge into "next" cannot be deferred and might create conflicts, which will have to be resolved before continuing on "next" development.

    What about <master> sub-branches, though?

    Putting out a new "stable" release, i.e. closing a "stable" <release> branch will merge into "stable" <develop> and "next" <develop> (=trunk), both of which are fine. But then it will merge into <master> trunk, which is wrong, because that is where "next" gets released - "stable" would have to have its own <master> branch. Is there a way to have the "stable" <release> branches be merged into a "stable" <master> branch instead of the <master> trunk?

    If not: What would renaming the master and develop branches in .flow (while keeping the prefix definitions) do? Would that allow me to have multiple independent sets of <develop> and <master> trunks?

    Again, thanks a lot for your help. I would really like to use hgflow, but I have to prove my use cases before I can convince my collaborators....

  5. Yujie Wu repo owner

    Just some discussion:

    Per my now understanding, your desired workflow requests independent <master>, <develop>, <release>, and <feature> streams for "stable and for "next"; separate repositories fits into this request more naturally. But this means whenever in the future a version is becoming "stable", user would have to create a new repository for this version, which sounds very awkward to me.

    With a single repo, I think you can use the <support> stream. The workflow is similar what I said above to John.

    # Update the workspace dir to <master> trunk.
    hg flow master
    # Create a <support> branch: support/stable.
    hg flow support start stable
    # Create a feature from stable.
    hg flow support/stable start stable_feature1
    # Finish the feature.
    hg flow support/stable finish
    # Once all new features are tested and ready for release, tag the snapshot in the stable branch.
    hg tag stable_rel_2013
    # Continue the stable line of development.
    hg flow support/stable start stable_feature_for_2014
    hg flow support/stable finish
    hg tag stable_rel_2014
    # If a feature needs to be backported to <develop> trunk, user can `promote` the feature branch into there.
    # Say user wants to merge the implementation as completed in the branch: support/stable/stable_feature_for_2014 into <develop> trunk, the user can do the following:
    hg flow support/stable stable_feature_for_2014
    hg flow support/stable promote develop

    This model assumes all releases along the "stable" line is sequential, which means user won't start developing for the 2014 release until the current 2013 release is done and so a <release> stage can be skipped.

    As for multiple <develop> and <master> trunks, I don't think it's possible unless you make the command line syntax more complicated. This is because when you finish a <feature> or <release> branch you would have to specify which trunk you want to merge to.

  6. Log in to comment