Plastic SCM - GitServer guide


What is GitServer?

Every Plastic SCM server can now serve repositories using the Git protocol (git and http supported).

This means that every Git client can directly push/pull to a Plastic SCM server.

Any tool in the Git ecosystem can now be directly connected to Plastic SCM using the native Git functionalities. Teams on Plastic can now benefit from all the DevOps, CI, and project management integrations developed for Git.

GitServer is the server side counterpart of GitSync (which allows every Plastic SCM client to push/pull to a git server) and closes the Git interoperability loop.


Who is it for?

GitServer can be used for a wide range of scenarios but its main goal is to serve as a "universal connector" for any Git software to connect to Plastic.

Any Git compatible git client can push/pull changes to GitServer which enables many different usage scenarios:

  1. Connect Git-compatible software to Plastic SCM - Developers can use GitServer to connect FishEye, CodeCollaborator, ReviewBoard, TeamCity and many others to Plastic SCM using the Git integrations.
  2. Use Plastic SCM as a central Git server - Developerscan push/pull from Git to a GitServer enabled Plastic SCM server.
  3. Serve as central repo for heterogeneous teams - Severalteams can now collaborate on Git and Plastic SCM. This can happen as a result of a gradual migration to Plastic SCM were some teams are still on Git, or just as part of a strategy where different teams will choose from Plastic and Git as their version control options, and still collaborate using Plastic as the central rendezvous point.

Configuring GitServer


Quick GitServer start

Enabling GitServer on a Plastic SCM server is very simple: just create an empty gitserver.conf file on your server's binary directory (where plasticd.exe is located) and restart the Plastic SCM server. It will start listening on git protocol default port: 9418.

Now you can push/pull from Git to Plastic SCM as follows:

git push --all git://localhost/default

will push your Git repo to the Plastic repository named default.


gitserver.conf file in detail

The gitserver.conf is the file controlling the GitServer configuration and it has the following format, where each line is optional:

# port configuration
tcp.port=9418
http.port=80

# mapping storage - the mappings between git and plastic objects
# the default path is automatically generated by the server
storage.baseDirectory=e:\gitserver\mappings

# mapping interval - how often GitServer looks for new changes
# on the Plastic side to make them available to git
# By default, it is 5 minutes (300 seconds)
mapping.interval=300

# repositories to be exported. By default, all repositories 
# will be available on GitServer unless a list is specified here
export.repo=code
export.repo=quake
export.repo=robotcode

Configuring http port on Windows

Windows imposes security restrictions on HTTP so special actions have to be taken to allow GitServer to use a given HTTP port. It only affects to processes that don't run under a privileged account. So, running Plastic SCM as a Windows Service won't require any special action to enable http.

If your Plastic SCM server runs in non-admin mode (not as a default Windows service), then all you need to do is to grant permissions to the particular user who runs the process. This can be done through the following command:

> netsh http add urlacl url=http://+:80/ user=DOMAIN\user

How does GitServer work?

Plastic SCM server can behave like a Git server transparently accessed by Git clients.

The changes can come to GitServer from different sources:

  • From Git with a git push operation. Once the Git command finishes, changes are immediately available for Plastic SCM & Git clients.
  • From Plastic with a check-in or replica operation. These changes are not instantly available for Git clients. A background thread checks every mapping.interval seconds if there are new Plastic changes in the repos "exported" to Git. If it finds changes, it starts calculating the mappings and once it is done, the new changes will be visible to Git.

Partial replica restrictions

Plastic SCM supports partial replicas, a feature that can't be mapped to Git. While this issue is extremely useful on pure-Plastic environments, it can be an issue in mixed Git/Plastic scenarios.


Partial replicas are not visible to Git

Consider the following scenario where John first pushes main to the main repo (the one synced to Git using GitServer) but doesn't push the branch main/task001 which has a merge to main:

Partial replicas are not visible to Git

When the GitServer code starts "indexing" the new changeset (number 10 in this example) to make them available to Git, it will only see changeset 10. The new changeset will be available as a Git commit and potentially pulled by Git clients.

Suppose that later John remembers to push main/task001 to central. The new branch task001 will be never made visible to Git because changeset 10 was already exported and recalculating task001 would change the "sha" of 10 and hence would break sync with remote git repos which already pulled 10 before.

It is very important to understand this limitation and make sure that the git mappings are only calculated when the right branches are in the Plastic repo meant to be synced to Git.


Unlinked branches are not visible to Git

Check the following scenario where the central repo has just received task002 using partial replica. The parents of task002 are not available on the main repo, so if the mappings to Git are calculated, the branch will be ignored:

Unlinked branches are not visible to Git

Even if task001 is pushed later on, task002 will remain invisible to Git repos if its mappings were calculated before task001 was pushed to the central repo.

Keep in mind that Git strongly discourages doing "rebases" and "rewriting history" on repos that were already pushed remotely. The same holds true in the scenarios described here, where considering the new history would mean rewriting it on the Git side, breaking remote Git repos.


Merges from ignored changes are ignored too

Suppose now a variation of the previous examples where an unlinked branch as a merge that was fully replicated:

Merges from ignored changes are ignored too

In this case task002 cannot be made visible to Git because it is an unlinked branch. It means that the new changeset 10 won't be made visible to Git either, because it means potentially breaking history. Once the parent for branch task002 is replicated, GitServer will be able to link the entire history and make changeset 10 visible to Git clients.


How to force to map branches even when its parents are not mapped

It is possible to force GitServer to make one branch available to Git even when some changesets don't meet the conditions.

In the previous scenario, it is possible to force GitServer to "map" changeset 10 even when task002 is not totally linked and will be never mapped to Git.

All you need to do is to add branch.toForceMap entries on gitserver.conf as follows:

# branches which changesets are made visible
# although they have unlinked merge sources
branch.toForceMap=/main

Unavailable Xlinks will force the containing branches to be ignored

Changesets with unresolved Xlinks will be also ignored by GitServer and hence won't be visible by the Git clients.

Consider the following scenario where the branch main@root contains an Xlink to main@xlink. In changeset 15 at root, the Xlinks points at changeset 4 at xlink, but this changeset wasn't replicated yet:

Unavailable Xlinks will force the containing branches to be ignored

This means that changeset 15 will be ignored and won't be visible to Git clients until the changeset it xlinks to is replicated.


How to force GitServer to ignore missing Xlinks

It is possible to configure GitServer to skip missing Xlinks to allow the synchronization with Git to happen even if some content is lost.

You just need to add unresolvedxlink.skip=true to your gitserver.conf as follows:

# skip the xlink entries that cannot be resolved
unresolvedxlink.skip=true

Pushing submodules to Plastic SCM

Git submodules are translated to Plastic SCM Xlinks. We can say that Xlinks are like evolved submodules to ease the developers' lifes.

When pushing some git changes/repo to GitServer, the operation can fail if there are submodules pointing to git repos that gitserver doesn't know how to resolve:

>git push --all git://localhost/default Counting objects: 143, done. Writing objects: 100% (143/143), 106.43 KiB | 0 bytes/s, done. Total 143 (delta 0), reused 143 (delta 0) error: invalid ref status from remote: The specified repository couldn't be found: mduem. To git://localhost/default ! [remote failure] master -> master (remote failed to report status) error: failed to push some refs to 'git://localhost/default'

In this case, there is a submodule pointing to a repo called mduem that GitServer doesn't find as a valid Plastic SCM repository.

To solve the issue, a repository named mduem must be created in Plastic, and the submodule repo will be pushed to Gitserver:

>cm mkrepmduem >git clone https://github.com/user/mduem.git Cloning into 'mduem'... remote: Counting objects: 461, done. Receiving objects: 95% (438/461) Receiving objects: 100% (461/461), 68.40 KiB | 0 bytes/s, done. Resolving deltas: 100% (172/172), done. Checking connectivity... done. >git push --all git://localhost/mduem Writing objects: 100% (453/453), 731.45 KiB | 0 bytes/s, done. Total 453 (delta 0), reused 453 (delta 0) To git://localhost/mduem * [new branch] master -> master >git push --all git://localhost/default Counting objects: 118, done. Writing objects: 100% (118/118), 83.75 KiB | 0 bytes/s, done. Total 118 (delta 0), reused 118 (delta 0) To git://localhost/default 46232e0..41c12e1 master -> master

In this case the Git submodule definition is as follows:

[submodule "mduem"]
        path = mduem
        url = git://github.com/user/mduem

Customizing Git submodule mappings to Plastic SCM Xlinks

Suppose that we want to customize our mapping between the Git submodule and the Plastic Xlink.

We can do it adding the following entry to the gitserver.conf file (we can add as many as we need for different Git submodules):

repository.mapping=git://github.com/user/mduem -> mduem-xlinked@localhost:8084 writable:true relativeserver:false

Which means that repo mduem will be translated to mduem-xlinked on the Plastic side of things.


Skipping Git submodules

It is possible to skip certain Git submodules so they're not mapped to Plastic SCM repositories. In order to do that, edit your gitserver.conf as follows:

# when a submoule points to one of the following
# git urls, it will be ignored.
ignore.submoduleUrl= git://github.com/user/mduem

You can add as many ignore.submoduleUrl entries as required.


Requirements

For Plastic SCM server to enable GitServer successfully, a valid Team Edition or Enterprise Edition license is required.

Personal Edition and Community Edition don't support GitServer.

GitServer works on all the supported Plastic SCM server platforms: Linux, Windows and MacOS X.


Current restrictions

Avoid fast-forward, rebase and deleting Git commits

Avoid fast-forward, rebasing and deleting commits on Git repositories that will be pushed to a GitServer.

Avoiding rebasing or deleting commits are already git-to-gitrestrictions to push to a regular git server.

The fast-forward restriction is present because of the internal differences between Plastic SCM and Git. In Git a single commit can be "pointed" by more than one branch head, so a single commit can be in more than one branch.

In Plastic SCM, every changeset is tied to a single branch, and it can't be on more than one branch at the same time. That's why it is a recommended practice to avoid fast-forward merges on Git repos meant to be synchronized with Plastic SCM.


Security is not enforced for repositories served by GitServer

GitServer doesn't perform any security checks for the exported repositories.

Git clients can download the entire repository content or push changes to the repo.

Remember, you can restrict the repositories that are visible to GitServer using the export.repo entry in gitserver.conf.


Disable deltification on Git repos

GitServer does not support deltified Git packages. It means packages have to be sent in non-deltified format.

This is a performance restriction to speed up metadata and data conversion between the two systems.

To disable deltification on the Git side, run the following command on your Git repository:

git config --global pack.window 0

If GitServer receives a pack with deltas during push the following error message will be displayed:

git deltas are not supported. Please, set the 'pack.window 0' config variable or run an 'git repack -a -f -d' command

The message includes clear instructions on how to "repack" the Git repository to disable deltas:

git repack -a -f -d

Shallow clones are not supported

GitServer does not support shallow clones. Depending on the Git client version, the following error message will be displayed:

> git clone git://localhost/default --depth=1 Cloning into 's'... fatal: Server does not support shallow clients

Compatibility with Git clients

We haven't seen any compatibility issues with git client versions since 1.7.2. Still, we strongly recommend you use the most up-to-date possible git client software.


git push doesn't show progress

git push will not show any progress while the objects are imported into Plastic SCM. This process can take seconds, minutes or hours depending on the push size.


Annotated tags

Annotated tags are correctly imported to Plastic SCM, but if they are cloned from GitServer again into Git, they will be exported as lightweight tags.


Branch names and hierarchies

The branch names with multiple levels can be different in Plastic SCM and Git.

For instance, the Plastic SCM branch /main/Fix-5.0/scm003 will be converted to main-Fix-5.0-scm003 in Git.


Supported Git protocols

Currently GitServer can be accessed through both git:// and http:// protocols.

SSH support will be added later.


Storage restrictions

Currently the file contents of the repositories exported by GitServer are duplicated. This means they are stored in the Plastic SCM format inside the database and in the GitServer storage folder.


Last updated

Apr 19, 2016
  • Now you can push/pull from Git to Plastic.
  • March 30, 2016
  • Publication date.