Branches/Releases

Cloud CMS stands apart from just about every other content management product on the market in that it offers a versioning model that is based around changesets. It is inspired by Git or Mercurial and provides a changeset versioning system that captures every touch - every create, update or delete - that you make.

Nothing is ever lost. Every data operation is fully transactional with every transaction payload is fully captured into its own changsets. Transactions span multiple documents and full "units of work" are written into the changeset history with every operation.

In the end, the changeset history is fully descriptive of every operation and data change that has occurred. This allows you to snapshot the repository at any moment in time. Or to roll back or forward to a specific moment in time.

This "Copy on Write" approach ensures that you're always able to make changes and restore a previous state should something go wrong. It allows you to try things out, see how they look and then approve them for go live or roll back in case you don't like it turned out. It is also the mechanism by which you can create vast updates, stage them for release and then push them live at a certain point in time.

Branches

Similar to Git or Mercurial, Cloud CMS offers branches so that you may maintain multiple, concurrent workspaces within which content is being worked on. Every repository has a master branch. A new branch is created by forking the master branch.

You can fork as many branches as you like. For all practical purposes, you can think of a branch as a copy of the branch from which it is forked. If you fork the master branch, then your new branch is basically a copy of the master branch. Under the hood, the implementation is optimized so that there isn't a literal copy of stuff until you touch something. But in essence, it is the same idea.

Once you have a branch, you can work on it at your own pace. The branch is effectively a copy and so if you make changes to things on it, you won't affect others. A change to a piece of content on a branch doesn't affect the original content on the original branch.

So you're free to make changes and try things out. If you don't like the way things are going, you can simply discard the branch. This tears down the branch and throws it away. Or, if you have something on the branch that you think might be interesting some day, you can keep it around. For example, you could freeze the branch to prevent others from making changes and then simply switch to another branch to keep on working.

Branches effectively provide expendable workspaces where you can build things at your own pace. Once you have something that you're happy with, you can merge the content. You can either merge the content back to the branch from which you forked, which is the most common scenario, you can merge the content to a completely different branch. This is sometimes referred to as pushing and pulling content between branches.

Branches and Snapshots

Each branch maintains a "tip view" as well as a "transactional view" along with the it's full changeset history. Whereas the latter is useful in terms of capturing all operations against a branch and potentially restoring from those changes, the "tip view" and "transactional view" are additionally maintained at runtime to maintain a latest view of what's happened inside of the branch.

Using these views, Cloud CMS provides support for Elastic Search and MongoDB on a per-branch basis. Each branch maintains its own managed indexes to support these. Thus, it is possible and very common within Cloud CMS to have two branches that yield completely different search or query results. In fact, this should very much be the case if you're using branches in any kind of interesting way.

Thus, Cloud CMS makes sure that branches are moving targets. You can make changes to them and Cloud CMS maintains all of the indexes and things behind the scenes so that they just work as expected. You just flip branch IDs in your API calls and you can run the same application logic against different sets of data.

A snapshot is a special kind of branch that is always frozen. You can create them at any time by identifying a changeset against which they should be created. A snapshot computes all of these indexes and everything else but locks itself against that specific changeset. It is used to capture a moment in time.

Snapshots are useful in two ways:

  • to provide your application with a "released" or "approved" view of your content. By creating a snapshot, you produce a frozen branch that can be used within your API calls to inspect the repository at that exact moment in time.
  • to improve performance of changeset history calculation for differencing during merge. Snapshots basically provide interleave frames that the algorithm can look to for a precomputed view of the world.

Branch API

Every repository has a master branch which is referred to as master. This is the branch that is used most often. If you aren't taking advantage of branching within Cloud CMS, then chances are that you've been working against the master branch all this time without knowing it.

From an API perspective, you can retrieve the a branch like this:

GET /repositories/{repositoryId}/branches/{branchId}

Here is what the master branch might look like:

{
    "_doc": "b7ccbaccf8dd30db947b",
    "root": "0:root",
    "tip": "24:897ec2b2d22bf7ee5ad4",
    "title": "master",
    "type": "MASTER",
    "snapshot": false
}

Where the properties are these:

  • root - the changeset where the branch begins and is rooted against
  • tip - the latest changeset written to the branch
  • title - a name for the branch
  • type - either MASTER for the master branch or CUSTOM for any other branch
  • snapshot - whether the branch is a snapshot

You can list of all of the branches like this:

GET /repositories/{repositoryId}/branches

Forking / Creating a Branch

To create a branch, you must fork at an existing changeset.

POST /repositories/{repositoryId}/branches?changeset={changesetId}