Getting Started With the Jazz SCM Command Line Interface
This article provides an introduction to the basic concepts and commands in the Jazz SCM command line tool. We will walk through a basic workflow that covers the typical set of activities performed by a developer in order to work on a project. Readers are expected to be familiar with Jazz source control concepts. If not, you can refer to Jazz Source Control: Design Objectives and Getting Started with Jazz Source Control articles which will help you to get started.
Prerequisites
This article assumes that the following steps have been completed:
- Rational Team Concert is installed on the client and server
- Jazz server is up and running
- Project areas and Team areas have been created
- Users have been created and given appropriate set of privileges
If you do not have the client and server running please refer to the Installing Rational Team Concert guide. After that, refer to the Jazz Tutorial on how to set up the project area and team area for a team.
Basic workflow
The scm tool can be found at <rtc install dir>/jazz/scmtools/eclipse. To launch the scm tool run either scm or lscm. lscm is a launcher/wrapper for scm and starts a daemon process so that subsequent execution of commands consumes less startup time. Run ‘lscm help’ to display the list of subcommands supported by the scm tool.
The first thing we need to do is to connect to a repository where we would create our workspaces.
~$ lscm login -r https://localhost:9443/jazz -n local -u ADMIN -P ADMIN
Logged in to https://localhost:9443/jazz
The -r/--repository option is the repository we are connecting to and -n/nickname option is the nickname of the repository. Here on going forward we will use the nickname in all our operations. As shown, we authenticated using the username/password but the login subcommand also supports --password-file, --certificate, --smartCard, --kerberos and --integratedWindows options if the jazz server is setup for the corresponding authentication.
To start working on a project we need to create a workspace that flows to our team’s stream. Let us start by creating a workspace in the repository named Workspace1 which will flow to the stream named Stream1.
~$ lscm create workspace -r local -s Stream1 Workspace1
Workspace (4819) "Workspace1" successfully created
To load the created workspace to our local file system, let us create a directory named sample and load the workspace into this directory.
~$ mkdir sample
~$ cd sample
~/sample$ lscm load -r local --all Workspace1
Successfully loaded items into the sandbox.
The --all option loads all the components of this workspace. In our example there is only one component Comp1 and the component has a folder named src with two files in it (index.html and cmd.java).
Let us say that we have a task assigned to modify one file (say index.html) and add a new file (say config.ini) to the component. Once we do those changes, we can confirm the changes by running the show status subcommand.
~/sample$ lscm show status
Workspace: (4819) "Workspace1" <-> (4816) "Stream1"
Component: (4818) "Comp1"
Baseline: (4825) 1 "Initial Baseline"
Unresolved:
a-- /src/config.ini
-c- /src/index.html
The status flag “a” signifies addition and “c” signifies content change. An important point to note here is that the show status subcommand by default scans the local file system for new changes with that in the repository. This could be an expensive operation if we have a very large number of files/folders in our workspace and we ran this subcommand from the root of the sandbox. We can limit the scan to a component level by running the subcommand within the component folder. To list the changes without performing the file system scan, use the -N/--no-local-refresh option.
Now, if we want to take a look at what were the changes that we made in index.html i.e., the difference between the local version of the file and the version in the repository, we can use the diff subcommand.
~/sample/src$ lscm diff -r local file index.html
diff -u -N src/index.html src/index.html
--- src/index.html 2010-11-10 12:00:36.000000000 +0530
+++ src/index.html 2010-11-10 12:08:38.000000000 +0530
@@ -6,6 +6,7 @@
<body>
<div>
<a href="/intl/en/about.html">About IBM</a>
+ <a href="/intl/en/location.html">IBM locations</a>
</div>
</body>
The “+” indicates we have added a new line in index.html. The output of diff subcommand is displayed in unified diff format.
After we have verified our changes and are happy with it, we will go ahead and commit all the changes made in the component using the checkin subcommand.
~/sample/src$ lscm checkin .
Workspace: (4819) "Workspace1" <-> (4816) "Stream1"
Component: (4818) "Comp1"
Outgoing:
Change sets:
(4827) -*--@ "<No comment>" 24-May-2017 03:08 PM
Changes:
--a-- /src/config.ini
---c- /src/index.html
A new outgoing change set (alias 4827) is created and the changes are included in that change set. What this means is that the changes have been uploaded to the repository but still not available to other members of the team. The “@” after the alias signifies that the change set is active and we can still modify it. Suppose we have a lot of changes in the component but want to checkin only a few changes, we could specific the paths to those items directly in the checkin subcommand.
Once we are done with our change, we can set the comment, complete the change set to indicate that we are done with the change set and associate a work item (say workitem number 101) to the change set for traceability.
~/sample$ lscm set changeset 4827 --comment "Modified index.html and added a new file config.ini" --complete
Change set comment has been set and marked as complete successfully.
~/sample$ lscm add workitem 4827 101
Link created.
The final step is to deliver the change from our workspace to the stream so that the changes are available to all the team members of the project.
~/sample$ lscm deliver
Delivering changes:
Repository: https://localhost:9443/jazz/
Workspace: (4816) "Stream1"
Component: (4818) "Comp1"
Change sets:
(4827) ----$ "Modified index.html and added a new file config.ini" 24-May-2017 03:19 PM
Changes:
--a-- /src/config.ini
---c- /src/index.html
Work items:
(4828) 101 "Define sprints/iterations"
The deliver command completed successfully.
If no options have been specified to the deliver subcommand, it will deliver all the changes from all the components to the stream. To deliver all the changes from a specific component use the “-C/--components” option or to deliver baselines use the “-b/--baselines” option or to deliver specific change sets use the “-c/--changes” option or to deliver work items use the “-W/--workitems” option.
Updating the workspace
In a project, team members will be working on changesets and delivering these items to the stream. We need to be always in sync with the stream so as to ensure that we are working with the latest copy of the code. Let us suppose that there were some changes made by another developer (say userB) in the src folder. To check whether our copy is up to date with that of the repository, we need to run the show status subcommand.
~/sample$ lscm show status -C
Workspace: (4819) "Workspace1" <-> (4816) "Stream1"
Component: (4818) "Comp1"
Baseline: (4825) 1 "Initial Baseline"
Incoming:
Change sets:
(4829) ----$ userB "new change from developer B" 24-May-2017 03:33 PM
Changes:
---c- /src/cmd.java
--d-- /src/config.ini
As we see, there is one incoming change set (alias 4829) with 2 changes in it. The “-C/--xchangeset” option in the show status subcommand implies that the change set information be expanded to include the changes without which it will only show the change set header information. In the output, the status flag “d” signifies that the file was deleted. To get the latest from the repository, we use the accept subcommand.
~/sample$ lscm accept
Accepting changes:
Repository: https://localhost:9443/jazz/
Workspace: (4819) "Workspace1"
Component: (4818) "Comp1"
Change sets:
(4829) ----$ userB "new change from developer B" 24-May-2017 03:33 PM
Changes:
---c- /src/cmd.java
--d-- /src/config.ini
The accept command completed successfully.
Similar to the deliver subcommand, the accept subcommand can accept changes from specific components or baselines or change sets or work items into the workspace.
Suppose we want to update our workspace from another stream, we do this by changing our workspace target flow to the new stream. After we change the target flow, we may see incoming and outgoing changes between our workspace and the target stream if there are any.
In our example, let us say developer B is working on task that is not yet delivered to the stream but would like us to test that task/change. We have to first change the Workspace1 target flow (which is currently set to Stream1) to the developer B’s workspace which is let us say Workspace2.
~/sample$ lscm set flowtarget Workspace1 Workspace2
Target changed.
~/sample$ lscm show status
Workspace: (4819) "Workspace1" <-> (4828) "Workspace2"
Component: (4818) "Comp1"
Baseline: (4825) 1 "Initial Baseline"
Incoming:
Change sets:
(4935) ----$ userB "<No comment>" 24-May-2017 03:44 PM
Notice that Workspace1 now flows to Workspace2 and we see an incoming change that developer B had created in Workspace2. We can now accept this change and test that functionality. Once we are done with our testing we can change our target flow back to Stream1. If the change is localized to a particular component, we can also change the target flow of individual components using the -C/--component option of set flowtarget subcommand.
Resolving conflicts
Let us consider a scenario where there is a new incoming change (by userB) from the stream and there is also an outgoing change from our local workspace both modifying the same file. In this case, there is a conflict between the incoming change and the outgoing change that has to be resolved. The show status subcommand below shows that there is a potential conflict.
~/sample$ lscm show status -C
Workspace: (4819) "Workspace1" <-> (4828) "Workspace2"
Component: (4818) "Comp1"
Baseline: (4825) 1 "Initial Baseline"
Outgoing:
Change sets:
(4840) -*!-@ "<No comment>" 24-May-2017 05:02 PM
Changes:
!--c- /src/cmd.java
Incoming:
Change sets:
(4839) --!-$ userB "new change from developer B" 24-May-2017 03:44 PM
Changes:
!--c- /src/cmd.java
~/sample$ lscm accept
Accepting changes:
Repository: https://localhost:9443/jazz/
Workspace: (4819) "Workspace1"
Component: (4818) "Comp1"
Change sets:
(4839) ---#$ userB "another change from dev B" 24-May-2017 03:44 PM
Changes:
-#-c- /src/cmd.java
Following workspaces still have conflicts after accept:
Workspace1
Run 'lscm resolve conflict' or 'lscm show conflicts' or 'lscm show status' for help in resolving the conflicts.
The “!” signifies that the incoming change has a potential conflict with the local resource and “#” signifies that accepting the incoming change set caused a conflict and needs to be resolved.
To get more details on the conflicts, we can use the show conflicts subcommand. To list the local contents of the file use the -m/--mine option, to list the contents of the file in the incoming change use the -p/--proposed option and to list the original contents of the file use the -a/--ancestor option.
~/sample$ lscm show conflicts
Conflicts:
Cc- /src/cmd.java (Modified <-> Modified)
Problem running 'show conflicts':
Unresolved conflicts remain.
~/sample/src$ lscm show conflicts -m cmd.java
Content:
import java.io.File;
public class Cmd {
public void Cmd() {
}
public int run() {
return 2;
}
public int doSomething() {
return 0;
}
}
Properties:
jazz.encoding - Cp1252
jazz.executable - false
jazz.line-delimiter - Platform
jazz.mime - text/plain
~/sample/src$ lscm show conflicts -p cmd.java
Content:
import java.io.File;
public class Cmd {
public void Cmd() {
}
public int run() {
return 2;
}
public int newMethod() {
return 1;
}
}
Properties:
jazz.encoding - Cp1252
jazz.executable - false
jazz.line-delimiter - Platform
jazz.mime - text/plain
We can have user properties for files and folders. The resolve conflict subcommand behaves the same way whether it is for content conflicts or property conflicts.
It is important to note that accepting the changes will merge all non-conflicting regions automatically. To disable auto-merge, use the --no-merge option in the accept subcommand. If we choose to merge manually, we can use the -i/--in-place-markers option to mark the conflicted regions in the file. In our above example, if we had used the -i option, the merged file will have the following content:
import java.io.File;
public class Cmd {
public void Cmd() {
}
public int run() {
return 2;
}
<<<<<<< mine
public int doSomething() {
return 0;
}
=======
public int newMethod() {
return 1;
}
>>>>>>> proposed
}
To resolve the conflicts, we have to run the resolve conflict subcommand with either the -c/--checkedin option to retain our change or -p/--proposed option to accept the incoming/proposed change. We choose to retain our change. Note: If the files were manually updated check in the changes before resolving the changes.
~/sample/src$ lscm resolve conflict --checkedin cmd.java
Conflicted items have been successfully resolved.
Working on multiple tasks
Let us suppose we were working on a task and we are interrupted with the arrival of a critical defect that needs to be fixed immediately. To start working on the new defect we have to put our current changes in a pending/suspended state and this can be accomplished by using the suspend subcommand.
~/sample$ lscm show status -C
Workspace: (4819) "Workspace1" <-> (4816) "Stream1"
Component: (4818) "Comp1"
Baseline: (4825) 1 "Initial Baseline"
Outgoing:
Change sets:
(4940) -*--@ "<No comment>" 24-May-2017 05:54 PM
Changes:
---c- /src/cmd.java
---c- /src/index.html
~/sample$ lscm suspend 4940
Change sets successfully suspended.
~/sample$ lscm show status
Workspace: (4819) "Workspace1" <-> (4816) "Stream1"
Component: (4818) "Comp1"
Baseline: (4825) 1 "Initial Baseline"
Suspended:
Change sets:
(4940) ----@ "<No comment>" 24-May-2017 05:54 PM
As we can see, the current change has been suspended. After we have completed and delivered the critical defect, we can resume our earlier suspended change by using the resume changeset subcommand. Resuming a suspended change could create conflicts and can be resolved by using the resolve conflict subcommand.
~/sample$ lscm resume changeset 4940
Resuming change sets:
Repository: https://localhost:9443/jazz/
Workspace: (4819) "Workspace1"
Component: (4818) "Comp1"
Change sets:
(4940) ----@ <No comment> 24-May-2017 05:54 PM
Changes:
---c- /src/cmd.java
---c- /src/index.html
If we forgot what changes we made in the earlier task, we can use the diff subcommand to diff all the changes in the change set. The diff subcommand not only supports comparing files and change sets but also between workspaces, streams, baselines or snapshots. In our example we had modified two files and the difference for those two files is shown below.
~/sample$ lscm diff -r local changeset 4940
diff -u -N src/cmd.java src/cmd.java
--- src/cmd.java 2010-11-11 15:39:46.000000000 +0530
+++ src/cmd.java 2010-11-12 11:36:37.000000000 +0530
@@ -8,4 +8,7 @@
public int run() {
return 2;
}
+
+ public void doSomething() {
+ }
}
diff -u -N src/index.html src/index.html
--- src/index.html 2010-11-10 12:08:38.000000000 +0530
+++ src/index.html 2010-11-12 11:52:20.000000000 +0530
@@ -6,7 +6,7 @@
<body>
<div>
<a href="/intl/en/about.html">About IBM</a>
- <a href="/intl/en/location.html">IBM locations</a>
+ <a href="/intl/en/locations.html">IBM worldwide locations</a>
</div>
</body>
History and Compare subcommand
The history subcommand is used to examine the history of a single file or of a component in the repository workspace or of a workspace/stream. In each of these cases, what is shown is a list of change sets, in reverse chronological order according to when each change set was added to the workspace or stream. For the history of an individual file, the change set list contains only those change sets affecting that file.
~/sample$ lscm history src/index.html
Change sets:
(4940) ----$ "<No comment>" Created By: ADMIN (24-May-2017 05:54 PM) Added By: ADMIN (24-May-2017 05:54 PM)
(4827) ----$ "Modified index.html and added a new file config.ini" Created By: ADMIN (24-May-2017 03:08 PM) Added By: ADMIN (24-May-2017 03:08 PM)
(4820) ----$ "<No comment>" Created By: ADMIN (24-May-2017 02:45 PM) Added By: ADMIN (24-May-2017 02:45 PM)
~/sample$ lscm history
Change sets:
(4941) ----$ "<No comment>" Created By: ADMIN (24-May-2017 05:58 PM) Added By: ADMIN (24-May-2017 05:59 PM)
(4940) ----$ "<No comment>" Created By: ADMIN (24-May-2017 05:54 PM) Added By: ADMIN (24-May-2017 05:54 PM)
(4939) ----$ "Merges" Created By: userB (24-May-2017 05:07 PM) Added By: ADMIN (24-May-2017 05:08 PM)
(4830) ----$ "<No comment>" Created By: ADMIN (24-May-2017 04:33 PM) Added By: ADMIN (24-May-2017 04:33 PM)
(4831) ----$ "<No comment>" Created By: ADMIN (24-May-2017 04:08 PM) Added By: ADMIN (24-May-2017 04:08 PM)
(4829) ----$ "new change from developer B" Created By: userB (24-May-2017 03:33 PM) Added By: ADMIN (24-May-2017 03:36 PM)
(4827) ----$ "Modified index.html and added a new file config.ini" Created By: ADMIN (24-May-2017 03:08 PM) Added By: ADMIN (24-May-2017 03:08 PM)
(4820) ----$ "<No comment>" Created By: ADMIN (24-May-2017 02:45 PM) Added By: ADMIN (24-May-2017 02:45 PM)
(4946) ----$ "Initial for Comp1" Created By: ADMIN (24-May-2017 02:34 PM) Added By: ADMIN (24-May-2017 02:34 PM)
Notice that there are more number of change sets in the component history listing as we had couple of operations that were not related to index.html (such as added/modified cmd.java file).
Suppose we want to see the differences between two repository objects such as workspaces, streams, baselines or snapshots, we would use the compare subcommand. In our example, let us assume that we have one outgoing change in our workspace and developer B has created two new changes and a baseline in Workspace2. We can see the difference between our workspace (Workspace1) and developer B’s workspace (Workspace2) as follows:
~/sample$ lscm compare -r local workspace Workspace1 workspace Workspace2
Outgoing Changes
Component (4818) "Comp1"
(4944) ADMIN <ADMIN> <No comment> 2010/11/18
Incoming Changes
Component (4818) "Comp1"
Baseline (4949) 2: Baseline10 ADMIN <ADMIN> 2010/11/18
(4947) userB <userB> <No comment> 2010/11/18
(4948) userB <userB> <No comment> 2010/11/18
The compare subcommand has -I/--include-types option which can filter out what to display in the output. For example, to display only workitems we could use -I w or to display only files from all the change sets we could use -I f. The -I f is particularly useful in scenarios where we want to find out what files got changed between two builds (usually differences between two build snapshots of the workspace/stream).
~/sample$ lscm compare -r local -I f workspace Workspace1 workspace Workspace2
/src/cmd.java
/src/index.html
Terminology
Below you can find the meaning of a few key notations/terms that is used in the scm tool.
Status flags
Several scm subcommands display the status of change sets and changes (files and folders) using the characters shown in the table below.
Flag | Status |
---|---|
* | The change set is current |
@ | The change set is active |
# | The incoming resource conflicts with the version of the resource in the repository workspace |
! | The incoming resource has a potential conflict with the resource in the repository workspace |
$ | The change set is completed |
a | The resource has been added |
c | The content of a file have been modified |
p | The properties of a file/folder have been changed |
d | The resource has been deleted |
m | The resource has been renamed or moved |
A | The change can be automatically merged |
C | Manually merge the conflict |
I | Apply other dependent changes or conflicts |
G | There is a gap related to this change |
M | A new (merged) change set that is created in a merge gap scenario |
S | The original (source) change set that is accepted at the start of a merge gap scenario |
l | The incoming and outgoing change sets are linked |
> | The current port target. All of the changes being ported are targeted for this change set |
UUIDs and aliases
Many scm subcommands take an argument that refers to a repository object. These references can take the form of a name (such as the name of a workspace), a UUID (a unique identifier assigned to each repository object), or an alias. Aliases are short strings of digits that you can use to refer to repository objects wherever such references are accepted by an scm subcommand. You can specify whether aliases, UUIDs, or both are displayed by setting the -a and -u options on the scm command line.
Related Articles
© Copyright 2011 IBM