gCTS is now an option for transporting and storing the codebase using a git-based server. One of the key point to realize is the fact that gCTS is CTS plus “g(it)”. It is still the good old transport system, but backed up by Git which adds some benefits. Comparing to abapGit, gCTS it is not so feature rich but might be easier for teams not accustomed to Git specifics and when they are using traditional single-server dev environment. abapGit has much more “usual” Git inside, giving you much more control over the code you want to commit (patch, diff, tags etc.).

From my not-so long journey with gCTS what I observed is:

  • The way you want to start to use gCTS matters. For totally new projects it is easier, for existing ones you need to plan the migration – switching packages to a new transport layer is one thing (as far as I know there is no tool for doing this automagically for the package hierarchy, you need to go to each one package and adjust), the other headaches I had was not paying attention that some objects from packages switched to gCTS were still locked in transports with my old transport layer. The best is to have all required objects released and then do the switch.

  • Pay attention to the logs accessible in Activities tab and clicking on the transport (or request ID in the after-dev systems).

Activities tab with transport
Transport log in gCTS
Log in the next system after development one

  • What happens if you use the same vSID for another repository? Here is a scenario – I have ZSAMPLE_1 package configured with vSID RE1. Then added ZSAMPLE_2 to another, new repo with RE1 vSID. Packages were also added to ZRE1 transport layer. When you release the transport dedicated for ZSAMPLE_2, changes will be committed to the repo of ZSAMPLE_1 too. The first sign you will find in the log of the transport:
Transport log in gCTS
  • As you see there are 2 VCS Checkin and imports. In the repo for ZSAMPLE_2 I have my objects (from A4HK900065) as expected:
First commit
  • …but the repo for ZSAMPLE_1 package also gets the changes for ZSAMPLE_2:
Second commit
  • So pay attention about these vSIDs/transport layers. The CDS below can be used to check
  • packages assignment to gCTS generated ones.
@AbapCatalog.sqlViewName: 'ZVSID'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'vSIDs and packages'
define view z_vsid
  as select from tmscsys
  association [1..*] to tdevc as _packages
    on $projection.TransportLayer = _packages.pdevclass
  concat('Z', sysnam) as TransportLayer,
  sysnam              as vSID,

       systyp =    'N'
    or systyp =    'V'
  and  systxt like 'gCTS%';
  • As a remote repo server not only major vendor ones can be used – I was playing around with Gogs
  • (as a container), it was working without problems and it is nice option if you don’t want to
  • mess with your GitHub/other online account. The setup I have for Docker-compose:
  container_name: gogs
  hostname: gogs
    - "10022:22"
    - "10880:3000"
  image: gogs/gogs
    - "gogs_data:/data"
  • The quickest Gogs setup is to use SQLite as db, no SSH, user + password as authentication.
  • Then in gCTS just use HTTP, in my case when I’m running ABAP Trial also from Docker, so using internal (Docker) ports:
Repository settings for Gogs
  • If the hosting provider of your choice offers workflow/processing features, then you can use it to fill some gaps of missing Git features and use it to bring more interesting post-processing steps. Here are sample actions like echoing only changed ABAP files with git diff and creating a pull request to the main branch on push to the dev branch.

GitHub actions result
Automated pull request
Changed files - output from the action

  • GitHub action file:
      - dev
    name: Create pull request
    runs-on: ubuntu-latest
      - uses: actions/checkout@v2
      - name: Create PR
        uses: repo-sync/pull-request@v2
          github_token: ${{ secrets.GITHUB_TOKEN }}
          destination_branch: "main"
          pr_title: "${{ github.event.commits[0].message }}"
          pr_body: ":crown: *An automated PR*"
          pr_label: "auto-pr"
  # Log changed ABAP files
  # Set the changed files as output for another step
    name: Changed ABAP files
    runs-on: ubuntu-latest
      abap: ${{ steps.changes.outputs.abap }}
      - name: Checkout repository
        uses: actions/checkout@v2
          fetch-depth: 2
      - name: Changed files
        id: changes
        run: |
          git diff --name-only --diff-filter=ACMRT HEAD~1 | grep .abap | sed -E 's/objects(.*)/\1/'
          echo "::set-output name=abap::$(git diff --name-only --diff-filter=ACMRT HEAD~1 | grep .abap | sed
           -E 's/objects(.*)/\1/' | xargs)"
  # Sample - use output from previous step
    runs-on: ubuntu-latest
    name: Changed ABAP files from other step
    needs: changed_files
      - name: Print changed files
        run: |
          echo " Changed ABAP files:"
          echo ${{needs.changed_files.outputs.abap}}

PS. This article is also published on SDN: https://blogs.sap.com/2021/11/13/gcts-with-gogs-github-actions-and-some-thoughts/