Chapter 1: What is an Xlink
Projects often need to reuse existing components that have been developed and are actively used as part of other projects. Plastic SCM encourages using separate repositories for different projects and components, and access shared components by "mounting" them in the project repository through Xlinks. This chapter will introduce what are Xlinks and how to use this powerful feature to share components among projects that evolve in parallel.
An Xlink is pretty similar to a symbolic link, like those found in Unix operating systems. It is a directory entry in your repository tree that points to another directory in a different repository. An Xlink, however, will also contain information about the specific version of the target directory to which it is pointing.
Xlinks can point to repositories with other Xlinks inside them, so Xlink component mounting can address really complex development scenarios.
Xlinks pointing to a given version of the target directory let the user specify, for instance, that project X on version 1.1 is using version 2.1 of library Y. When a new version of the library is labeled, say 2.2, the code of the project can be updated to use it and maybe version 1.2 of project X uses library Y 2.2.
Since Xlinks are versioned, the Xlink in old project X version 1.1 still points to library Y 2.1 and the original configuration can be completely rebuilt without any issue. The following figure depicts how it looks like:
Chapter 2: Creating and Modifying Xlinks
An Xlink is defined using the Plastic SCM command line client, through the xlink command. An Xlink is
defined with at least two arguments:
The directory entry to create in the current repository. This is a directory that will be used to.
The directory to mount in the target repository. You can Xlink not only to the root of another
repository, but also to any directory path inside by mounting a "subtree" on the parent repo as
Partial Xlinks are available on Read-only Xlinks (see below).
"Writable partial Xlinks" are not supported yet because they would overly complicate the merge (what if you
have conflicts on parts you are not mounting?).
Remarks: At this point, you need to use the
command line to create partial Xlinks. GUI support will
Restrictions: This restriction only applies to the
Plastic Gluon client. It is not recommended to use the
'partial readonly Xlink' feature in Gluon workspaces where multiple Xlinks pointing to the same repository
are loaded. The reason is that Gluon workspaces use a single cache per repository, so if there are multiple
Xlinks pointing to the same path with different root paths, it can potentially lead to weird issues.
The version and repository to mount at point 1 above. The version of the directory to mount is
specified using either a changeset specification or a label specification.
You can create two different types of Xlinks, depending on what you want to do with the target repository:
Read-only Xlinks - Are recommended for situations where you are the user of an existing
component, but you don't influence its development. In the sample above, you were Xlinking an existing
library and only calling it from your project, but not making any changes to it.
Writable Xlinks - On the other hand, let you make changes inside the Xlinked repository.
You'll notice in the Workspace Explorer of the GUI client that the Type column contains
wXlink where it used to be Xlink for read-only Xlinks.
Creating an Xlink using the command line
The command used to create the Xlink in the sample referred in section
What is an
looks like this:
cm xlink component1 / 1@mylibrary
In the exmample above:
component1 is the directory in the project repository that will point to the mounted
mylibrary component. This directory must not exist already in the repository. The xlink
command will create an item for it and it will throw an error if a file of directory already existed with the
- / is the directory in the target repository, as described above.
- 1 is the changeset number in the target repository.
mylibrary is the target repository. Together with the changeset it forms a changeset
specification. In this case, there is no server specified. If the server is to be specified, the
spec would look like this: 1@mylibrary@servername:8087
It is also possible to specify a label instead of a changeset. Since a label is actually a pointer to a changeset,
the two specifications are interchangeable. To do so keep in mind that specifying an xlink with a label only uses
the label to retrieve the changeset to which it points and sets the xlink to it. This means that if the label is
moved afterwards, the Xlink will still point to the original changeset.
To create a partial Xlink (read-only):
cm xlink component1Src /src/dll cs:478@mylibrary
where /src/dll is the subdirectory where the partial Xlink will be mounted.
You can create a Writable Xlink in the command line specifying the -w modifier:
cm xlink -w component1 / 1@mylibrary
To get further information about how to create an Xlink in the Command Line, refer to the command line interface
and use the cm help xlink command.
Creating an Xlink using the GUI
Xlinks can not only be created from the command line. They can be created from the GUI client that Plastic SCM
provides. You'll note the new option in the Workspace Explorer context menu:
Remember that, at this moment, partial Xlinks must be created only from the command line.
You can create an Xlink by right-clicking any directory or existing Xlink and selecting the
Create Xlink option. It will create a new Xlink inside the selected directory.
This is how the new dialog looks like:
In this dialog, you can configure the name of the Xlink and the target changeset of the Xlink. To select the target
changeset, you have to:
- Select the target Plastic SCM server
- Then, a repository inside that server,
- And finally, a changeset in the repository.
In this dialog box, you can also set the Writable and Relative
server options for the Xlink. And also the expansion rules if you
are creating a writable Xlink.
Updating an Xlink
The Xlink is created in the workspace and appears as a pending change in the Pending Changes View
(or cm status --added command), as depicted in the following figure:
Once it is checked in, the Xlink needs to be updated. So, the contents of the mounted directory are downloaded into
the workspace. This can be done in the GUI by clicking the Update workspace button:
Modifying an Xlink using the command line
The target of an existing Xlink can be modified using the -e modifier of the xlink command.
In this case, the syntax is similar to the creation syntax. But the Xlink must exist already.
The following example modifies an existing Xlink component1 to point to changeset 5 on
cm xlink -e component1 / 5@mylibrary
To get further information about how to modify an Xlink in the Command Line, refer to the command line interface
and use the cm help xlink command.
Modifying an Xlink using the GUI
Xlinks can also be modified by using the Plastic SCM GUI client. When you right-click an existing Xlink, the
following context menu will pop up:
When you click the Edit Xlink option, a dialog box will pop up:
You can edit the target changeset of the Xlink. You can also edit the
expansion rules if you are modifying a writable Xlink.
Exploring the Xlinked repository
The Plastic SCM GUI views display the information of the top-level repository loaded in the workspace. But, what if
you want to see the Branch Explorer or the Changesets views of an Xlinked repository?
The Workspace Explorer makes this easy through the Repository submenu. When you right-click
an item inside an Xlinked repository, the Repository submenu lets you open the most
important views for the repository where the item is located: i.e. the Xlinked repository. For your convenience,
the first entry in the menu contains the repository name of the item:
Chapter 3: Xlink Expansion Rules
The Xlink Expansion Rules define how branches are created on the Xlinked repositories, and how
the branches in the parent repository relate to the branches in the Xlinked repository.
Xlink created in top level branch
The regular scenario is very simple. The developer defines a new Xlink from the quake repo to the
zlib repo. They set the wXlink between changesets on the main branches of each repo.
The expansion rule for the wXlink at this point will be very simple:
Since the two Xlinked changesets are on branches with the same name and the same level (top level branches in this
case), expanding the wXlink is very simple as explained below:
Now, the developer creates a branch task001 to implement a new feature.
Then, the developer modify the file /src/foo.c that is inside the wXlink, so it's stored inside the
Because the developer is using a writable Xlink, the branch auto-expansion mechanism of Xlinks
will create a new branch main/task001@zlib as follows:
At this point, the expansion rules will be as follows:
Please note how a new rule has been automatically created by Plastic
( Is defined by user = No ) to track the new branch expansion that happened.
New automatically created rules will be created if more branches are automatically expanded through the branch
Adding an Xlink on a second level branch
Consider now the following very common example. Suppose you have to create a new wXlink, but you create a task
branch to do the job. So, you're isolated while you test the new layout and it will be merged later to main.
Your scenario will be as follows:
In this situation, you don't really want to create an Xlink expansion rule from
main/xlink-creation@quake -> main@zlib nor this rule to set how branches are created on the Xlinked
repo. Most likely what you want to do is eventually Xlink the main branches.
Plastic SCM will detect this situation and will inform you as follows:
And will create a rule main@quake -> main@zlib:
Now suppose that just after creating the wXlink on the branch task001, you need to modify a file
inside the wXlink. Since the main to main wXlink is already defined, the branch expansion will
work correctly and will automatically create a /main/xlink-creation branch inside the
And the expansion rules at this point will be as follows:
Creating asymmetric Xlink hierarchies
So far the created wXlinks have been symmetric: main linked to main, main/task001 to main/task001 and so on.
Expansion rules are especially helpful when asymmetric links are required. Suppose you need to link the branch main@quake to branch main/fix@zlib. The initial expansion rule will be set this way, and it will enable a parallel asymmetric evolution like the following picture shows:
The initial versions of Plastic SCM with Xlink support didn't include Xlink expansion rules. The expansion was controlled by matching branch names, so while simple asymmetric hierarchies were supported, complex cases were not. Consider the following example:
That will be handled in the following way now:
Advanced expansion cases
Some projects need to set more than one Xlink to the same repository, maybe because they depend on two different
versions of the same component.
Consider the following example:
The erp repo Xlinks twice to the zlib: one for the server code that uses the
most up-to-date 1.9 version of zlib, and one for the iphone code that uses the older
(Note: the erp project could be structured on a different way, maybe dividing the server and client on
different repositories, but this is not the goal of this explanation).
Once the Xlinks are setup, let's inspect /server/zlib:
Please note how the Is defined by user is set to true. In Plastic
internals jargon, this rule is a traveling rule which means: it doesn't apply to the current branch and
has to travel to the final one (like when you create a rule in /main/task001 for
, it has to travel to main during the merge) or it hasn't been applied yet.
Consider now the situation where you make a change inside /server/zlib. The situation will be:
Where the /server/zlib wXlink has been updated to point to the newly expanded branch
main/server@zlib while the other wXlink hasn't been modified yet.
At this point, if you edit the wXlink /server/zlib, you'll see the rule has been modified and it is
now as follows:
The rule now directly applies to the branch association so it is not considered anymore as a traveling rule
(or defined by user).
This is a complex scenario and understanding how it works helps to get a deeper understanding of Xlink branch
Initially an Xlink is created from main@erp to main@zlib with a rule
main -> main/server (main/server branch is still empty):
Then the developer creates main/task001@erp and makes a change inside wXlink.
Please note how the branch expansion doesn't happen as initially expected only because main/server is
empty and it doesn't contain changesets to start /main/server/task001 from, so
main/task001@zlib is created instead:
Now the developer merges main/task001@erp back to main and the following happens
(now the rule is used as expected). The rule defined by the user is finally used when the correct conditions are met:
Chapter 4: Merging links
Merging a branch also affects the auto-expanded branches in the wXlinked repositories. The merge operation is done on the top-level repository (the repository to which the workspace is pointing to). It will then evaluate any new versions of wXlinks that have been created and consider the changes in the linked repositories in the merge process as well.
In this sample scenario, we have the same 2 repositories we used in previous sections: ProjectX and MyLibrary. ProjectX is the top-level repository and contains a wXlink component1 pointing to MyLibrary. In ProjectX we have created two child branches: task0127 and task0243.
We then made changes in the file events.h, located in the Xlinked MyLibrary repository in both branches. This, indeed, expanded branches task0127 and task0243 to the MyLibrary repository:
Now, what happens when you try to merge from branch task0127 to branch task0243, as depicted in the figure below?
The merge operation will consider the changes made to the wXlink in both branches and then evaluate the changes in the wXlinked repositories themselves to include them in the merge. So, as a user, you'll have to resolve any possible conflicts as you would with a normal "single repository" merge.
Now the merging of Form1.cs is resolved but, what about the wXlink? The answer is that the merge operation will also update the WXlink to point to the result of the merge in the MyLibrary repository. That is, as a result of the merge operation, there is a new version of Form1.cs with the merged changes, and the WXlink in the ProjectX repository will point to this new changeset. For this reason, the Pending Changes view shows a pending merge link for the ProjectX repository, as depicted in the next figure:
The overall result is that you only need to tell Plastic SCM "I want to merge this branch" in your workspace, and the merge operation will handle the changes made in wXlinked repositories.
Chapter 5: Relative Xlinks
When Xlinks are replicated, the target they point to is still the original one. So, say that you are replicating a repository with an xlink component1 pointing to changeset number 6 on repository MyLibrary on server mainserver.location1.com:8087. The destination of your replica is on another Plastic SCM server at otherserver.location2.com:8087. When you replicate the top-level repository, the Xlink in your replicated repository will still point to mainserver. If it is reachable from the location2.com network, the data for MyLibrary repository will be downloaded from location1.com.
Most of the time, you'll want to replicate the MyLibrary repository to location2.com as well, and perform any changes in the local replica.
To tell the Xlink that you want to use the MyLibrary repository found in your default server (that of the top-level repository), you need to create the Xlink with a relative server.
This is achieved with the -rs modifier when the Xlink is created, as in the following example:
cm xlink -rs component1 / 6@mylibrary
When this link is replicated, it'll try to locate MyLibrary repository in the local server, rather than mainserver.location1.com.
Note that changeset number 6
may no longer have number 6
in the replicated repository (changesets are internally identified by their GUID, not their number, since replicas may have different numbering.
The Xlink will be pointing to the right changeset even if the number changes, because it uses the changeset GUID rather than the changeset number to locate it.
Read the Plastic SCM book to learn how replication works.
January 21, 2019
- We updated the screenshots related to the Xlink dialogs to show how they look like now.
We also included some notes to remark that you can only manage expansion rules when you are creating or
editing writable links.
April 10, 2019
Specify that we only support partial Xlinks pointing to directory paths.
December 17, 2016
Partial readonly Xlinks are now available.