<html>
<head>
<title>The Branching Papers -- Perforce FAQs</title>
<head>
<body bgcolor=#ffffff>
<font size=-2><b><a href="branching.html#br01">[INDEX]</a></b></font>
<p>
<b>
We have a product that will be
ported and released on HP and on Solaris. Should we branch
//depot/main into
//depot/variant-hp and
//depot/variant-sol?
And then should we branch off of those for each release?
That seems like a lot of branches to maintain.
</b>
<blockquote>
I suspect your platform-specific porting can be done in client workspaces
mapped to //depot/main. In this day and age, we expect source code to
be portable enough that a product can be built on any platform from the
same codeline. However, your actual situation may require a branch, so
read through the following scenarios and decide for yourself.
<p>
Let's say Ruth and Bob are working on fixing generic bugs, Harry is
working on HP, and Susan is working on Solaris. A summary of
their client specs might look like this:
<pre>
Client Root View
------ ---- ----
ruth-bugs /ruth_fs/bugfix //depot/main/... //ruth-bugs/...
bob-bugs /bobsdisk/work //depot/main/... //bob-bugs/....
harry-hp /hp1/harry //depot/main/... //harry-hp/...
susan-sol /work/solport //depot/main/... //susan-sol/...
</pre>
Each works in his/her own workspace. Before they check in changes
from their workspaces, they will have to make sure their changes do
not disrupt the build or cause regressions, because they're all
checking changes into the same codeline, //depot/main. However,
that should not be a problem for typical porting and bug fixing.
<p>
On the other hand, say Harry and Susan are both working on a complex
internationalization retrofit of a stable product. Their code
changes <i>are</i> likely to cause destabilization, <i>and</i> they need to
check in their untested changes so they can share them with each
other while they're implementing their retrofit. In this case you
would need a separate codeline. Everything would be branched from
the //depot/main codeline into //depot/i18n, for example, using
this branch spec:
<pre>
Branch: i18n-retro
View: //depot/main/... //depot/i18n/...
</pre>
and these commands:
<pre>
p4 integ -v -b i18n-retro
p4 submit
</pre>
(The -v flag causes p4 to do the branching on the server, without
involving the client workspace. Even though the //depot/i18n files still have
to be mapped in your client view, they aren't copied to your workspace
just to branch them in the depot.
This is <i>extremely</i> efficient -- try it!)
<p>
Once the codeline is branched, Harry and Susan would set up their
client views to work in the //depot/i18n codeline. Now you'd have
clients mapped to two codeline branches:
<pre>
Client Root View
------ ---- ----
ruth-bugs /ruth_fs/bugfix //depot/main/... //ruth-bugs/...
bob-bugs /bobsdisk/work //depot/main/... //bob-bugs/....
harry-i18n /local/i18n //depot/i18n/... //harry-i18n/...
susan-retro /work/retro //depot/i18n/... //susan-retro/...
</pre>
When Harry checks in a change, Susan can pull his change into her
workspace with <b>p4 sync</b>. However, when Ruth and Bob <b>sync</b>, their
workspaces are unaffected by Harry's I18N-specific changes.
<p>
As Ruth and Bob fix bugs, however, Harry and Susan are going to
need those fixes. So Harry, as the czar of the //depot/i18n codeline,
periodically pulls the //depot/main changes into //depot/i18n with:
<pre>
p4 integ -b i18n-retrofit
p4 resolve
p4 submit
</pre>
Anytime Harry does this, Susan can then update her I18N workspace with
the bug fixes using <b>p4 sync</b>.
<p>
Eventually Harry and Susan reach their goal of making the I18N
product work. Now their changes need to be integrated into
//depot/main. Ruth, as the czar of //depot/main, pulls changes
from //depot/i18n with:
<pre>
p4 integ -r -b i18n-retrofit
p4 resolve
[builds product & runs regression tests]
p4 submit
</pre>
So now, the new release is ready. Let's say Ruth is in charge of
the release. (It's good to have someone in charge.) Since development
is likely to be ongoing in //depot/main, Ruth is going to branch
//depot/main into //depot/r3. So here's what the branch spec looks
like:
<pre>
Branch: r3
View: //depot/main/... //depot/r3/...
</pre>
She creates another client for herself so she can have a //depot/r3
workspace:
<pre>
Client: ruthr3
Root: /ruth_fs/r3
View: //depot/r3/... //ruthr3/...
</pre>
She branches the //depot/main codeline into //depot/r3 with these commands:
<pre>
p4 integ -v -b r3
p4 submit
</pre>
Now you have three codelines:
<pre>
//depot/i18n +-------------
/
//depot/main -------+------+----------
\
//depot/r3 +----------
</pre>
Ruth and her staff build the Release 3 product from the //depot/r3
codeline on all platforms. They use dedicated release workspaces on
each platform, and set up client specs for each one. E.g.:
<pre>
Client Root View
------ ---- ----
rel3-bsd /nfs1/rel3/bsd //depot/r3/... //rel3-bsd/...
rel3-hp /nfs1/rel3/hp //depot/r3/... //rel3-hp/...
rel3-sol /nfs1/rel3/sol //depot/r3/... //rel3-sol/...
</pre>
Note that in this example all three of these workspaces are sitting
on the same filesystem, /nfs1. If your source code and build system
are set up in a way that allows you to build product for more than
one platform from the same source code directory tree, you could
even use a single workspace, e.g.,
<pre>
Client Root View
------ ---- ----
rel3 /nfs1/rel3 //depot/r3/... //rel3/...
</pre>
As long as the mount looks like "/nfs1" from every platform, you can
use the same client spec regardless of which platform you're on.
<p>
Now, what happens if a bug is found in the I18N retrofit? Let's say
Release 3 has been out the door for some time, everything hunky-dory,
but now there's this critical I18N bug that has to be fixed for
Release 3 customers.
<p>
With Inter-File Branching, you could fix the bug in any of the
three codelines, and integrate the fix from that codeline into the
other two. However, the <i>best</i> place to fix it is in //depot/r3.
Why?
<p>
<ul>
<p><li>
If you fix it in //depot/i18n, you have to integrate the fix from
there into //depot/main, and from there into //depot/r3. That's one
extra integrate-resolve step.
<p><li>
If you fix it in //depot/main, <i>and</i> there has been subsequent new
development there, you are applying the fix to code that has evolved
beyond Release 3. Perforce does facilitate integrating individual
deltas, but it's extra work for you during the 'resolve' process.
</ul>
<p>
So, Harry is going to fix the I18N bug, and he does it in a new client
workspace he sets up for //depot/r3. His client spec looks something
like:
<pre>
Client: harry-r3
Root: /local/r3
View: //depot/r3/... //harry-r3/...
</pre>
Harry uses these commands to handle the bug fix:
<pre>
setenv P4CLIENT harry-r3
p4 sync # Gets files into his new r3 workspace
...... # Does some debugging
p4 open foo.c bar.c # Makes problem files writeable
...... # Edits, rebuilds, & tests
p4 submit # Checks in bug fix to //depot/r3
</pre>
So now Ruth can rebuild the release after doing a <b>p4 sync</b> in her
//depot/r3 workspace.
<p>
She can also integrate all Release 3 bug fixes into the //depot/main with:
<pre>
setenv P4CLIENT ruth-bugs
p4 sync
p4 integ -r -b r3
p4 resolve
p4 submit
</pre>
If bug fixes are going into //depot/r3, and new development is going
into //depot/main, what is //depot/i18n good for? Nothing, now. Once
all changes have been integrated from //depot/i18n into //depot/main,
//depot/i18n can be retired.
<p>
Using a client spec that has a view of //depot/main, you can check to
see if there are any changes that still need integrating with:
<pre>
p4 integ -n -r -b i18n-retro
</pre>
And you can either leave the //depot/i18n files in place in the depot,
or you can tidy up by deleting the files and the branch spec:
<pre>
p4 delete //depot/i18n/...
p4 submit
p4 branch -d i18n-retro
</pre>
(You need to use a client spec that has a view of //depot/i18n to
delete the files.)
<p>
You won't save much space on the server by deleting the files
(because branched files are only virtual copies unless modified), but
by deleting them you are leaving an obvious signpost that they are
no longer needed.
<p>
If you've read this far, I congratulate you. I hope I've come within
at least shouting distance of the answer to your questions...
</blockquote>
<p>
<i>(January 1998)</i>
<p>
<font size=-2><b><a href="branching.html#br01">[INDEX]</a></b></font>
<hr>
<h6>This is file $Id: //guest/laura_wingerd/perforce/faq/br01.html#2 $ in the
<a href="http://public.perforce.com/public/index.html">
Perforce Public Depot</a></h6>
</body>
</html>