# Gitea Community - auto-protect default branch

**URL:** <https://forum.gitea.com/t/gitea-community-auto-protect-default-branch/9035>\
**Category:** Install/Maintain/Configure\
**Created:** [April 23, 2024, 8:46pm UTC](https://forum.gitea.com/t/gitea-community-auto-protect-default-branch/9035 "2024-04-23T20:46:53Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Vasiliy](https://avatars.discourse-cdn.com/v4/letter/v/ee7513/32.png) [@Vasiliy](https://forum.gitea.com/u/Vasiliy)\
**Post date:** [April 23, 2024, 8:46pm UTC](https://forum.gitea.com/t/gitea-community-auto-protect-default-branch/9035/1 "2024-04-23T20:46:53Z")

</div>

For every repo we need the default branch (main/master) to be protected (no direct changes).  
Could not find a config option, created a SQL trigger to automatically protect the default branch of every repository in the Gitea with SQL Server DB:

1. The trigger is created on the `repository` table and executed after `INSERT` or `UPDATE`.
2. Inserts rows into the `protected_branch` table for each repository’s default branch that is not already protected.
3. Hardcoded column values of the `protected_branch` table:

- `repo_id`: The ID of the repository.
- `branch_name`: The name of the default branch.
- `enable_whitelist`: An empty string indicating that the whitelist is not enabled.
- `whitelist_user_i_ds`, `whitelist_team_i_ds`, `merge_whitelist_user_i_ds`, `merge_whitelist_team_i_ds`, `status_check_contexts`, `approvals_whitelist_user_i_ds`, `approvals_whitelist_team_i_ds`: These columns are set to `'null'` as placeholders.
- `required_approvals`: Set to 1, indicating that at least one approval is required for merging.
- `protected_file_patterns`: Set to `'*.*'`, which means all files are protected.
- `unprotected_file_patterns`: An empty string indicating no unprotected file patterns.
- `created_unix`, `updated_unix`: The current timestamp in Unix format (seconds since ‘1970-01-01 00:00:00’).

1. The `WHERE` clause in the `SELECT` statement checks if there is no existing protected branch entry for the repository’s default branch using a correlated subquery. This ensures that a new protected branch entry is only inserted if it doesn’t already exist.

The trigger is executed automatically whenever a new repository is inserted or an existing repository is updated in the `repository` table.

– =============================================  
– Author: Vasiliy Goncharenko  
– Create date: 2024.04.23  
– Description: Make every Gitea ‘default’ branch as protected  
– =============================================  
CREATE OR ALTER TRIGGER dbo.repository\_mark\_default\_branch\_as\_protected ON repository  
AFTER INSERT,UPDATE  
AS  
BEGIN  
SET NOCOUNT ON;

```
-- Make every Gitea 'default' branch as protected (if added as a trigger into repository)
INSERT INTO protected_branch (repo_id, branch_name, enable_whitelist, whitelist_user_i_ds, whitelist_team_i_ds, merge_whitelist_user_i_ds, merge_whitelist_team_i_ds, status_check_contexts, approvals_whitelist_user_i_ds, approvals_whitelist_team_i_ds, required_approvals, protected_file_patterns, unprotected_file_patterns, created_unix, updated_unix)
SELECT r.id, r.default_branch, '', 'null', 'null', 'null', 'null', 'null', 'null', 'null', 1, '*.*', '', DATEDIFF(second, '1970-01-01 00:00:00', GETDATE()), DATEDIFF(second, '1970-01-01 00:00:00', GETDATE())
FROM repository r
WHERE NOT EXISTS (
	SELECT 1
	FROM protected_branch pb
	WHERE pb.repo_id = r.id AND pb.branch_name = r.default_branch
);

```

END  
GO

---

<div class="post-metadata">

**Author:** ![Jefry-nolastname](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.gitea.com/jefry-nolastname/32/6601_2.png) [@Jefry-nolastname](https://forum.gitea.com/u/Jefry-nolastname)\
**Post date:** [January 23, 2025, 7:15am UTC](https://forum.gitea.com/t/gitea-community-auto-protect-default-branch/9035/2 "2025-01-23T07:15:07Z")

</div>

Thankyou, this trigger actually very useful and I wish this post could be pinned as a must have. This feature shouldn’t have to be exclusive to the enterprise version since main/primary branch should be protected by default to avoid conflicts.
