Nuxeo Server

Versioning

Updated: January 12, 2018 Page Information Edit on GitHub

The Nuxeo Repository includes a versioning system. At any time, you can ask the repository to create and archive a version of a document. Versioning can be done automatically, according to some versioning policies, or on-demand, through the UI.

Each version has:

  • A label
  • A major version number
  • A minor version number

The versioning service is configurable so you can define the numbering policy.

Functional Overview

Document versions enable you and other users to easily revert to a specific version of the document if needed, without having to edit the document. The Nuxeo Platform offers both automatic and manual versioning of documents.

Every document holds a version number, which is a piece of information about the evolution of the document. A version number (V.v) is composed of a major version number (V) and a minor version number (v). When a document is created, its version number can be 0.0, 0.1 or 1.0 depending on automatic versioning rules. Minor version increment are typically used for secondary changes. Major version increment is usually reserved to significant modifications. When a document is edited without a new version being created, the version number is suffixed with a + (0.1+ for instance), to indicate that the version was modified since it was created.

Version number 0.0
Version number 0.0 is considered as a draft of the document, which will need to be saved into a first version, either minor or major. Draft version 0.0 is not archived.

Automatic Versioning

Two automatic versioning behaviors are applied by default: one for files (and associated document types) and one for notes.

  • Files and other document types with schema file:file, like pictures, are created in version 0.0. A new minor version is automatically created when you edit a document that was last modified by another user. This minor version holds the modifications of the previous contributor, so that no data is lost. Your changes are applied on top of this version, the version number becoming for instance 0.1+. When you edit a document that was last edited by yourself, no version is automatically saved. You can however decide to manually create a new version of the document.

  • For notes, a new version is created for every modification, whether you are the last contributor of the note or not. The created version holds the your changes. When they are created, notes have a version number of 0.1.

This automatic versioning applies in case of:

  • Modification of the main file or its attachments using drag and drop
  • Manual edit of the attachments
  • Modification of the document (main file, properties, attachments) via bulk edit

The following actions don’t trigger the automatic versioning of the document:

  • Tagging the document
  • Adding the document to a collection
  • Changing the relations of the document
  • Commenting the document

Automatic versioning is disabled on CMIS connector due to conflict between our specifications and CMIS specifications.

Manual Versioning

You can decide to manually create a new version of the document.

In case of a file document types the automatic version is done first and then the manual version. So if you edit the document and select the option “Increment major version”, a minor version is created and then a major version: the minor version is the automatic one holding the previous contributor’s work, and the major one is the manual version with your modifications. If you select “Increment minor version”, two minor versions are created following the same principle. And if you chose “Skip version increment”, only the automatic versioning behavior is applied and the document version number is 0.1+ for instance.

For notes, if you use the Edit form, only the manual versioning rules applied. Selecting “Increment major version” save your changes in a major version, “Increment minor version” saves them in a minor version and choosing “Skip version increment” doesn’t create a new version and the version number is +ed (0.1+ for instance).

To create new version in a Web UI application:

  1. Go on the View tab of the desired document.
  2. In the top right section of metadata, click on Create Version.
  3. Select the version that you want and click on Create Version to confirm.

To create a new version of your document in a JSF application:

  1. Click on the Edit tab of the document.
  2. At the bottom of the form, in the Update version, select your versioning option and click Save.
    Versions are accessible from the History tab of the document.

The automatic versioning after the modification of the document won't work in a JSF application.

Concepts

  • Placeful. A placeful document is one which is stored in a folder, and therefore has a parent in which it is visible as a child.
  • Placeless. A placeless document isn't stored in a given folder, it's just available in the storage through its id. Having no parent folder it doesn't inherit any security, so it is usually only accessible by system code.
  • Working Copy. The document that you edit. It is usually stored in a Workspace's folder but this is just convention. It is also often called the Live Document. There is at most one Working Copy per version series. In other systems it is also called the Private Working Copy because only the user that created it can work on it; this is less strict in the Nuxeo Platform.
  • Version. An immutable, archived version of a document. It is created from a working copy by a check in operation.
  • Version Number. The label which is uniquely attached to a version. It formed of two integers separated by a dot, like "2.1". The first integer is the major version number, the second one is the minor version number.
  • Major Version. A version whose minor version number is 0. It follows that a minor version is a version whose minor version number is not 0.
  • Version Series. The list of versions that have been successively created from an initial working copy. The version series id is a unique identifier that is shared by the working copy and all the versions of the version series.
  • Versionable Document. The document which can be versioned, in effect the working copy.
  • Check In. The operation by which a new version is created from a working copy.
  • Check Out. The operation by which a working copy is made available.

Check In and Check Out

"Check In" and "Check Out" in the Nuxeo Platform both refer to operations that can be carried out on documents, and to the state a working copy can be in.

Checked In and Checked Out States

A working copy in the Checked Out state can be modified freely by users having access rights to the document. A document ceases to be Checked Out when the Check In operation is invoked. After initial creation a document is in the Checked Out state.

A working copy in the Checked In state is identical to the version that was created when the Check In operation was invoked on the working copy. In the Checked In state, a working copy is (at low level) not modifiable. To be modified it must be switched to the Checked Out state first. This latter operation is automatically done in the Nuxeo Platform when a document is modified.

Check In and Check Out Operations

From a working copy in the Checked Out state, invoking the Check In operation does several things:

  • the final version number is determined,
  • a new version is created,
  • the working copy is placed in the Checked In state.

When invoking the Check In operation, a flag is passed to indicate whether a major version or a minor version should be created. Depending on whether the new version should be major or minor, the version number is incremented differently; for instance, starting from a working copy with the version number "2.1" (displayed as "2.1+"), a minor version would be created as "2.2" and a major version as "3.0".

Given a Checked In working copy, invoking the Check Out operation has little visible effect, it's just a state change for the working copy. A "+" is displayed after the version number to make this apparent, see below.

In other systems than the Nuxeo Platform, the Check In operation that creates a new version removes the Working Copy, whose role has been fulfilled. This is not the case in the Nuxeo Platform, where the Working Copy remains in a special Checked In state. In these other systems, the Check Out operation can also be invoked on a Version to create a new Working Copy (this assumes that there is no pre-existing Working Copy in the system). This kind of operation will be made available in future versions of the platform but is not present at the moment.

Version Number

The initial version number of a freshly created working copy is "0.0".

When displaying the version number for a Checked Out document, the version number is usually displayed with a "+" following it, to show that it's not the final version number but that the working copy is modified and derived from that version. The final version number will be determined at Check In time. The exception to this display rule is the version "0.0", because displaying "0.0+" would be redundant and misleading as there is actually no previously archived "0.0" version from which it is derived.

The version number is changed by a Check In operation; either the minor version number is incremented, or the major version number is incremented and the minor version number is set to 0.

Automatic Versioning System

The automatic versioning system is based on a combination of policies and filters. Policies state the behavior of desired versioning and filters state whether or not document needs to be versioned.

The automatic system is triggered:

  • For createDocument: after document save in DB
  • For saveDocument:
    • Before document save in DB and after firing beforeDocumentModification event
    • After document save in DB and before firing documentModified event

During this call to the automatic versioning system, the engine will search for the first policy whose filter(s) match the current context. If a matching policy is found, the engine will use the increment option to check in the document (unless increment = NONE), then exit.

The system is not triggered before update if the document is already checked in.

The system is not triggered after update if a manual versioning is asked (VersioningService.VERSIONING_OPTION in document context data).

To contribute new policies and filters, check out the extension points documentation:

Versioning Policies

Each versioning policy defines:

  • A unique id which allows to override default policies
  • The increment policy (between NONE, MINOR or MAJOR)
  • If the versioning has to be applied before or after the actual modification (beforeUpdate defaults to false)
  • The order in which the policy should be taken into account related to other policies.

Example:

<extension target="org.nuxeo.ecm.core.versioning.VersioningService" point="policies">
  <policy id="note-and-file-policy" order="1" beforeUpdate="true" increment="MAJOR">
    <filter-id>note-filter</filter-id>
    <filter-id>file-filter</filter-id>
  </policy>
</extension>

Filters referenced by the policy are AND-ed: All filters must match in order to apply the policy.

Setting NONE as increment policy will stop policies evaluation if no policy with a lower order applies.

Nuxeo reserved order range [1,10] to contribute system policies. Notice that default contributions are also provided with a higher range; These are not system policies and as such have a lower impact, making them easier to override.

Versioning Filters

A versioning filter defines the condition(s) the document has to fulfill so that the versioning can be applied. The standard filter can be composed of the following elements:

  • Type: On which document type the versioning applies
  • Schema: Apply the versioning if the document contains this schema
  • Facet: Apply the versioning if the document contains this facet
  • Condition: Defines a condition in EL to access properties of the document before/after modification

Example:

<extension target="org.nuxeo.ecm.core.versioning.VersioningService" point="filters">
  <filter id="my-standard-filter">
      <type>MyDocType</type>
      <schema>MySchema</schema>
      <facet>MyFacet</facet>
      <condition>#{previousDocument.foo != currentDocument.foo}</condition>
  </filter>
</extension>

Same element tags are OR-ed and different elements are AND-ed.

The example below will be interpreted as:

(documentType == type1 || documentType == type2) && document.hasSchema(schema1)
<extension target="org.nuxeo.ecm.core.versioning.VersioningService" point="filters">
  <filter id="my-standard-filter">
    <type>type1</type>
    <type>type2</type>
    <schema>schema1</schema>
  </filter>
</extension>

If the standard filter is not enough to cover all your requirements, the filter can be customized with a Java class implementing the VersioningPolicyFilter interface to define a particular condition:

Example:

<filter id="my-class-filter" class="foo.bar.CustomVersioningFilter"/>

Source-Based Versioning

For source-based versioning (like with Nuxeo Drive or the REST API for example), a property is provided in the context data of the document (source), so it can be accessed in the EL condition.

We inject the source context parameter value for:

  • drive
  • REST API, by getting its value from the HTTP header source.
  • file importers, the value will be fileimporter-%NAME%
  • bulkEdit

See the example.

For more details about source-based versioning with Nuxeo Drive, check out the page How to Customize Nuxeo Drive Versioning Policy.

Automatic Versioning Example

Default Policies

Below are the default versioning policies defined in Nuxeo Platform:

<extension target="org.nuxeo.ecm.core.versioning.VersioningService" point="policies">
  <policy id="no-versioning-for-system-before-update" beforeUpdate="true" increment="NONE" order="1">
    <filter-id>system-document</filter-id>
  </policy>
  <policy id="no-versioning-for-system-after-update" increment="NONE" order="1">
    <filter-id>system-document</filter-id>
  </policy>
  <policy id="note-as-wiki" increment="MINOR" order="50">
    <filter-id>note-filter</filter-id>
  </policy>
  <policy id="collaborative-save" increment="MINOR" beforeUpdate="true" order="100">
    <filter-id>last-contributor-different-filter</filter-id>
  </policy>
</extension>

<extension target="org.nuxeo.ecm.core.versioning.VersioningService" point="filters">
  <filter id="system-document" class="org.nuxeo.ecm.core.versioning.NoVersioningPolicyFilter" />
  <filter id="note-filter">
    <type>Note</type>
  </filter>
  <filter id="last-contributor-different-filter">
    <schema>file</schema>
    <condition>#{previousDocument.dc.lastContributor != currentDocument.dc.lastContributor}</condition>
  </filter>
</extension>

What happens when you save a document using CoreSession#saveDocument?

  1. Before saving the document in DB, the engine will evaluate no-versioning-for-system-before-update:

    • If its filter matches (here system-document) then no version will be created because policy increment is NONE
    • If the filter doesn't match, next beforeUpdate policy will be evaluated, here collaborative-save: If its filter matches then a MINOR version will be created before saving document in DB. The filter matches if the current document has schema file and previous contributor is not the current one.
    • If it doesn't match collaborative-save, no more policy is found and no versioning is applied.
  2. After saving the document in DB, the engine will evaluate no-versioning-for-system-after-update.

    • If its filter matches (here system-document) then no version will be created because policy increment is NONE
    • If it doesn't match, next after update policy will be evaluated, here note-as-wiki: If document is a Note, a MINOR version will be performed
    • If it doesn't match note-as-wiki, no more policy is found and no versioning is applied.

system-document is a filter used to not automatically version system document such as workspace or document having SystemDocument facet.

Disabling Policy

In order to disable a built-in policy, you can declare the policy in your component with an empty increment.

<!-- Don't forget to require the component defining the policy -->
<require>org.nuxeo.ecm.core.versioning.default-policies</require>
<extension target="org.nuxeo.ecm.core.versioning.VersioningService" point="policies">
  <policy id="note-as-wiki"/>
</extension>

Source-Based

In this example will see how we can leverage the source-based versioning to automatically version document handled by a specific layer.

  1. Define a versioning rule for that:

    <component name="">
     <extension target="org.nuxeo.ecm.core.versioning.VersioningService" point="policies">
       <policy id="my-source-policy" order="20" increment="MINOR">
         <filter-id>my-source-versioning-filter</filter-id>
       </policy>
     </extension>
    
     <extension target="org.nuxeo.ecm.core.versioning.VersioningService" point="filters">
       <filter id="my-source-versioning-filter">
         <condition>#{currentDocument.contextData.source == "mySource"}</condition>
       </filter>
     </extension>
    
    </component>
    
  2. Use this source to trigger an automatic versioning. Note that in a real case we will provide more conditions on the filter.

    • From Java API:

      private CoreSession session;
      
      public DocumentModel updateMyDoc(DocumentModel doc) {
       // do some stuff on documents
       doc.putContextData(CoreSession.SOURCE, "mySource");
       return session.saveDocument(doc);
      }
      
    • From REST:

      curl -XPUT -u Administrator:Administrator http://localhost:8080/nuxeo/api/v1/id/37b1502b-26ff-430f-9f20-4bd0d803191e \
          -H 'Accept: application/json+nxentity' \
          -H 'source: mySource' \
          -d '{
             "entity-type": "document",
             "repository": "default",
             "uid": "37b1502b-26ff-430f-9f20-4bd0d803191e",
             "properties": {
                 "dc:title": "The new title",
                 "dc:description": "Updated via a very cool and easy REST API",
             }
         }'
      
3 days ago Solen Guitter NXDOC-1459: Improve automatic versioning documentation
3 days ago Solen Guitter Fix typos, caps and formatting
24 days ago manonlumeau FG review 2
a month ago Manon Lumeau add tags for doc days
2 months ago manonlumeau Added content-review-lts2017 label
3 months ago manonlumeau NXDOC-1346-FT review screenshot
a year ago Solen Guitter 17
2 years ago Manon Lumeau 16
3 years ago Solen Guitter 15 | Add info about behavior when saving a document without modifying it
3 years ago Solen Guitter 14
3 years ago Alain Escaffre 13
3 years ago Solen Guitter 12 | Removed 5.4 reference and formatting
4 years ago Solen Guitter 11 | Added related topics
4 years ago Solen Guitter 10 | Updated links and terminology
4 years ago Solen Guitter 9
5 years ago Solen Guitter 7
5 years ago Solen Guitter 8 | Migrated to Confluence 4.0
6 years ago Solen Guitter 6 | Updated links to 5.5
6 years ago Solen Guitter 5 | Updated link to 5.5
6 years ago Florent Guillaume 4
7 years ago Florent Guillaume 3
7 years ago Florent Guillaume 2
7 years ago Florent Guillaume 1
History: Created by Florent Guillaume