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
andhotfix
branches are created from themain
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 themain
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. Themain
branch is protected – direct commits are not allowed.- Feature branches and merge requests
When creating a
feature
branch, always do this from the up-to-datemain
or, if required, from another feature branch. To merge changes from yourfeature
branch tomain
, 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.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.
- Safe merge
Safe merge is an additional safety step before finally merging changes from a
feature
branch tomain
. Based on the merge request changes, Space creates a temporary merge commit with the latest changes from bothmain
andfeature
branches. This commit has its ownref
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 fromfeature
are finally merged tomain
.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-datemain
. If required, last minute changes are cherry-picked frommain
to a particularrelease
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:
You have a project hosted on GitHub (or another Git hosting).
(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.
Go to the JetBrains Space page and click Try for free.
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
Open your Space instance in the browser.
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:
On the main menu, click Administration (expand the menu if you don't see this item).
Choose Billing & Plans.
In the Subscription Plan, click Try premium features.
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.
In the project sidebar, choose Repositories.
Click New repository.
In the New repository window:
Choose GitHub Mirror.
Specify your GitHub repository URL.
Click Get a new token to get an access token from GitHub. Once you get it, paste the token to the text field.
Click Create.
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.
In the project sidebar, choose Repositories.
Choose the repository, and open its Settings.
Open the Protected Branches tab, then click New rule.
In the New Branch Protection Rule window:
Add
+:main
to Branch name patterns. This is the pattern that allows Space to determine to which branches it must apply the rule.Check that Push and Force push under the Regulated actions are set to Nobody.
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
Open your Space instance and in the project sidebar, choose Repositories.
Choose the repository, and open its Settings.
Open the Protected Branches tab, then edit the previously created rule.
Under Quality Gates for Merge Requests, turn the switch On.
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.
To add code owners
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 themain
branch, theCODEOWNERS
file must be located in themain
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.
In the repository settings, open the Protected Branches tab, then edit the previously created rule.
If Quality Gates for Merge Requests are not yet enabled, turn them On.
In Requirements, open Approvals and select the Require approval from code owners checkbox.
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
.
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).
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:
On the main menu, click Extensions, then New application.
Specify an application name, e.g.
TeamCity
and click Create.Go to application settings, namely, to the Authorization tab.
Under In-context Authorization, click Authorize in Project.
Select your project (acme-corp in our case) and click Authorize.
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
Click Save.
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.
Now, let's configure the way TeamCity should authenticate in Space:
In the application settings, switch to the Authentication tab.
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 isacme-corp
, the URI will behttps://acme-corp.teamcity.com/oauth/space/accessToken.html
Copy the Client ID and Client secret. These are credentials that TeamCity will use to authenticate in Space.
Now, let's configure connection on the TeamCity side:
Open your TeamCity instance and go to Project Settings | Connections.
Click Add Connection and choose the JetBrains Space connection type.
Provide the connection settings: URL of your Space instance, and Client ID and Client secret obtained in the previous step.
Now, we should change the VCS root for our TeamCity project to Space:
Open your TeamCity instance and go to Project Settings | VCS Roots.
Click
Edit
for the VCS root that points to your current Git server.In Fetch URL, click the Space icon and sign in to your Space instance.
Click the Space icon one more time and choose the required Git repository in Space.
Change the VCS root name so that it corresponds to the new Git repository name and click Regenerate ID.
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.
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.
In the project sidebar, choose Repositories.
Choose the repository, and open its Settings.
Open the Protected Branches tab, then edit the previously created rule.
If Quality Gates for Merge Requests are not yet enabled, turn them On.
In Requirements, open Jobs and select the Automation job.
First, we must add a build feature that will let TeamCity report build statuses to Space:
Open your TeamCity instance and go to Build Configuration Settings | Build Features.
Click Add build feature and choose Commit Status Publisher.
Specify the settings: Space VCS root, JetBrains Space as Publisher, and the connection to Space. Click Save.
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.
Open your Space instance and in the project sidebar, choose Repositories.
Choose the repository, and open its Settings.
Open the Protected Branches tab, then edit the previously created rule.
If Quality Gates for Merge Requests are not yet enabled, turn them On.
In Requirements, open External checks and select the TeamCity build.
Done! After you complete this step, it won't be possible to merge a change until the corresponding CI/CD build is successfully finished.
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.
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.
Open the repository settings.
Open the Protected Branches tab, then edit the previously created rule.
Turn Safe Merge On and click Select under Configuration file.
Select the file and click Save.
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 inrefs/merge/<merge-request-name>/safe-merge
.In TeamCity, open project settings, then VCS Roots.
Edit the VCS root, namely, in Branch specification, add the line
+:(refs/merge/*)
In order Space could communicate with TeamCity, we need to get a TeamCity access token:
In TeamCity, open your profile, then Access Tokens, then click Create access token.
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
Copy the token value to a secure location.
Save the TeamCity token to a secret storage in Space:
Open your Space instance, then your project.
In the project sidebar, choose Settings.
Open the Secrets & Parameters tab, click Create, and choose Secret.
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.In Value, paste the token value from the previous step and click Save.
All preparations are done, so we can set up safe merge now.
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.
Open the repository settings.
Open the Protected Branches tab, then edit the previously created rule.
Turn Safe Merge On and click Select under Configuration file.
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.
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.