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 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 - Developers can push/pull from Git to a GitServer enabled Plastic SCM server.
  3. Serve as a central repo for heterogeneous teams - Several teams can now collaborate on Git and Plastic SCM. This can happen due to a gradual migration to Plastic SCM where 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 collaborate using Plastic as the central rendezvous point.

Configuring GitServer


Quick GitServer start

To enable GitServer on a Plastic SCM server:

  1. Create an empty gitserver.conf file on your server's binary directory (where plasticd.exe is located)
  2. 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

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

Important! Plastic SCM client installation is also required.

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 must be taken to allow GitServer to use a given HTTP port. It only affects 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), all you need to do is 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

Configuring http authentication

GitServer can secure the Git clients using the HTTP basic authentication.

This means that the Git client will ask you to enter the username and the password when connecting to GitServer if this authentication is enabled.

To configure the HTTP authentication, you just need to add the following entry in the gitserver.conf file:

# http authentication
http.basicauth=true

Of course, GitServer must be configured to listen in the HTTP protocol:

# http authentication
http.port=8080
http.basicauth=true
Important! The Plastic SCM server must be configured in LDAP, AD, or UP security modes to authenticate users. This way, the Git client can enter a valid user/password supported by the server.
Note: The security is only checked at the repository level, which means the server will only check if the user authenticated through Git has permissions in Plastic to view the specified repository (in the Git URL).

How does GitServer work?

The 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 the recent 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 useful in 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 never be 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 essential to understand this limitation and ensure 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 a 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.

Remember 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 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 never be mapped to Git.

All you need to do is 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


How to force GitServer to ignore missing Xlinks


Pushing submodules to Plastic SCM

Git submodules are translated to Plastic SCM Xlinks. In some ways, Xlinks are like evolved submodules to ease the developers' lifes.

When pushing some git changes/repo to GitServer, the operation can fail if submodules are 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 repository create mduem >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


Skipping Git submodules

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

# when a submodule 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 the Plastic SCM server to enable GitServer successfully, a valid 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.


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 simultaneously. 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 a 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 a 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 the GitServer storage folder.


Recreating the GitServer mappings folder

If you need to recreate the GitServer mappings folder for any reason, we cannot guarantee that the new Git SHAs will match the old ones.

The following are examples of actions that will create new Git SHAs that won't match the old ones:

  • If you edit the comment of a changeset.
  • If you perform a replica that affects any of the changesets already mapped(for example, adding new merge links).

So after the Git mappings are recreated, always create a new Git repo and clone it from Plastic.

If you re-use the previous Git repo, you could end up with duplicated commits (and also duplicate changesets when you push back to Plastic).


Last updated

March 22, 2019
  • We replaced the references to deprecated repository administration commands like cm mkrep for their new counterparts.
November 23, 2018
November 08, 2018
November 02, 2018
April 19, 2016
March 30, 2016
  • Publication date.