Sharing symbolic links in Rational Team Concert
Chris McGee, IBM Canada
Last updated: May 24, 2012
Build basis: Rational Team Concert 4.0
What are symbolic links? They live amongst your files and directories on your computer’s file system but they have no contents of their own. Instead, when they are inspected they reveal the contents of a target file or directory. Whenever the contents of the target changes so too does the contents of the symlink. They are also known as soft links or symlinks.
When a symlink is created on your computer all that is kept are the details about the target. For instance, all platforms store the path of the target while the Windows platform stores the target type as well (file/directory). A target path can look like C:compiler-xyzheadersstdio.h or ../../modulexyz/headers. The paths must follow the conventions for file system paths set by the platform. For example, the Windows platform uses "" separate segments in a path while Unix platforms use "/".
Simple Windows file system tree with symlinks
A symlink is completely dependent on its target. If the target cannot be found (no permission, moved, deleted or renamed) then it is considered broken. When it is broken it is not able to show any contents and often produces errors when programs try to access them. On the Windows platform a symlink is also broken if the type of the link (file/directory) does not match the type of the target. Since symlinks can also target other symlinks they are broken if any element in the chain is broken.
Broken file-type symlink in Windows
Broken directory-type symlink in Windows
Broken symlink on Unix
You can think of a symlink as having either absolute or relative target. An absolute target is one that uses the root of the local file system directly to identify the location of a targeted file or directory. It doesn’t matter where the symlink is located in this case because the platform doesn’t take its location into account when trying to find the target item.
c:compiler-xyzheadersstdio.h # Windows - symlink targets the header file at this location /home/cmcgee/xyz/images # Unix - symlink targets the images directory at this location
However, these types of symlinks can be difficult to share with other people if they don’t have the same file system layout as you do. For example, they may not have a drive identified as "H" on their system and your symlink has a target path of H:mycompilerheaders. Also, other people may not be using the same platform. The target path /usr/include may not exist on Windows, for example.
The other kind of symlink target is called "relative." Relative paths use certain anchors that are resolved relative to the parent directory of the symlink itself. For instance, a target path ../dir2 resolves to a directory called "dir2" that is located in the directory above where the symlink is located. If the path doesn’t have any anchors or any slash ( or /) at the start of the path then it is relative to the parent directory where the symlink is located. E.g. dir3/myfile.txt targets a file called "myfile.txt" in a directory called "dir3" that sits beside the symlink.
..module2module2.h # Windows - symlink target the module2.h header file up one directory and over in the module2 directory ../../images/banner.gif # Linux - symlink targets the banner.gif image file up two directories and over in the images directory directory3util.c # Windows - symlink targets the util.c C file of directory3. directory3 is in the same directory as the symlink file.txt # Windows/Linux - symlink targets file.txt beside the symlink in the same directory
Symlinks with a relative target tend to work well when shared with other people because they are not as susceptible to differences in the way that other people’s computers are set up. Relative links are more likely to break with more localized differences in the directory structure such as moving the symlink or a file/directory that it uses in its target.
How useful are symlinks if they can be easily broken? They help to avoid duplication (copy/paste) of file and directory structures by allowing you to link in the file or directory elsewhere. When you change the contents of a file or directory these changes show up immediately without having to update all of the duplicates with that change. If you keep these files and directories in source control then symlinks are especially helpful to avoid duplicate or diverging histories for the same item.
Getting ready for symlinks
On Unix platforms there is no special setup required. You may create symlinks in any directory where you have permissions to write. Also, any program you run has the same capability.
Not all versions of Windows support symlinks. Windows 7, Windows Server 2008 R2 or later are recommended as they have full symlink support. If anyone in your team is using an older version of Windows then symlinks may not be accepted/loaded into their sandbox properly.
On the Windows platform symlinks require you to have a special permission. You need to have this permission in order to create symlinks yourself and Rational Team Concert (RTC) needs it to create symlinks for you. Fortunately, there are two different ways to do this:
- Run the program As Administrator
- Right-click on the program you want to run (e.g. Command Prompt or RTC) and choose the Run as administrator option.
- If this option is not available then request access from your system administrator.
- Add the symlink permission to your user account
- Request that your system administrator give you permission on Local Security Policy > Local Policies > User Rights Assignment > Create symlinks
- Turn off your "User Account Control" (UAC) by going to "User Account Control" in the control panel and turning the big slider down to "Never notify"
- You may need to restart your RTC client for these changes to take effect
Create a team setup guide
In order to help minimize the instances of broken symlinks you should have a document that describes the layout for everyone’s file system. For example, some of your symlinks may assume that a certain compiler is always installed into "C:mycompiler" This assumption should be documented in a setup guide. Other symlinks may contain relative paths that assume that everyone loads a certain Jazz Source Control (SCM) component from their repository workspace in the same sandbox as the symlink. The required Jazz SCM components and their assumed locations in the sandbox should be documented so everyone does it the same way. There are more details on the variety of ways to load Jazz SCM components from a repository workspace into sandboxes in the article Loading Content from a Jazz Source Control Repository.
Adding symlinks to Jazz SCM
Jazz SCM does not provide its own tool to create symlinks on your file system. Instead, you use the built-in command for your platform to create the symlinks in your sandbox. Once the symlink is created Jazz SCM can discover the link and you can check it into a changeset much like how you check in your files and directories.
On the Windows platform the command is called "mklink" and it is invoked using the Windows command prompt. Because Windows has special permissions for symlinks you must either run the command prompt as an administrator or have received the special permission as described in the previous section. You can execute the command as shown in this example.
mklink otherfile.txt ..module2file.txt # Creates a symlink with the file type called otherfile.txt that targets "..module2file.txt" mklink /d otherdir ..module2 # Creates a symlink with the directory type called otherdir that target "..module2"
The "ln" command is available on all Unix platforms. The special "-s" switch must be used in order to create a symlink and not a hard link. You can execute the ln command as shown in this example.
ln -s ../module2/file.txt otherfile.txt # Creates a symlink called otherfile.txt that targets "../module2/file.txt" ln -s ../module2 otherdir # Creates a symlink called otherdir that targets "../module2"
Once your symlink is in your sandbox you may need to refresh in order to show it in your pending changes view. In the RTC Eclipse client you can refresh using the special menu on the top-right of the pending changes view and choose "Refresh Sandboxes and Remote Changes" A similar menu item can be found in the RTC for Visual Studio IDE client. The Windows Shell Explorer client and Command Line Interface (CLI) should discover the symlink automatically. More details on working with external tools can be found in the article Using the RTC Eclipse client with other Tools.
Symlink addition in pending changes view
When the pending changes view shows the symlink you should see that it has a special icon representing symlinks. You can check in the change and deliver as you would with any other type of change. Jazz SCM will check to see if your links are broken and warn you about them. You can accept change sets with symlinks, which creates the symlinks in your sandbox.
It is important to keep in mind that symlinks are managed separately in Jazz SCM from their target. When you check in a symlink it only checks in the symlink and not the target. If you want to share the target file/directory in Jazz SCM you may need to share or check it as well. When you change the shared target contents through a symbolic link the target change will show up in the pending changes view and not the symlink.
If you want to make a change to a symlink then you can delete it from your sandbox using the command prompt and repeat the above steps to create a new one in its place.
Sharing symlinks across platforms
There are differences in the way that symlinks work on different platforms. The Windows platform uses back-slashes (""), while Unix uses forward-slashes ("/"). Also, Windows requires a target type while Unix does not.
Jazz SCM tries to manage the symlinks to help them to work on your platform. One way that it does this is to change the slashes to the correct form whenever it creates symlinks in your sandbox. However, absolute paths from Windows will generally not work on Unix and vice-versa so Jazz SCM leaves those paths unchanged. If a symlink uses a relative-path then Jazz SCM will try to change the slashes.
Sharing a symlink from Windows platform to Unix platform is relatively easy. The type of the symlink (file/directory) is captured along with the target path when you check it in to Jazz SCM. On Unix the type is unnecessary.
However, when a symlink is shared from Unix it does not record the type because the type is not there on that platform. If you are on Windows you may find that the symlink is broken because the target is a directory and not a file. When a link is broken on the Windows platform due to a type mismatch you will often see an "Access Denied" or "The directory name is invalid". Otherwise, you might find that it shows up as a directory with no children or a file that opens with an I/O error.
Jazz SCM has a special property called "directory" for symlinks, which is available on all Jazz SCM clients and platforms. In the RTC Eclipse client you can find the directory property in the properties page of your symlink by right-clicking on it in the Package Explorer or Project Explorer, choosing Properties and clicking on the Jazz Source Control section. You can check this property to set the symlink target type to directory or uncheck to leave it as a file type. On the Windows platform it will update the symlink in your sandbox so you can check to see if it is fixed right away. Whenever you change this property on any platform there will be a new local change in your pending changes view. You can check in and deliver a change to the directory property in order to fix the symlink for the Windows users on your team.
It is very easy to forget about the symlink type when you are working with the Unix platform because your symlinks work fine even without setting the type. There is a preference in RTC that will check for interoperability problems with your symlinks whenever you check them in on any platform: Team > Jazz Source Control > Notification Dialogs > Default action after symlinks have been checked-in with warnings. In this preference you can specify what level of verification you want when you check in your symlinks. This preference is worth mentioning in your team setup guide mentioned earlier and is applicable to both Unix and Windows clients.
Managing symlinks in RTC client for Visual Studio IDE
The RTC client for Visual Studio IDE needs to be refreshed whenever you create symbolic links and want to check them in. You can do this manually through the refresh sandbox context menu on the pending changes view or you can turn on the automatic detection of changes in the filesystem using the preference called Automatically detect when file is changes outside the environment.
Visual Studio client preferences
The RTC client for Visual Studio IDE will warn you about broken symbolic links on checkin much like the way that the eclipse client does. In order to add non-interoperability checks on symbolic links you can turn it on using the preference called Prompt when broken or non-interoperable in the preference page shown above.
The directory property for a symbolic link can be found in the RTC-specific property sheet. If you change the directory property of a symbolic link it will change the symbolic link type in your sandbox and create a pending local change in a very similar way to the eclipse client.
Visual Studio symlink properties
Managing symlinks in RTC command-line client
When using the RTC command-line client (CLI) symlink additions or changes made in your sandbox will appear the next time you invoke the ‘lscm status’ command and can be checked in like any other file or directory.
$ lscm status Workspace: (1074) "MyWorkspace1" <-> (1074) "Stream1" Component: (1075) "Component1" Baseline: (1076) 1 "Initial Baseline" Unresolved: a-- /module1/symlink
When you check in a broken symlink the check in command will report this to you after it finishes. If you provide the "-v" option then it will also report any non-interoperable links:
$ lscm checkin symlink-broken -v Workspace: (1074) "MyWorkspace1" <-> (1074) "Stream1" Component: (1075) "Component1" Baseline: (1076) 1 "Initial Baseline" Outgoing: Change sets: (1133) *--@ "<No comment>" 04-Jun-2012 11:19 AM Changes: --a-- /module1/symlink-broken Interoperability checks failed for symbolic links: /MyTools/symlink-broken Target: /foo/bar/foo Type: file Broken symbolic links for: /MyTools/symlink-broken Target: /foo/bar/foo Type: file
The value of the directory property of the symlink can be found in the list properties subcommand.
$ lscm list properties symlink /home/cmcgee/sandbox/module1/symlink jazz.link-type - file jazz.read-access - Public
If you need to change the type of the symlink then you can use the set property subcommand.
$ lscm property set jazz.link-type directory symlink jazz.link-type successfully set to directory
When you change the type of the symbolic link the change is visible the next time you run the lscm status subcommand and the change can be checked in and delivered the usual way.
$ lscm status Workspace: (1074) "MyWorkspace1" <-> (1074) "Stream1" Component: (1075) "Component1" Baseline: (1076) 1 "Initial Baseline" Unresolved: --p /module1/symlink
In this article you learned about symlinks, also known as symlinks or soft links. Symlinks have a target and on some platforms they have a type (file/directory). The target of a symlinks can be relative or absolute each have different ways that they can become broken. You learned about how you can share symlinks in Jazz SCM in order to avoid duplicated history and/or diverging history for the same files/directories. Symlinks are easily broken but with a good team setup guide and with Jazz SCM’s ability to warn about checking in broken links plus its ability to fix up the slashes on relative paths for different platforms you should find that breakages are less frequent.
For more information
- Loading Content from a Jazz Source Control Repository.
- Using the RTC Eclipse client with other Tools.
About the author
Chris McGee works for IBM and is a member of the RTC Source Control team. Previously, he had worked on UML modeling tools for the IBM Rational Software Architect product.
© Copyright 2012 IBM Corporation