Plastic SCM - GitSync guide
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).
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.
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.
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:
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:
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.
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):
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:
- First, pull the changes from Git.
- A new "subbranch" will be created, placing the 88ffa changeset correctly.
- The next steps will be resolving the merge conflict at the Plastic SCM side and then completing the push:
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
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
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
asalim = email@example.com
ubuntu = firstname.lastname@example.org
Mapping Plastic SCM Xlinks and Git submodules
A Git submodule is just a pointer to a commit in a different repository. It doesn't propagate operations between submodules or handle the branching between the repositories, so this very basic information is enough for the submodules work.
A Plastic Xlink object is more complex than the Git submodule: the Xlinks allow the user to set relative servers, set rules for the branch expansion, and define whether the Xlink is writable or not.
In general terms, we can say that Git submodules and Plastic Xlinks have the same mission: pointing to a commit in a different repository. So a direct mapping can be established between:
- A Git commit ↔ A Plastic changeset
- A Git repository URL ↔ A Plastic repository specification
GitSync lets you create Plastic Xlinks from Git submodules and vice versa. The Git submodules and the Plastic Xlinks can be synchronized using GitSync:
- The Git submodules are converted into Plastic Xlinks during the pull operation.
- The Plastic Xlinks are converted into Git submodules during the push operation.
Before synchronizing a repository with Xlinks/Submodules, the target repositories must be synchronized.
To synchronize a repository with Xlinks/Submodules, the mapping information must be added on the
gitsync.conf file. This info is added on the submodules section with the following format:
git_repository_url -> plastic_repository_spec [writable:true|false] [relativeserver:true|false]
- If the Git submodule has to be converted on a writable Plastic Xlink, the
writable field must be included as
writable:true. If the
writable field is omitted or set to false, the Xlink is created as read only.
- If the Git submodule must be converted on a Plastic Xlink with a relative server, the field
relativeserver must be included as
relativeserver:true. If the
relativeserver field is omitted or it is set to false, then the Xlink is created against the Plastic repository server (as non-relative Xlink).
This would be a valid configuration example:
git://localhost/code -> code@localhost:8084 writable:true relativeserver:true
git://localhost/doc -> doc@localhost:8084 writable:false relativeserver:true
Two Git operations are restricted when using GitSync:
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.
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:
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.
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.
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:
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:
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:
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.
Press Sync, and the process (pull) will start up as follows:
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:
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:
Once the replication is complete, go back to the workspace explorer and update the workspace to download the source files.
Refresh the Branch Explorer and you'll be able to render the just imported Git changesets in a typical Plastic SCM way:
And now, right-clicking any changeset (commit in Git jargon), you'll be able to check differences with our built-in diff system:
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.
Create a new GitHub repository to export your Plastic repository to GitHub:
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:
The Sync dialog will be launched.
Enter the GitHub repository URL and the credentials if needed:
Click the Sync button to start the synchronization. In this case, you're pushing (or exporting) your Plastic repository:
We're currently pushing Plastic SCM changesets and branches directly to my GitHub repository.
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:
Once the push operation is finished, you can see a summary of the objects that have been exporting:
If you go back to GitHub and refresh the dokancode repository, you'll see the exported objects from Plastic:
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:
Delete the license.txt file:
Edit the dokan-net-0.6.0\readme_dokan.txt file:
And move it to dokan-net-0.6.0\DokanNet folder:
And then, create a new branch (scm007).
Add two new files:
And edit one of those files:
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.
Go to synchronize the Plastic repo with the GitHub one by running Sync with Git:
By clicking Sync, the synchronization will begin and will pull to the Plastic repo the changes you performed on the GitHub side:
Once the synchronization is complete:
You can see a summary with the imported objects:
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:
You can open the Changesets view to see these GitHub changes:
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:
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:
In this branch:
Add a new file:
Edit the DokanOperation.cs file:
These are the new changes:
Once the changes are done, synchronize the GitHub repository by running Sync with Git:
Once the synchronization is done, you can see the summary:
The summary tells you that the synchronization has sent two changesets involved in one branch:
If you go to GitHub, you can see these new changes that were done on Plastic:
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:
The - character is also allowed as part of the branch name like the following examples:
|Branch - Git side
||Branch - Plastic side
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:
Branch scm008 - The DokanResetTimeout method is edited in the DokanNet.cs file, moved, and a new field is added:
Branch scm009 - The DokanNet.cs file is moved to another folder, then the method DokanResetTimeout is moved to another class and edited:
Once the changes are done on different branches, they'll be merged to the main branch:
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:
Merge on the Git side
Now we're going to see how a merge in Git is tracked on Plastic.
Create new branch in Git, create a new file and edit another one:
Once the commits are done, perform a merge from the branch (in this case, scm010) to the master branch:
The merge is complete, and these changes have to be pulled to the remote Git repo:
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:
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:
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:
- 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.
- 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:
In the main branch, edit the DokanNet.cs file:
Add 3 new files:
Once the changes are done, synchronize both repos using Sync with Git:
When the synchronization is finished, a message will pop up saying a merge is 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:
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.
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).
To solve this conflict, run a merge from the "GitHub" head (the head of the subbranch):
The changes that are going to be merged:
Click the Process all merges button to automatically merge all items.
The last step is to checkin (confirm) the changes in the Pending changes view:
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:
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.
To use this feature:
You must have the command line SSH client ssh in your PATH environment variable.
You must add your private SSH key to your ssh-agent. Follow
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 email@example.com:PlasticSCM/Myrepo.git
instead of the HTTPS one:
$ cm sync rep2 git https://github.com/PlasticSCM/Myrepo.git
September 24, 2020
GitSync supports to sync with Git repositories using the SSH protocol.
May 26, 2020
We highlighted the recommendation about the
operations restricted when using GitSync.
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