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.
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:
To enable GitServer on a Plastic SCM server:
gitserver.conf
file on your server's binary directory (where
plasticd.exe
is located)
Now you can push/pull from Git to Plastic SCM as follows:
git push --all git://localhost/defaultThis command will push your Git repo to the Plastic repository named default.
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
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\userGitServer 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
The Plastic SCM server can behave like a Git server transparently accessed by Git clients.
The changes can come to GitServer from different sources:
git push
operation. Once the Git command finishes, changes are immediately available for Plastic SCM & Git clients.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.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.
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:
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.
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:
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.
Suppose now a variation of the previous examples where an unlinked branch as a merge that was fully replicated:
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.
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
It is possible to configure GitServer to skip missing Xlinks to allow synchronization with Git even if some content is lost.
Add unresolvedxlink.skip=true
to your gitserver.conf
as follows:
# skip the xlink entries that cannot be resolved unresolvedxlink.skip=true
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 -> masterIn this case, the Git submodule definition is as follows:
[submodule "mduem"] path = mduem url = git://github.com/user/mduem
Suppose that we want to customize our mapping between the Git submodule and the Plastic Xlink.
We can do it by 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
This means that repo mduem will be translated to mduem-xlinked on the Plastic side of things.
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.
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.
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.
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
.
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 0If 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' commandThe message includes clear instructions on how to "repack" the Git repository to disable deltas:
git repack -a -f -dGitServer 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 clientsWe 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 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.
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.
Currently, GitServer can be accessed through both git:// and http:// protocols.
SSH support will be added later.
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.
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:
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).