Perforce 2003.2 User's Guide
<< Previous Chapter
Labels
Table of Contents
Index
Perforce on the Web
Next Chapter >>
Job Tracking

Chapter 9
Branching

Perforce's Inter-File BranchingTM mechanism allows any set of files to be copied within the depot, and allows changes made to one set of files to be copied, or integrated, into another. By default, the new file set (or codeline) evolves separately from the original files, but changes in either codeline can be propagated to the other with the p4 integrate command.

What is Branching?

Branching is a method of keeping two or more sets of similar (but not identical) files synchronized. Most software configuration management systems have some form of branching; we believe that Perforce's mechanism is unique because it mimics the style in which users create their own file copies when no branching mechanism is available.

Suppose for a moment that you're writing a program and are not using an SCM system. You're ready to release your program: what would you do with your code? Chances are that you'd copy all your files to a new location. One of your file sets would become your release codeline, and bug fixes to the release would be made to that file set; your other files would be your development file set, and new functionality to the code would be added to these files.

What would you do when you find a bug that's shared by both file sets? You'd fix it in one file set, and then copy the edits that you made into the other file set.

The only difference between this homegrown method of branching and Perforce's branching methodology is that Perforce manages the file copying and edit propagation for you. In Perforce's terminology, copying the files is called making a branch. Each file set is known as a codeline, and copying an edit from one file set to the other is called integration. The entire process is called branching.

When to Create a Branch

Create a branch when two sets of code files have different rules governing when code can be submitted, or whenever a set of code files needs to evolve along different paths. For example:

They would branch the release codeline from the development codeline. When the development codeline is ready, it is integrated into the release codeline. Afterwards, patches and bug fixes are made in the release code, and at some point in the future, integrated back into the development code.

The developers create a branch from the existing UNIX code, and now have two copies of the same code. These two codelines can then evolve separately. If bugs are found in either codeline, bug fixes can be propagated from one codeline to the other with the Perforce p4 integrate command.

One basic strategy is to develop code in //depot/main/ and create branches for releases (for example, //depot/rel1.1/). Make bug fixes that affect both codelines in //depot/main/ and integrate them into the release codelines. Make release-specific bug fixes in the release branch and, if required, integrate them back into the //depot/main/ codeline.

Perforce's Branching Mechanisms: Introduction

Perforce provides two mechanisms for branching. One method requires no special setup, but requires the user to manually track the mappings between the two sets of files. The second method remembers the mappings between the two file sets, but requires some additional work to set up.

In the first method, the user specifies both the files that changes are being copied from and the files that the changes are being copied into. The command looks like this:

In the second method, Perforce stores a mapping that describes which set of files get branched to other files, and this mapping, or branch specification, is given a name. The command the user runs to copy changes from one set of files to the other looks like this:

These methods are described in the following two sections.

Branching and Merging, Method 1:
Branching with File Specifications

Use p4 integrate fromfiles tofiles to propagate changes from one set of files (the source files) to another set of files (the target files). The target files need to be contained within the current client workspace view. The source files do not need to be, so long as the source files are specified in depot syntax. If the target files do not yet exist, the entire contents of the source files are copied to the target files. If the target files have already been created, changes can be propagated from one set of files to the other with p4 resolve. In both cases, p4 submit must be used to store the new file changes in the depot. Examples and further details are provided below.

Creating branched files

To create a copy of a file that will be tracked for branching, use the following procedure:

  1. Determine where you want the copied (or branched) file(s) to reside within the depot and within the client workspace. Add the corresponding mapping specification to your client view.

  2. Run p4 integrate fromfiles tofiles. The source files are copied from the server to target files in the client workspace.

  3. Run p4 submit. The new files are created within the depot, and are now available for general use.

Why not just copy the files?

Although it is possible to accomplish everything that has been done thus far by copying the files within the client workspace and using p4 add to add the files to the depot, when you use p4 integrate, Perforce is able to track the connections between related files in an integration record, allowing easy propagation of changes between one set of files and another.

Branching not only enables you to more easily track changes, it creates less overhead on the server. When you copy files with p4 add, you create two copies of the same file on the server. When you use branching, Perforce performs a "lazy copy" of the file, so that the depot holds only one copy of the original file and a record that a branch was created.

Propagating changes between branched files

After a file has been branched from another with p4 integrate, Perforce can track changes that have been made in either set of files and merge them using p4 resolve into the corresponding branch files. (You'll find a general discussion of the resolve process in Chapter 5, Perforce Basics: Resolving File Conflicts. File resolution with branching is discussed in "How Integrate Works" on page 108).

The procedure is as follows:

  1. Run p4 integrate fromfiles tofiles to tell Perforce that changes in the source files need to be propagated to the target files.

  2. Use p4 resolve to copy changes from the source files to the target files. The changes are made to the target files in the client workspace.

  3. Run p4 submit to store the changed target files in the depot.

There is one fundamental difference between resolving conflicts in two revisions of the same file, and resolving conflicts between the same file in two different codelines. The difference is that Perforce will detect conflicts between two revisions of the same file and then schedule a resolve, but there are always differences between two versions of the same file in two different codelines, and these differences usually don't need to be resolved manually. (In these cases, a p4 resolve -as or p4 resolve -am to accept the Perforce-recommended revision is usually sufficient. See "Using Flags with Resolve to Automatically Accept Particular Revisions" on page 71 for details.)

In their day-to-day use, there is no difference between branched files and non-branched files. The standard Perforce commands like sync, edit, delete, submit, and so on. are used with all files, and evolution of both codelines proceeds separately. When changes to one codeline need to be propagated to another, you must tell Perforce to do this with p4 integrate, but if the codelines evolve separately, and changes never need to be propagated, you'll never need to integrate or resolve the files in the two codelines.

Propagating changes from branched files to the original files

A change can be propagated in the reverse direction, from branched files to the original files, by supplying the branched files as the source files, and the original files as the target files.

Branching and Merging, Method 2:
Branching with Branch Specifications

To map a set of source files to target files, you can create a branch specification and use it as an argument to p4 integrate. To create and use a branch specification, do the following:

  1. Use p4 branch branchname to create a view that indicates which target files map to which source files.

  2. Make sure that the new files and directories are included in the p4 client view of the client workspace that will hold the new files.

  3. Use p4 integrate -b branchname to create the new files.

  4. To propagate changes from source files to target files, use p4 integrate -b branchname [tofiles]. Perforce uses the branch specification to determine which files the merged changes come from

  5. Use p4 submit to submit the changes to the target files to the depot.

The following example demonstrates the same branching that was performed in the example above, this time using a branch specification.

Once the branch has been created and the files have been copied into the branched codeline, changes can be propagated from the source files to the target files with p4 integrate -b branchname.

Branch Specification Usage Notes

Integration Usage Notes

If you omit the tofiles argument, all the files in the branch are affected.

If the target file doesn't exist, the source file is copied to target, target is opened for branch, and Perforce begins tracking the integration history between the two files. The next integration of the two files will treat this revision of source as base.

If the target file exists, and was originally branched from the source file with p4 integrate, then a three-way merge is scheduled between target and source. The base revision is the previously integrated revision of source.

If the target file exists, but was not branched from the source, then these two file revisions did not begin their lives at a common, older file revision, so there can be no base file, and p4 integrate rejects the integration. This is referred to as a baseless merge. To force the integration, use the -i flag; p4 integrate will use the first revision of source as base. (Actually, p4 integrate uses the most recent revision of source that was added to the depot as base. Since most files are only opened for add once, this will almost always be the first revision of source.)

Note

In previous versions of Perforce (99.1 and earlier), integration of a target that was not originally branched from the source would schedule a two-way merge, in which the only resolve choices were accept yours and accept theirs. As of Perforce 99.2, it is no longer possible to perform a two-way merge of a text file (even when possible, it was never desirable).

Deleting Branches

To delete a branch, use

Deleting a branch deletes only the branch specification, making the branch specification inaccessible from any subsequent p4 integrate commands. The files themselves can still be integrated with p4 integrate fromfiles tofiles, and the branch specification can always be redefined. If the files in the branched codeline are to be removed, they must be deleted with p4 delete.

Advanced Integration Functions

Perforce's branching mechanism also allows integration of specific file revisions, the re-integration and re-resolving of already integrated code, and merging of two files that were previously not related.

Integrating specific file revisions

By default, the integrate command integrates into the target all the revisions of the source since the last source revision that integrate was performed on. A revision range can be specified when integrating; this prevents unwanted revisions from having to be manually deleted from the merge while editing. In this case, the revision used as base is the first revision below the specified revision range.

The argument to p4 integrate is the target, the file revision specifier is applied to the source.

Re-integrating and re-resolving files

After a revision of a source file has been integrated into a target, that revision is usually skipped in subsequent integrations with the same target. If all the revisions of a source have been integrated into a particular target, p4 integrate returns the error message All revisions already integrated. To force the integration of already-integrated files, specify the -f flag to p4 integrate.

Similarly, a target that has been resolved but not (yet) submitted can be re-resolved by specifying the -f flag to p4 resolve, which forces re-resolution of already resolved files. When this flag is used, the original client target file has been replaced with the result file by the original resolve process; when you re-resolve, yours is the new client file, the result of the original resolve.

How Integrate Works

The following sections describe the mechanism behind the integration process.

The yours, theirs, and base files

The following table explains the terminology yours, theirs, and base files.

Term
Meaning

yours

The file to which changes are being propagated (also called the target file). This file in the client workspace is overwritten by the result when you resolve.

theirs

The file from which changes are read (also known as the source file). This file resides in the depot, and is not changed by the resolve process.

base

The last integrated revision of the source file. When you use integrate to create the branched copy of the file in the depot, the newly-branched copy is base.

The integration algorithm

p4 integrate performs the following steps:

  1. Apply the branch view to any target files provided on the command line to produce a list of source/target file pairs. If no files are provided on the command line, a list of all source/target file pairs is generated, including each revision of each source file that is to be integrated.

  2. Discard any source/target pairs for which the source file revisions have already been integrated. Each revision of each file that has been integrated is recorded, to avoid making you merge changes more than once.

  3. Discard any source/target pairs whose source file revisions have integrations pending in files that are already opened in the client.

  4. Integrate all remaining source/target pairs. The target file is opened on the client for the appropriate action and merging is scheduled.

Integrate's actions

The integrate command will take one of three actions, depending on particular characteristics of the source and target files:

Action
Meaning

branch

If the target file does not exist, it is opened for branch. The branch action is a variant of add, but Perforce keeps a record of which source file the target file was branched from. This allows three-way merges to be performed between subsequent source and target revisions with the original source file revision as base.

integrate

If both the source and target files exist, the target is opened for integration, which is a variant of edit. Before a user can submit a file that has been opened for integration, the source and target must be merged with p4 resolve.

delete

When the target file exists but no corresponding source file is mapped through the branch view, the target is marked for deletion. This is consistent with integrate's semantics: it attempts to make the target tree reflect the source tree.

By default, when you integrate using a branch specification, the original codeline contains the source files, and the branched codeline is the target. However, if you reverse the direction of integration by specifying the -r flag, the branched codeline contains the source, and the original files are the targets.

Integration Reporting

The branching-related reporting commands are:

Command
Function

p4 integrate -n [filepatterns]

Previews the results of the specified integration, but does not perform the integration. (To perform the integration, omit the -n flag.)

p4 resolve -n [filepatterns]

Displays files that are scheduled for resolve by p4 integrate, but does not perform the resolve. (To perform the resolve, omit the -n flag.)

p4 resolved

Displays files that have been resolved but not yet submitted.

p4 branches

Displays all branches.

p4 integrated filepatterns

Displays the integration history of the specified files.

p4 filelog -i [filepatterns]

Displays the revision histories of the specified files, including the integration histories of files from which the specified files were branched.

For More Information

Although Perforce's branching mechanism is relatively simple, the theory of branching can be very complex. When should a branch be created? At what point should code changes be propagated from one codeline to another? Who is responsible for performing merges? These questions will arise no matter what SCM system you're using, and the answers are not simple. Three on-line documents can provide some guidance in these matters.

A white paper on InterFile Branching, which describes Perforce's branching mechanism in technical detail, is available from:

Christopher Seiwald and Laura Wingerd's Best SCM Practices paper provides a discussion of many source configuration management issues, including an overview of basic branching techniques. This paper is available at:

Streamed Lines: Branching Patterns for Parallel Software Development is an extremely detailed paper on branching techniques. You'll find it at:


Perforce 2003.2 User's Guide
<< Previous Chapter
Labels
Table of Contents
Index
Perforce on the Web
Next Chapter >>
Job Tracking
Please send comments and questions about this manual to [email protected].
Copyright 1997-2003 Perforce Software. All rights reserved.
Last updated: 12/12/03