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:
- 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.
- Use Plastic SCM as a central Git server - Developers can push/pull from Git to a GitServer enabled Plastic SCM server.
- Serve as central repo for heterogeneous teams - Several teams 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.
Quick GitServer start
Enabling GitServer on a Plastic SCM server is very simple:
Create an empty
gitserver.conf file on your server's binary directory (where
plasticd.exe is located)
And then, 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
gitserver.conf is the file controlling the GitServer configuration and it has the following format, where each line is optional:
# port configuration
# mapping storage - the mappings between git and plastic objects
# the default path is automatically generated by the server
# 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)
# repositories to be exported. By default, all repositories
# will be available on GitServer unless a list is specified here
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
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
# http authentication
Of course, GitServer must be configured to listen in the HTTP protocol:
# http authentication
Important: To authenticate users, the Plastic SCM server must be configured in LDAP, AD or UP security modes. This way the Git client can enter a valid user/password supported by the server.
Note: The security is only checked at repository level which means that 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?
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
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:
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:
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:
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
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:
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
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.
! [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)
* [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)
46232e0..41c12e1 master -> master
In this case the Git submodule definition is as follows:
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.
You can add as many
ignore.submoduleUrl entries as required.
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.
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
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 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.
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.
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 please, 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 finally also duplicated changesets when you push back to Plastic).
March 22, 2019
We replaced the references to deprecated repository administration commands like cm mkrep for their new counterparts.
November 23, 2018
We added a note to remind you that the Plastic SCM client installation is required.
November 08, 2018
Now, you can secure the Git clients using the http basic authentication.
November 02, 2018
We added a new restriction about Recreating the GitServer mappings folder.
April 19, 2016
Now, you can push/pull from Git to Plastic.
March 30, 2016