JetBrains Space Help

Branching. Space Git Flow

Choosing the right branching strategy for your team is important because it can have a significant impact on the development process, including how safe it is to introduce code changes, how often new features are released, and how quickly changes can be delivered to the production environment.

Some common strategies include:

Git flow

This strategy is useful for teams that have a clear release process and need to keep the production environment stable.

  • The main branch is for production code only.

  • The develop branch is for development code.

  • feature branches are created from the develop branch.

  • release and hotfix branches are created from the main branch.

GitHub flow

This strategy emphasizes collaboration, frequent releases, and a streamlined development process.

  • The main branch is for production code only.

  • Development is done in separate feature branches and then merged into the main branch when ready.

  • Pull requests are used for code review and to discuss changes before merging.

  • Releases are cut from the main branch and tagged for easy versioning.

Trunk-based development

This strategy requires strict discipline and collaboration among developers to maintain a stable trunk branch.

  • All code is committed to a single branch, usually called trunk.

  • The trunk branch is always production-ready.

  • Development work is done directly on the trunk branch.

  • No long-lived feature branches.

  • Before pushing the changes, developers perform a full "pre-integrate" build (compile, unit tests, etc.) on their local machines.

  • After the changes are already in trunk, there could be a "post-integrate" code review.

Each strategy has its own strengths and weaknesses, and the best choice depends on the specific needs of your team. Though in Space you can implement almost any flow, we recommend that you consider employing a strategy that is native to Space – Space Git flow.

Space Git flow

Space Git flow is similar to GitHub flow, with a greater emphasis on the safety of making changes to the main branch and the ability to scale to large projects and teams. In JetBrains, we use this flow for many of our products, including JetBrains Space itself.

The main concepts of the Space Git flow are listed below. You can consider these as your to-do list. Though most of the items are optional, the more you get, the closer you will be to the best and safest flow possible.

Protected branches

A single main branch is always production-ready. The main branch is protected – direct commits are not allowed.

Learn how to protect a branch

Feature branches and merge requests

When creating a feature branch, always do this from the up-to-date main or, if required, from another feature branch. To merge changes from your feature branch to main, you must create a merge request.

Merge requests and quality gates

Before the changes can be actually merged, a merge request must pass through quality gates (set of conditions). There are three quality gates; each is optional:

  • Approval in a turn-based code review: After commenting on the changes, the reviewer passes the turn to the author. The author then applies the comments and feedback to the code, making any necessary revisions. Once the revisions are made, the author adds new commits to the code review and passes the turn back to the reviewer. The process continues until the review is finally approved by the reviewer(s).

    The reviewer can be assigned automatically based on the code owners feature – the CODEOWNERS file outlines who owns certain paths or files in a repository.

    Learn how to set up code owners

  • A successfully completed Space Automation job.

  • An external check, which passes if an external service approves the merge request by sending an HTTP API request to Space. For example, this could be an external CI/CD service like JetBrains TeamCity.

    Learn how to set up the 'green build' quality gates

Merge request in Space Git Flow
Safe merge

Safe merge is an additional safety step before finally merging changes from a feature branch to main. Based on the merge request changes, Space creates a temporary merge commit with the latest changes from both main and feature branches. This commit has its own ref and can be used to perform the required quality checks, e.g., an Automation job or a TeamCity build that compiles the project and runs tests. If the checks are successful, the changes from feature are finally merged to main.

You can use safe merge instead of or in addition to the 'green build' quality gate. Learn how to set up safe merge

Release branches

If the project implies some public releases, you should use release branches created from the up-to-date main. If required, last minute changes are cherry-picked from main to a particular release branch.

How the Space Git flow works in a project

Here's a showcase of a project that fully implements the Space Git flow.

Tutorial. Set up Space Git flow for your project

The best part about Space Git flow is that you can easily employ it for your existing project even if you don't currently use JetBrains Space.

Suppose:

  1. You have a project hosted on GitHub (or another Git hosting).

  2. (Optional) You use JetBrains TeamCity for CI/CD purposes.

Here's how you can switch to the Space Git flow.

Step 1. Create a Space organization

First things first – We start with creating a new organization in Space.

  1. Go to the JetBrains Space page and click Try for free.

  2. Fill in your profile and organization settings. The most important one is the URL of your future Space instance. Usually, it contains the name of your company or team. In our tutorial, it'll be acme-corp.jetbrains.space

  3. Open your Space instance in the browser.

  4. Some of the Space Git flow features require at minimum the Organization plan. You can try it for free during the 30-day trial period. To switch to the Organization plan:

    1. On the main menu, click administration.png Administration (expand the menu if you don't see this item).

    2. Choose Billing & Plans.

    3. In the Subscription Plan, click Try premium features.

      Switch to Org plan
    4. Click Confirm.

Done! We have a working Space instance with enabled Organization plan features.

Step 2. Mirror your existing Git repository

In this tutorial, we suppose that you have an existing Git repository hosted somewhere. In fact, this could be any Git hosting but for the sake of simplicity, let it be GitHub. Now, our goal is to create its mirror in Space.

  1. In the project sidebar, choose Repositories.

  2. Click New repository.

  3. In the New repository window:

    1. Choose GitHub Mirror.

    2. Specify your GitHub repository URL.

    3. Click Get a new token to get an access token from GitHub. Once you get it, paste the token to the text field.

    New repository
  4. Click Create.

  5. Important! Ensure all developers have switched to the new Git remote (the mirror in Space). Otherwise, all repository restrictions we apply in the further steps won't make any sense.

Done! We have a working mirror of your repository in Space. The commits you push to the Space mirror will be delivered to the GitHub repository and vice versa.

Step 3. Protect the main branch

The next step is to protect the main branch from direct commits. After doing this, the only way a change can make it to main is through a merge request.

  1. In the project sidebar, choose Repositories.

  2. Choose the repository, and open its Settings.

    Repo settings
  3. Open the Protected Branches tab, then click New rule.

  4. In the New Branch Protection Rule window:

    1. Add +:main to Branch name patterns. This is the pattern that allows Space to determine to which branches it must apply the rule.

    2. Check that Push and Force push under the Regulated actions are set to Nobody.

    Protect main branch
  5. Click Save.

Done! Nobody is allowed to push or force push commits to the main branch of our project. The only way to push to main now is to use merge requests.

Step 4. Add obligatory code reviews and code owners

One of the main ways to ensure code quality is introducing merge requests – a developer must make an explicit request to merge their changes to a protected branch. Before being merged, the changes must pass through the so-called quality gates. The first quality gate we set up in this tutorial is an obligatory code review – your colleagues must review and approve the code changes before they can be merged into main.

To simplify assignment of a right person for a code review, you can employ the code owners feature. This is a CODEOWNERS file that assigns the particular files and directories to the corresponding team members. After a code review is created, Space automatically assigns a reviewer based on CODEOWNERS.

To add a code review quality gate

  1. Open your Space instance and in the project sidebar, choose Repositories.

  2. Choose the repository, and open its Settings.

  3. Open the Protected Branches tab, then edit the previously created rule.

    Edit rule
  4. Under Quality Gates for Merge Requests, turn the switch On.

  5. In Requirements, open Approvals and specify the required reviewers in the From field. This could be a particular user or a user group. In the require ... approval field, specify how many approvals are enough. For example:

    • From Project Member require 2 approval: a merge request must be approved by at least 2 project members (any members).

    • From Project Admin, John Doe require 1 approval: a merge request must be approved either by John or by any user with the Project Admin role.

    Approve merge request gate

To add code owners

  1. In your project repository, create a CODEOWNERS file. The file must be located either in the project root or in the .space directory.

    Important! The CODEOWNERS file must be on the target branch of the merge request. So, if you protect the main branch, the CODEOWNERS file must be located in the main branch as well.

    In the CODEOWNERS file, assign specific parts of the code base to specific users or user groups. For example:

    # John handles Gradle files *.gradle John.Doe # Sarah handles the source code src Sarah.Connor # CODEOWNERS file is for Project Admins CODEOWNERS "Project Admin"

    For more information about the file syntax, refer to Code Owners.

  2. In the repository settings, open the Protected Branches tab, then edit the previously created rule.

  3. If Quality Gates for Merge Requests are not yet enabled, turn them On.

  4. In Requirements, open Approvals and select the Require approval from code owners checkbox.

    Approve merge request gate

Done! Now, a merge request will require an obligatory code review.

Important: the reviewers you add via the From field and the reviewers assigned based on the CODEOWNERS file do not exclude, but complement each other. Approval is required from all reviewers specified in From and CODEOWNERS.

Approve code review gate

Step 5. Connect your CI/CD server to Space

We suppose that CI/CD is already configured for your project via JetBrains TeamCity. If this is not the case, you can configure the CI/CD server built in Space – Space Automation. In this tutorial, we will provide instructions for both TeamCity and Automation.

If you decide to go with Space Automation, skip this step (better not just skip it, but configure Automation for your project following our examples).

  1. First we need to get an authentication token so that TeamCity could log in to Space. To get a token, we should register an application in Space. TeamCity will work in Space on behalf of this application:

    1. On the main menu, click Extensions Extensions, then New application.

    2. Specify an application name, e.g. TeamCity and click Create.

    3. Go to application settings, namely, to the Authorization tab.

    4. Under In-context Authorization, click Authorize in Project.

    5. Select your project (acme-corp in our case) and click Authorize.

    6. Click Configure and select the following permissions:

      • Project | View project details

      • Git Repositories | Report external status checks

      • Git Repositories | Read Git repositories

      • Code Review | View code reviews

    7. Click Save.

    8. Return back to the Authorization tab and click Configure under Global Authorization. Here we'll need the Members | View member profiles permission (it'll allow TeamCity to get info about a user who starts a build). Click Save.

    App Authorization
  2. Now, let's configure the way TeamCity should authenticate in Space:

    1. In the application settings, switch to the Authentication tab.

    2. Under Authentication flows, enable Authorization Code Flow and click Save. Enter the redirect URI https://<server>:<port>/oauth/space/accessToken.html of your TeamCity Server. For example, if our TeamCity cloud instance is acme-corp, the URI will be https://acme-corp.teamcity.com/oauth/space/accessToken.html

    3. Copy the Client ID and Client secret. These are credentials that TeamCity will use to authenticate in Space.

    App Authorization
  3. Now, let's configure connection on the TeamCity side:

    1. Open your TeamCity instance and go to Project Settings | Connections.

    2. Click Add Connection and choose the JetBrains Space connection type.

    3. Provide the connection settings: URL of your Space instance, and Client ID and Client secret obtained in the previous step.

    Connection to Space
  4. Now, we should change the VCS root for our TeamCity project to Space:

    1. Open your TeamCity instance and go to Project Settings | VCS Roots.

    2. Click Edit for the VCS root that points to your current Git server.

    3. In Fetch URL, click the Space icon and sign in to your Space instance.

      Space VCS root
    4. Click the Space icon one more time and choose the required Git repository in Space.

      Space VCS root
    5. Change the VCS root name so that it corresponds to the new Git repository name and click Regenerate ID.

      Space VCS root
    6. Run the build to ensure the changes were correct.

Done! The CI/CD server is connected to Space, so, we're ready to use it for the 'green build' requirement.

Step 6. Add the 'green build' quality gate

One more quality gate that ensures code quality is the 'green build' requirement. The changes are allowed to be merged into main only if a CI/CD server can successfully build the source branch (the one that contains the changes, e.g., a feature branch). In this step, we'll show how you can do this for both Space Automation and TeamCity.

  1. We imply that you have already created an Automation job that builds your project. If not, it's a good time to do this: open your Space instance, select Jobs in the project sidebar and follow the instructions. Don't forget to check our Automation examples.

  2. In the project sidebar, choose Repositories.

  3. Choose the repository, and open its Settings.

  4. Open the Protected Branches tab, then edit the previously created rule.

    Edit rule
  5. If Quality Gates for Merge Requests are not yet enabled, turn them On.

  6. In Requirements, open Jobs and select the Automation job.

    Job check
  1. First, we must add a build feature that will let TeamCity report build statuses to Space:

    1. Open your TeamCity instance and go to Build Configuration Settings | Build Features.

    2. Click Add build feature and choose Commit Status Publisher.

      Add feature
    3. Specify the settings: Space VCS root, JetBrains Space as Publisher, and the connection to Space. Click Save.

      Publisher settings
    4. Run the build to send the build status to Space for the first time. We do this so that Space could understand that the project has a corresponding TeamCity build.

  2. Open your Space instance and in the project sidebar, choose Repositories.

  3. Choose the repository, and open its Settings.

  4. Open the Protected Branches tab, then edit the previously created rule.

    Edit rule
  5. If Quality Gates for Merge Requests are not yet enabled, turn them On.

  6. In Requirements, open External checks and select the TeamCity build.

    External check

Done! After you complete this step, it won't be possible to merge a change until the corresponding CI/CD build is successfully finished.

Green build gate

Step 7. Set up 'safe merge'

In projects with large number of merge requests, it makes sense to prefer the Safe Merge feature over a simple 'green build' quality gate. Safe merge creates a temporary merge commit with the latest updates from your main and feature branches, and then testing it with Automation jobs or TeamCity builds. This is important because while you were working on a feature branch, the main branch could have received changes that conflict with your work. By using safe merge, you can catch these conflicts before actually merging the branches.

  1. Let's start with creating a JSON file that will configure safe merge settings. The exact file location doesn't matter. The main requirement is that you must create the file in the target repository. In our example, it's main.

    Create the file and edit its content. In our case, we need a simple configuration that will specify the Automation job that must be run during safe merge:

    // If you want to use this example in a real JSON file, delete all comments first! { // Safe Merge version number. Should be "1.0" "version": "1.0", // What to do it build fails. // This setting is helpful for builds with flaky tests. "retry-policy": { // How many build attempts are allowed "num-retries": 3, // Use the same temporary merge commit on a retry // or create a new one "reuse-merge": true }, "builds": [ { "job": { // Automation job name "name": "Build and run tests" } } ] }

    For details on configuration syntax, refer to the safe merge documentation.

  2. Open the repository settings.

  3. Open the Protected Branches tab, then edit the previously created rule.

  4. Turn Safe Merge On and click Select under Configuration file.

    Safe merge enable
  5. Select the file and click Save.

  1. Let's start by adding a new branch specification to the project's VCS root in TeamCity. We must do this because TeamCity monitors only the refs/heads/* branches by default, but Space creates temporary merge commits in refs/merge/<merge-request-name>/safe-merge.

    1. In TeamCity, open project settings, then VCS Roots.

    2. Edit the VCS root, namely, in Branch specification, add the line

      +:(refs/merge/*)
    TeamCity branch specification
  2. In order Space could communicate with TeamCity, we need to get a TeamCity access token:

    1. In TeamCity, open your profile, then Access Tokens, then click Create access token.

      Create token in TeamCity
    2. Provide token options like name and expiration date. For the sake of security, limit the permission scope per project and grant the following permissions:

      • Run build

      • Stop / remove from queue any personal build

      • Stop build / remove from queue

      • View build configuration settings

      • View build runtime parameters and data

      Create token in TeamCity
    3. Copy the token value to a secure location.

  3. Save the TeamCity token to a secret storage in Space:

    1. Open your Space instance, then your project.

    2. In the project sidebar, choose Settings.

    3. Open the Secrets & Parameters tab, click Create, and choose Secret.

      Create secret
    4. In Key, provide a secret name, e.g. teamcity-token. We will use this name to refer to this token in the safe merge configuration.

    5. In Value, paste the token value from the previous step and click Save.

    Create secret

    All preparations are done, so we can set up safe merge now.

  4. Now, we should create a JSON file that will configure safe merge settings. The exact file location doesn't matter. The main requirement is that you must create the file in the target repository. In our example, it's main.

    Create the file and edit its content. In our case, we need a simple configuration that will specify the TeamCity server settings and the build configuration that must be run during safe merge:

    // If you want to use this example in a real JSON file, delete all comments first! { // Safe Merge version number. Should be "1.0" "version": "1.0", // What to do it build fails. // This setting is helpful for builds with flaky tests. "retry-policy": { // How many build attempts are allowed "num-retries": 3, // Use the same temporary merge commit on a retry // or create a new one "reuse-merge": true }, "builds": [ { "teamcity": { // Build configuration ID // You can get it in build config settings "configuration": "AcmeProject_BuildAndRunTests", // URL of your TeamCity instance "url": "https://acme-corp.teamcity.com", // Key of the secret that stores TeamCity token // Created in one of the previous steps // Format: ${secret-key} "token": "${teamcity-token}", } } ] }

    For details on configuration syntax, refer to the safe merge documentation.

  5. Open the repository settings.

  6. Open the Protected Branches tab, then edit the previously created rule.

  7. Turn Safe Merge On and click Select under Configuration file.

    Safe merge enable
  8. Select the file and click Save.

That's it! The safe merge feature is enabled for your project. Now, the Merge button in a merge request will change to Safe merge. Clicking it will create a temporary merge commit and run the CI/CD build we've specified in the JSON file. If the build is successful, this will end up with merging the changes into the main branch. If you want only to run the build without actually merging the changes, click Dry run.

Safe merge

Conclusion

We believe that Space Git flow addresses the challenges of large projects and teams and guarantees that code changes are thoroughly reviewed and tested before being merged. Though, this tutorial is a good starting point, it's obvious that every project is different and the final flow configuration may require some adjustments to fully meet your needs.

Last modified: 16 June 2023