Drawings SDK Developer Guide > Using Drawings Revision Control > Using DRC API
Using DRC API

Using the API for working with Drawings Revision Control (DRC), you can:

  • Import a .dwg database into revision control storage.
  • Check out a revision control database.
  • Create a new branch.
  • Get a list of branches.
  • Get the name of the current working branch.
  • Get the tip of the branch.
  • Commit current changes to a branch.
  • Get information about a commit.
  • Compare branches.
  • Merge branches.
  • Switch to a branch.
  • Switch to a certain revision of a branch.
  • Set (reset) the branch tip to a certain revision.
  • Create a patch.
  • Apply a patch.
  • Export a database to a .dwg or .dxf file.
  • Compress revision control storage.

All of the above features are implemented by a set of functions of the OdTfRevisionControl namespace.

Importing a .dwg Database into Revision Control Storage

To import a drawing database into revision control storage, there are two functions. The first one is used for initially importing a database into newly created empty revision control storage to create a zero revision.

void import(OdStreamBuf* pStream, OdDbDatabase* pDb, const OdString& branch = L"master", const OdTfCommitInfo& message = OdTfCommitInfo());

You can also import a drawing database into existing revision control storage as a new revision, as if you had made a new commit.

void importAsCommit(OdDbDatabase* pDbTo, OdDbDatabase* pDbFrom, const OdString& branch = L"master", const OdTfCommitInfo& message = OdTfCommitInfo());

If it is impossible or undesirable to perform a complete import due to resource limitations, perform a partial import using the beginPartialImport(), writeObjectPartial() and endPartialImport() functions.

Checking Out a Revision Control Database

The checkout() function is used to read a database from the storage or to create a link between an empty database and the storage.

The following function creates a database and updates it from the storage.

OdDbDatabasePtr checkout(OdStreamBuf* strm, OdDbHostAppServices* pHostApp, const OdString& localBranch, const OdString& sourceBranch = L"master", bool partial = false);

The next function creates a link between an empty database and the storage.

void checkout(OdDbDatabase* pDb, OdStreamBuf* strg, OdDbHostAppServices* pHostApp, const OdString& localBranch, const OdString& sourceBranch = L"master", bool partial = false);

Note: A database must be empty and created with default values for all parameters.

The above two functions are basically the same. The sourceBranch parameter defines the branch that the database is checked out from. The localBranch branch is set as current for the commit while the sourceBranch is set as the default for the merge.

Checkout can be full (default) or partial. Partial checkout is similar to .dwg partial file loading, when only several root objects are loaded in memory. If the database has an index to determine the set of objects to load, loading can be accelerated with the loadObjects() function which uses multiple threads.

Creating a New Branch

The resetBranch() function is also used for creating a new branch.

bool resetBranch(OdDbDatabase* pDb, const OdString& branch, const OdTfDigest& sha);

To create a new branch, pass an unused branch name to the function. The name of each branch within a single revision control storage is unique. If no branch with the given name exists, the new branch is created. The function returns true if the new branch was created; false otherwise.

Getting a List of Branches

To get a list of branches, use the following function.

bool getBranchList(OdDbDatabase* pTf, BranchList& list);

This function returns the list of branches from the revision control storage associated with the specified database.

Getting the Name of the Current Working Branch

The working branch is the branch that is set as default for commits. To get the name of the working branch, use the following function.

OdString getCurrentBranch(OdDbDatabase* pDb, OdTfDigest* head = 0);

The function returns the name of the current working branch in the storage of a specified database. Optionally it also returns a hash code of the current working branch.

Getting the Tip of the Branch

You can get a hash code and commit information of the revision on the tip of a specified branch using the next function.

bool getBranchTip(OdDbDatabase* pDb, const OdString& branch, OdTfDigest& sha, OdTfCommitInfo* commit = 0);

The function returns the hash code of the revision on the tip of the branch with the given name. Optionally it also returns the commit information of the revision.

Committing Current Changes to a Branch

Committing is saving changes in the runtime drawing database to the current active branch of the revision control storage as a new revision. Use the following functions to make a commit.

OdTfDigest commit(OdDbDatabase* pDb, const OdTfCommitInfo& message, const OdString& mergeCommitOtherBranch = OdString::kEmpty, OdTfDigest* mergeCommitOtherParent = 0, const OdDbObjectIdArray* objectsToSave = 0);

The function creates a commit object and shifts the current branch tip. By default, a commit is full, meaning that all changed objects are saved in a new revision. A commit can also be partial when not all changed objects are saved. To perform a partial commit, use the objectsToSave optional parameter for listing objects to be saved.

Most merges also need to be committed.

Getting Information about a Commit

To get commit information of a specific revision, use the following function.

OdTfCommitInfo getCommitInfo(OdDbDatabase* pDb, const OdTfDigest& sha);

The function returns commit information of a revision, that has the corresponding hash code, from the storage of a specified database.

Comparing Branches

There are two functions that compare revisions in the storage and compare a revision with the working copy of a database. The first function is designed to get a list of differences between two revisions.

void getRevisionDifference(OdDbDatabase* pDb, const OdTfDigest& newRevision, const OdTfDigest& oldRevision, ChangeList& result);

The function returns a list of handles of the objects that differ between revisions. Revisions can be unrelated.

The other function is designed to get a list of differences between the last revision of the current branch in the storage and a runtime drawing database.

OdDbObjectIdArray getLocalChanges(OdDbDatabase* pDb);

The function returns an array of object IDs that were changed since the last commit.

Merging Branches

Merging is combining two branches into one. To merge changes use the following function.

bool merge(OdDbDatabase* pDb, OdDbHandleArray& conflicts, OdTfMergePolicy mp = kOdTfMergePreferTheirs, const OdString& branch = OdString::kEmpty, bool noFastForward = false);

The function merges changes from the storage to the runtime database. If the branch name is not specified, the source branch for merging is the branch that this database was checked out from (like "git pull"). The merge operation does not automatically commit changes; only the runtime database is changed. So, the commit is needed to save the merge result as a new revision in the storage.

Note: If the merge was fast forward, no merge commit is necessary. Fast forward merging is performed if the current branch originates from the branch that is the source for the merge and no commits were made to the source branch since the current branch was created.

Switching to a Branch

Switching is changing the working branch, i.e. setting another branch as the default for commits. The next function is used to switch between branches.

void switchBranch(OdDbDatabase* pDb, const OdString& branchName, const bool& hard = true);

The runtime database is automatically updated to the revision on the tip of the branch with the specified name. All uncommitted changes are lost if the hard parameter is true (default). Setting this parameter to false prevents the switch if there are uncommitted changes in the database. If you need to switch to a revision that is different from the revision on the tip of the destination branch, use the resetBranch() function to switch between revisions.

Switching to a Specific Revision of a Branch

To switch to a specific revision of a branch, simply switch to the branch using switchBranch() and then set the branch tip to the required revision using resetBranch().

Note: Passing a non-existent branch name to resetBranch() when setting the branch tip creates a new branch with a tip that has the corresponding hash.

void switchBranch(OdDbDatabase* pDb, const OdString& branchName, const bool& hard = true);
bool resetBranch(OdDbDatabase* pDb, const OdString& branch, const OdTfDigest& sha);

Setting the Branch Tip to a Specific Revision

To set (or reset) a branch tip to a specific revision, use the resetBranch() function.

bool resetBranch(OdDbDatabase* pDb, const OdString& branch, const OdTfDigest& sha);

The branch name given as a parameter for the function must match the name of an existing branch; or the sha parameter must match the hash of an existing revision.

Note: If no other branch points to the revision that is the current branch tip, and you don't have it saved, it may become inaccessible.

Creating a Patch

A patch is a set of changes between two revisions. To create a patch, use the following function of the revision control API:

OdStreamBufPtr makePatch(OdDbDatabase* pDb, const OdTfDigest& from, const OdTfDigest& to);

Applying a Patch

There are two functions in the API for applying a patch:

void applyPatch (OdDbDatabase* pDb, OdStreamBuf* s, const OdString& branch);
void applyPatchViaBranch (OdDbDatabase* pDb, OdStreamBuf* s, OdDbHandleArray& conflicts, OdTfMergePolicy mp, const OdString& sourceBranch, const OdString& localBranch = OdString::kmp)

The applyPatch() function fails if the branch tip is not at the same revision as the patch start (specified in the from parameter of the makePatch() function). See below.

The applyPatchViaBranch() function can be used if the tip of the branch does not match the start parameter of the patch (specified in the from parameter of the makePatch() function). The applyPatchViaBranch() function creates a temporary branch with a tip equal to the revision specified in the from parameter of the makePatch() function. After that, the patch is applied to the temporary branch which is then merged into the original branch, as shown next.

Exporting a Database to a .dwg or .dxf File

Every revision of the database in the storage can be exported as an ordinary drawing file in .dwg or .dxf file format. Just switch to the required revision and use one of the following two functions.

void exportDwg(OdDbDatabase* pDb, OdStreamBuf* pStreamBuf, OdDb::DwgVersion fileVersion, bool saveThumbnailImage = false);
void exportDxf(OdDbDatabase* pDb, OdStreamBuf* pStreamBuf, OdDb::DwgVersion fileVersion, bool saveThumbnailImage = false, int dxfPrecision = 16);

Note: Direct use of OdDbDatabase::writeFile() to save the database to a file breaks the link between the database and the revision control storage.

Compressing the Revision Control Storage

In the initial, non-compressed state, each revision in the storage contains full state stamps of objects that were changed. Compression reduces the size of the storage by removing the full state object stamps and replacing them with the information containing the differences of the object from the previous revision (called deltas). To compress the revision control storage, use the following function:

void compressRevisionData(OdDbDatabase* pDb, OdUInt16 referenceDistance = 10, const bool auditCompressedData = true);

Some of the revisions in the storage remain uncompressed after compression. They are called reference revisions. This is intended to reduce the number of processed revisions to restore the required state of the database, and therefore increase the speed of switching between revisions. The distance between neighboring reference revisions can be adjusted by altering the referenceDistance parameter. To reduce the resulting size of the storage, increase the parameter value. To reduce switching time, reduce the parameter value.

There is a built-in mechanism for the compression verification. It is intended to ensure that the compression does not corrupt the storage and cause loss of data. It restores the newly compressed revision and compares the result with the original. Since this operation takes computing resources and increases the time required to perform compression, it can be turned off by setting the auditCompressedData parameter to false.

See Also

Copyright © 2002 – 2021. Open Design Alliance. All rights reserved.