Vaccaperna logo

 

Services
Articles
  About SCM
  Choosing an SCM Tool
  Defect Tracking Tools
  Perforce Resources
  Introduction to Perforce Branching
  Perforce Branching Case Study
  Release Branching Pattern
Testimonials
Contact us
Home > Articles > Release Branching Pattern

 

Branching - Maintaining Many Releases

 

by Robert Cowham, Perforce Consulting Partner

 


 

Introduction

 

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