From 35efd28232ebeacfefb6093d4490751615dd13d4 Mon Sep 17 00:00:00 2001 From: Brendan Date: Mon, 20 Oct 2025 13:04:18 +0200 Subject: [PATCH 1/3] Update and clarify signed commits behavior --- doc/user/project/repository/push_rules.md | 40 +++++++++++++- .../repository/signed_commits/_index.md | 54 +++++++++++++++++-- 2 files changed, 89 insertions(+), 5 deletions(-) diff --git a/doc/user/project/repository/push_rules.md b/doc/user/project/repository/push_rules.md index 414f862843d345..9a4c1a3dc544d4 100644 --- a/doc/user/project/repository/push_rules.md +++ b/doc/user/project/repository/push_rules.md @@ -318,7 +318,7 @@ You can combine multiple patterns into one expression. This example combines all ## Require signed commits -[Signed commits](signed_commits/_index.md) are digital signatures used to verify authenticity. +Signed commits are digital signatures used to verify authenticity. Use the **Reject unsigned commits** push rule to require all commits to have cryptographic signatures. When you enable this rule: @@ -336,6 +336,10 @@ To enable the **Reject unsigned commits** push rule: 1. Select **Reject unsigned commits**. 1. Select **Save push rules**. +The behavior of this rule varies depending on your merge strategy and how commits are created. +For information about how this rule works with merge requests, see +[Signed commits ](signed_commits/_index.md). + ## Reject commits that aren't DCO certified Commits signed with the [Developer Certificate of Origin](https://developercertificate.org/) (DCO) @@ -371,9 +375,43 @@ The **Reject unsigned commits** push rule ignores commits that are authenticated GitLab (either through the UI or API). When this push rule is enabled, unsigned commits might still appear in the commit history if a commit was created in GitLab itself. +This commonly happens in these scenarios: + +- **Squash and merge**: When you squash commits during merge, GitLab creates a new squashed commit + that is signed by GitLab (when configured), even if the original commits were unsigned. +- **Web IDE commits**: Commits created through GitLab's web interface are signed by GitLab. +- **Code Suggestions**: Applied suggestions create commits signed by GitLab. +- **API-created commits**: Commits created through GitLab's API are signed by GitLab. + As expected, commits created outside GitLab and pushed to the repository are rejected. For more information, see [issue #5361](https://gitlab.com/gitlab-org/gitaly/-/issues/5361). +### Merge requests with unsigned commits succeed despite push rule + +If you have the **Reject unsigned commits** push rule enabled but merge requests with unsigned +commits are still being merged successfully, this is likely due to one of these factors: + +**Squash and merge is enabled:** +- When squashing is enabled, GitLab creates a single squashed commit that replaces all + individual commits in the merge request. +- This squashed commit is signed by GitLab (when commit signing is configured), allowing + the merge to succeed even if individual commits were unsigned. + +**Commits were created through GitLab's web interface:** +- Commits created through the Web IDE, single-file editor, or Code Suggestions are + automatically signed by GitLab. +- These commits bypass the unsigned commit restriction. + +**Fork synchronization:** +- Push rules are bypassed during [fork synchronization](forking_workflow.md#update-your-fork). +- Changes applied during fork updates don't validate against push rules. + +To ensure all commits are signed: +1. Disable squash and merge if you want to enforce signing on individual commits. +1. Configure [commit signing for GitLab UI commits](signed_commits/web_commits.md) to ensure + web-created commits are signed. +1. Educate contributors on [setting up commit signing](signed_commits/_index.md) for their local Git clients. + ### Bulk update push rules for all projects To update the push rules to be the same for all projects, diff --git a/doc/user/project/repository/signed_commits/_index.md b/doc/user/project/repository/signed_commits/_index.md index 8516e7bb8dad42..3cf2463c32d2b7 100644 --- a/doc/user/project/repository/signed_commits/_index.md +++ b/doc/user/project/repository/signed_commits/_index.md @@ -97,11 +97,57 @@ To restore the green verified label, verify the mapped email address, or remove ## Enforce signed commits with push rules -You can require signed commits across your projects using push rules. -The **Reject unsigned commits** push rule prevents any unsigned commits from being pushed -to a repository, helping organizations maintain code integrity and meet compliance requirements. +You can require signed commits across your projects by using push rules. +The **Reject unsigned commits** push rule prevents unsigned commits from being pushed +to a repository. This helps organizations maintain code integrity and meet compliance requirements. -For more information about how this rule works and its limitations, see [Require signed commits](../push_rules.md#require-signed-commits). +The push rule validates commits at push time, not at merge time. The behavior varies +depending on how commits are created and merged. To enable this rule, see [Require signed commits](../push_rules.md#require-signed-commits). + +For direct pushes: + +- All commits pushed directly to branches must be signed. +- Unsigned commits are rejected at push time. + +For merge requests, the behavior depends on your project's merge strategy: + +- Fast-forward merge: + - All commits in the merge request must be signed. + - Each commit is validated when the merge request is merged. + +- Merge commit (no squashing): + - All commits in the merge request must be signed. + - GitLab creates an additional merge commit, which is signed by GitLab if + commit signing for GitLab UI commits is configured. + +- Squash and merge: + - Individual commits in the merge request don't need to be signed. + - GitLab creates a single squashed commit, which is signed by GitLab if + commit signing for GitLab UI commits is configured. + - This allows unsigned commits from Web IDE, Code Suggestions, and community forks to be merged. + +### Commits created by GitLab + +Commits created through the GitLab web interface are automatically signed by GitLab +when [commit signing for GitLab UI commits](web_commits.md) is configured. +These commits bypass the unsigned commit restriction: + +- Web IDE and single-file editor commits. +- Commits created when you [apply suggestions](../../merge_requests/reviews/suggestions.md#apply-suggestions). + +### Community fork contributions + +Commits from community forks follow the same signing requirements as other commits. +If contributors can't sign their commits, consider enabling +[squash and merge](../../merge_requests/squash_and_merge.md) to allow their contributions. +When squashing is enabled, GitLab creates a signed squash commit regardless of +the signature status of individual commits. + +### Multiple authors + +Each commit must be signed by its committer. +For [co-authored commits](../../merge_requests/reviews/suggestions.md#batch-suggestions), +the commit is signed by the committer, not all authors. ## Troubleshooting -- GitLab From a51e7397a17a10902e13468930a2cbf366752bce Mon Sep 17 00:00:00 2001 From: Brendan Date: Mon, 20 Oct 2025 13:08:52 +0200 Subject: [PATCH 2/3] Remvoe troubleshooting section --- doc/user/project/repository/push_rules.md | 34 ----------------------- 1 file changed, 34 deletions(-) diff --git a/doc/user/project/repository/push_rules.md b/doc/user/project/repository/push_rules.md index 9a4c1a3dc544d4..4cbb7e9970bf9d 100644 --- a/doc/user/project/repository/push_rules.md +++ b/doc/user/project/repository/push_rules.md @@ -375,43 +375,9 @@ The **Reject unsigned commits** push rule ignores commits that are authenticated GitLab (either through the UI or API). When this push rule is enabled, unsigned commits might still appear in the commit history if a commit was created in GitLab itself. -This commonly happens in these scenarios: - -- **Squash and merge**: When you squash commits during merge, GitLab creates a new squashed commit - that is signed by GitLab (when configured), even if the original commits were unsigned. -- **Web IDE commits**: Commits created through GitLab's web interface are signed by GitLab. -- **Code Suggestions**: Applied suggestions create commits signed by GitLab. -- **API-created commits**: Commits created through GitLab's API are signed by GitLab. - As expected, commits created outside GitLab and pushed to the repository are rejected. For more information, see [issue #5361](https://gitlab.com/gitlab-org/gitaly/-/issues/5361). -### Merge requests with unsigned commits succeed despite push rule - -If you have the **Reject unsigned commits** push rule enabled but merge requests with unsigned -commits are still being merged successfully, this is likely due to one of these factors: - -**Squash and merge is enabled:** -- When squashing is enabled, GitLab creates a single squashed commit that replaces all - individual commits in the merge request. -- This squashed commit is signed by GitLab (when commit signing is configured), allowing - the merge to succeed even if individual commits were unsigned. - -**Commits were created through GitLab's web interface:** -- Commits created through the Web IDE, single-file editor, or Code Suggestions are - automatically signed by GitLab. -- These commits bypass the unsigned commit restriction. - -**Fork synchronization:** -- Push rules are bypassed during [fork synchronization](forking_workflow.md#update-your-fork). -- Changes applied during fork updates don't validate against push rules. - -To ensure all commits are signed: -1. Disable squash and merge if you want to enforce signing on individual commits. -1. Configure [commit signing for GitLab UI commits](signed_commits/web_commits.md) to ensure - web-created commits are signed. -1. Educate contributors on [setting up commit signing](signed_commits/_index.md) for their local Git clients. - ### Bulk update push rules for all projects To update the push rules to be the same for all projects, -- GitLab From cbf3fde639a683bd53dd5bf9f0555a262eb19c38 Mon Sep 17 00:00:00 2001 From: Brendan Date: Mon, 20 Oct 2025 13:22:01 +0200 Subject: [PATCH 3/3] Fix spacing in reference link --- doc/user/project/repository/push_rules.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/user/project/repository/push_rules.md b/doc/user/project/repository/push_rules.md index 4cbb7e9970bf9d..539944ae471fc8 100644 --- a/doc/user/project/repository/push_rules.md +++ b/doc/user/project/repository/push_rules.md @@ -338,7 +338,7 @@ To enable the **Reject unsigned commits** push rule: The behavior of this rule varies depending on your merge strategy and how commits are created. For information about how this rule works with merge requests, see -[Signed commits ](signed_commits/_index.md). +[Signed commits](signed_commits/_index.md). ## Reject commits that aren't DCO certified -- GitLab