Brad Appleton | <brad@bradapp.net> | Motorola Network Solutions Group |
Stephen P. Berczuk | <berczuk@acm.org> | NetSuite Development |
Ralph Cabrera | <cabrerar@agcs.com> | AG Communication Systems |
Robert Orenstein | <rlo@perforce.com> | Perforce Software |
Send us your comments! |
|
Pattern | Codeline Policy | |
---|---|---|
Aliases | Policy per Codeline | |
Context | You are developing software within a system that utilizes multiple codelines. | |
Problem | How do the developers know which codeline to save their code in, and when to save it? | |
Forces |
| |
Solution |
In addition to using naming conventions and meaningful branch/codeline
names, formulate a coherent purpose for each codeline. Describe the
purpose in a clear and concise policy. The policy should be brief, and
should spell out the "rules of the road" for the codeline, including:
Keep in mind that not all codeline policies will require all of the above information. Only specify what is needed. Some VC tools allow you to associate a comment with each branch and codeline name. This is an ideal place to store the description of a suitably brief codeline policy (see Self-Documenting Codeline). Developers can run a branch-description for the codeline, instead of digging around for its documentation. Otherwise, store the codeline policy in a well known, readily accessible place (and perhaps provide a simple command or macro that will quickly display the policy for a given codeline name).
| |
Variants | ||
P1.1 |
Self-Documenting CodelineSome version control (VC) tools let you attach things like labels, attributes, comments, or access controls to branch-names. Those that do usually have some kind of listing or "describe" command to look at all the information for the branch-name at once. Some even support hyperlinks between elements in the VC system database. These can be used to specify (and enforce) things like codeline access, codeline purpose, propagation relationships with other codelines, and other information that can go into a longer comment field.If your VC system is one such tool, you can take advantage of this to take information that would otherwise go into a "policy document" and make it a part of the VC system's branch-data for that branch. The advantages here are that there is better locality of reference between the information about the branch, and the branch-itself. And of course its not just documentation either; the VC system understands its semantics for things like branch-locking/access. If your VC system allows you to capture all your required branch-policy information this way, it's a good way to avoid having a document that has to be separately maintained. | |
P1.2 |
Codeline ConventionsThis variant basically specifies a policy that is common to multiple codelines. Sometimes you may start off using one policy for each codeline, and that works okay for starters. But then after about 3-5 codelines, it can become more convenient to take the common, or more generally applicable information about how branching will be used, and gather it together in a single place. The types of things you will typically see in such a document are:
Again, try to keep it short and sweet. For codeline conventions, 1-2 pages is a good guideline. Since there will be multiple codelines, and you want to avoid extra documentation and maintenance overhead for each one, keeping the policies brief and self-documenting can be important. Some projects may have to be more verbose than others in documenting their codeline conventions. Figure out what you need to require from such a document, and then try to use least burdensome amount of formality and length that will meet your needs. | |
Resulting Context |
The codeline now has a coherently communicated purpose which is readily available to the entire project team. This sets the stage for how the codeline can and should be used. Codeline access issues are resolved by determining whether or not they violate the intended purpose of the codeline. Some extra documentation overhead and maintenance is imposed, but it is kept to a bare minimum, and is often worth the extra effort. | |
Related Patterns |
Codeline Ownership and Policy Branch describe tactics for resolving policy conflicts. The owner of the codeline policy document should be the current owner of the codeline. Restricted-Access Line may be applicable if the codeline policy calls for tight permission or control. Every branch creation and branch structuring pattern will require a corresponding codeline policy for each codeline. |
Pattern | Codeline Ownership |
---|---|
Aliases | Branch Ownership |
Context | You are a developer working with at least one codeline in a set of Multiple codelines. A Codeline Policy has been used to define policies for codeline checkin/checkout. Someone wants to do something to a codeline that its policy doesn't seem to address, or else the policy appears vague regarding this particular issue. |
Problem | Should the action affecting the codeline be performed or not? How can this be decided while at the same time ensuring the integrity and consistency of the codeline? |
Forces |
|
Solution |
Assign one owner per codeline. It is the owner's responsibility to
|
Variants | |
P2.1 |
Codeline DictatorshipAn extremely restrictive form of codeline ownership whereby checkouts and subbranches of a branch are restricted, in addition to checkins. The dictator may be a single person, or an entire site. A common example is a Remote Development Line: remote developers might be prevented from creating new versions and branches that do not originate from the remote branch. Thus, the local branch is reserved exclusively for the "master" development site. This is essentially how ClearCase Multisite defines the notion of "branch mastership." |
Resulting Context |
|
Related Patterns |
A Codeline Policy should specify the usage rules that the codeline-owner is expected to ensure. Branch locking may be used to impose a Restricted-Access Line enforcing mastership or ownership policies. Code Ownership ([Cope]) will apply for codelines serving as component branches or component lines; the code and codeline owners should be the same. Similarly, Owner per Deliverable ([Cockburn97]) should be applied for functional branches and subproject-lines; |
Pattern | Relaxed-Access Line |
---|---|
Context | When determining the Codeline Policy for a codeline, you need to decide the access-control policy of the codeline. |
Problem | How restrictive or exclusionary should the access control policy be for the codeline? |
Forces |
|
Solution |
If the codeline is being used for development or maintenance (rather than
exclusively for integration) and if the group working on the codeline
is relatively small, experienced, and reliable, then give the developers
relatively free reign to do what they already know how to do: work
together to develop software in a timely fashion. Use the bare minimum
of checks and controls but make sure the codeline-owner takes his job
seriously and is always aware of the state of the codeline and whether
or not its integrity is about to be compromised by a particularly
risky/complex development task.
|
Variants | |
P3.1 |
Guarded Merge AccessOne way of addressing possible merge/integration conflicts is to let developers checkin to the codeline as they see fit, but to perform an automated check ensuring there will be no merge conflicts upon checkin. Some VC tools provide triggers as a convenient way of performing such checks. A pre-checkin or pre-submit trigger can invoke the VC tool's automated merge tool in "what-if" mode and abort the operation unless the merge is trivial or has no conflicts at all. If your VC tool doesn't have triggers then you would typically use a "wrapper" instead, wrapping your own command or script around the checkin/submit command (or else you could always have the codeline-owner perform the merge-query). If your VC tool doesn't have such nice merge facilities, you would need to put that together on your own, using history information stored in the repository to build and traverse the version tree for a given file.If the merge tools think the merge is trivial, then the checkin/submit proceeds. Otherwise, the person who made the changes is required to re-sync their changes with the latest state of the codeline (importing any recent codeline changes into their workspace) and resolve the merge conflicts in their own workspace before attempting to check them in to the codeline again. |
Resulting Context |
The codeline has a more laissez-faire access policy which trades off safety for liveness. This is more likely to be an acceptable risk for a small, experienced group of developers. While "glitches" may have a higher impact on the codeline, their likelihood is decreased by the more trustworthy nature of the group and the work they are performing. When glitches do occur, the group working on the codeline is often intelligent enough to quickly contain and correct the problem. |
Related Patterns |
MYOC (Merge Your Own Code) and its variant
PYOC (Propagate Your Own Code) are the most common
by-products of (and reasons for) using Relaxed Access Lines.
If, in your environment, there is less risk and better communication
associated with developers merging their own changes to the codeline,
then this is one of the primary reasons to employ relaxed access.
Docking Line is another kind of relaxed-access line. if you cant afford the risk to the codeline, but still want developers to merge their own changes, you can create another line of integration. Developers to use push their changes to this line using MYOC, while a "build manager" pulls changes from the docking line into the main integration line. Subproject Line and LAG Development Line are often employed with relaxed access control to allow several developers to work closely together for the same (sub)project effort (e.g., a release, or subset of features). |
Pattern | Restricted-Access Line |
---|---|
Aliases | Branch Locking |
Context | Same as for Relaxed-Access Line |
Problem | Same as for Relaxed-Access Line |
Forces | Same as for Relaxed-Access Line |
Solution |
If the codeline will have a large number of developers (or a sufficient
number of inexperienced developers) and the work taking place on
the codeline is very risky, or consists primarily of integration, or
corresponds to a promotion-level or lifecycle phase that is not very
close to the initial level, then restrict who is allowed to checkin
code on the codeline to either just the codeline owner, or a to a small
set of trusted, reliable developers.
Some VC tools support access control for branches so that they may be locked against checkin or checkout. Sometimes the access control will allow you to specify everyone, and/or a list of users or groups to include/exclude from the codeline access-list. If the VC tool you are using has these features, they prove quite convenient for enforcing codeline access-restrictions. If the VC tools doesn't support such features, the triggers or wrappers for checkin/checkout will be required (and they will need to determine, or else query the user for, the target codeline). |
Variants | |
P4.1 |
Codeline Freeze/RetirementIt is common to suspend ("freeze") development to perform release integration and engineering activities. Afterward the codeline or branch may be decommissioned, sent into "retirement" by cutting it off and merging it back to a parent codeline or to the Mainline. Or development on the codeline may be resumed ("thawed" or "melted") after the release has been "cut." During the time it is frozen however, no one may make any changes to the codeline that aren't deemed necessary for successful integration and release. The only codeline activities permitted are those which sync and stabilize its contents.When using branches, you may continue development on one codeline while conducting release engineering on another (see Anti-Freeze Line). You may still want to freeze any new changes (other than integration) on the codeline that is being prepared for release, but remaining development activities can carry on in separate codelines. |
P4.2 |
Export Lock (a.k.a. Integration Lock)When developers use MYOC to export their changes to the codeline, there may be contention between multiple developers trying to commit their changes for export during the same time period. Just before a completed change is about to be merged back into the codeline, the developer acquires an export lock. No one but the holder of the export lock may checkin to the codeline during that time. Also, the developer may only checkin all their changes at once, or none at all (logical changes to the codeline must be "atomic").If the merge can be performed quickly and cleanly, and its correctness can be verified shortly thereafter, then the developer keeps the export lock and does not have to reconcile changes against a moving "target." If retaining the export lock during the merge would adversely impact others, the developer relinquishes the export lock and reconciles with the current state of the codeline (allowing others the opportunity to export their changes). When the developer is once again ready to export, there may now be new codeline changes to contend with, and the same decision of whether or not to keep or relinquish the temporary export lock will be faced once again. |
P4.3 |
Private Line (also Private Branch)Sometimes a codeline or branch is primarily intended for a single person to perform a single task or series of tasks. In these cases it is common the prevent all users other than the codeline owner from checking-out (and in) files from the codeline. Sometimes even branching off the private line is forbidden to all but the codeline owner.Also, if a codeline is used as a Component Line, and if only the code-owner is allowed to checkin the code she owns, it makes good sense to restrict all access on the component-line to the code-owner (who also serves as the codeline owner, of course). |
P4.4 |
Role-based Line Access (Role Branch)Sometimes, instead of being restricted to one or more users, a branch is restricted to one or more development roles. Any person may use the branch or codeline as long as they are playing the correct role at that time. This is typically done using a special user-id or group-id for each development role requiring special access. For example, in order to gain merge access to a codeline, it might be the case that a developer fulfilling an integration role must first become user 'integratr' or be a member of the 'integratr' user-group. |
Resulting Context |
Restricted-access provides an added level of safety and security for the codeline. If the codeline is shared, then you lose some of the benefits of choosing file-branching over file-locking (resulting in more waiting time), but the restriction is larger-grained and not absolute; so you still keep many of the benefits of branching versus locking while ensuring that efforts on the codeline remain as isolated and/or as consistent and stable as demanded by the nature of the codeline. |
Related Patterns |
Both Remote Development Line and Inside/Outside Lines are forms of restricted access lines. So is a Stable Receiving Line and a codeline where the Codeline Owner is responsible for performing all the integration. |
Pattern | Merge Early and Often |
---|---|
Aliases | Codeline Update per Task |
Context | For a given codeline, maintenance and/or development activity is regularly occurring. Some of the work may be happening directly on the codeline, while other tasks ultimately intended for this codeline may be taking place on Task Branches or Subproject Lines. Furthermore, the codeline may also require periodic synchronization with changes on Remote Lines and changes often need to be propagated from a maintenance-line to a release-line, or from a release-line to a codeline for a subsequent release. |
Problem | When should changes be merged into the codeline and how frequently should they be merged? |
Forces |
|
Solution |
Integrate new changes into the codeline as soon as they are ready;
Do not integrate portions of a logical change before the entire change
completed. But once the entire change has been completed (much like
a transaction) it should be immediately considered for integration
into the codeline and merged in as soon as conveniently possible.
|
Variants | |
P5.1 |
Propagate Early and Often (a.k.a Propagation per Task)This is basically the same thing but it refers specifically to the case where changes already integrated (or merged) into one codeline need to be propagated (merged) into another codeline.
|
P5.2 |
Multi-Merge Early and OftenIf the codeline owner must be responsible for all merging (due to the nature of the codeline requiring a high degree of reliability and consistency that only the line owner can take responsibility for), then, for a high-volume (high activity-load) codeline, it may not always be feasible to merge every change-task as soon as it is complete.In this case, merge-tasks need to be queued or batched up into manageable chunks and then regularly merged in. A suitable interval should be chosen based upon the number of tasks and their average complexity. Daily might be best for high activity codelines, whereas as weekly will be better for others. Start off trying for daily (or nightly) multi-merges (tested via Daily or Nightly Builds). If that is too burdensome then try semi-weekly, and then weekly. If a shorter time period is needed than try twice a day (daily & nightly). It will take a little while to find the correct rhythm, and it may fluctuate form time to time, but it does need to be done as frequently and regularly as manageable and should be done at least weekly.
This may be combined with change-propagation to yield
"Multi-Propagating":
|
Resulting Context |
The codeline is incrementally updated at fairly regular intervals to
reflect the current state of progress for that codeline. Subsequent
development on that codeline now takes place in the context of the newly
merged changes. While this may introduce some difficulty if a change
later needs to be backed out, it serves as a forcing function to help
identify and flesh out risks early in the development cycle when their
is more time and opportunity to address them intelligently.
Developers using dynamic configuration selection may seen changes sooner than they would have liked. Although they would have to see them eventually before merging back to the codeline, they may require some control over when they see such changes that would impact their own work. |
Related Patterns |
MYOC (Merge Your Own Code), PYOC (Propagate Early and Often), and Change Propagation Queues follow naturally from this pattern. Branch per Task may be suitable for developers using dynamic configuration selection. Floating Labels (see Virtual Codeline) may also be a good alternative. |
Pattern | MYOC (Merge Your Own Code) |
---|---|
Aliases | Get the right person to do the merge! |
Context | You are a developer working on code in either a branch off of the codeline, or on the codeline itself. After you have finished debugging and testing your changes, you wish to follow Merge Early and Often and have your changes merged back into the codeline. |
Problem | Who should perform the merge, and who assumes the burden of ensuring it is integrated correctly? |
Forces |
|
Solution |
If either the change-owner or the code-owner also happens to be the
codeline owner, then have the codeline-owner merge the code. Otherwise,
unless reliability and process control obligations are so strict as
to forbid merging by anyone but the codeline-owner, always strive to have
the either the change-owner or the code-owner perform the merge.
On occasion, this will require cooperation and collaboration from all three parties, especially the codeline-owner if the codeline-state is higher risk or has significantly changed. Remember that a change to merge may conflict with a previous change in the codeline. Resolving this conflict may require additional assistance from the person who performed or merged the conflicting changes. Hopefully, it will be the case that the change-owner and the code-owner are one and the same, or else that the code-owner and the codeline-owner are the same person (in which case the codeline may be a Component Line). If all three of these owners are different people, you may need another level of integration (see Staged Integration Lines). Otherwise, if the codeline is necessarily restrictive or the degree of risk/complexity for merging to the codeline is very high, the codeline owner may have to perform the merge. In this case a better solution may be to (again) add another level of integration to create a Docking Line. |
Variants | |
P6.1 |
PYOC (Propagate Your Own Code)If change-tasks are propagated on a task-by-task basis, then pretty much the same scenario occurs when it is time for a change-task that has been integrated in one codeline to be propagated to another codeline. So now we have two codeline owners, the owner of the receiving codeline and the owner of the sending (or originating) codeline. Despite this difference, the rule of thumb is still pretty much unchanged. |
Resulting Context |
Developer's take responsibility for their code and changes throughout the codeline's lifespan instead of playing "pass the buck" and becoming alienated from each other's efforts and responsibilities. The codeline owner still needs to monitor/verify the codeline after merges, but isn't overburdened with a high-volume of merges to perform. |
Related Patterns |
This pattern requires a sufficiently Relaxed-Access Line. If that
is not feasible then a Docking Line, or Staged Integration
Lines may be a good compromise that allows developers to merge their
own changes to another codeline which eventually cycles those changes
(under more protective jurisdiction) back into the development line.
PYOC (Propagate Your Own Change) often follows directly from use of MYOC. |
Pattern | Early Branching |
---|---|
Aliases | Branch Early and Often |
Context | During project planning and later in course of development efforts, you become aware of various tasks and subproject that will best be performed in parallel with other development efforts. These might be major features or fixes, major or minor releases, patches, or new platforms (or even geographically distributed development). |
Problem | When should you create new branches or codelines for parallel tasks and subprojects that are forthcoming in the near future? |
Forces |
|
Solution |
Create new branches and codeline as soon as the corresponding parallel
work efforts begin. Even if they don't yet conflict with any current
work on existing codelines, separate those activities into logically
separate branches which are later merged back into parent codelines.
|
Resulting Context |
Each branch and codeline has a logically coherent purpose that is conceptually clear and easily maps to tasks, subprojects, features and releases. Although these activities might have easily occurred on the same codeline without any conflict, each branch helps to isolate logically distinct efforts and to encapsulate a cohesive unit of functionality, effort, or delivery. |
Related Patterns |
Branch per Task and Codeline per Release are essentially concrete forms of early branching. When early branching results in more branches and shorter-lived branches than its counterpart of deferred branching, then such early branches will more frequently need to be restricted access lines. Early branching also increases the importance of using a Mainline. |
Pattern | Deferred Branching |
---|---|
Aliases | Lazy Branching, Late Branching |
Context | Same as for Early Branching |
Problem | Same as for Early Branching |
Forces | Same as for Early Branching |
Solution |
Instead of spawning off a new task branch, subproject line, or release
line, as soon as effort begins for the corresponding goal, wait to
start the new branch until work for that release actually starts to
conflict with work that is already on the codeline. This doesn't mean
that you should wait to branch until one or more files have conflicting
changes. What it means is you should wait to branch until a logical
change (feature, function, bug-fix) that is needed only for the new task,
and not yet desired in the original codeline, is about to take place.
For releases, perform development for the new latest-and-greatest release on the LAG Development Line until it is no longer the latest release effort (then branch off into a major release-line as in Codeline per Major Release). When work is first ready to begin for the new release-line, instead of starting a new branch for the new effort, you start a new branch for the old effort (that was, upto now, taking place on the LAG-line).
Similarly, with features and fixes, if they would need to be merged back to the original codeline by release-time anyway, and aren't of a significantly high risk/complexity or long duration, then go ahead and perform them on the codeline (see Branch per Major Task). |
Resulting Context |
Deferred Branching requires less integration/merging and
propagation of changes from codeline to codeline. It does so at the
risk of less isolation, trading off "safety" for "liveness".
The branches that are created may seem less "singular in purpose" than with Early Branching. With Early Branching the type of work for each branch/codeline happened only on that branch. With Deferred Branching the work happens first on the original codeline, and than later gets branched-off to another codeline. This may seem inconsistent or cause people conceptual difficulty in understanding and remembering what kind of work should be occurring on the codeline. Sometimes this can be addressed by adopting a slightly different perspective for the purpose of the codeline. For example, instead of defining the purpose of the codeline to be for a specific release, define it to be for the latest and greatest development effort of the project (LAG-Line) of for the latest and greatest maintenance efforts for a previous release (Codeline per Major Release). However, this conceptual reorientation this cannot always be accomplished in a suitably coherent and consistent manner, and even when it can, some team members may have significant difficult making the adjustment. |
Related Patterns |
LAG Development Line, Branch per Major Task, and Codeline per Major Release are essentially concrete forms of deferred branching. Deferred branches serving as LAG lines are often used as a kind of Mainline. |