| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
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 synchronized two or more sets of similar, but not identical, files. Most software configuration management systems have some form of branching; we believe that Perforce's mechanism is unique in that 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 file 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 whenever two sets of code have different rules governing when code should be submitted, or whenever a set of files needs to evolve along different paths. For example:
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
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 at the start. 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:
p4 integrate fromfiles tofiles 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: p4 integrate -b branchname [tofiles] 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 donor files) to another set of files (the target files). The target files need to be contained within the current client workspace view; the donor files need not be, as long as the donor files are specified in depot syntax. If the target files do not yet exist, the entire contents of the donor files will be 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 FilesTo create a copy of a file that will be tracked for branching, use the following procedure:
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Version 2.0 of Elm has just been released, and work on version 3.0 is about to commence.
Work on the current development release always proceeds in //depot/elm_proj/...,
and it is determined that maintenance of version 2.0 will take place in
//depot/elm_r2.0/... The files in //depot/elm_proj/... need to be branched
into //depot/elm_r2.0/..., so Ed does the following:
He decides that he'll want to work on the new //depot/elm_r2.0/... files within his client workspace at /usr/edk/elmproj/r2.0. He uses p4 client to add the following mapping to his client view: //depot/elm_r2.0/... //eds_elm/r2.0/... p4 integrate //depot/elm_proj/... //depot/elm_r2.0/... which copies all the files under //depot/elm_proj/... to the correct location in his client workspace. Finally, he runs p4 submit, which adds the newly created branched files to the depot. Why Not Just Copy the Files?It is certainly 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. But when you do this with p4 integrate, Perforce tracks the connections between related files in an integration record, allowing easy propagation of changes between one set of files and another.Propagating Changes Between Branched FilesOnce 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 into the corresponding branch files. The procedure is as follows: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
p4 integrate elm_proj/src/elm.c //depot/elm_r2.0/src/elm.c
The file has been scheduled for resolve. He types p4 resolve, and the standard merge dialog appears on his screen.
He resolves the conflict with the standard use of p4 resolve. When he's done, the result file overwrites the file in his branched client, and it still must be submitted to 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. 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, etc. 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. 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 FilesA change can be propagated in the reverse direction, from branched files to the original files, by supplying the branched files as the donor files, and the original files as the target files.Ed wants to integrate some changes in //depot/elm_r2.0/src/screen.c file to the original version of the same file. He types p4 integrate //depot/elm_r2.0/src/screen.c //depot/elm_proj/src/screen.c and then runs p4 resolve. The changes in the branched file can now be merged into his source file.
| Branching and Merging, Method 2: Branching with Branch Specifications
In the method described above, the user must manually track which donor files go with which target files. A slightly different branching mechanism allows Perforce to track this for you; the target files are mapped to donor files in a branch specification, and the name of the branch specification is provided as an argument to p4 integrate.The downside is that the initial setup is slightly more complicated; the benefit is that the user no longer needs to remember the exact mappings between target files and donor files. To create and use a branch specification, do the following:
|
|
|
Version 2.0 of Elm has just been released, and work on version 3.0 is about to commence.
Work on the current development release always proceeds in //depot/elm_proj/...,
and it is determined that maintenance of version 2.0 will take place in
//depot/elm_r2.0/... The files in //depot/elm_proj/... need to be branched
into //depot/elm_r2.0/..., so Ed does the following:
| Ed creates a branch specification called elm2.0 by typing p4 branch elm2.0. The following form is displayed:
The default View: above would branch the entire depot into itself, which is useless. The view should map the original codeline's files on the left to branched files on the right. Ed changes the View: and Description: fields as follows:
Ed wants to work on the new //depot/elm_r2.0/... files within his client workspace at /usr/edk/elmproj/r2.0. He uses p4 client to add the following mapping to his client view: //depot/elm_r2.0/... //eds_elm/r2.0/... He runs p4 integrate -b elm2.0, which copies all the files under //depot/elm_proj/... to the correct location in his client workspace; then he runs p4 submit, which adds the newly branched files to the depot. Once the branch has been created and the files have been copied into the branched codeline, changes can be propagated from target files to donor files with p4 integrate -b branchname. A bug has been fixed in the original codeline's src/elm.c file. Ed wants to propagate the same bug fix to the branched codeline he's been working on. He types p4 integrate -b elm2.0 ~edk/elm_r2.0/src/elm.c
The file has been scheduled for resolve. He types p4 resolve, and the standard merge dialog appears on his screen.
He resolves the conflict with the standard use of p4 resolve. When he's done, the result file overwrites the file in his branched client, and it still must be submitted to the depot.
| Branch Specification Usage Notes
| |