REST API: The Plastic SCM API


Introduction

Welcome to the Plastic SCM client REST API documentation!

This API allows programmers to perform Plastic client operations in their machine, provided that a Plastic client is already in place and configured. It's implemented in a REST fashion, meaning that virtually any language can interact with it through HTTP connections. Each of the supported Plastic client operations is exposed using a different URI and HTTP method. You can have a look at the detailed endpoint documentation for further information.


How to use the API

Executing commands through the Plastic REST API is extremely simple: using your programming language of choice, you just need to perform an HTTP request against the appropriate URI, setting the HTTP method matching your targeted endpoint and including the request body format stated by said endpoint. You can have a look to our API client examples in the following sections or to our advanced API examples if you need a starting point!


Starting the local API

The API requests are received by a simple, standalone HTTP server, exposed by the plasticapi.exe command. You can find it in the Plastic SCM client directory (C:\Program Files\PlasticSCM5\client by default). Once executed, it waits for incoming requests indefinitely, listening on port 9090.

You can execute it on a PowerShell or cmd terminal by running:

C:\Program Files\PlasticSCM5\client\plasticapi.exe [params]

The available parameters are:

  • -p <port-number> - makes the server listen on port <port-number> instead of 9090.
  • -r - allows remote connection (i.e. coming from a different host).

In order to accept remote connections on a Windows machine, the following command must be executed with administrator privileges:

netsh http add urlacl url=http://+:<port-number>/ user=<user>

Where <port-number> is the desired API port and <user> is the user who will run the API program, in Windows format: <domain>\<user>.


Java example

Program

package com.codice.examples;


import com.codice.examples.actions.CreateRepositoryAction;
import com.codice.examples.actions.RenameAction;
import com.codice.examples.models.Repository;
import retrofit.Callback;
import retrofit.RestAdapter;
import retrofit.RetrofitError;
import retrofit.client.Response;

import java.util.List;
import java.util.Scanner;

public class Program {

    static IApi apiClient;
    static Scanner in;
    static String instructions = "1 - List repositories (cm lrep)\n" +
    "2 - Create a repository (cm mkrep)\n" +
    "3 - Rename a repository (cm rnrep)\n" +
    "4 - Delete a repository (cm rmrep)\n" +
    "\n"                                   +
    "Select an option (1/2/3/4): ";

    static void initApiClient() {
        RestAdapter adapter = new RestAdapter.Builder()
                .setEndpoint("http://localhost:9090")
                .build();

        apiClient = adapter.create(IApi.class);
    }

    static void listRepositories() {
        List<Repository> repositories = apiClient.getRepositories();
        for(Repository repo : repositories) {
            System.out.println(String.format("%d_%d %s %s",
                    repo.getRepId().getId(),
                    repo.getRepId().getModuleId(),
                    repo.getName(),
                    repo.getServer()));
        }
    }

    static void createRepository() {
        System.out.print("Write a name for the repository: ");
        String name = in.nextLine();
        System.out.print("Write the direction of the server: ");
        String server = in.nextLine();

        CreateRepositoryAction action =
                new CreateRepositoryAction(name, server);

        Repository newRepo = apiClient.createRepository(action);
        System.out.println(String.format(
                "Repository %s successfully created!", newRepo.getName()));
    }

    static void renameRepository() {
        listRepositories();
        System.out.print("Write the name of the repository to rename: ");
        String repository = in.nextLine();
        System.out.print(String.format("Write a new name for %s: ", repository));
        String newName = in.nextLine();

        RenameAction action = new RenameAction(newName);
        Repository renamedRepo =
                apiClient.renameRepository(repository, action);
        System.out.println(
                String.format("Repository %s successfully renamed to %s.",
                        repository, renamedRepo.getName())
        );
    }

    static void deleteRepository() {
        listRepositories();
        System.out.print("Write the name of the repository to delete: ");
        String repository = in.nextLine();

        apiClient.deleteRepository(repository, new Callback<Void>() {
            @Override
            public void success(Void aVoid, Response response) {
                // Retrofit limitation. Here, we should only check the
                // status code.
                System.out.println("Repository successfully deleted!");
            }

            @Override
            public void failure(RetrofitError retrofitError) {

            }
        });
    }

    public static void main(String[] args) {
        initApiClient();

        System.out.print(instructions);
        in = new Scanner(System.in);
        String optionStr = in.nextLine();
        int option;

        try {
            option = Integer.valueOf(optionStr);
        } catch (NumberFormatException e) {
            option = 1;
        }

        switch (option) {
            case 1:
            default:
                listRepositories();
                break;
            case 2:
                createRepository();
                break;
            case 3:
                renameRepository();
                break;
            case 4:
                deleteRepository();
                break;
        }

    }
}

Actions

package com.codice.examples.actions;


import com.sun.istack.internal.NotNull;

public class CreateRepositoryAction {

    private String name;
    private String server;

    public CreateRepositoryAction(@NotNull String name,
                                  @NotNull String server) {
        this.name = name;
        this.server = server;
    }
}

package com.codice.examples.actions;


import com.sun.istack.internal.NotNull;

public class RenameAction {

    private String name;

    public RenameAction(@NotNull String name) {
        this.name = name;
    }
}

Models

package com.codice.examples.models;


public class Owner {

    private String name;
    private boolean isGroup;

    public String getName() { return name; }
    public boolean isGroup() { return isGroup; }
}

package com.codice.examples.models;


public class RepId {

    private int id;
    private int moduleId;

    public int getId() { return id; }
    public int getModuleId() { return moduleId; }
}

package com.codice.examples.models;


import java.util.UUID;

public class Repository {

    private RepId repId;
    private Owner owner;
    private String name;
    private UUID guid;
    private String server;

    public RepId getRepId() { return repId; }
    public Owner getOwner() { return owner; }
    public String getName() { return name; }
    public UUID getGuid() { return guid; }
    public String getServer() { return server; }
}

IApi

package com.codice.examples;


import com.codice.examples.actions.CreateRepositoryAction;
import com.codice.examples.actions.RenameAction;
import com.codice.examples.models.Repository;
import retrofit.Callback;
import retrofit.http.*;

import java.util.List;

public interface IApi {

    @GET("/api/v1/repos")
    List<Repository> getRepositories();

    @POST("/api/v1/repos")
    Repository createRepository(@Body CreateRepositoryAction params);

    @PUT("/api/v1/repos/{repname}")
    Repository renameRepository(@Path("repname") String repositoryName,
                                @Body RenameAction params);

    @DELETE("/api/v1/repos/{repname}")
    void deleteRepository(@Path("repname") String repositoryName,
                          Callback<Void> callback); // Retrofit limitation.
}

C# example

Program

using Csharp_examples.Actions;
using Csharp_examples.Models;
using Csharp_examples.Utils;
using System;
using System.Collections.Generic;

namespace Csharp_examples
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.Write(mActions);
            string optionStr = Console.ReadLine();

            int option;
            Int32.TryParse(optionStr, out option);

            switch (option)
            {
                case 1:
                default:
                    ListRepositories();
                    break;
                case 2:
                    CreateRepository();
                    break;
                case 3:
                    RenameRepository();
                    break;
                case 4:
                    DeleteRepository();
                    break;
            }
        }

        static void ListRepositories()
        {
            List<Repository> repositories = ApiUtils.ReadRepositoryList().Result;

            foreach (Repository repo in repositories)
            {
                Console.WriteLine(string.Format(" {0}_{1} {2} {3}",
                    repo.RepId.Id, repo.RepId.ModuleId, repo.Name, repo.Server));
            }
        }

        static void CreateRepository()
        {
            Console.Write("Write a name for the repository: ");
            string name = Console.ReadLine();
            Console.Write("Write the direction of the server: ");
            string server = Console.ReadLine();

            CreateRepository action = new CreateRepository()
            {
                Name = name,
                Server = server
            };

            Repository newRepo = ApiUtils.CreateRepository(action).Result;
            Console.Write(string.Format("Repository {0} successfully created!", newRepo.Name));
        }

        static void RenameRepository()
        {
            ListRepositories();
            Console.Write("Write the name of the repository to rename: ");
            string repository = Console.ReadLine();
            Console.Write(string.Format("Write a new name for {0}: ", repository));
            string newName = Console.ReadLine();

            Rename action = new Rename()
            {
                Name = newName
            };

            Repository renamedRepo = ApiUtils.RenameRepository(repository, action).Result;
            Console.Write(string.Format("Repository {0} successfully renamed to {1}.",
                repository, renamedRepo.Name));
        }

        static void DeleteRepository()
        {
            ListRepositories();
            Console.Write("Write the name of the repository to delete: ");
            string repository = Console.ReadLine();

            ApiUtils.DeleteRepository(repository).Wait();
            Console.Write(string.Format("Repository {0} successfully deleted!", repository));
        }

        static string mActions = @"1 - List repositories (cm lrep)
2 - Create a repository (cm mkrep)
3 - Rename a repository (cm rnrep)
4 - Delete a repository (cm rmrep)

Select an option (1/2/3/4): ";
    }
}

Actions

namespace Csharp_examples.Actions
{
    public class CreateRepository
    {
        public string Name { get; set; }
        public string Server { get; set; }
    }
}

namespace Csharp_examples.Actions
{
    public class Rename
    {
        public string Name { get; set; }
    }
}

Models

namespace Csharp_examples.Models
{
    public class Owner
    {
        public string Name { get; set; }
        public bool IsGroup { get; set; }
    }
}

namespace Csharp_examples.Models
{
   public class RepId
    {
        public int Id { get; set; }
        public int ModuleId { get; set; }
    }
}

using System;

namespace Csharp_examples.Models
{
    public class Repository
    {
        public RepId RepId { get; set; }
        public Owner Owner { get; set; }
        public string Name { get; set; }
        public Guid Guid { get; set; }
        public string Server { get; set; }
    }
}

Utils

using Csharp_examples.Actions;
using Csharp_examples.Models;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

namespace Csharp_examples.Utils
{
    public class ApiUtils
    {
        static HttpClient GetHttpClient()
        {
            HttpClient client = new HttpClient();
            client.BaseAddress = new Uri("http://localhost:9090/");
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(
                new MediaTypeWithQualityHeaderValue("application/json"));

            return client;
        }

        public static async Task<List<Repository>> ReadRepositoryList()
        {
            HttpClient client = GetHttpClient();
            using (client)
            {
                HttpResponseMessage response = await client.GetAsync("api/v1/repos");

                if (response.StatusCode != System.Net.HttpStatusCode.OK)
                    throw new Exception(string.Format(
                        "API Status Code {0}. Expected OK.", response.StatusCode));

                return await response.Content.ReadAsAsync<List<Repository>>();
            }
        }

        public static async Task<Repository> CreateRepository(CreateRepository createParams)
        {
            HttpClient client = GetHttpClient();
            using (client)
            {
                HttpResponseMessage response =
                    await client.PostAsJsonAsync("api/v1/repos", createParams);

                if (response.StatusCode != System.Net.HttpStatusCode.OK)
                    throw new Exception(string.Format(
                        "API Status Code {0}. Expected OK.", response.StatusCode));

                return await response.Content.ReadAsAsync<Repository>();
            }
        }

        public static async Task<Repository> RenameRepository(string repositoryName, Rename renameParam)
        {
            HttpClient client = GetHttpClient();
            string uri = string.Format("api/v1/repos/{0}", repositoryName);
            using (client)
            {
                HttpResponseMessage response =
                    await client.PutAsJsonAsync(uri, renameParam);

                if (response.StatusCode != System.Net.HttpStatusCode.OK)
                    throw new Exception(string.Format(
                        "API Status Code {0}. Expected OK.", response.StatusCode));

                return await response.Content.ReadAsAsync<Repository>();
            }
        }

        public static async Task DeleteRepository(string repositoryName)
        {
            HttpClient client = GetHttpClient();
            string uri = string.Format("api/v1/repos/{0}", repositoryName);
            using (client)
            {
                HttpResponseMessage response =
                    await client.DeleteAsync(uri);

                if (response.StatusCode != System.Net.HttpStatusCode.NoContent)
                    throw new Exception(string.Format(
                        "API Status Code {0}. Expected NoContent.", response.StatusCode));
            }
        }
    }
}

Python example

cm lrep

import sys
import requests

__api_url = "http://localhost:9090/api/v1"


def print_repositories(repositories):
    line = "{0} {1} {2}"
    for repo in repositories:
        print(line.format(repo["repId"]["id"],
                          repo["name"],
                          repo["server"]))


def get_repositories():
    url = __api_url + "/repos"
    req = requests.get(url)
    if req.status_code is 200:
        return req.json()
    print("The repository list could not be retrieved.", file=sys.stderr)
    exit(-1)


def main():
    try:
        print_repositories(get_repositories())
    except requests.RequestException as e:
        print(e)
        exit(-1)


if __name__ == "__main__":
    main()

cm mkrep

import sys
import requests

__api_url = "http://localhost:9090/api/v1"


def create_repository(name, server):
    url = __api_url + "/repos"
    params = {"name": name,
              "server": server}
    req = requests.post(url, params)
    if req.status_code is not 200:
        print("The repository could not be created", file=sys.stderr)
        exit(-1)


def main():
    name = input("Write a name for the new repository: ")
    server = input("Enter the PlasticSCM server address: ")
    try:
        create_repository(name, server)
    except requests.RequestException as e:
        print(e)
        exit(-1)

if __name__ == "__main__":
    main()

cm rnrep

import sys
import requests

__api_url = "http://localhost:9090/api/v1"


def print_repositories(repositories):
    line = "{0} {1} {2}"
    for repo in repositories:
        print(line.format(repo["repId"]["id"],
                          repo["name"],
                          repo["server"]))


def get_repositories():
    url = __api_url + "/repos"
    req = requests.get(url)
    if req.status_code is 200:
        return req.json()
    print("The repository list could not be retrieved.", file=sys.stderr)
    exit(-1)


def rename_repo(old_name, new_name):
    url = __api_url + "/repos/" + old_name
    params = {"name": new_name}
    req = requests.put(url, params)
    if req.status_code is not 200:
        print("The repository could not be created.", file=sys.stderr)
        exit(-1)


def main():
    try:
        print_repositories(get_repositories())
        old_name = input("\nWrite the name of the repository to rename: ")
        new_name = input("Write a new name for the repository " + old_name + ": ")
        rename_repo(old_name, new_name)
        print_repositories(get_repositories())
    except requests.RequestException as e:
        print(e, file=sys.stderr)
        exit(-1)

if __name__ == "__main__":
    main()

cm rmrep

import sys
import requests

__api_url = "http://localhost:9090/api/v1"


def print_repositories(repositories):
    line = "{0} {1} {2}"
    for repo in repositories:
        print(line.format(repo["repId"]["id"],
                          repo["name"],
                          repo["server"]))


def get_repositories():
    url = __api_url + "/repos"
    req = requests.get(url)
    if req.status_code is 200:
        return req.json()
    print("The repository list could not be retrieved.", file=sys.stderr)
    exit(-1)


def remove_repo(name):
    url = __api_url + "/repos/" + name
    req = requests.delete(url)
    if req.status_code is not 204:
        print("The repository could not be deleted", file=sys.stderr)
        exit(-1)


def main():
    try:
        print_repositories(get_repositories())
        repo = input("Write the name of the repository to delete: ")
        remove_repo(repo)
        print_repositories(get_repositories())
    except requests.RequestException as e:
        print(e, file=sys.stderr)
        exit(-1)

if __name__ == "__main__":
    main()

cm lwk

import sys
import requests

__api_url = "http://localhost:9090/api/v1"


def print_workspaces(wkspaces):
    line = "Name: {0}, path: {1}"
    for wkspace in wkspaces:
        print(line.format(wkspace["name"],
                          wkspace["path"]))


def get_workspaces():
    url = __api_url + "/wkspaces"
    req = requests.get(url)
    if req.status_code is 200:
        return req.json()
    print("Workspace list could not be retrieved.", file=sys.stderr)
    exit(-1)


def main():
    try:
        print_workspaces(get_workspaces())
    except requests.RequestException as e:
        print(e, file=sys.stderr)
        exit(-1)

if __name__ == "__main__":
    main()

cm mkwk

import sys
import requests

__api_url = "http://localhost:9090/api/v1"


def print_repositories(repositories):
    line = "{0} {1} {2}"
    for repo in repositories:
        print(line.format(repo["repId"]["id"],
                          repo["name"],
                          repo["server"]))


def get_repositories():
    url = __api_url + "/repos"
    req = requests.get(url)
    if req.status_code is 200:
        return req.json()
    print("The repository list could not be retrieved.", file=sys.stderr)
    exit(-1)


def create_workspace(name, path, repository):
    url = __api_url + "/wkspaces"
    params = {"name": name,
              "path": path,
              "repository": repository}
    req = requests.post(url, params)
    if req.status_code is not 200:
        print("The workspace could not be created.", file=sys.stderr)
        exit(-1)


def main():
    try:
        print_repositories(get_repositories())
        repository = input("Write the name of a repository to create a new workspace to: ")
        name = input("Write the name for the new workspace: ")
        path = input("Write the path for the new workspace: ")
        create_workspace(name, path, repository)
    except requests.RequestException as e:
        print(e, file=sys.stderr)
        exit(-1)


if __name__ == "__main__":
    main()

cm rmwk

import sys
import requests

__api_url = "http://localhost:9090/api/v1"


def print_workspaces(wkspaces):
    line = "Name: {0}, path: {1}"
    for wkspace in wkspaces:
        print(line.format(wkspace["name"],
                          wkspace["path"]))


def get_workspaces():
    url = __api_url + "/wkspaces"
    req = requests.get(url)
    if req.status_code is 200:
        return req.json()
    print("Workspace list could not be retrieved.", file=sys.stderr)
    exit(-1)


def remove_workspace(name):
    url = __api_url + "/wkspaces/" + name
    req = requests.delete(url)
    if req.status_code is not 204:
        print("The workspace could not be deleted.", file=sys.stderr)
        sys.exit(-1)


def main():
    try:
        print_workspaces(get_workspaces())
        name = input("Write the name of the workspace to delete: ")
        remove_workspace(name)
    except requests.RequestException as e:
        print(e, file=sys.stderr)
        exit(-1)


if __name__ == "__main__":
    main()

API Reference

Repositories

List all repositories

GET /api/v1/repos

Response

Status: 200 OK

[
    {
        "repId":
        {
            "id": 1,
            "moduleId": 0
        },
        "name": "default",
        "guid": "c43e1cf9-50b0-4e0d-aca5-c1814d016425",
        "owner":
        {
            "name": "all",
            "isGroup": false
        },
        "server": "localhost:8084"
    }
]

Get a single repository

GET /api/v1/repos/:repname

Response

Status: 200 OK

{
    "repId":
    {
        "id": 1,
        "moduleId": 0
    },
    "name": "default",
    "guid": "c43e1cf9-50b0-4e0d-aca5-c1814d016425",
    "owner":
    {
        "name": "all",
        "isGroup": false
    },
    "server": "localhost:8084"
}

Create a repository

POST /api/v1/repos

Parameters

Name Type Description
name string Required. The name of the new repository.
server string The target server where the repository should be created.

Example

{
    "name": "repName",
    "server": "myserver:8084"
}

Response

The repository data will be returned once the operation is complete.

Status: 200 OK

{
    "repId":
    {
        "id": 2,
        "moduleId": 0
    },
    "name": "repName",
    "guid": "c45b8af3-1a10-d31f-baca-c00590d12456",
    "owner":
    {
        "name": "all",
        "isGroup": false
    },
    "server": "myserver:8084"
}

Rename a repository

PUT /api/v1/repos/:repname

Parameters

Name Type Description
name string Required. The new name for the repository.

Example

{
    "name": "newName"
}

Response

The updated repository data will be returned once the operation is complete.

Status: 200 OK

{
    "repId":
    {
        "id": 2,
        "moduleId": 0
    },
    "name": "newName",
    "guid": "c45b8af3-1a10-d31f-baca-c00590d12456",
    "owner":
    {
        "name": "all",
        "isGroup": false
    },
    "server": "myserver:8084"
}

Remove a repository

DELETE /api/v1/repos/:repname

Response

Status: 204 No Content


Workspaces

List all workspaces

GET /api/v1/wkspaces

Response

Status: 200 OK

[
    {
        "name": "my_wk",
        "guid": "e93518f8-20a6-4534-a7c6-f3d9ebac45cb",
        "path": "c:\\path\\to\\workspace",
        "machineName": "MACHINE"
    }
]

Get a single workspace

GET /api/v1/wkspaces/:wkname

Response

Status: 200 OK

{
    "name": "my_wk",
    "guid": "e93518f8-20a6-4534-a7c6-f3d9ebac45cb",
    "path": "c:\\path\\to\\workspace",
    "machineName": "MACHINE"
}

Create a workspace

POST /api/v1/wkspaces

Parameters

Name Type Description
name string Required. The name of the new workspace.
path string Required. The target path where the repository should be created.
repository string The source repository for the new workspace.

Example

{
    "name": "new_wk",
}

Response

The workspace data will be returned once the operation is complete.

Status: 200 OK

{
    "name": "new_wk"
    "guid": "ed3248d2-5591-407a-94e6-84dac0ce015b"
    "path": "c:\\the\\path\\to\\new_wk"
    "machineName": "MACHINE"
}

Rename a workspace

PUT /api/v1/wkspaces/:wkname

Parameters

Name Type Description
name string Required. The new name for the workspace.

Example

{
    "name": "newName"
}

Response

The updated workspace data will be returned once the operation is complete.

Status: 200 OK

{
    "name": "newName"
    "guid": "ed3248d2-5591-407a-94e6-84dac0ce015b"
    "path": "c:\\the\\path\\to\\new_wk"
    "machineName": "MACHINE"
}

Remove a workspace

DELETE /api/v1/wkspaces/:wkname

Response

Status: 204 No Content


Branches

List all branches

GET /api/v1/repos/:repname/branches

Parameters

Name Type Description
q string An optional constraints string using the cm find command syntax.

Example

GET http://localhost:9090/api/v1/repos/myrepo/branches?q=id > 50

Response

Status: 200 OK

[
    {
        "name": "/main/task001/task002",
        "id": 1388,
        "parentId": 1067,
        "lastChangeset": 1383,
        "comment": "Testing: implement new smoke tests.",
        "creationDate": "2015-06-30T15:18:08",
        "guid": "0ced86fe-37cb-4801-8f6d-0081edb46d39",
        "owner": {
            "name": "codice-master",
            "isGroup": false
        },
        "repository": {
            "name": "mainrepo",
            "repId": {
                "id": 1,
                "moduleId": 0
            },
            "guid": "c43e1cf9-50b0-4e0d-aca5-c1814d016425",
            "owner": {
                "name": "all",
                "isGroup": false
            },
            "server": "localhost:8084"
        }
    }
]

Get a single branch

GET /api/v1/repos/:repname/branches/:branchname

Please note that branch names are hierarchical.

Request example

GET /api/v1/repos/mainrepo/branches/main/task001/task002

Response

Status: 200 OK

{
    "name": "/main/task001/task002",
    "id": 1388,
    "parentId": 1067,
    "lastChangeset": 1383,
    "comment": "Testing: implement new smoke tests.",
    "creationDate": "2015-06-30T15:18:08",
    "guid": "0ced86fe-37cb-4801-8f6d-0081edb46d39",
    "owner": {
        "name": "codice-master",
        "isGroup": false
    },
    "repository": {
        "name": "mainrepo",
        "repId": {
            "id": 1,
            "moduleId": 0
        },
        "guid": "c43e1cf9-50b0-4e0d-aca5-c1814d016425",
        "owner": {
            "name": "all",
            "isGroup": false
        },
        "server": "localhost:8084"
    }
}

Create a branch

POST /api/v1/repos/:repname/branches

Parameters

Name Type Description
name string Required. The branch name. Do not use hierarchy here.
originType string Required. The type of source to retrieve the parent changeset of the new branch. It can be changeset, label or branch. See examples for further detail.
origin string Required. The point of origin from which the branch will be created.
topLevel boolean Whether or not the branch will be top-level (i.e. it will have no parent). Set to false by default.

Examples

{
    "name": "newBranch",
    "originType": "branch",
    "origin": "/main/scm003",
    "topLevel": false
}
{
    "name": "newBranch",
    "originType": "label",
    "origin": "BL000",
    "topLevel": true
}
{
    "name": "newBranch",
    "originType": "changeset",
    "origin": "97",
    "topLevel": false
}

Response

The created branch info will be returned once the operation is complete.

Status: 200 OK

{
  "name": "/main/scm003/newBranch",
  "id": 1395,
  "parentId": 1067,
  "lastChangeset": 1383,
  "creationDate": "2015-07-01T09:01:08",
  "guid": "3416a2b4-f88a-43b1-8319-3424bc23c77b",
  "owner": {
    "name": "tester",
    "isGroup": false
  },
  "repository": {
    "name": "default",
    "repId": {
      "id": 1,
      "moduleId": 0
    },
    "guid": "c43e1cf9-50b0-4e0d-aca5-c1814d016425",
    "owner": {
      "name": "all",
      "isGroup": false
    },
    "server": "localhost:8084"
  }
}

Rename a branch

PATCH /api/v1/repos/:repname/branches/:branchname

Parameters

Name Type Description
name string Required. The new name for the branch. Please have in mind that branch hierarchy cannot be changed.

Example

{
    "name": "/main/task001/task003"
}

Response

The updated branch info will be returned once the operation is complete.

Status: 200 OK

{
    "name": "/main/task001/task003",
    "id": 1388,
    "parentId": 1067,
    "lastChangeset": 1383,
    "comment": "Testing: implement new smoke tests.",
    "creationDate": "2015-06-30T15:18:08",
    "guid": "0ced86fe-37cb-4801-8f6d-0081edb46d39",
    "owner": {
        "name": "codice-master",
        "isGroup": false
    },
    "repository": {
        "name": "mainrepo",
        "repId": {
            "id": 1,
            "moduleId": 0
        },
        "guid": "c43e1cf9-50b0-4e0d-aca5-c1814d016425",
        "owner": {
            "name": "all",
            "isGroup": false
        },
        "server": "localhost:8084"
    }
}

Remove a branch

Only empty branches with no children can be removed.

DELETE /api/v1/repos/:repname/branches/:branchname

Response

Status: 204 No Content


Labels

List all labels

GET /api/v1/repos/:repname/labels

Parameters

Name Type Description
q string An optional constraints string using the cm find command syntax.

Example

GET http://localhost:9090/api/v1/repos/myrepo/labels?q=date > '2015-07-01'

Response

Status: 200 OK

[
  {
    "name": "BL000",
    "id": 1391,
    "changeset": 100,
    "comment": "",
    "creationDate": "2015-07-01T07:45:56",
    "branch": {
      "name": "/main",
      "id": 3,
      "parentId": -1,
      "lastChangeset": 101,
      "comment": "main branch",
      "creationDate": "2015-04-09T07:17:00",
      "guid": "5fc2d7c8-05e1-4987-9dd9-74eaec7c27eb",
      "owner": {
        "name": "all",
        "isGroup": false
      },
      "repository": {
        "name": "default",
        "repId": {
          "id": 1,
          "moduleId": 0
        },
        "guid": "c43e1cf9-50b0-4e0d-aca5-c1814d016425",
        "owner": {
          "name": "all",
          "isGroup": false
        },
        "server": "localhost:8084"
      }
    },
    "owner": {
      "name": "tester",
      "isGroup": false
    },
    "repository": {
      "name": "default",
      "repId": {
        "id": 1,
        "moduleId": 0
      },
      "guid": "c43e1cf9-50b0-4e0d-aca5-c1814d016425",
      "owner": {
        "name": "all",
        "isGroup": false
      },
      "server": "localhost:8084"
    }
  }
]

Get a single label

GET /api/v1/repos/:repname/labels/:labelname

Response

Status: 200 OK

{
  "name": "BL000",
  "id": 1391,
  "changeset": 100,
  "branch": {
    "name": "/main",
    "id": 3,
    "parentId": -1,
    "lastChangeset": 101,
    "comment": "main branch",
    "creationDate": "2015-04-09T07:17:00",
    "guid": "5fc2d7c8-05e1-4987-9dd9-74eaec7c27eb",
    "owner": {
      "name": "all",
      "isGroup": false
    },
    "repository": {
      "name": "default",
      "repId": {
        "id": 1,
        "moduleId": 0
      },
      "guid": "c43e1cf9-50b0-4e0d-aca5-c1814d016425",
      "owner": {
        "name": "all",
        "isGroup": false
      },
      "server": "localhost:8084"
    }
  },
  "comment": "",
  "creationDate": "2015-07-01T07:45:56",
  "owner": {
    "name": "tester",
    "isGroup": false
  }
  "repository": {
    "name": "default",
    "repId": {
      "id": 1,
      "moduleId": 0
    },
    "guid": "c43e1cf9-50b0-4e0d-aca5-c1814d016425",
    "owner": {
      "name": "all",
      "isGroup": false
    },
    "server": "localhost:8084"
  }
}

Create a label

POST /api/v1/repos/:repname/labels/

Parameters

Name Type Description
name string Required. The new name for the label.
changeset integer Required. The changeset to label.
comment string The comment to add to the label.
applyToXlinks boolean If true, all xlinked changesets present in the specified changeset tree will be labelled as well. Set to false by default.

Example

{
    "name": "BL001",
    "changeset": 99,
    "comment": "Stable baseline - 1",
    "applyToXlinks": false
}

Response

The created label info will be returned once the operation is complete.

Status: 200 OK

{
  "name": "BL001",
  "id": 1401,
  "changeset": 99,
  "comment": "Stable baseline - 1",
  "creationDate": "2015-07-01T10:19:14",
  "branch": {
    "name": "/main",
    "id": 3,
    "parentId": -1,
    "lastChangeset": 101,
    "comment": "main branch",
    "creationDate": "2015-04-09T07:17:00",
    "guid": "5fc2d7c8-05e1-4987-9dd9-74eaec7c27eb",
    "owner": {
      "name": "all",
      "isGroup": false
    },
    "repository": {
      "name": "default",
      "repId": {
        "id": 1,
        "moduleId": 0
      },
      "guid": "c43e1cf9-50b0-4e0d-aca5-c1814d016425",
      "owner": {
        "name": "all",
        "isGroup": false
      },
      "server": "localhost:8084"
    }
  },
  "owner": {
    "name": "tester",
    "isGroup": false
  },
  "repository": {
    "name": "default",
    "repId": {
      "id": 1,
      "moduleId": 0
    },
    "guid": "c43e1cf9-50b0-4e0d-aca5-c1814d016425",
    "owner": {
      "name": "all",
      "isGroup": false
    },
    "server": "localhost:8084"
  }
}

Rename a label

PATCH /api/v1/repos/:repname/labels/:labelname

Parameters

Name Type Description
name string Required. The new name for the label.

Example

{
    "name": "v1.0.0",
}

Response

The updated label info will be returned once the operation is complete.

Status: 200 OK

{
  "name": "v1.0.0",
  "id": 1401,
  "changeset": 99,
  "comment": "Stable baseline - 1",
  "creationDate": "2015-07-01T10:19:14",
  "branch": {
    "name": "/main",
    "id": 3,
    "parentId": -1,
    "lastChangeset": 101,
    "comment": "main branch",
    "creationDate": "2015-04-09T07:17:00",
    "guid": "5fc2d7c8-05e1-4987-9dd9-74eaec7c27eb",
    "owner": {
      "name": "all",
      "isGroup": false
    },
    "repository": {
      "name": "default",
      "repId": {
        "id": 1,
        "moduleId": 0
      },
      "guid": "c43e1cf9-50b0-4e0d-aca5-c1814d016425",
      "owner": {
        "name": "all",
        "isGroup": false
      },
      "server": "localhost:8084"
    }
  },
  "owner": {
    "name": "tester",
    "isGroup": false
  },
  "repository": {
    "name": "default",
    "repId": {
      "id": 1,
      "moduleId": 0
    },
    "guid": "c43e1cf9-50b0-4e0d-aca5-c1814d016425",
    "owner": {
      "name": "all",
      "isGroup": false
    },
    "server": "localhost:8084"
  }
}

Remove a label

DELETE /api/v1/repos/:repname/labels/:labelname

Response

Status: 204 No Content


Changesets

List all changesets

GET /api/v1/repos/:repname/changesets

Parameters

Name Type Description
q string An optional constraints string using the cm find command syntax.

Example

GET http://localhost:9090/api/v1/repos/myrepo/changesets?q=date > '2015-07-01'

Response

Status: 200 OK

[
  {
    "id": 0,
    "parentId": -1,
    "comment": "Root dir",
    "creationDate": "2015-04-09T07:17:00",
    "guid": "0497ef04-4c81-4090-8458-649885400c84",
    "branch": {
      "name": "\/main",
      "id": 3,
      "parentId": -1,
      "lastChangeset": 101,
      "comment": "main branch",
      "creationDate": "2015-04-09T07:17:00",
      "guid": "5fc2d7c8-05e1-4987-9dd9-74eaec7c27eb",
      "owner": {
        "name": "all",
        "isGroup": false
      },
      "repository": {
        "name": "default",
        "repId": {
          "id": 1,
          "moduleId": 0
        },
        "guid": "c43e1cf9-50b0-4e0d-aca5-c1814d016425",
        "owner": {
          "name": "all",
          "isGroup": false
        },
        "server": "localhost:8084"
      }
    },
    "owner": {
      "name": "all",
      "isGroup": false
    },
    "repository": {
      "name": "default",
      "repId": {
        "id": 1,
        "moduleId": 0
      },
      "guid": "c43e1cf9-50b0-4e0d-aca5-c1814d016425",
      "owner": {
        "name": "all",
        "isGroup": false
      },
      "server": "localhost:8084"
    }
  },
  ...
]

List all changesets by branch

GET /api/v1/repos/:repname/branches/:branchname/changesets

Parameters

Name Type Description
q string An optional constraints string using the cm find command syntax.

Example

GET http://localhost:9090/api/v1/repos/myrepo/branches/main/changesets?q=changesetid > 50

Response

Status: 200 OK

[
  {
    "id": 77,
    "parentId": 76,
    "comment": "checkin TaskOnBranch test",
    "creationDate": "2015-06-02T08:59:12",
    "guid": "799e4fd3-1161-4f8f-be4f-067dbe98ed89",
    "branch": {
      "name": "/main/scm003",
      "id": 1067,
      "parentId": 3,
      "lastChangeset": 1383,
      "comment": "text\r\n",
      "creationDate": "2015-06-02T08:46:11",
      "guid": "e99e8843-9bd9-43eb-ad67-c170b516a032",
      "owner": {
        "name": "testing01",
        "isGroup": false
      },
      "repository": {
        "name": "default",
        "repId": {
          "id": 1,
          "moduleId": 0
        },
        "guid": "c43e1cf9-50b0-4e0d-aca5-c1814d016425",
        "owner": {
          "name": "all",
          "isGroup": false
        },
        "server": "localhost:8084"
      }
    },
    "owner": {
      "name": "testing01",
      "isGroup": false
    },
    "repository": {
      "name": "default",
      "repId": {
        "id": 1,
        "moduleId": 0
      },
      "guid": "c43e1cf9-50b0-4e0d-aca5-c1814d016425",
      "owner": {
        "name": "all",
        "isGroup": false
      },
      "server": "localhost:8084"
    }
  }
]

Get a single changeset

GET /api/v1/repos/:repname/changesets/:changesetid

Response

Status: 200 OK

{
  "id": 77,
  "parentId": 76,
  "comment": "checkin TaskOnBranch test",
  "creationDate": "2015-06-02T08:59:12",
  "guid": "799e4fd3-1161-4f8f-be4f-067dbe98ed89",
  "branch": {
    "name": "/main/scm003",
    "id": 1067,
    "parentId": 3,
    "lastChangeset": 1383,
    "comment": "text\r\n",
    "creationDate": "2015-06-02T08:46:11",
    "guid": "e99e8843-9bd9-43eb-ad67-c170b516a032",
    "owner": {
      "name": "testing01",
      "isGroup": false
    },
    "repository": {
      "name": "default",
      "repId": {
        "id": 1,
        "moduleId": 0
      },
      "guid": "c43e1cf9-50b0-4e0d-aca5-c1814d016425",
      "owner": {
        "name": "all",
        "isGroup": false
      },
      "server": "localhost:8084"
    }
  },
  "owner": {
    "name": "testing01",
    "isGroup": false
  },
  "repository": {
    "name": "default",
    "repId": {
      "id": 1,
      "moduleId": 0
    },
    "guid": "c43e1cf9-50b0-4e0d-aca5-c1814d016425",
    "owner": {
      "name": "all",
      "isGroup": false
    },
    "server": "localhost:8084"
  }
}

Changes

Get pending changes in workspace

GET /api/v1/wkspaces/:wkname/changes

Parameters

Name Type Description
types string A comma-separated list detailing the desired change types to display in the response. Available types: added, checkout, changed, copied, replaced, deleted, localdeleted, moved, localmoved, private, ignored, hiddenchanged, controlledchanged, all

Response

Status: 200 OK

[
    {
        "changes": [
            "CH",
            "MV"
        ],
        "path": "c:\\Users\\scm-user\\wkspaces\\main-wk\\audio-prj\\orchestrated.fspro",
        "oldPath": "c:\\Users\\scm-user\\wkspaces\\main-wk\\audio-prj\\audio-prj.fspro",
        "serverPath": "/audio-prj/orchestrated.fspro",
        "oldServerPath": "/audio-prj/audio-prj.fspro",
        "isXlink": false,
        "localInfo": {
            "modifiedTime": "2015-07-02T11:16:07.0042908Z",
            "size": 57906,
            "isMissing": false
        },
        "revisionInfo": {
            "id": 65,
            "parentId": -1,
            "itemId": 187,
            "type": "text",
            "size": 57896,
            "hash": "tLq1aWZ24MGupAHKZAgYFA==",
            "branchId": 3,
            "changesetId": 3,
            "isCheckedOut": false,
            "creationDate": "2015-04-09T09:51:20",
            "repositoryId": {
                "id": 1,
                "moduleId": 0
            },
            "owner": {
                "name": "scm-user",
                "isGroup": false
            }
        }
    }
]

Undo pending changes in workspace

DELETE /api/v1/wkspaces/:wkname/changes

Parameters

Name Type Description
paths string[] A list of file paths to be restored. They can be either full paths or workspace-relative paths. See examples for further info.

Examples

{
    "paths": [
        "c:\\Users\\scm-user\\wkspaces\\main-wk\\audio-prj\\orchestrated.fspro"
    ]
}
{
    "paths": [
        "audio-prj/orchestrated.fspro"
    ]
}

Response

Status: 200 OK

{
    "affectedPaths": [
        "c:\\Users\\scm-user\\wkspaces\\main-wk\\audio-prj\\orchestrated.fspro"
    ]
}

Workspace Update and Switch

Retrieve update/switch status

GET /api/v1/wkspaces/:wkname/update

GET /api/v1/wkspaces/:wkname/switch

Response

Status: 200 OK

{
    "status": "Not running"
}

Status: 200 OK

{
    "status": "Failed",
    "message": "No route to host 'localhost:8084'"
}

Status: 200 OK

{
    "status": "Calculating",
    "totalFiles": 1356,
    "totalBytes": 3246739,
    "updatedFiles": 0,
    "updatedBytes": 0
}

Status: 200 OK

{
    "status": "Running",
    "totalFiles": 1356,
    "totalBytes": 3246739,
    "updatedFiles": 356,
    "updatedBytes": 894433
}

Status: 200 OK

{
    "status": "Finished",
    "totalFiles": 1356,
    "totalBytes": 3246739,
    "updatedFiles": 1356,
    "updatedBytes": 3246739
}

Launch a workspace update

POST /api/v1/wkspaces/:wkname/update

Response

Status: 200 OK

{
    "status": "Running",
    "totalFiles": 0,
    "totalBytes": 0,
    "updatedFiles": 0,
    "updatedBytes": 0
}

Switch workspace to a different branch/label/changeset

POST /api/v1/wkspaces/:wkname/switch

Parameters

Name Type Description
objectType string Required. The type of switch destination. It can be changeset, label or branch. See examples for further detail.
object string Required. The target point the workspace will be set to.

Examples

{
    "objectType": "branch",
    "object": "/main/task001"
}
{
    "objectType": "changeset",
    "object": "1136"
}
{
    "objectType": "label",
    "object": "BL001"
}

Response

Status: 200 OK

{
    "status": "Running",
    "totalFiles": 0,
    "totalBytes": 0,
    "updatedFiles": 0,
    "updatedBytes": 0
}

Checkin

Retrieve checkin status

GET /api/v1/wkspaces/:wkname/checkin

Response

Status: 200 OK

{
    "status": "Not running"
}

Status: 200 OK

{
    "status": "Failed",
    "message": "No route to host 'localhost:8084'"
}

Status: 200 OK

{
    "status": "Checkin finished",
    "totalSize": 57990,
    "transferredSize": 57990
}

Check in pending changes

POST /api/v1/wkspaces/:wkname/checkin

Parameters

Name Type Description
paths string[] The list of target paths to be checked in. Set to the workspace root if empty or not present.
comment string The checkin comment.
recurse boolean If set to true, directories present in the paths parameter will have their children recursively checked in. If paths is empty or not present, its value is overridden to true. Defaults to false.

Examples

{
}
{
    "comment": "Upgrade core engine"
}
{
    "paths": [
      "src/foo.c",
      "src/bar/baz.c",
      "doc"
    ],
    "comment": "Upgrade core engine",
    "recurse": true
}

Response

Status: 200 OK

{
    "status": "Checkin operation starting...",
    "totalSize": 0,
    "transferredSize": 0
}

Repository contents

Retrieve an item

GET /api/v1/repos/:repname/branches/:branchname/contents/:itempath

GET /api/v1/repos/:repname/changesets/:changesetid/contents/:itempath

GET /api/v1/repos/:repname/labels/:labelname/contents/:itempath

Directories will contain a list of items. Xlinks will contain an object referencing to the xlinked changeset.

Examples

GET /api/v1/repos/myrepo/branches/main/scm003/contents/src/lib/foo.c

GET /api/v1/repos/myrepo/changesets/5378/contents/src/lib/foo.c

GET /api/v1/repos/myrepo/labels/BL001/contents/src/lib/foo.c

Response

Status: 200 OK

{
  "revisionId": 771,
  "type": "file",
  "size": 57913,
  "name": "soundproject.fspro",
  "path": "/fmod/soundproject.fspro",
  "isUnderXlink": false,
  "hash": "/2ygGGfoXDq9bbKZJCzj9g==",
  "content": "http://localhost:9090/api/v1/repos/myrepo/revisions/771/blob",
  "repository": {
    "repId":
    {
        "id": 1,
        "moduleId": 0
    },
    "name": "myrepo",
    "guid": "c43e1cf9-50b0-4e0d-aca5-c1814d016425",
    "owner":
    {
        "name": "all",
        "isGroup": false
    },
    "server": "localhost:8084"
  }
}

Status: 200 OK

{
  "revisionId": 3648,
  "type": "directory",
  "size": 0,
  "name": "lib",
  "path": "/lib",
  "isUnderXlink": false,
  "items": [
    {
      "revisionId": 6878,
      "type": "xlink",
      "size": 0,
      "name": "xlink",
      "path": "/lib/xlink",
      "xlinkTarget": {
        "changesetGuid": "41acf2bd-1484-4679-a634-2570d9a7801b",
        "changesetId": 2,
        "repository": "big",
        "server": "localhost:8084"
      }
    }
  ],
  "repository": {
    "repId":
    {
        "id": 1,
        "moduleId": 0
    },
    "name": "myrepo",
    "guid": "c43e1cf9-50b0-4e0d-aca5-c1814d016425",
    "owner":
    {
        "name": "all",
        "isGroup": false
    },
    "server": "localhost:8084"
  }
}

Status: 200 OK

{
  "revisionId": 2427,
  "type": "directory",
  "size": 0,
  "name": "mono",
  "path": "/lib/xlink/mono",
  "isUnderXlink": true,
  "items": [
    {
      "revisionId": 46348,
      "type": "file",
      "size": 26383,
      "name": "COPYING.LIB",
      "path": "/lib/xlink/mono/COPYING.LIB",
      "hash": "uFbSL8ON1UNln1XUYeAc7w==",
      "content": "http://localhost:9090/api/v1/repos/myrepo/revisions/46348/blob"
    },
    {
      "type": "directory",
      "size": 0,
      "name": "data",
      "path": "/lib/xlink/mono/data"
    }
  ],
  "repository": {
    "repId":
    {
        "id": 1,
        "moduleId": 0
    },
    "name": "myrepo",
    "guid": "c43e1cf9-50b0-4e0d-aca5-c1814d016425",
    "owner":
    {
        "name": "all",
        "isGroup": false
    },
    "server": "localhost:8084"
  }
}

Retrieve a single revision

GET /api/v1/repos/:repname/revisions/:revid

Response

Status: 200 OK

{
  "revisionId": 3526,
  "type": "file",
  "size": 71,
  "name": "foo.c",
  "path": "/src/lib/foo.c",
  "changeset": 1406,
  "branch": "br:/main/scm003",
  "hash": "tNYiUA4VyMJxJrK0kic7mg==",
  "contents": "http://localhost:9090/api/v1/repos/myrepo/revisions/3526/blob",
  "repository": {
    "repId":
    {
        "id": 1,
        "moduleId": 0
    },
    "name": "myrepo",
    "guid": "c43e1cf9-50b0-4e0d-aca5-c1814d016425",
    "owner":
    {
        "name": "all",
        "isGroup": false
    },
    "server": "localhost:8084"
  }
}

Status: 200 OK

{
  "revisionId": 5355,
  "type": "directory",
  "size": 0,
  "name": "lib",
  "path": "/src/lib",
  "changeset": 1406,
  "branch": "br:/main/scm003",
  "repository": {
    "repId":
    {
        "id": 1,
        "moduleId": 0
    },
    "name": "myrepo",
    "guid": "c43e1cf9-50b0-4e0d-aca5-c1814d016425",
    "owner":
    {
        "name": "all",
        "isGroup": false
    },
    "server": "localhost:8084"
  }
}

Retrieve revision contents

GET /api/v1/repos/:repname/revisions/:revid/blob

Response

Stream: application/octet-stream

Retrieve the revision history of an item

GET /api/v1/repos/:repname/branches/:branchname/history/:itempath

GET /api/v1/repos/:repname/changesets/:changesetid/history/:itempath

GET /api/v1/repos/:repname/labels/:labelname/history/:itempath

Examples

GET /api/v1/repos/myrepo/branches/main/scm003/history/src/lib/foo.c

GET /api/v1/repos/myrepo/changesets/5378/history/src/lib/foo.c

GET /api/v1/repos/myrepo/labels/BL001/history/src/lib/foo.c

Response

Status: 200 OK

[
    {
        "revisionId": 104,
        "type": "text",
        "owner": {
            "name": "tester",
            "isGroup": false
        },
        "creationDate": "2015-04-09T09:51:20",
        "comment": "Restore method implementation",
        "revisionLink": "http://localhost:9090/api/v1/repos/myrepo/revisions/104",
        "changesetId": 3,
        "changesetLink": "http://localhost:9090/api/v1/repos/myrepo/changesets/3",
        "branchName": "/main",
        "branchLink": "http://localhost:9090/api/v1/repos/myrepo/branches/main",
        "repositoryName": "myrepo",
        "repositoryLink": "http://localhost:9090/api/v1/repos/myrepo"
    }
]

Diff

Changeset diff

GET /api/v1/repos/:repname/changesets/:changesetid/diff

GET /api/v1/repos/:repname/changesets/:changesetid/diff/:sourcechangesetid

If no source changeset ID is passed, the diff operation is performed using the parent changeset as source.

Response

Status: 200 OK

[
  {
    "status": "Changed",
    "path": "/lib/xlink",
    "isDirectory": true,
    "isUnderXlink": false,
    "xlink": {
      "changesetGuid": "ff92e897-b662-40f1-9a1f-a17349cbc7c6",
      "repository": "big",
      "server": "localhost:8084"
    },
    "baseXlink": {
      "changesetGuid": "c75c04ec-3546-46e4-bbb7-031b523dca7d",
      "repository": "big",
      "server": "localhost:8084"
    },
    "isItemFSProtectionChanged": false,
    "itemFileSystemProtection": "NOT_DEFINED",
    "repository": {
      "name": "default",
      "server": "localhost:8084"
    }
  },
  {
    "status": "Changed",
    "path": "/lib/xlink/mono/.gitignore",
    "revisionId": 150892,
    "isDirectory": false,
    "size": 1616,
    "hash": "u0gJQzQnjLNUUHRI1+QQLg==",
    "isUnderXlink": true,
    "merges": [
      {
        "mergeType": "Merged",
        "sourceChangeset": {
          "id": 3,
          "parentId": 2,
          "comment": "multiple changes",
          "creationDate": "2015-07-16T10:01:32",
          "guid": "4d064ea0-4694-41b2-adec-15c3df243dd7",
          "branch": {
            "name": "\/main\/scm002",
            "id": 150865,
            "parentId": 3,
            "lastChangeset": 3,
            "comment": "",
            "creationDate": "2015-07-16T10:01:30",
            "guid": "764c4842-aab8-451a-b802-29162d2a399f",
            "owner": {
              "name": "tester",
              "isGroup": false
            },
            "repository": {
              "name": "big",
              "repId": {
                "id": 4,
                "moduleId": 0
              },
              "guid": "301b269c-6d24-4347-afc1-f095da43f3f2",
              "owner": {
                "name": "testing01",
                "isGroup": false
              },
              "server": "localhost:8084"
            }
          },
          "repository": {
            "name": "big",
            "repId": {
              "id": 4,
              "moduleId": 0
            },
            "guid": "301b269c-6d24-4347-afc1-f095da43f3f2",
            "owner": {
              "name": "testing01",
              "isGroup": false
            },
            "server": "localhost:8084"
          }
        }
      }
    ],
    "isItemFSProtectionChanged": false,
    "itemFileSystemProtection": "NOT_DEFINED",
    "modifiedTime": "2015-07-16T10:04:21",
    "createdBy": {
      "name": "tester",
      "isGroup": false
    },
    "repository": {
      "name": "big",
      "repId": {
        "id": 4,
        "moduleId": 0
      },
      "server": "localhost:8084"
    }
  }
]

Branch diff

GET /api/v1/repos/:repname/branches/:branchname/diff

Response

Status: 200 OK

[
  {
    "status": "Changed",
    "path": "/lib/xlink",
    "isDirectory": true,
    "isUnderXlink": false,
    "xlink": {
      "changesetGuid": "ff92e897-b662-40f1-9a1f-a17349cbc7c6",
      "repository": "big",
      "server": "localhost:8084"
    },
    "baseXlink": {
      "changesetGuid": "c75c04ec-3546-46e4-bbb7-031b523dca7d",
      "repository": "big",
      "server": "localhost:8084"
    },
    "isItemFSProtectionChanged": false,
    "itemFileSystemProtection": "NOT_DEFINED",
    "repository": {
      "name": "default",
      "server": "localhost:8084"
    }
  },
  {
    "status": "Changed",
    "path": "/lib/xlink/mono/.gitignore",
    "revisionId": 150892,
    "isDirectory": false,
    "size": 1616,
    "hash": "u0gJQzQnjLNUUHRI1+QQLg==",
    "isUnderXlink": true,
    "merges": [
      {
        "mergeType": "Merged",
        "sourceChangeset": {
          "id": 3,
          "parentId": 2,
          "comment": "multiple changes",
          "creationDate": "2015-07-16T10:01:32",
          "guid": "4d064ea0-4694-41b2-adec-15c3df243dd7",
          "branch": {
            "name": "\/main\/scm002",
            "id": 150865,
            "parentId": 3,
            "lastChangeset": 3,
            "comment": "",
            "creationDate": "2015-07-16T10:01:30",
            "guid": "764c4842-aab8-451a-b802-29162d2a399f",
            "owner": {
              "name": "tester",
              "isGroup": false
            },
            "repository": {
              "name": "big",
              "repId": {
                "id": 4,
                "moduleId": 0
              },
              "guid": "301b269c-6d24-4347-afc1-f095da43f3f2",
              "owner": {
                "name": "testing01",
                "isGroup": false
              },
              "server": "localhost:8084"
            }
          },
          "repository": {
            "name": "big",
            "repId": {
              "id": 4,
              "moduleId": 0
            },
            "guid": "301b269c-6d24-4347-afc1-f095da43f3f2",
            "owner": {
              "name": "testing01",
              "isGroup": false
            },
            "server": "localhost:8084"
          }
        }
      }
    ],
    "isItemFSProtectionChanged": false,
    "itemFileSystemProtection": "NOT_DEFINED",
    "modifiedTime": "2015-07-16T10:04:21",
    "createdBy": {
      "name": "tester",
      "isGroup": false
    },
    "repository": {
      "name": "big",
      "repId": {
        "id": 4,
        "moduleId": 0
      },
      "server": "localhost:8084"
    }
  }
]

Workspace actions

Add

POST api/v1/wkpaces/:wkname/content/:path

Parameters

Name Type Description
addPrivateParents boolean If true, the command will add any parent directories which are not under version control yet.
checkoutParent boolean If true, the parent node of the selected item will be checked out as a result.
recurse boolean If true, causes all the children items to be recursively added.

Example

POST http://localhost:9090/api/v1/wkspaces/mywk/content/src/lib

{
  "addPrivateParents": true,
  "checkoutParent": false,
  "recurse": true
}

Response

Status: 200 OK

{
    "affectedPaths": [
      "c:\\wkspaces\\mywk\\src\\lib\\descriptor.h",
      "c:\\wkspaces\\mywk\\src\\lib\\code.c"
    ]
}

Checkout

PUT api/v1/wkspaces/:wkname/content/:path

Example

PUT http://localhost:9090/api/v1/wkspaces/mywk/content/src/lib/code.c

Response

Status: 200 OK

{
    "affectedPaths": [
      "c:\\wkspaces\\mywk\\src\\lib\\code.c"
    ]
}

Move

PATCH api/v1/wkspaces/:wkname/content/:path

Parameters

Name Type Description
destination string Required. Destination path to move the selected item.

Example

PATCH http://localhost:9090/api/v1/wkspaces/mywk/content/src/lib/foo.c

{
  "destination": "src/bar.c"
}

Response

Status: 200 OK

{
    "affectedPaths": [
      "c:\\wkspaces\\mywk\\src\\bar.c"
    ]
}

Current limitations

As you know, the Plastic SCM client REST API is still in a development stage. This means that not every CLI/GUI operation is available for our API at the moment, much to our regret.


Unavailable operations

  • Merge from/to
  • Query pagination
  • Xlink management
  • Replication
  • Permissions management
  • Shelves
  • Revert
  • Undelete
  • File info
  • Code reviews
  • Annotate code
  • Attribute management
  • Statistics
  • Trigger management
  • Gluon compatibility (cm partial)

Last updated

Aug 4, 2016
  • Fixed the parameter names in the Switch workspace to a different branch/label/changeset reference.
  • Jul 7, 2016
  • Limitation removed - The execution on Linux is available.
  • Aug 31, 2015
  • Welcome to the Plastic SCM client REST API documentation.