|
Branching - Maintaining Many Releases
by Robert Cowham, Perforce Consulting Partner
 
This article shows a fairly common requirement which is how to maintain
multiple releases in Perforce.
There is an
introductory branching article which you should read first which gives an overview of the
integrate command.
Please note you can do this using the Perforce command line or either GUI
(P4Win and P4V).
Note that the principles are the same, but that the new release of Perforce
(2004.2) has better common ancestor detection which makes the process rather
easier. Examples are shown for a server version 2003.2 and 2004.2.
Introduction
It is very standard branching practice to make changes on the mainline and
then branch to release lines for maintenance. You then make changes on the
release line for bug fixes and typically propagate all the changes back to the
mainline.
The problem comes when you are maintaining multiple releases.

In the example above, we started maintaining rel1 and made several
changes (36, 38 and 39) to fix various bugs. We propagated these back to the
mainline (as change 44) and as a result all those bugs are fixed in rel2 because it was
branched from the mainline after that point.
The problem is what do we do when we have a bug fix (51 above), which
needs to be made to both rel1 and rel2 and the mainline? One option is to fix it
in rel1 and propagate to main, and then selectively integrate it to rel2. The
selective bit is important since there are likely to be other changes to the
mainline which we don't want in rel2 (or indeed we would have made them there!).
Selective integrations, while possible, causes problems.
So, an easier solution might be as shown above. We propagate 51 to
rel2 and then down to the mainline. This works fine (note that if we
subsequently have rel3 also out and are still supporting rel1 then more
propagation is required - definitely a business case for refusing to support too
many releases - but that's another story).
Details with 2003.2 Server
We can demonstrate the problem with a single file.
C:\bruno_ws>p4 info
User name: bruno
Client name: bruno_ws
Server date: 2004/10/05 14:54:53 +0100 GMT Daylight Time
Server version: P4D/NTX86/2003.2/59362 (2004/05/12)
C:\bruno_ws>p4 filelog main\jam\Build.com
//depot/main/jam/Build.com
... #7 change 620 edit on 2001/11/12 by seiwald@spice (text) 'Mucho jam reorgani
zation in ant'
... #6 change 410 edit on 2000/12/21 by seiwald@boomer (text) 'Changes from syba
se. '
... #5 change 139 edit on 1999/05/02 by seiwald@spice (text) 'VMS DECC changes.
'
... #4 change 109 edit on 1999/02/28 by seiwald@spice (text) 'No !. '
... #3 change 81 edit on 1999/02/08 by seiwald@spice (text) 'VMS help. '
... #2 change 36 edit on 1999/01/11 by seiwald@spice (text) 'VMS ready. '
... #1 change 1 add on 1998/09/23 by seiwald@spice (text) 'Initial revision '
So let's branch r1.0 from an earlier version of the file - in this case #5, edit
the file and submit the change.
C:\bruno_ws>p4 integ //depot/main/jam/build.com#5 //depot/r1.0/jam/build.com
//depot/r1.0/jam/build.com#1 - branch/sync from //depot/main/jam/Build.com#1,#5
C:\bruno_ws>p4 submit
Change 712 created with 1 open file(s).
Submitting change 712.
Locking 1 files ...
branch //depot/r1.0/jam/build.com#1
Change 712 submitted.
C:\bruno_ws>p4 edit //depot/r1.0/jam/build.com
//depot/r1.0/jam/build.com#1 - opened for edit
C:\bruno_ws>p4 edit //depot/r1.0/jam/build.com
C:\bruno_ws>notepad r1.0\jam\build.com
The actual change we made was a very simple edit.
C:\bruno_ws>p4 diff
==== //depot/r1.0/jam/build.com#1 - c:\bruno_ws\r1.0\jam\build.com ====
0a1
> r1.0 change
C:\bruno_ws>p4 submit
Change 713 created with 1 open file(s).
Submitting change 713.
Locking 1 files ...
edit //depot/r1.0/jam/build.com#2
Change 713 submitted.
So now we propagate the change back to the mainline - in this instance an
automatic merge does what we want.
C:\bruno_ws>p4 integ //depot/r1.0/jam/build.com //depot/main/jam/build.com
//depot/main/jam/Build.com#7 - integrate from //depot/r1.0/jam/build.com#2
C:\bruno_ws>p4 resolve -am
c:\bruno_ws\main\jam\build.com - merging //depot/r1.0/jam/build.com#2
Diff chunks: 3 yours + 1 theirs + 0 both + 0 conflicting
//bruno_ws/main/jam/build.com - merge from //depot/r1.0/jam/build.com
C:\bruno_ws>p4 diff
==== //depot/main/jam/Build.com#7 - c:\bruno_ws\main\jam\build.com ====
0a1
> r1.0 change
C:\bruno_ws>p4 submit
Change 714 created with 1 open file(s).
Submitting change 714.
Locking 1 files ...
integrate //depot/main/jam/Build.com#8
Change 714 submitted.
We now create the r2.0 codeline.
C:\bruno_ws>p4 integ //depot/main/jam/build.com //depot/r2.0/jam/build.com
//depot/r2.0/jam/build.com#1 - branch/sync from //depot/main/jam/Build.com#1,#8
C:\bruno_ws>p4 submit
Change 715 created with 1 open file(s).
Submitting change 715.
Locking 1 files ...
branch //depot/r2.0/jam/build.com#1
Change 715 submitted.
So let's make another change in the r1.0 codeline.
C:\bruno_ws>p4 edit //depot/r1.0/jam/build.com
//depot/r1.0/jam/build.com#2 - opened for edit
C:\bruno_ws>notepad r1.0\jam\build.com
C:\bruno_ws>p4 diff
==== //depot/r1.0/jam/build.com#2 - c:\bruno_ws\r1.0\jam\build.com ====
1a2
> r1.0 second change
C:\bruno_ws>p4 submit
Change 716 created with 1 open file(s).
Submitting change 716.
Locking 1 files ...
edit //depot/r1.0/jam/build.com#3
Change 716 submitted.
However, this change can't just be propagated between r1.0 and r2.0:
C:\bruno_ws>p4 integ //depot/r1.0/jam/build.com //depot/r2.0/jam/build.com
//depot/r2.0/jam/build.com - can't integrate from //depot/r1.0/jam/build.com#1,#
3 without -i flag
So we have to do a baseless integrate (the "-i" flag). We will do
this, but first find out the changelist to set up as the base of our merge.
Let's find the last change in r1.0 which is also included in r2.0.
C:\bruno_ws>p4 changes -i -m 5 //depot/r1.0/jam/...
Change 716 on 2004/10/05 by bruno@bruno_ws 'asdfasdf asd '
Change 713 on 2004/10/05 by bruno@bruno_ws 'r1.0 change 1 '
Change 712 on 2004/10/05 by bruno@bruno_ws 'r1.0 branch '
Change 139 on 1999/05/02 by seiwald@spice 'VMS DECC changes. '
Change 109 on 1999/02/28 by seiwald@spice 'No !. '
C:\bruno_ws>p4 changes -i -m 5 //depot/r2.0/jam/...
Change 715 on 2004/10/05 by bruno@bruno_ws 'create 2.0 branch '
Change 714 on 2004/10/05 by bruno@bruno_ws 'Merged into main '
Change 713 on 2004/10/05 by bruno@bruno_ws 'r1.0 change 1 '
Change 620 on 2001/11/12 by seiwald@spice 'Mucho jam reorganization in ant'
Change 410 on 2000/12/21 by seiwald@boomer 'Changes from sybase. '
So we have @713 as the latest one, and we can propagate all changes up to and
including that change into r2.0 using the -i flag, "resolve -ay" to
discard the changes, which keeps the rel2.0 files unchanged.
C:\bruno_ws>p4 integ -i //depot/r1.0/jam/build.com@713 //depot/r2.0/jam/build.c
om
//depot/r2.0/jam/build.com#1 - integrate from //depot/r1.0/jam/build.com#1,#2
C:\bruno_ws>p4 resolve -ay
c:\bruno_ws\r2.0\jam\build.com - vs //depot/r1.0/jam/build.com#1,#2
//bruno_ws/r2.0/jam/build.com - ignored //depot/r1.0/jam/build.com
C:\bruno_ws>p4 submit
Change 717 created with 1 open file(s).
Submitting change 717.
Locking 1 files ...
integrate //depot/r2.0/jam/build.com#2
Change 717 submitted.
Having done all that, we can now propagate directly between r1.0 and r2.0
without needing the -i flag and the changes will be propagated easily.
C:\bruno_ws>p4 integ //depot/r1.0/jam/build.com //depot/r2.0/jam/build.com
//depot/r2.0/jam/build.com#2 - integrate from //depot/r1.0/jam/build.com#3
C:\bruno_ws>p4 resolve -am
c:\bruno_ws\r2.0\jam\build.com - merging //depot/r1.0/jam/build.com#3
Diff chunks: 3 yours + 1 theirs + 0 both + 0 conflicting
//bruno_ws/r2.0/jam/build.com - merge from //depot/r1.0/jam/build.com
C:\bruno_ws>p4 diff
==== //depot/r2.0/jam/build.com#2 - c:\bruno_ws\r2.0\jam\build.com ====
1a2
> r1.0 second change
C:\bruno_ws>p4 submit
Change 718 created with 1 open file(s).
Submitting change 718.
Locking 1 files ...
integrate //depot/r2.0/jam/build.com#3
Change 718 submitted.
C:\bruno_ws>p4 integ //depot/r2.0/jam/build.com //depot/main/jam/build.com
//depot/main/jam/Build.com#8 - integrate from //depot/r2.0/jam/build.com#2,#3
C:\bruno_ws>p4 resolve -am
c:\bruno_ws\main\jam\build.com - merging //depot/r2.0/jam/build.com#2,#3
Diff chunks: 0 yours + 1 theirs + 0 both + 0 conflicting
//bruno_ws/main/jam/build.com - copy from //depot/r2.0/jam/build.com
C:\bruno_ws>p4 diff
==== //depot/main/jam/Build.com#8 - c:\bruno_ws\main\jam\build.com ====
1a2
> r1.0 second change
C:\bruno_ws>p4 submit
Change 719 created with 1 open file(s).
Submitting change 719.
Locking 1 files ...
integrate //depot/main/jam/Build.com#9
Change 719 submitted.
The Result
Thus we see that to get the right result with a pre-2004.2 server requires a
little work to create a direct branching relationship between r1.0 and r2.0 with
the -i flag before we can propagate any changes. Steps to create that
relationship are:
- find latest change in r1.0 that is also in r2.0
- integrate with -i from
- resolve -ay to discard changes
- submit
This only needs to be done once, but is a somewhat tricky step.
The new feature in Perforce 2004.2 will automatically do the above for us and
such integrations are quite a bit easier as a result.
In a related issued, 2004.2 handles renames nicely if we don't want to
propagate the renames but do want changes to be propagated - the subject of
another article!
Resources
Please send feedback and comments on this page to
Back to the top
Contact us
© Vaccaperna Systems Ltd
|