Plastic SCM - GitSync guide


Intro

Plastic SCM is a full-featured DVCS (Distributed Version Control Software). And, Plastic SCM also speaks the Git network protocol.

Plastic SCM can push and pull changes directly to any remote Git server. This is because Plastic supports the https:// and git:// protocols for pushing and pulling changesets.

This feature immediately turns Plastic SCM into a DVCS fully compatible with Git. The advantage of this is that you can use Plastic or Git on your workstation and still participate in Git projects (GitHub, CodePlex, and many more).

Plastic - push/pull - Git

What is GitSync?

This can be a first approach: GitSync is a native Windows DVCS connected to GitHub. So, it virtually turns Plastic SCM into a full-fledged Windows client for Git.

Note: GitSync is not technically a new Git client: You would be using Plastic SCM on the client-side but can push/pull to Git servers (using https or Git protocols).

Imagine that you're a developer using GitHub (or Bitbucket, or maybe CodePlex). In any case, there are things you like: using a cloud-based repository for your code and Windows to develop. And things you don't like: being forced to use the CLI and lacking really awesome GUI tools.

So, you wish you had everything: Cloud repositories, the DVCS power, and awesome tools for Windows.

That's what you get with GitSync.


Feature list

The capabilities of GitSync are:

  • Direct push/pull - Including all commits, comments, branches, merge tracking, and tags.
  • Adding/deleting or moving files - No limits at any of the two sides.
  • Full merge tracking - You can merge on the Git side, and Plastic will recognize the merge tracking. And, the same is true in the Plastic-to-Git direction. That's the benefit of Plastic SCM and Git being full DVCS!
  • Conflict management - You can make changes on the same branch on the Git and Plastic sides concurrently and Plastic will handle the data exchange, pull the changes, request the user to run a merge, then push the solved conflict (as you'd do if you just were using a full Git setup).

How does it work?

An entire push and pull process will show you GitSync works.


Initial scenario

You have a Git repo, and you pull it on Plastic. As a result, you get an exact clone with the branches and commits you had in Git now converted to Plastic, and what's best about this is Plastic SCM is able to render those branches and commits in the Branch Explorer:

How GitSync works - Initial scenario

Creating a new commit in the Git repo

The following image shows what happens when a new commit is created on the Git side and how the pull from Plastic SCM retrieves it.

Instead of just performing a simple change, the figure shows a merge from big_feature branch into master. The result in Plastic SCM mimics what happened at the Git side, adding the merge link (which is rendered as a green line) on the Plastic Branch Explorer:

How GitSync works - Creating new commit on the Git side

Creating a new changeset in the Plastic repo

The next step is performing a change in Plastic SCM and pushing the change to Git. To create a more complete example, a merge will also be made instead of just creating a new changeset.

The changesets 6 and 7 are created on the Plastic side, then they're pushed to Git. As you can see in the figure below, the merge information (multiple parents on the Git repo) is also sent from Plastic to Git.

How GitSync works - Creating new commit on the Plastic side

So far, the changes were done at one side or the other, but not at the two sides concurrently.


Performing changes concurrently: conflicts

The following picture shows what happens when developers work on the same branch at the same time. A new commit is created in Git (on green) and another in Plastic (orange):

How GitSync works - Performing changes concurrently: conflicts

If the Plastic developer tries to push to Git, an error will show up since there are conflicting changes (which would happen on a similar scenario on a pure Plastic or pure Git setup). The steps to follow are:

  1. First, pull the changes from Git.
  2. A new "subbranch" will be created, placing the 88ffa changeset correctly.
    How GitSync works - Performing changes concurrently: conflicts
  3. The next steps will be resolving the merge conflict at the Plastic SCM side and then completing the push:
    How GitSync works - Performing changes concurrently: conflicts

Both repositories will look the same at the end of the interaction and let developers work together on both sides.

Note: Since Plastic SCM is a full DVCS (like Git), it can clone a Git repository and later push changes to it... entirely! We do not restrict to a single branch. You can create branches on Plastic and push them to Git and create branches on Git and pull them to Plastic.

The gitsync.conf file

The GitSync configuration file (gitsync.conf) lets you include information automatically used during the GitSync operations.

This information is related to the mapping between two Plastic SCM and Git objects:

  • User accounts
  • Xlinks/Submodules information
Important! The gitsync.conf file must be located in:
  • In the Plastic SCM client folder.
  • In the plastic4 directory (under $HOME/.plastic4 on Linux/Mac systems or C:\Users\user\AppData\Local\plastic4 on Windows).

Mapping user accounts

In the gitsync.conf file, we can define a mapping between Plastic and Git (emails). This information will be used as author and committer when committing to Git.

This info is added on the email-mapping section in the following format:

plastic_user = git_email_address

An example of gitsync.conf file:

[email-mapping]
asalim = asalim@mymailprovider.com
ubuntu = ubuntu@linuxprovider.com

Mapping Plastic SCM Xlinks and Git submodules


GitSync restrictions

Two Git operations are restricted when using GitSync:

  • rebase command
  • merge (fast-forward) command

These Git commands don't take into account the history of your changes. Although the user can work in a parallel way, Git talks about history like something linear. But Plastic prioritizes keeping the changes history.

Plastic SCM takes into account the whole history of the changes you make. This means that Plastic doesn't rewrite history (a design decision).

The changes history is reflected when working on branches and merging. Because Plastic SCM can solve and show how the history is, we recommend you avoid using those Git commands when working with GitSync.

  • Rebasing is a subtle topic in Git - You can only do it before you push (in fact, many recommend that you never use it). Most of the time, it is used to understand the history without going crazy with all the merging:
    GitSync restrictions - Git rebase
    Note: We don't handle rebases in Git fashion.
  • The Git fast-forward merge command does something similar, linearly solving the merge:
    GitSync restrictions - Git fast-forward merge
    Note: Use the merge --no-ff command to keep the history.

Plastic has the Branch Explorer, which lets you understand what is going on graphically. This way, you are not distracted and you don't miss rebasing.

When you diff a branch with several merges, it is hard to see what you really changed on the branch and what comes from the merge... this is also solved in Plastic:

GitSync - Plastic merge
Important! We recommend not using the Git rebase and merge (fast-forward) command to avoid issues when synchronizing your Plastic-Git repositories.

In general, do not use those commands that rewrite the history of the repository. For example, delete or move changeset, delete or move labels.

Direct push/pull

As we've seen previously, Plastic can push and pull directly to remote Git servers using both native Git and HTTPS protocols, including well-known sites such as GitHub, BitKeeper, CodePlex, and many more.

When we started developing the Git-bidirectional synchronization with Plastic SCM, we had the following scenarios in mind:

  • Developers already using Plastic SCM want to contribute to projects on GitHub, CodePlex, BitKeeper, and others.
  • Developers working on teams using Git as a primary server prefer to use Plastic SCM but need to contribute changes back to the main server.
  • Teams gradually adopting Plastic SCM need to contribute to other teams on Git.

We went the hard way for a solution: we didn't come up with some sort of intermediate script to convert changes from one system to the other or do fast-import/export, imposing a ton of limitations. But we actually implemented was the Git network protocols in Plastic as a layer able to directly pull and push to Git.

Plastic starts a negotiation phase with the remote Git server, as a Git command would do, speaking the Git protocol. It is a core feature, not an add-on script.

As we've said, GitSync implements the smart-protocol and:

  • It can negotiate with a remote Git receive-pack to upload data (negotiating which changesets/commits are needed and generating the correct pack file from Plastic repository data to be sent to Git).
  • It can also negotiate with a remote upload-pack to decide which commits need to be packaged, download the pack and import it into Plastic.

The first pull

Let's start by connecting to a GitHub repository.

  1. If you go to GitHub and browse the repos, you'll probably find a list of "trendy" repos. The corefx repository is used in the example below:
    GitSync - First pull - Select GitHub repo

    Now, to pull it to Plastic, a repo is created to "host it" (called corefx too) and in the initially empty Branch Explorer, the context menu option to launch Sync with Git:

    GitSync - First pull - Sync with Git
  2. Then you launch the Sync dialog (which is very similar to the replication dialog to push/pull changes between Plastic servers) and enter the URL of the Git repo:
    GitSync - First pull - Sync dialog

    No need for credentials now since we're just pulling (cloning) from a public repo. You'll need to specify them if you need to push, and the server requires you to be an authenticated user.

    Note: If you use Github and need authentication, you must use a token and not a password. For more information, see Creating a personal access token

  3. Press Sync, and the process (pull) will start up as follows:
    GitSync - First pull - Sync
    Note: This operation can be done by using the command line in the following way: cm sync corefx git https://github.com/corefx/corefx.git

    Assuming the local corefx repo is empty, it will calculate the changesets and branches it needs to pull from the remote GitHub repo and will pull them:

    GitSync - First pull - Sync command line

    To pull new changes done on the GitHub side, simply re-run the same command:

    cm sync corefx git https://github.com/corefx/corefx.git

    And it will now calculate and pull only the new changes made on the Git side if any.

    You're currently pulling Git changesets and branches directly to your local Plastic SCM repository:

    GitSync - First pull - Pulling
    GitSync - First pull - Pulling summary
  4. Once the replication is complete, go back to the workspace explorer and update the workspace to download the source files.
  5. Refresh the Branch Explorer and you'll be able to render the just imported Git changesets in a typical Plastic SCM way:
    GitSync - First pull - Branch Explorer

    And now, right-clicking any changeset (commit in Git jargon), you'll be able to check differences with our built-in diff system:

    GitSync - First pull - Diff

Now you're ready to do more changes in Plastic, whether branches, merges, anything. Then repeat the same process to sync to Git (which will in turn push or pull changes and even ask you to solve merges before pushing back to Git if concurrent changes were done on the same branches).


Pushing to Git

We're going to push one of our Plastic repositories to GitHub. This process is similar to the previous one.

  1. Create a new GitHub repository to export your Plastic repository to GitHub:
    GitSync - First push - Create GitHub repo
  2. In this example, the dokancode Plastic repo is used. In the Branch Explorer view, right-click one of its branches and select the Sync with Git menu option:
    GitSync - First push - Sync with Git

    The Sync dialog will be launched.

  3. Enter the GitHub repository URL and the credentials if needed:
    GitSync - First push - Sync dialog
  4. Click the Sync button to start the synchronization. In this case, you're pushing (or exporting) your Plastic repository:
    GitSync - First push - Sync

    We're currently pushing Plastic SCM changesets and branches directly to my GitHub repository.

    Note: This operation can be done by using the command line in the following way: cm sync dokancode git https://github.com/mbctesting/dokancode.git

    Assuming the GitHub dokancode repo is empty, GitSync will calculate the changesets and branches it needs to push from the Plastic repo, and will push them:

    GitSync - First push - Sync command line

    Once the push operation is finished, you can see a summary of the objects that have been exporting:

    GitSync - First push - Pushing
    GitSync - First push - Pushing summary
  5. If you go back to GitHub and refresh the dokancode repository, you'll see the exported objects from Plastic:
    GitSync - First push - GitHub

Now you're ready to work with the repository in both sides: Plastic SCM and GitHub. You'll be able to create branches, do changes, and synchronize again by pulling/pushing.


Working on both sides

In this section, you'll learn how to work with the dokancode repo, in the GitHub and Plastic sides, applying some basic operations.

Important! Before performing any changes at either of the sides, you must synchronize your repo (using the Sync with Git action) to avoid conflicts.

Changes on the Git side

As an example, some operations will be run on the master branch:

  1. Delete the license.txt file:
    GitSync - Git side - Delete a file
  2. Edit the dokan-net-0.6.0\readme_dokan.txt file:
    GitSync - Git side - Edit a file
  3. And move it to dokan-net-0.6.0\DokanNet folder:
    GitSync - Git side - Move a file
  4. And then, create a new branch (scm007).
    GitSync - Git side - Create new branch
  5. Add two new files:
    GitSync - Git side - Add new file
    GitSync - Git side - Add new file
  6. And edit one of those files:
    GitSync - Git side - Edit new file

The commits are done, and you can see them on the Plastic side.

GitSync can calculate what's new on the other side, negotiate with the remote server, and push the changes.

  1. Go to synchronize the Plastic repo with the GitHub one by running Sync with Git:
    GitSync - Git side - Sync with Git
    GitSync - Git side - Synchronize
  2. By clicking Sync, the synchronization will begin and will pull to the Plastic repo the changes you performed on the GitHub side:
    GitSync - Git side - Sync

    Once the synchronization is complete:

    GitSync - Git side - Sync finished
  3. You can see a summary with the imported objects:
    GitSync - Git side - Sync summary
  4. If you go back to the Branch Explorer and refresh the view, you'll see the changes done on GitHub that have been imported to Plastic:
    GitSync - Git side - Branch Explorer
  5. You can open the Changesets view to see these GitHub changes:
    GitSync - Git side - Changesets view
  6. And, if you want to go deeper, you can confirm the changes done with the readme_dokan.txt file on GitHub. You can see the history of that file to check that those changes have been applied with the synchronization:
    GitSync - Git side - Changes

Now you can continue performing changes on Plastic.


Changes on the Plastic side

As an example, changes are made to the scm005 branch. At this point, both the Git and Plastic have the same content. You can check it on both sides:

GitSync - Plastic side
GitSync - Git side

In this branch:

  1. Add a new file:
    GitSync - Plastic side - Add new file
  2. Edit the DokanOperation.cs file:
    GitSync - Plastic side - Edit file

    These are the new changes:

    GitSync - Plastic side - New changes
  3. Once the changes are done, synchronize the GitHub repository by running Sync with Git:
    GitSync - Plastic side - Sync with Git
  4. Once the synchronization is done, you can see the summary:
    GitSync - Plastic side - Sync summary

    The summary tells you that the synchronization has sent two changesets involved in one branch:

    GitSync - Plastic side - Changesets
  5. If you go to GitHub, you can see these new changes that were done on Plastic:
    GitSync - Plastic side - GitHub

Plastic and Git branches conversion

Note that the Plastic main branch is mapped to the Git master branch. This mapping is also considered for the children branches of main on Plastic. This means that the Plastic branches are converted into Git branches by removing the hierarchy and replacing the / with -. And this rule is also valid when a Git branch is converted into a Plastic branch: the - character is used to recreate the hierarchy in Plastic.

In the examples before, the Plastic branch /main/scm005 is converted to master-scm005. And the Git branch scm007 under master is converted to /main/scm007:

GitSync - Plastic and Git hierarchy

The - character is also allowed as part of the branch name like the following examples:

Branch - Git side Branch - Plastic side
master /main
master-fix-5.0 /main/fix-5.0
master-fix-5.0-task1 /main/fix-5.0/task1

Full merge tracking

Since Plastic SCM handles the same concepts as Git (DAG, commits, merge links, and so on), it is straightforward to share the merge tracking. You do a merge in Git, you can get it back to Plastic. If you do a merge in Plastic, you can even push the merge link back to Git.

The most difficult feature for us to handle is the "precise item tracking"; we do (and Git doesn't). Plastic has an internal id associated with each file and directory. It means we can easily handle tons of merge conflicts that are hard to track for Git (like a divergent move, something trivial for Plastic).

In the following examples, you'll see how the merge tracking works when using GitSync.


Merge on the Plastic side

In the following example, two branches are created:

  1. Branch scm008 - The DokanResetTimeout method is edited in the DokanNet.cs file, moved, and a new field is added:
    GitSync - Plastic side - Merge - Edit file
  2. Branch scm009 - The DokanNet.cs file is moved to another folder, then the method DokanResetTimeout is moved to another class and edited:
    GitSync - Plastic side - Merge - Move file
  3. Once the changes are done on different branches, they'll be merged to the main branch:
    GitSync - Plastic side - Merge
    GitSync - Plastic side - Merge result
  4. Now the repositories will be synchronized on both sides using the Sync with Git. This will push the merges on the Git side.

The new branches have been pushed and the merge tracking looks like this on Git:

GitSync - Plastic side - Pushed to Git

Merge on the Git side

Now we're going to see how a merge in Git is tracked on Plastic.

  1. Create new branch in Git, create a new file and edit another one:
    GitSync - Git side - Merge - Changes
    GitSync - Git side - Merge - Changes
  2. Once the commits are done, perform a merge from the branch (in this case, scm010) to the master branch:
    GitSync - Git side - Merge
    Note: The merge is done using the --no-ff option as we've seen in the GitSync restrictions section.
    GitSync - Git side - Merge done

    The merge is complete, and these changes have to be pulled to the remote Git repo:

    GitSync - Git side - Merge - Changes
  3. Once the local Git changes have been pulled to the remote Git repo, synchronize your repos. This means that the latest changes will be pulled to the Plastic repo. Run Sync with Git:
    GitSync - Git side - Merge - Sync with Git
  4. Refresh the Branch Explorer once the synchronization is finished. You'll see how the changes and merge done on Git have been pulled into Plastic:
    GitSync - Git side - Merge - Branch Explorer

Conflict management

As seen in the How it works section, you can make changes concurrently both in Plastic and Git. This means that you can work on the same branch on the two systems and reconcile changes (as you do when using a pure Plastic or Git environment).

In the Changes on the Git side section, some changes were made on GitHub:

  1. In the master branch - The license.txt file was deleted, the dokan-net-0.6.0\readme_dokan.txt file was edited, and moved to the dokan-net-0.6.0\DokanNet folder.
  2. Then a new branch was created (scm007) where - two new files were added (ArrayIndex.cs and ArrayInitialization.cs) and (ArrayIndex.cs) was edited.

Now, to perform some changes in Plastic:

  1. In the main branch, edit the DokanNet.cs file:
    GitSync - Conflict management - Plastic side - Edit file
  2. Add 3 new files:
    GitSync - Conflict management - Plastic side - Add files

Once the changes are done, synchronize both repos using Sync with Git:

GitSync - Conflict management - Sync with Git
GitSync - Conflict management - Sync with Git

When the synchronization is finished, a message will pop up saying a merge is needed.

GitSync - Conflict management - Merge needed

This is because we made some changes in the same branch in Git and Plastic.

In the summary, you'll see that the main (or master) branch is the one that requires a merge operation:

GitSync - Conflict management - Merge needed - Summary

Changes were made in the master branch in Git, and some other changes in the main branch on the Plastic side. Remember, that main and master is the same branch but using different names (see the Git-Plastic Dictionary for further information).

As seen in the How it works section, you have to resolve the merge conflict at the Plastic side.

  1. If you update the Branch Explorer, you'll see that:
    • First, the main branch has multiple "heads" that must be merged. This is because these conflicts are handled as a subbranch in Plastic SCM.
    • Second, the scm007 branch has been synchronized (pulled from GitHub to Plastic SCM).
    GitSync - Conflict management - Merge needed - Branch Explorer
  2. To solve this conflict, run a merge from the "GitHub" head (the head of the subbranch):
    GitSync - Conflict management - Merge needed - Merge from GitHub head

    The changes that are going to be merged:

    GitSync - Conflict management - Merge needed - Changes to be merged
  3. Click the Process all merges button to automatically merge all items.
  4. The last step is to checkin (confirm) the changes in the Pending changes view:
    GitSync - Conflict management - Merge needed - Checkin
  5. Once you click the Checkin button, you'll see that the two "heads" are merged into only one head, the one from the main branch:
    GitSync - Conflict management - Merge solved
  6. The merge conflict is now solved. Complete the synchronization by pushing in the Git side the changes done in the Plastic one. This is done by using Sync with Git.

Once this operation is finished, both repos are fully synchronized. This means that you have the same content on both sides.


SSH protocol support

GitSync supports sync with Git repositories using the SSH protocol.

The SSH protocol lets you connect and authenticate to remote servers and services.


Prerequisites

To use this feature:

  1. You must have the command line SSH client ssh in your PATH environment variable.
  2. You must add your private SSH key to your ssh-agent. Follow these instructions to add your SSH key to the ssh-agent.

    The SSH agent now manages your SSH keys and remembers your passphrase.


How to use it

You can use GitSync the same way as you usually do with HTTP protocol, by using the Plastic GUI or the CLI.

Let's see an example. If you use the command line, you have to specify the URL accordingly for the SSH protocol:

$ cm sync rep2 git git@github.com:PlasticSCM/Myrepo.git

instead of the HTTPS one:

$ cm sync rep2 git https://github.com/PlasticSCM/Myrepo.git

Last updated

September 24, 2020
May 26, 2020
June 16, 2017
  • Read how the branches conversion between Plastic and Git, and vice versa, works. We also updated the related screenshots.
April 12, 2016
  • Publication date.