Branching lets multiple developers work on isolated copies of the same application. Each developer gets their own branch where changes stay separate from the live application until explicitly merged through a pull request. This helps in protecting production quality through mandatory code reviews before changes go live and provide complete change history through Git integration, making every modification traceable and reversible.
- **Master Branch**: The main branch containing your live application and its linear development history. The master branch is locked. Changes can only enter through approved pull requests, never through direct edits.
- **Sub-Branches**: Independent copies created from the master branch where you make changes freely. Each sub-branch is isolated until merged back to master.
### Versions as Tags
Versions exist only on the master branch and act as tags that mark stable points in your application's development. When you save a version, ToolJet automatically creates a corresponding tag on your Git provider, making each milestone traceable in your repository.
- **Draft Version**: The current working state on master. Only one draft can be active at a time. This is where merged changes land before being finalized.
- **Saved Version**: A finalized, locked milestone that is automatically committed and tagged in Git. No further edits are allowed on a saved version.
- **Released Version**: A saved version that has been promoted through environments and released to production.
**Example**: You create an application and start building on a sub-branch. After merging your changes into master, you pull the changes to *v1*. When you save it, ToolJet commits and creates a `<appname>/v1` tag in Git. You then promote _v1_ through staging and production. Later, you create a new draft _v2_ from _v1_ to continue development. _v1_ remains locked and tagged in Git as a reference point.
To enable branching, you need to configure Git Sync first. Follow the [Git Sync Guide](/docs/development-lifecycle/gitsync/overview) to set it up. Once Git Sync is configured, branching is enabled by default (only during beta). Specify your default branch name (typically "master" or "main") This becomes your master branch where live applications reside.
If you run separate ToolJet instances for different environments (e.g., one for development, another for staging or production), you can connect them to the same Git repository. Git acts as the bridge between instances. Changes saved and tagged on one instance can be pulled into another.
For example:
- **Development instance**: Developers create branches, build features, commit changes, and merge pull requests. Saved versions are automatically tagged in Git.
- **Staging/Production instance**: Pull saved versions from Git to deploy and release them. No manual export or import needed.
This lets you enforce environment separation at the infrastructure level while keeping all instances in sync through a single Git repository.
To decide whether a single or multi-instance setup is right for your organization, refer to [Choosing Your Instance Setup](/docs/tj-setup/instances#choosing-your-instance-setup).
Pull requests are how changes move from sub-branches to the master branch. All pull request management happens in your Git provider (GitHub, GitLab, etc.).
1. Switch to the master branch with an active draft.
2. Click **Save Version**.
3. Enter a version number (e.g., v2, v2.1).
4. Click **Save**.
The version is automatically committed to Git. Once saved, no further commits are allowed on that version. Saved versions represent completed milestones.