Branch

Type {{#dataTypeArticle objectTypeId}}{{objectTypeId}}{{/dataTypeArticle}}
Datastore Type {{#dataTypeArticle datastoreTypeId}}{{datastoreTypeId}}{{/dataTypeArticle}}
Supports {{#article "security/authorities"}}authorities{{/article}}, {{#article "security/permissions"}}permissions{{/article}}, {{#article "transfer"}}transfer{{/article}}

You can have as many branches as you want. Each branch is a completely isolated workspace. Thus, you can create your own branch for your own projects. You can work on those projects and when you're happy with it, you can share it with the rest of the team.

Or, you can create a branch and invite a bunch of people to work with you. They're your own workspaces. You can play with them however you want.

Changesets and Branches

You can think of a branch in the same way as you might think of the tree of a branch. Like that old Maple tree in the backyard when you were a kid. Remember that tree? You used to climb it. Then one day, you fell out of it and now, pretty much, that's all you hear about when you go home for family reunions.

Anyway, yeah, so a branch is like a tree branch. Each tree branch stems from a previous branch. And branches are made up of changesets.

A changeset is a bit like a layer from a transparency. When you write content into a branch, it goes onto a new changeset. Every time you make a change, like when you update something or delete something, it also goes onto a new changeset. And so, in this way, branches grow in length.

Branches also maintain a "tip" view which is the sum total of all changes, creates, updates and deletes that you make while working with the branch. Thus, at all times, the full "changeset history" of everything you've done is maintained but so is a "tip" view that gives you a real-time view of what is effectively a top-most version of all your content.

Configuration

The branch configuration contains system and custom properties. You can write your own properties onto this configuration document if you wish. You might use those properties to query and retrieve the branch at a later time.

Some system properties are read-only and others are writable. You can adjust the writable properties to modify the behavior and characteristics of the branch.

The following table presents you the system properties.

Branch Properties

Property Type Default Read-Only Description
title text The title of the data store.
description text A description for the data store.
root text Read-Only The changeset ID that constitutes the root of this branch.
readonly boolean Whether this branch is marked as read-only. If it is, then any create, delete or update operations against content in this branch will fail. Branches are often placed into a read-only state once they are end-of-life'd.
snapshot boolean Read-Only Whether this branch is a snapshot. A snapshot is intended to produce a production-ready, non-writable view of the repository for publication.
frozen boolean Whether this branch is a frozen.
join-branch text Read-Only If this branch was joined with another branch to form a new branch, then this is the ID of the new branch.
root-branch text Read-Only If this branch was forked from another branch (which is the case for all branches other than the master branch), then this is the ID of the branch from which this branch was forked.
type text Read-Only The type of branch - either: custom or master.
Only one branch will be marked as master. Everything else is custom.
tip text Read-Only The changeset ID that constitutes the tip of this branch.
archives array Read-Only An array that describes archives that have been deployed to this branch.

Any system properties that are shown to be Read-Only are not modifiable on calls to create() or update(). Anything else is fair game.

Create a Branch

You can create as many new branches as you'd like. To create a branch, you simply need to specify the root changeset for the new branch. You can create a branch from any existing changeset. The root changeset identifies the point at which the new branch "branches off" from the old branch.

// assume we have a repository
var repository = ...;

repository.createBranch("0:root").then(function() {
    console.log("Created branch: " + this.getId());
});

Here is an example where we create a branch that "branches off" from the master branch and another example to create a branch with an object.

Update a Branch

You can update any of the non-system properties of a branch. You can also add your own custom properties.

// assume we have a branch
branch.set("title", "My collaboration workspace");
branch.set("description", "Workspace for catalog items");
branch.update();

Delete a Branch

Branch deletion at present is not supported.

However, in its place, you can accomplish must of the same desired effect by marking a branch as "frozen". Frozen branches are effectively disabled.

Freeze a Branch

You can mark a branch as frozen to indicate that no further work should occur on the branch. A frozen branch cannot be updated, written to, or deleted from. New changesets cannot be added to the frozen branch. Effectively, the branch is no longer permitted to grow in size.

In addition, frozen branches cannot be forked. In other words, you cannot stem a new branch from a frozen branch.

Here is an example of freezing a branch:

branch.set("frozen", true);
branch.update();

You are also able to unfreeze branches at any time which restores them to their normal operational state.

Mark a branch as read-only

Alternatively, you may simple want to mark a branch as read-only. A read-only branch can still be utilized but not create, update or deletion operations may be performed against it. Read-only branches can be forked.

Here is an example marking a branch as read-only:

branch.set("readonly", true);
branch.update();

Read a Branch

You can read a branch by its ID.
As a special case, you can retrieve the master branch by using the text master.

// assume we have a repository
var repository = ...;

// assume we have a branch Id
var branchId = "4b5b685c980c10f98beb";

// read the branch
repository.readBranch(branchId).then(function() {
    console.log("Found branch: " + this.getId());
});

// read the master branch
repository.readBranch("master").then(function() {
    console.log("Found master branch");
});

List Branches

You can retrieve a list of branches for your repository quite easily. The following code hands back the full list.

// assume we have a repository
var repository = ...;

repository.listBranches().each(function() {
    console.log("Branch title: " + this.get("title"));
});

You can then iterate over the list to pick at what you'd like.

// assume we have a repository
var repository = ...;

repository.listBranches().each(function() {
    console.log("Branch title: " + this.get("title"));
});

Retrieving the full list is potentially an expensive operation, depending how many branches you have. The more your retrieve, the more data goes over the wire and so forth. Thus, you might wish to paginate your call and retrieve a subset of the total list at a time.

Here is an example that retrieves in pages of size 10. It starts on the second page (by skipping to starting index 20). It also sorts by the title field in a descending sequence.

// assume we have a repository
var repository = ...;

repository.listBranches({
    "limit": 10,
    "skip": 20,
    "sort": { "title": -1 }
}).each(function() {
    console.log("Branch title: " + this.get("title"));
});

You don't have to have all of the pagination parameters (limit, skip and sort). You might only want to include one or two. It's up to you.

Query Branches

You can run custom queries against your branches to find exactly what you're looking for. Here is a query that looks for branches whose field department is "sales".

// assume we have a repository
var repository = ...;

repository.queryBranches({
    "department": "sales"
});

Here is that same query followed by an iteration over the result map.

// assume we have a repository
var repository = ...;

repository.queryBranches({
    "department": "sales"
}).each(function(id) {
    console.log("Found an Branch: " + id + " with title: " + this.get("title"));
});

Cloud CMS utilizes the MongoDB query syntax under the hood. As such, you can really go to town. You're able to express queries with some pretty rich complexity.

Here is a query that finds all branches created after July 4, 2012.

// assume we have a repository
var repository = ...;

repository.queryBranches({
    "department": "sales"
},{
    "limit": 10,
    "skip": 20,
    "sort": {
        "title": -1
    }
}).each(function(id) {
    console.log("Found an Authentication Grant: " + id + " with title: " + this.get("title"));
});

Finally, you can mix queries with pagination to reduce data over the wire and speed up performance. Here is that same query with some pagination thrown in. We limit to pages of size 10 and sort by title.

// assume we have a repository
var repository = ...;

repository.queryBranches({
    "department": "sales"
},{
    "limit": 10,
    "skip": 20,
    "sort": {
        "title": -1
    }
}).each(function(id) {
    console.log("Found an Authentication Grant: " + id + " with title: " + this.get("title"));
});

List Mount Nodes

You can retrieve a list of mount nodes for a given branch. Mount nodes are starting points for container-based navigation of the node hierarchy. You can designate specific container nodes as "mount points" by associating them to the "root node" (with QName r:root) via an association type of a:has_mount.

Here is a quick way to find them:

// TODO