Branches allow your team to work on multiple versions of code at the same time. They allow developers to work without unintentionally manufacturing bugs and errors in the mainline. Once the feature is stable, it can be merged.
In SVN, branches are generated as directories within a repository. The “branch” runs parallel to the “trunk” directory. Relationships between the branches and the trunk are not always clear. It is up to development to create external documentation and a naming schema to track changes. This is not optimal and can cause issues, especially when merging.
Occasionally developers will merge from the trunk to the branch to keep files up to date. During this process changes are often duplicated in the branch. These updates may not include all the changes because developers have no visibility into what other people are working on. When someone goes to commit, their version of the trunk might look very different from the existing mainline. Get ready for multiple conflicts and missing files.
Working in parallel means that you are able to deploy, fix bugs, and develop new features all at once. But with SVN, limited visibility slows productivity. Using our example, we can see that two developers are working on separate releases on the 1.0 trunk.
The 1.4 release was able to be merged and pushed out to development, but the 2.0 dev branch has some issues. Branches that hang out in development for a longer period of time pose a greater risk when merging. SVN does not store information about where on the trunk the branch belongs. Now developers have to spend time combing through changes to see which ones are missing. This means every file rename, file deletion, or change to the directory structure.
Manually resolving each error is tedious. Even with “merge tracking” a developer may never be able to figure out what a branch needs to commit. This can lead to delayed deployments and over time, a less stable code base.
For companies that want to improve development and gain visibility, there is another option – Perforce Streams.
Perforce Streams is an advanced branching technology. Streams are a better way to branch, and make the ultimate merging of the work easier, resulting in fewer errors.
Using Streams, you can visually see where the code came from and where it is going. This lightweight branching model makes operations fast. You can easily switch between branches and develop different versions at the same time.
Let’s go over some Stream basics to get you started.
The stream graph shows the hierarchy in a stream depot. It conveys important information about the relationships between streams, the workflow used to propagate changes across streams, and to show any pending integrations.
The parent-child relationships defined in the metadata determines where Perforce places the stream in the hierarchy. In this first release, the stream type defines the position of the child streams. Perforce displays child release streams above the mainline, and child development streams below the mainline. Child streams above the first level of release streams are always drawn above the parent, regardless of the stream type, development, or release.
Similarly, child streams below the first level of development are always drawn below the parent. For example, when creating a patch for a release stream, a developer would create a development branch as a child of the release stream. As you can see, Perforce places the development branch above the release stream in the stream graph. The stream graph illustrates the intended flow of change by displaying arrows between the streams.
The arrows represent channels that help ensure that each change gets to the right place in the right way. The best practice is “merge down, and copy up.” This simple, built-in rule prevents the kind of issues common with other VCS systems. Less stable, work in progress development Streams may well have conflicts that need to be resolved prior to shipping. While the release streams contain code that is theoretically proven stable, and either in production or verified as ready to ship.
The color of the arrow between parent and child reflects the state of pending changes within a code line:
- Gray signifies that there are no pending changes.
- Green indicates that changes are pending and ready to integrate.
- Orange indicates that changes are pending, but another process must be run before they are ready to integrate.
To propagate changes across streams, you can open the streams integration dialogue box, and either merge or copy. You can also double click on the stream to display suggestions for the appropriate integration strategy and get links to the proper command. This makes merging easier and results in fewer errors.