@need 3200

@node Development Branches -- The star-merge Style of Cooperation
@chapter Development Branches -- The star-merge Style of Cooperation

In earlier chapters, we developed an extended example out of the
@code{hello-world} project.


Alice and Bob, the primary programmers on the project, started one
archive and created some revisions there.


Candice, a user of the project, created her own archive, started a
branch of the @code{hello-world} project, and began maintaining her own
local modifications.


In this chapter, we'll begin to consider a situation that is more
typical of free software projects in the real world.   Here, we'll
consider Alice and Bob to be the maintainers of a public project, and
Candice as a major remote contributor to the project.  We'll identify
the new revision control needs that arise from that arrangement, and
look at some @code{arch} commands that help to satisfy those needs.

@need 3200

@section Promoting an Elementary Branch to a Development Branch

So far, if you've been following the examples, Candice has an
elementary branch.  She made a branch from the mainline, made some
local changes, and has kept her branch up-to-date with Alice and Bob's
mainline.


We're supposing, at this point, that Alice and Bob want to merge
Candice's changes into the mainline.


Well, that merging work has already been done.  Candice's latest
revision is exactly the tree that Alice and Bob want.   They can 
incorporate that merge into their mainline very simply, by committing
Candice's latest revision to their own mainline:

@example
@group

@end group
@group
        % larch get -A lord@@emf.net--2003-candice \
                    hello-world--candice--0.1 \
                    hw-C
        [...]
@end group
@group


@end group
@group
        % cd hw-C
@end group
@group

@end group
@group
        % larch set-tree-version -A lord@@emf.net--2003-example \
                    hello-world--mainline--0.1
@end group
@group

@end group
@group
        % larch make-log
        ++log.hello-world--mainline--0.1--lord@@emf.net--2003-example
@end group
@group

@end group
@group
        [... edit log file (consider `larch log-for-merge') ... ]
@end group
@group

@end group
@group
        % cat ++log.hello-world--mainline--0.1--lord@@emf.net--2003-example
        Summary: merge from Candice's Branch
        Keywords: 
@end group
@group

@end group
@group
        Patches applied:
@end group
@group

@end group
@group
          * lord@@emf.net--2003-candice/hello-world--candice--0.1--patch-2
             merge from mainline sources
@end group
@group

@end group
@group
          * lord@@emf.net--2003-candice/hello-world--candice--0.1--patch-1
             Punctuated the output correctly
@end group
@group

@end group
@group
          * lord@@emf.net--2003-candice/hello-world--candice--0.1--base-0
             tag of 
              lord@@emf.net--2003-example/hello-world--mainline--0.1--patch-1
@end group
@group

@end group
@group
        % larch commit
        [....]
@end group
@group

@end group
@end example

@strong{Read Carefully Note:}  Note carefully the @geindex trick
@dfn{trick} we just used.
Candice's latest revision was exactly what Alice and Bob wanted --
they combined @code{get} with @code{set-tree-version} to turn Candice's tree
into one they could easily commit to their own mainline.




@need 3200

@section Simple Development Branches

Let's consider what happens as development proceeds on both branches.
For this purpose, we'll introduce something new: a way of diagraming
branches and the merges between them.


After the examples so far, we have this situation:

@example
@group

@end group
@group
      mainline-0.1                    candice-0.1
      ------------                    -----------
        base-0             -----------> base-0 (a tag)
        patch-1  ---------'             patch-1
        patch-2             ----------> patch-2
        patch-3  ----------'  --------'
        patch-4  <-----------'
@end group
@group

@end group
@end example

@noindent
which tells us that the @code{candice} branch is a tag 
of @code{patch-1} from the mainline;  that at @code{patch-2} of the @code{candice}
branch, there was a merge of everything up to @code{patch-3} of the
@code{mainline}; and finally that @code{patch-4} of the mainline merges
in everything up to @code{patch-2} from the @code{candice} branch.


Whenever we have a such a diagram in which none of the merge lines
cross, that is a @geindex simple development branch
@dfn{simple development branch}.


The significance of a simple development branch is that it's a model
for how two development efforts can work asynchronously on one
project.  Within each effort -- on each branch -- programmer's use the
"update/commit" style of cooperation (see @ref{The update/commit Style of Cooperation}).   However, changes on one branch have no
effect on the other until the two branches are merged.




@need 3200

@section Introducing The Development Branch Merging Problem

Let's suppose that more work happens on both the @code{mainline} and
@code{candice} branches, leaving us with:

@example
@group

@end group
@group
      mainline-0.1                    candice-0.1
      ------------                    -----------
        base-0             -----------> base-0 (a tag)
        patch-1  ---------'             patch-1
        patch-2             ----------> patch-2
        patch-3  ----------'  --------' patch-3
        patch-4  <-----------'          patch-4
        patch-5
        patch-6
@end group
@group


@end group
@group
        % larch revisions --summary -A lord@@emf.net--2003-candice \
                          hello-world--candice--0.1
        base-0
            tag of 
            lord@@emf.net--2003-example/hello-world--mainline--0.1--patch-1
@end group
@group
        patch-1
            Punctuated the output correctly
        patch-2
@end group
@group
            merge from mainline sources
        patch-3
            added a period to output string
        patch-4
            capitalized the output string
@end group
@group



@end group
@group
        % larch revisions --summary -A lord@@emf.net--2003-example \
                          hello-world--mainline--0.1
        base-0
            initial import
        patch-1
@end group
@group
            Fix bugs in the "hello world" string
        patch-2
            commented return from main
        patch-3
            added copywrong statements
@end group
@group
        patch-4
@end group
@group
            merge from Candice's Branch
        patch-5
            fixed the copyrwrong for hw.c
        patch-6
            fixed the copyrwrong for main.c
@end group
@group




@end group
@end example

Let's consider a scenario in which our goal is to merge the new work
on the @code{mainline} branch into the @code{candice} branch.  In other words,
we want to wind up with:

@example
@group

@end group
@group
      mainline-0.1                    candice-0.1
      ------------                    -----------
        base-0             -----------> base-0 (a tag)
        patch-1  ---------'             patch-1
        patch-2             ----------> patch-2
        patch-3  ----------'  --------' patch-3
        patch-4  <-----------'          patch-4
        patch-5               --------> patch-5
        patch-6  ------------'
@end group
@group

@end group
@end example

How can we perform that merge?  Let's start with the latest pre-merge
candice revision (@code{patch-4}):

@example
@group

@end group
@group
        % larch get -A lord@@emf.net--2003-candice \
                       hello-world--candice--0.1--patch-4 \
                       hw-C-4
        [....]
@end group
@group

@end group
@group
        % cd hw-C-4
@end group
@group

@end group
@end example

Here are two techniques that don't work:

@need 3200

@subsection replay Does Not Solve the Development Branch Merge Problem

@code{replay} will try to apply all "missing" changes from the @code{mainline}
into the @code{candice} tree.   The list of changeset it will apply is
given by:

@example
@group

@end group
@group
        % larch whats-missing --summary \
                              -A lord@@emf.net--2003-example \
                              hello-world--mainline--0.1
        patch-4
            merge from Candice's Branch
        patch-5
            fixed the copyrwrong for hw.c
        patch-6
            fixed the copyrwrong for main.c
@end group
@group

@end group
@end example

Problematic in that list is @code{patch-4}.   It's a merge that includes
all of the changes from the @code{candice} branch up to it's @code{patch-2}
level.   Yet those changes are already present in the @code{patch-4}
revision of the @code{candice} branch -- so @code{replay} will be applying them
redundantly (cause patch conflicts).


@strong{Advanced User Note:}  The @code{replay} command has options that would
allows us to skip the @code{patch-4} revision from the mainline.   That
sort of@emph{ solves the problem, but it has some drawbacks.  First, it
means that `patch-4' will continue to appear in the `whats-missing'
output of the `candice' branch.   Second, there is nothing that
guarantees us that the `patch-4' changeset contains }only* merges from
the @code{candice} branch.   If Alice and Bob made other changes in
@code{patch-4}, and we skip that changeset, those other changes will be
lost.




@need 3200

@subsection update Does Not Solve the Development Branch Merge Problem

Suppose we try to @code{update} from the @code{mainline} branch.  Recall that
@code{update} will compute a changeset from the youngest @code{mainline}
ancestor of the project tree to the tree itself, then apply that
changeset to the latest @code{mainline} revision.


We have a notation for this.  A changeset from @code{X} to @code{Y} is written:

@example
@group
        delta(X, Y)
@end group
@group
@end group
@end example

In this case, @code{update} will start by computing a changeset from the
@code{mainline} @code{patch-3} revision to our project tree:

@example
@group
        delta(mainline--0.1--patch-3, hw-C-4) 
@end group
@group
@end group
@end example

The tree that results for applying a changeset from @code{X} to @code{Y} to a
tree @code{Z} is written:

@example
@group
        delta(X, Y) [ Z ]
@end group
@group
@end group
@end example

In other words, the result of @code{update} in our example can be described
as:

@example
@group
        delta(mainline--0.1--patch-3, hw-C-4) [mainline--0.1--patch-6]
@end group
@group
@end group
@end example

Here's the problem, though.   The @code{patch-3} revision of @code{mainline} was
not previously merged with the @code{candice} branch.   Thus, the changeset

@example
@group
        delta(mainline--0.1--patch-3, hw-C-4)
@end group
@group
@end group
@end example

@noindent
will include, among other changes, the changes from @code{patch-1} and
@code{patch-2} of the candice branch.


Unfortunately, the tree we'll be applying that changeset to,
@code{mainline--0.1--patch-6}, has already been merged with
@code{base-0...patch-2} of the @code{candice} branch.


As with @code{replay}, @code{update} will cause merge conflicts by making
redundant changes.







@need 3200

@section Solving One Instance of the Development Branch Merging Problem

Using just our @code{delta} notation, let's look at solving this merge
problem cleanly.


One possibility is that we want to give highest priority to the
@code{mainline} branch, merging in changes from @code{candice} and then lowest
priority to merging in any local changes that are only in the project
tree.  A solution that accomplishes that cleanly, without spurious 
conflicts from redundant changes is:

@example
@group

@end group
@group
   tmp = delta(X, Y)[Z]
     where X = lord@@emf.net--2003-candice/hello-world--candice--0.1--base-0
           Y = lord@@emf.net--2003-candice/hello-world--candice--0.1--patch-2
           Z = lord@@emf.net--2003-example/hello-world--mainline--0.1--patch-4
@end group
@group
   

@end group
@group
   answer = delta(L,M)[tmp]
@end group
@group

@end group
@group
     where L = lord@@emf.net--2003-example/hello-world--mainline--0.1--patch-4
           M = /usr/lord/examples/wd/hw-AnB
@end group
@group

@end group
@end example

@strong{Usage Note:} The concept of "priority" in merging has to do with
how (non-spurious) conflicts are handled.  By giving higher priority
to the @code{mainline}, we ensure that conflicting changes from the other
two trees involved will be the ones that appear in @code{.rej} files.  That
can be important if, for example, we want to minimize changes made
relative to the @code{mainline} as conflicts are resolved.  (See
@ref{Inexact Patching -- How Conflicts are Handled}.)


A similar looking but different solution arises if we want to give
higher priority to the @code{candice} branch than the @code{mainline}:

@example
@group


@end group
@group
   tmp = delta(X, Y)[Z]
     where X = lord@@emf.net--2003-candice/hello-world--candice--0.1--patch-2
           Y = lord@@emf.net--2003-example/hello-world--mainline--0.1--patch-6
           Z = lord@@emf.net--2003-candice/hello-world--candice--0.1--patch-4
@end group
@group
   

@end group
@group
   answer = delta(L,M)[tmp]
@end group
@group

@end group
@group
     where L = lord@@emf.net--2003-candice/hello-world--candice--0.1--patch-4
           M = /usr/lord/examples/wd/hw-C-4
@end group
@group


@end group
@end example

We could, in fact, implement those solutions in "brute force" way:
studying the merge histories of the two branches, coming up with those
solutions, checking out the necessary trees, using @code{mkpatch} to
compute changesets, and @code{dopatch} to apply them.   As we'll soon see,
however, @code{arch} has built-in support for this kind of merge.




@need 3200

@section star-merge -- Solving the Development Branch Merging Problem in General

It's a bit beyond the scope of this tutorial to explain the complete
solution to the development branch merging problem in general.  The
two solutions shown above illustrate two cases, but slightly different
solutions are sometimes necessary.


What you should know is that when you have simple development
branches (see @strong{Simple Development Branches} in @ref{Development Branches -- The star-merge Style of Cooperation}), the command
@code{star-merge} knows how to merge between them without causing spurious
merge conflicts.


@code{star-merge} (with the @code{--in-place} option, as illustrated here)
expects three arguments: two @code{arch} versions and a project tree (whose
name should start with @code{./}).   The order of these arguments
determines the precedence of changes from each source.


For example, our two solutions from the previous section can be
achieved with:

@example
@group

@end group
@group
        # giving the mainline branch precedence over the candice
        # branch:
        # 
@end group
@group

@end group
@group
        % larch star-merge --in-place \
                  lord@@emf.net--2003-example/hello-world--mainline--0.1 \
                  lord@@emf.net--2003-candice/hello-world--candice--0.1 \
                  ./hw-C-4
@end group
@group


@end group
@group
        # giving the candice branch precedence over the mainline
        # branch:
        # 
@end group
@group

@end group
@group
        % larch star-merge --in-place \
                  lord@@emf.net--2003-candice/hello-world--candice--0.1 \
                  lord@@emf.net--2003-example/hello-world--mainline--0.1 \
                  ./hw-C-4
@end group
@group



@end group
@end example

@strong{Usage Note:}  Notice that the merge solutions we found earlier both 
involved the applications of two changesets.  In general, it's
possible that either or both of those can result in patch conflicts.
If conflicts occur after the first merge, @code{star-merge} stops and gives
you a chance to resolve the conflicts.   The @code{--finish} option to
@code{star-merge} can then be used to apply the second changeset (see
@code{larch star-merge --help}).


@strong{Usage Notes:} Recall that before we used @code{star-merge}, we did the
first merge back from @code{candice} to @code{mainline} using a
@code{get/set-tree-version/commit} trick (see @strong{Promoting an Elementary Branch to a Development Branch} in @ref{Development Branches -- The star-merge Style of Cooperation}).  In general, the first merge from an
elementary branch back to its parent branch should always be done in
that way.  (Users sometimes request that @code{star-merge} should have that
trick "built in" to its operation.  Perhaps some day it will.)







