feat(proto): merge request mergeability, its Watch event and the merge commit mode
- commit
- c671ff44c6025b2c1819dced069baee101b836c1
- author
- brice · · 2026-10-19 12:32 UTC
- committer
- brice · · 2026-10-19 14:35 UTC
- parent
- 2aff1f7
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
14 files · +717 -298
M docs/services.md +2 -2
| @@ -5,10 +5,10 @@ | |||
| 5 | 5 | | `RepoService` | `ListRepos`, `GetRepo`, `CreateRepo`, `UpdateRepo` (field mask, merge settings), `DeleteRepo` | | |
| 6 | 6 | | `GitService` | `ListRefs`, `GetTree`, `ListPaths`, `GetBlob` (streamed), `ListCommits`, `GetCommit` (structured diff), `ResolveRevision` | | |
| 7 | 7 | | `TokenService` | `CreateToken` (secret shown once), `ListTokens`, `RevokeToken` | | |
| 8 | - | | `MergeRequestService` | `CreateMergeRequest`, `ListMergeRequests`, `GetMergeRequest` (commits, diff, comments), `AddComment`, `EditComment`, `DeleteComment`, `ResolveComment`, `CloseMergeRequest`, `MergeMergeRequest`, `MarkRead` | | |
| 8 | + | | `MergeRequestService` | `CreateMergeRequest`, `ListMergeRequests`, `GetMergeRequest` (commits, diff, comments), `AddComment`, `EditComment`, `DeleteComment`, `ResolveComment`, `CloseMergeRequest`, `MergeMergeRequest` (modes fast-forward, squash, merge commit), `MarkRead`. Open merge requests carry `mergeability` (up to date, behind, conflict, or checking) and `Watch` publishes `MergeRequestMergeability` when it changes (feature `merge_requests.mergeability`) | | |
| 9 | 9 | | `IssueService` | `CreateIssue`, `ListIssues`, `GetIssue` (comments), `AddIssueComment`, `CloseIssue`, `ReopenIssue`; owner only: `ListPendingIssues`, `ApproveIssue`, `RejectIssue`. Feature `issues`. Issues share numbers with merge requests | | |
| 10 | 10 | | `SessionService` | `CreateLoginLink`, `SignOutEverywhere` (owner only) | | |
| 11 | - | | `EventService` | `Watch` (streamed, resumable). Topics `home`, `repo:<name>` and `owner` (owner rights only). Events 17–21: `issue_opened`, `issue_closed`, `issue_reopened`, `issue_commented`, and `issue_submitted` (only on `owner`, no content) | | |
| 11 | + | | `EventService` | `Watch` (streamed, resumable). Topics `home`, `repo:<name>` and `owner` (owner rights only). Events 17–21: `issue_opened`, `issue_closed`, `issue_reopened`, `issue_commented`, and `issue_submitted` (only on `owner`, no content). Event 22: `merge_request_mergeability` | | |
| 12 | 12 | | `ServerService` | `GetVersion` (version and features), `GetSigningKey`, `RotateOIDCKey` (owner only) | | |
| 13 | 13 | | `TrustedKeyService` | `ListTrustedKeys`, `AddTrustedKey` and `RemoveTrustedKey` (owner only). `Commit.verification` carries the result of the check (feature `commit_signatures`) | | |
| 14 | 14 | | `RunService` | `ListRuns`, `GetRun`, `GetJob`, `GetJobLog` (streamed, follow), `ListAnnotations`, `GetStepSummaries`, `CancelRun`, `RerunRun`, `DispatchWorkflow`, `ListWorkflows`, `DisableWorkflow`, `EnableWorkflow`, `ListChecks`, `ListRunners`, `RemoveRunner` | | |
| @@ -5,10 +5,10 @@ | |||||
| 5 | | `RepoService` | `ListRepos`, `GetRepo`, `CreateRepo`, `UpdateRepo` (field mask, merge settings), `DeleteRepo` | | 5 | | `RepoService` | `ListRepos`, `GetRepo`, `CreateRepo`, `UpdateRepo` (field mask, merge settings), `DeleteRepo` | | ||
| 6 | | `GitService` | `ListRefs`, `GetTree`, `ListPaths`, `GetBlob` (streamed), `ListCommits`, `GetCommit` (structured diff), `ResolveRevision` | | 6 | | `GitService` | `ListRefs`, `GetTree`, `ListPaths`, `GetBlob` (streamed), `ListCommits`, `GetCommit` (structured diff), `ResolveRevision` | | ||
| 7 | | `TokenService` | `CreateToken` (secret shown once), `ListTokens`, `RevokeToken` | | 7 | | `TokenService` | `CreateToken` (secret shown once), `ListTokens`, `RevokeToken` | | ||
| 8 | - | | `MergeRequestService` | `CreateMergeRequest`, `ListMergeRequests`, `GetMergeRequest` (commits, diff, comments), `AddComment`, `EditComment`, `DeleteComment`, `ResolveComment`, `CloseMergeRequest`, `MergeMergeRequest`, `MarkRead` | | 8 | + | | `MergeRequestService` | `CreateMergeRequest`, `ListMergeRequests`, `GetMergeRequest` (commits, diff, comments), `AddComment`, `EditComment`, `DeleteComment`, `ResolveComment`, `CloseMergeRequest`, `MergeMergeRequest` (modes fast-forward, squash, merge commit), `MarkRead`. Open merge requests carry `mergeability` (up to date, behind, conflict, or checking) and `Watch` publishes `MergeRequestMergeability` when it changes (feature `merge_requests.mergeability`) | |
| 9 | | `IssueService` | `CreateIssue`, `ListIssues`, `GetIssue` (comments), `AddIssueComment`, `CloseIssue`, `ReopenIssue`; owner only: `ListPendingIssues`, `ApproveIssue`, `RejectIssue`. Feature `issues`. Issues share numbers with merge requests | | 9 | | `IssueService` | `CreateIssue`, `ListIssues`, `GetIssue` (comments), `AddIssueComment`, `CloseIssue`, `ReopenIssue`; owner only: `ListPendingIssues`, `ApproveIssue`, `RejectIssue`. Feature `issues`. Issues share numbers with merge requests | | ||
| 10 | | `SessionService` | `CreateLoginLink`, `SignOutEverywhere` (owner only) | | 10 | | `SessionService` | `CreateLoginLink`, `SignOutEverywhere` (owner only) | | ||
| 11 | - | | `EventService` | `Watch` (streamed, resumable). Topics `home`, `repo:<name>` and `owner` (owner rights only). Events 17–21: `issue_opened`, `issue_closed`, `issue_reopened`, `issue_commented`, and `issue_submitted` (only on `owner`, no content) | | 11 | + | | `EventService` | `Watch` (streamed, resumable). Topics `home`, `repo:<name>` and `owner` (owner rights only). Events 17–21: `issue_opened`, `issue_closed`, `issue_reopened`, `issue_commented`, and `issue_submitted` (only on `owner`, no content). Event 22: `merge_request_mergeability` | |
| 12 | | `ServerService` | `GetVersion` (version and features), `GetSigningKey`, `RotateOIDCKey` (owner only) | | 12 | | `ServerService` | `GetVersion` (version and features), `GetSigningKey`, `RotateOIDCKey` (owner only) | | ||
| 13 | | `TrustedKeyService` | `ListTrustedKeys`, `AddTrustedKey` and `RemoveTrustedKey` (owner only). `Commit.verification` carries the result of the check (feature `commit_signatures`) | | 13 | | `TrustedKeyService` | `ListTrustedKeys`, `AddTrustedKey` and `RemoveTrustedKey` (owner only). `Commit.verification` carries the result of the check (feature `commit_signatures`) | | ||
| 14 | | `RunService` | `ListRuns`, `GetRun`, `GetJob`, `GetJobLog` (streamed, follow), `ListAnnotations`, `GetStepSummaries`, `CancelRun`, `RerunRun`, `DispatchWorkflow`, `ListWorkflows`, `DisableWorkflow`, `EnableWorkflow`, `ListChecks`, `ListRunners`, `RemoveRunner` | | 14 | | `RunService` | `ListRuns`, `GetRun`, `GetJob`, `GetJobLog` (streamed, follow), `ListAnnotations`, `GetStepSummaries`, `CancelRun`, `RerunRun`, `DispatchWorkflow`, `ListWorkflows`, `DisableWorkflow`, `EnableWorkflow`, `ListChecks`, `ListRunners`, `RemoveRunner` | | ||
M gen/ermite/ermiteconnect/merge_request.connect.go +12 -6
| @@ -127,9 +127,12 @@ type MergeRequestServiceClient interface { | |||
| 127 | 127 | // never merged unseen. Fails with invalid_argument if head_id is empty or | |
| 128 | 128 | // not a commit id, and with failed_precondition if the merge request is not | |
| 129 | 129 | // open, if the source branch no longer points to head_id ("branch moved, | |
| 130 | - | // read again"), if the target is not an ancestor of the head (rebase and | |
| 131 | - | // push again), if the mode is not allowed by RepoSettings, or if a check | |
| 132 | - | // fails and RepoSettings.failing_checks_block is set. Merges of one | |
| 130 | + | // read again"), if the mode is fast-forward and the target is not an | |
| 131 | + | // ancestor of the head (rebase and push again, or merge with squash or | |
| 132 | + | // merge commit), if the mode is squash or merge commit and the head | |
| 133 | + | // conflicts with the target or shares no history with it (rebase and push | |
| 134 | + | // again), if the mode is not allowed by RepoSettings, or if a check fails | |
| 135 | + | // and RepoSettings.failing_checks_block is set. Merges of one | |
| 133 | 136 | // repository run one at a time. Repeating a call that succeeded fails with | |
| 134 | 137 | // failed_precondition (not open). On success the server publishes | |
| 135 | 138 | // MergeRequestMerged then Pushed for the target branch. | |
| @@ -339,9 +342,12 @@ type MergeRequestServiceHandler interface { | |||
| 339 | 342 | // never merged unseen. Fails with invalid_argument if head_id is empty or | |
| 340 | 343 | // not a commit id, and with failed_precondition if the merge request is not | |
| 341 | 344 | // open, if the source branch no longer points to head_id ("branch moved, | |
| 342 | - | // read again"), if the target is not an ancestor of the head (rebase and | |
| 343 | - | // push again), if the mode is not allowed by RepoSettings, or if a check | |
| 344 | - | // fails and RepoSettings.failing_checks_block is set. Merges of one | |
| 345 | + | // read again"), if the mode is fast-forward and the target is not an | |
| 346 | + | // ancestor of the head (rebase and push again, or merge with squash or | |
| 347 | + | // merge commit), if the mode is squash or merge commit and the head | |
| 348 | + | // conflicts with the target or shares no history with it (rebase and push | |
| 349 | + | // again), if the mode is not allowed by RepoSettings, or if a check fails | |
| 350 | + | // and RepoSettings.failing_checks_block is set. Merges of one | |
| 345 | 351 | // repository run one at a time. Repeating a call that succeeded fails with | |
| 346 | 352 | // failed_precondition (not open). On success the server publishes | |
| 347 | 353 | // MergeRequestMerged then Pushed for the target branch. | |
| @@ -127,9 +127,12 @@ type MergeRequestServiceClient interface { | |||||
| 127 | // never merged unseen. Fails with invalid_argument if head_id is empty or | 127 | // never merged unseen. Fails with invalid_argument if head_id is empty or | ||
| 128 | // not a commit id, and with failed_precondition if the merge request is not | 128 | // not a commit id, and with failed_precondition if the merge request is not | ||
| 129 | // open, if the source branch no longer points to head_id ("branch moved, | 129 | // open, if the source branch no longer points to head_id ("branch moved, | ||
| 130 | - | // read again"), if the target is not an ancestor of the head (rebase and | 130 | + | // read again"), if the mode is fast-forward and the target is not an |
| 131 | - | // push again), if the mode is not allowed by RepoSettings, or if a check | 131 | + | // ancestor of the head (rebase and push again, or merge with squash or |
| 132 | - | // fails and RepoSettings.failing_checks_block is set. Merges of one | 132 | + | // merge commit), if the mode is squash or merge commit and the head |
| 133 | + | // conflicts with the target or shares no history with it (rebase and push | |||
| 134 | + | // again), if the mode is not allowed by RepoSettings, or if a check fails | |||
| 135 | + | // and RepoSettings.failing_checks_block is set. Merges of one | |||
| 133 | // repository run one at a time. Repeating a call that succeeded fails with | 136 | // repository run one at a time. Repeating a call that succeeded fails with | ||
| 134 | // failed_precondition (not open). On success the server publishes | 137 | // failed_precondition (not open). On success the server publishes | ||
| 135 | // MergeRequestMerged then Pushed for the target branch. | 138 | // MergeRequestMerged then Pushed for the target branch. | ||
| @@ -339,9 +342,12 @@ type MergeRequestServiceHandler interface { | |||||
| 339 | // never merged unseen. Fails with invalid_argument if head_id is empty or | 342 | // never merged unseen. Fails with invalid_argument if head_id is empty or | ||
| 340 | // not a commit id, and with failed_precondition if the merge request is not | 343 | // not a commit id, and with failed_precondition if the merge request is not | ||
| 341 | // open, if the source branch no longer points to head_id ("branch moved, | 344 | // open, if the source branch no longer points to head_id ("branch moved, | ||
| 342 | - | // read again"), if the target is not an ancestor of the head (rebase and | 345 | + | // read again"), if the mode is fast-forward and the target is not an |
| 343 | - | // push again), if the mode is not allowed by RepoSettings, or if a check | 346 | + | // ancestor of the head (rebase and push again, or merge with squash or |
| 344 | - | // fails and RepoSettings.failing_checks_block is set. Merges of one | 347 | + | // merge commit), if the mode is squash or merge commit and the head |
| 348 | + | // conflicts with the target or shares no history with it (rebase and push | |||
| 349 | + | // again), if the mode is not allowed by RepoSettings, or if a check fails | |||
| 350 | + | // and RepoSettings.failing_checks_block is set. Merges of one | |||
| 345 | // repository run one at a time. Repeating a call that succeeded fails with | 351 | // repository run one at a time. Repeating a call that succeeded fails with | ||
| 346 | // failed_precondition (not open). On success the server publishes | 352 | // failed_precondition (not open). On success the server publishes | ||
| 347 | // MergeRequestMerged then Pushed for the target branch. | 353 | // MergeRequestMerged then Pushed for the target branch. | ||
M gen/ermite/ermiteconnect/server.connect.go +2 -2
| @@ -53,7 +53,7 @@ type ServerServiceClient interface { | |||
| 53 | 53 | // it first to check compatibility. | |
| 54 | 54 | GetVersion(context.Context, *connect.Request[ermite.GetVersionRequest]) (*connect.Response[ermite.GetVersionResponse], error) | |
| 55 | 55 | // GetSigningKey returns the public key with which the server signs the | |
| 56 | - | // commits it creates (squash merges, see MergeMode). It needs no | |
| 56 | + | // commits it creates (squash and merge commits, see MergeMode). It needs no | |
| 57 | 57 | // authentication: the key is public, and anyone verifying a commit needs it. | |
| 58 | 58 | // Servers that implement it list "signing_key" in | |
| 59 | 59 | // GetVersionResponse.features. | |
| @@ -132,7 +132,7 @@ type ServerServiceHandler interface { | |||
| 132 | 132 | // it first to check compatibility. | |
| 133 | 133 | GetVersion(context.Context, *connect.Request[ermite.GetVersionRequest]) (*connect.Response[ermite.GetVersionResponse], error) | |
| 134 | 134 | // GetSigningKey returns the public key with which the server signs the | |
| 135 | - | // commits it creates (squash merges, see MergeMode). It needs no | |
| 135 | + | // commits it creates (squash and merge commits, see MergeMode). It needs no | |
| 136 | 136 | // authentication: the key is public, and anyone verifying a commit needs it. | |
| 137 | 137 | // Servers that implement it list "signing_key" in | |
| 138 | 138 | // GetVersionResponse.features. | |
| @@ -53,7 +53,7 @@ type ServerServiceClient interface { | |||||
| 53 | // it first to check compatibility. | 53 | // it first to check compatibility. | ||
| 54 | GetVersion(context.Context, *connect.Request[ermite.GetVersionRequest]) (*connect.Response[ermite.GetVersionResponse], error) | 54 | GetVersion(context.Context, *connect.Request[ermite.GetVersionRequest]) (*connect.Response[ermite.GetVersionResponse], error) | ||
| 55 | // GetSigningKey returns the public key with which the server signs the | 55 | // GetSigningKey returns the public key with which the server signs the | ||
| 56 | - | // commits it creates (squash merges, see MergeMode). It needs no | 56 | + | // commits it creates (squash and merge commits, see MergeMode). It needs no |
| 57 | // authentication: the key is public, and anyone verifying a commit needs it. | 57 | // authentication: the key is public, and anyone verifying a commit needs it. | ||
| 58 | // Servers that implement it list "signing_key" in | 58 | // Servers that implement it list "signing_key" in | ||
| 59 | // GetVersionResponse.features. | 59 | // GetVersionResponse.features. | ||
| @@ -132,7 +132,7 @@ type ServerServiceHandler interface { | |||||
| 132 | // it first to check compatibility. | 132 | // it first to check compatibility. | ||
| 133 | GetVersion(context.Context, *connect.Request[ermite.GetVersionRequest]) (*connect.Response[ermite.GetVersionResponse], error) | 133 | GetVersion(context.Context, *connect.Request[ermite.GetVersionRequest]) (*connect.Response[ermite.GetVersionResponse], error) | ||
| 134 | // GetSigningKey returns the public key with which the server signs the | 134 | // GetSigningKey returns the public key with which the server signs the | ||
| 135 | - | // commits it creates (squash merges, see MergeMode). It needs no | 135 | + | // commits it creates (squash and merge commits, see MergeMode). It needs no |
| 136 | // authentication: the key is public, and anyone verifying a commit needs it. | 136 | // authentication: the key is public, and anyone verifying a commit needs it. | ||
| 137 | // Servers that implement it list "signing_key" in | 137 | // Servers that implement it list "signing_key" in | ||
| 138 | // GetVersionResponse.features. | 138 | // GetVersionResponse.features. | ||
M gen/ermite/event.pb.go +207 -112 generated file: collapsed
M gen/ermite/merge_request.pb.go +375 -159 generated file: collapsed
M gen/ermite/repo.pb.go +1 -1 generated file: collapsed
M gen/ermite/server.pb.go +4 -1
| @@ -85,7 +85,10 @@ type GetVersionResponse struct { | |||
| 85 | 85 | // secrets, vars, environment, permissions and trusted fields and Run.trusted), | |
| 86 | 86 | // "ci.dispatch" (RunService.DispatchWorkflow), "ci.concurrency" | |
| 87 | 87 | // (CI_STATUS_PENDING and RunJob.concurrency_group), "ci.cache" (Job.cache) | |
| 88 | - | // and "ci.artifacts" (JobArtifactService and ArtifactService). | |
| 88 | + | // and "ci.artifacts" (JobArtifactService and ArtifactService). The merge | |
| 89 | + | // request identifier "merge_requests.mergeability" covers | |
| 90 | + | // MergeRequest.mergeability, the MergeRequestMergeability event and | |
| 91 | + | // MERGE_MODE_MERGE_COMMIT. | |
| 89 | 92 | Features []string `protobuf:"bytes,2,rep,name=features,proto3" json:"features,omitempty"` | |
| 90 | 93 | unknownFields protoimpl.UnknownFields | |
| 91 | 94 | sizeCache protoimpl.SizeCache | |
| @@ -85,7 +85,10 @@ type GetVersionResponse struct { | |||||
| 85 | // secrets, vars, environment, permissions and trusted fields and Run.trusted), | 85 | // secrets, vars, environment, permissions and trusted fields and Run.trusted), | ||
| 86 | // "ci.dispatch" (RunService.DispatchWorkflow), "ci.concurrency" | 86 | // "ci.dispatch" (RunService.DispatchWorkflow), "ci.concurrency" | ||
| 87 | // (CI_STATUS_PENDING and RunJob.concurrency_group), "ci.cache" (Job.cache) | 87 | // (CI_STATUS_PENDING and RunJob.concurrency_group), "ci.cache" (Job.cache) | ||
| 88 | - | // and "ci.artifacts" (JobArtifactService and ArtifactService). | 88 | + | // and "ci.artifacts" (JobArtifactService and ArtifactService). The merge |
| 89 | + | // request identifier "merge_requests.mergeability" covers | |||
| 90 | + | // MergeRequest.mergeability, the MergeRequestMergeability event and | |||
| 91 | + | // MERGE_MODE_MERGE_COMMIT. | |||
| 89 | Features []string `protobuf:"bytes,2,rep,name=features,proto3" json:"features,omitempty"` | 92 | Features []string `protobuf:"bytes,2,rep,name=features,proto3" json:"features,omitempty"` | ||
| 90 | unknownFields protoimpl.UnknownFields | 93 | unknownFields protoimpl.UnknownFields | ||
| 91 | sizeCache protoimpl.SizeCache | 94 | sizeCache protoimpl.SizeCache | ||
M gen/ermite/types.pb.go +17 -5 generated file: collapsed
M gen_test.go +6 -0
| @@ -114,6 +114,12 @@ func TestEnumNumbers(t *testing.T) { | |||
| 114 | 114 | if got := ermite.MergeMode_MERGE_MODE_SQUASH; got != 2 { | |
| 115 | 115 | t.Errorf("MERGE_MODE_SQUASH = %d, want 2", got) | |
| 116 | 116 | } | |
| 117 | + | if got := ermite.MergeMode_MERGE_MODE_MERGE_COMMIT; got != 3 { | |
| 118 | + | t.Errorf("MERGE_MODE_MERGE_COMMIT = %d, want 3", got) | |
| 119 | + | } | |
| 120 | + | if got := ermite.MergeabilityState_MERGEABILITY_STATE_CONFLICT; got != 4 { | |
| 121 | + | t.Errorf("MERGEABILITY_STATE_CONFLICT = %d, want 4", got) | |
| 122 | + | } | |
| 117 | 123 | if got := ermite.MergeRequestState_MERGE_REQUEST_STATE_CLOSED; got != 3 { | |
| 118 | 124 | t.Errorf("MERGE_REQUEST_STATE_CLOSED = %d, want 3", got) | |
| 119 | 125 | } | |
| @@ -114,6 +114,12 @@ func TestEnumNumbers(t *testing.T) { | |||||
| 114 | if got := ermite.MergeMode_MERGE_MODE_SQUASH; got != 2 { | 114 | if got := ermite.MergeMode_MERGE_MODE_SQUASH; got != 2 { | ||
| 115 | t.Errorf("MERGE_MODE_SQUASH = %d, want 2", got) | 115 | t.Errorf("MERGE_MODE_SQUASH = %d, want 2", got) | ||
| 116 | } | 116 | } | ||
| 117 | + | if got := ermite.MergeMode_MERGE_MODE_MERGE_COMMIT; got != 3 { | |||
| 118 | + | t.Errorf("MERGE_MODE_MERGE_COMMIT = %d, want 3", got) | |||
| 119 | + | } | |||
| 120 | + | if got := ermite.MergeabilityState_MERGEABILITY_STATE_CONFLICT; got != 4 { | |||
| 121 | + | t.Errorf("MERGEABILITY_STATE_CONFLICT = %d, want 4", got) | |||
| 122 | + | } | |||
| 117 | if got := ermite.MergeRequestState_MERGE_REQUEST_STATE_CLOSED; got != 3 { | 123 | if got := ermite.MergeRequestState_MERGE_REQUEST_STATE_CLOSED; got != 3 { | ||
| 118 | t.Errorf("MERGE_REQUEST_STATE_CLOSED = %d, want 3", got) | 124 | t.Errorf("MERGE_REQUEST_STATE_CLOSED = %d, want 3", got) | ||
| 119 | } | 125 | } | ||
M proto/ermite/event.proto +15 -0
| @@ -132,6 +132,9 @@ message Event { | |||
| 132 | 132 | // IssueSubmitted: an issue is awaiting moderation. Delivered only on the | |
| 133 | 133 | // "owner" topic, never on "home" or "repo:<name>", and carries no content. | |
| 134 | 134 | IssueSubmitted issue_submitted = 21; | |
| 135 | + | // MergeRequestMergeability: the mergeability of an open merge request | |
| 136 | + | // changed. | |
| 137 | + | MergeRequestMergeability merge_request_mergeability = 22; | |
| 135 | 138 | } | |
| 136 | 139 | } | |
| 137 | 140 | ||
| @@ -184,6 +187,18 @@ message MergeRequestMerged { | |||
| 184 | 187 | MergeRequest merge_request = 1; | |
| 185 | 188 | } | |
| 186 | 189 | ||
| 190 | + | // MergeRequestMergeability reports the mergeability of an open merge request. | |
| 191 | + | // It is published when the state changes, or when a check settles a result | |
| 192 | + | // that readers had not seen yet (they saw CHECKING), not on every push. | |
| 193 | + | message MergeRequestMergeability { | |
| 194 | + | // Repo is the name of the repository. | |
| 195 | + | string repo = 1; | |
| 196 | + | // Number is the number of the merge request. | |
| 197 | + | int64 number = 2; | |
| 198 | + | // Mergeability is the new result. | |
| 199 | + | Mergeability mergeability = 3; | |
| 200 | + | } | |
| 201 | + | ||
| 187 | 202 | // MergeRequestClosed reports a merge request closed without merging. | |
| 188 | 203 | message MergeRequestClosed { | |
| 189 | 204 | // MergeRequest is the merge request after closing. | |
| @@ -132,6 +132,9 @@ message Event { | |||||
| 132 | // IssueSubmitted: an issue is awaiting moderation. Delivered only on the | 132 | // IssueSubmitted: an issue is awaiting moderation. Delivered only on the | ||
| 133 | // "owner" topic, never on "home" or "repo:<name>", and carries no content. | 133 | // "owner" topic, never on "home" or "repo:<name>", and carries no content. | ||
| 134 | IssueSubmitted issue_submitted = 21; | 134 | IssueSubmitted issue_submitted = 21; | ||
| 135 | + | // MergeRequestMergeability: the mergeability of an open merge request | |||
| 136 | + | // changed. | |||
| 137 | + | MergeRequestMergeability merge_request_mergeability = 22; | |||
| 135 | } | 138 | } | ||
| 136 | } | 139 | } | ||
| 137 | 140 | ||||
| @@ -184,6 +187,18 @@ message MergeRequestMerged { | |||||
| 184 | MergeRequest merge_request = 1; | 187 | MergeRequest merge_request = 1; | ||
| 185 | } | 188 | } | ||
| 186 | 189 | ||||
| 190 | + | // MergeRequestMergeability reports the mergeability of an open merge request. | |||
| 191 | + | // It is published when the state changes, or when a check settles a result | |||
| 192 | + | // that readers had not seen yet (they saw CHECKING), not on every push. | |||
| 193 | + | message MergeRequestMergeability { | |||
| 194 | + | // Repo is the name of the repository. | |||
| 195 | + | string repo = 1; | |||
| 196 | + | // Number is the number of the merge request. | |||
| 197 | + | int64 number = 2; | |||
| 198 | + | // Mergeability is the new result. | |||
| 199 | + | Mergeability mergeability = 3; | |||
| 200 | + | } | |||
| 201 | + | ||||
| 187 | // MergeRequestClosed reports a merge request closed without merging. | 202 | // MergeRequestClosed reports a merge request closed without merging. | ||
| 188 | message MergeRequestClosed { | 203 | message MergeRequestClosed { | ||
| 189 | // MergeRequest is the merge request after closing. | 204 | // MergeRequest is the merge request after closing. | ||
M proto/ermite/merge_request.proto +58 -4
| @@ -44,6 +44,50 @@ enum Verdict { | |||
| 44 | 44 | VERDICT_CHANGES_REQUESTED = 2; | |
| 45 | 45 | } | |
| 46 | 46 | ||
| 47 | + | // MergeabilityState tells whether the head of an open merge request can be | |
| 48 | + | // merged into its target. | |
| 49 | + | enum MergeabilityState { | |
| 50 | + | // Not set. | |
| 51 | + | MERGEABILITY_STATE_UNSPECIFIED = 0; | |
| 52 | + | // The server has no result yet for the current tips of both branches. It | |
| 53 | + | // is replaced by another state when the check completes. | |
| 54 | + | MERGEABILITY_STATE_CHECKING = 1; | |
| 55 | + | // The target is an ancestor of the head: every mode can merge. | |
| 56 | + | MERGEABILITY_STATE_UP_TO_DATE = 2; | |
| 57 | + | // The target has commits the head lacks, but the head merges cleanly: | |
| 58 | + | // squash and merge commit can merge, fast-forward cannot. | |
| 59 | + | MERGEABILITY_STATE_BEHIND = 3; | |
| 60 | + | // The head does not merge cleanly into the target, or the branches share no | |
| 61 | + | // history: no mode can merge. | |
| 62 | + | MERGEABILITY_STATE_CONFLICT = 4; | |
| 63 | + | } | |
| 64 | + | ||
| 65 | + | // Mergeability is the result of checking an open merge request against the | |
| 66 | + | // tips of its branches. | |
| 67 | + | message Mergeability { | |
| 68 | + | // State is the result. | |
| 69 | + | MergeabilityState state = 1; | |
| 70 | + | // TargetId is the commit the target branch pointed to when checked. Empty | |
| 71 | + | // while CHECKING. | |
| 72 | + | string target_id = 2; | |
| 73 | + | // HeadId is the commit the source branch pointed to when checked. Empty | |
| 74 | + | // while CHECKING. | |
| 75 | + | string head_id = 3; | |
| 76 | + | // Behind is the number of commits of the target that the head lacks. Set | |
| 77 | + | // only when state is BEHIND. | |
| 78 | + | int32 behind = 4; | |
| 79 | + | // BehindCapped says that Behind is a lower bound: the server stops counting | |
| 80 | + | // at 1,000. | |
| 81 | + | bool behind_capped = 5; | |
| 82 | + | // ConflictPaths are the paths that conflict, at most 20. Set only when | |
| 83 | + | // state is CONFLICT; empty when the branches share no history. | |
| 84 | + | repeated string conflict_paths = 6; | |
| 85 | + | // ConflictPathsTruncated says that more paths conflict than listed. | |
| 86 | + | bool conflict_paths_truncated = 7; | |
| 87 | + | // CheckedAt is when the server computed the result. Unset while CHECKING. | |
| 88 | + | google.protobuf.Timestamp checked_at = 8; | |
| 89 | + | } | |
| 90 | + | ||
| 47 | 91 | // MergeRequest asks to merge one branch of a repository into another branch | |
| 48 | 92 | // of the same repository. It is about a branch, not about who wrote it. | |
| 49 | 93 | message MergeRequest { | |
| @@ -81,12 +125,19 @@ message MergeRequest { | |||
| 81 | 125 | // merged or closed it is the head at that moment. | |
| 82 | 126 | string head_id = 11; | |
| 83 | 127 | // MergedCommitId is the id of the commit the target branch points to after | |
| 84 | - | // the merge: the head for a fast-forward, the new commit for a squash. | |
| 128 | + | // the merge: the head for a fast-forward, the new commit for a squash or a | |
| 129 | + | // merge commit. | |
| 85 | 130 | // Empty unless state is MERGED. | |
| 86 | 131 | string merged_commit_id = 12; | |
| 87 | 132 | // MergeMode is how the merge request was merged. MERGE_MODE_UNSPECIFIED | |
| 88 | 133 | // unless state is MERGED. | |
| 89 | 134 | MergeMode merge_mode = 13; | |
| 135 | + | // Mergeability tells whether the head can be merged into the target. Set | |
| 136 | + | // while the merge request is OPEN, with state CHECKING until the server has | |
| 137 | + | // a result for the current tips; never set once merged or closed. It is a | |
| 138 | + | // hint: MergeMergeRequest checks again. Set only by servers with the | |
| 139 | + | // "merge_requests.mergeability" feature. | |
| 140 | + | Mergeability mergeability = 14; | |
| 90 | 141 | } | |
| 91 | 142 | ||
| 92 | 143 | // Comment is a note on a merge request, either general or attached to a line | |
| @@ -233,9 +284,12 @@ service MergeRequestService { | |||
| 233 | 284 | // never merged unseen. Fails with invalid_argument if head_id is empty or | |
| 234 | 285 | // not a commit id, and with failed_precondition if the merge request is not | |
| 235 | 286 | // open, if the source branch no longer points to head_id ("branch moved, | |
| 236 | - | // read again"), if the target is not an ancestor of the head (rebase and | |
| 237 | - | // push again), if the mode is not allowed by RepoSettings, or if a check | |
| 238 | - | // fails and RepoSettings.failing_checks_block is set. Merges of one | |
| 287 | + | // read again"), if the mode is fast-forward and the target is not an | |
| 288 | + | // ancestor of the head (rebase and push again, or merge with squash or | |
| 289 | + | // merge commit), if the mode is squash or merge commit and the head | |
| 290 | + | // conflicts with the target or shares no history with it (rebase and push | |
| 291 | + | // again), if the mode is not allowed by RepoSettings, or if a check fails | |
| 292 | + | // and RepoSettings.failing_checks_block is set. Merges of one | |
| 239 | 293 | // repository run one at a time. Repeating a call that succeeded fails with | |
| 240 | 294 | // failed_precondition (not open). On success the server publishes | |
| 241 | 295 | // MergeRequestMerged then Pushed for the target branch. | |
| @@ -44,6 +44,50 @@ enum Verdict { | |||||
| 44 | VERDICT_CHANGES_REQUESTED = 2; | 44 | VERDICT_CHANGES_REQUESTED = 2; | ||
| 45 | } | 45 | } | ||
| 46 | 46 | ||||
| 47 | + | // MergeabilityState tells whether the head of an open merge request can be | |||
| 48 | + | // merged into its target. | |||
| 49 | + | enum MergeabilityState { | |||
| 50 | + | // Not set. | |||
| 51 | + | MERGEABILITY_STATE_UNSPECIFIED = 0; | |||
| 52 | + | // The server has no result yet for the current tips of both branches. It | |||
| 53 | + | // is replaced by another state when the check completes. | |||
| 54 | + | MERGEABILITY_STATE_CHECKING = 1; | |||
| 55 | + | // The target is an ancestor of the head: every mode can merge. | |||
| 56 | + | MERGEABILITY_STATE_UP_TO_DATE = 2; | |||
| 57 | + | // The target has commits the head lacks, but the head merges cleanly: | |||
| 58 | + | // squash and merge commit can merge, fast-forward cannot. | |||
| 59 | + | MERGEABILITY_STATE_BEHIND = 3; | |||
| 60 | + | // The head does not merge cleanly into the target, or the branches share no | |||
| 61 | + | // history: no mode can merge. | |||
| 62 | + | MERGEABILITY_STATE_CONFLICT = 4; | |||
| 63 | + | } | |||
| 64 | + | ||||
| 65 | + | // Mergeability is the result of checking an open merge request against the | |||
| 66 | + | // tips of its branches. | |||
| 67 | + | message Mergeability { | |||
| 68 | + | // State is the result. | |||
| 69 | + | MergeabilityState state = 1; | |||
| 70 | + | // TargetId is the commit the target branch pointed to when checked. Empty | |||
| 71 | + | // while CHECKING. | |||
| 72 | + | string target_id = 2; | |||
| 73 | + | // HeadId is the commit the source branch pointed to when checked. Empty | |||
| 74 | + | // while CHECKING. | |||
| 75 | + | string head_id = 3; | |||
| 76 | + | // Behind is the number of commits of the target that the head lacks. Set | |||
| 77 | + | // only when state is BEHIND. | |||
| 78 | + | int32 behind = 4; | |||
| 79 | + | // BehindCapped says that Behind is a lower bound: the server stops counting | |||
| 80 | + | // at 1,000. | |||
| 81 | + | bool behind_capped = 5; | |||
| 82 | + | // ConflictPaths are the paths that conflict, at most 20. Set only when | |||
| 83 | + | // state is CONFLICT; empty when the branches share no history. | |||
| 84 | + | repeated string conflict_paths = 6; | |||
| 85 | + | // ConflictPathsTruncated says that more paths conflict than listed. | |||
| 86 | + | bool conflict_paths_truncated = 7; | |||
| 87 | + | // CheckedAt is when the server computed the result. Unset while CHECKING. | |||
| 88 | + | google.protobuf.Timestamp checked_at = 8; | |||
| 89 | + | } | |||
| 90 | + | ||||
| 47 | // MergeRequest asks to merge one branch of a repository into another branch | 91 | // MergeRequest asks to merge one branch of a repository into another branch | ||
| 48 | // of the same repository. It is about a branch, not about who wrote it. | 92 | // of the same repository. It is about a branch, not about who wrote it. | ||
| 49 | message MergeRequest { | 93 | message MergeRequest { | ||
| @@ -81,12 +125,19 @@ message MergeRequest { | |||||
| 81 | // merged or closed it is the head at that moment. | 125 | // merged or closed it is the head at that moment. | ||
| 82 | string head_id = 11; | 126 | string head_id = 11; | ||
| 83 | // MergedCommitId is the id of the commit the target branch points to after | 127 | // MergedCommitId is the id of the commit the target branch points to after | ||
| 84 | - | // the merge: the head for a fast-forward, the new commit for a squash. | 128 | + | // the merge: the head for a fast-forward, the new commit for a squash or a |
| 129 | + | // merge commit. | |||
| 85 | // Empty unless state is MERGED. | 130 | // Empty unless state is MERGED. | ||
| 86 | string merged_commit_id = 12; | 131 | string merged_commit_id = 12; | ||
| 87 | // MergeMode is how the merge request was merged. MERGE_MODE_UNSPECIFIED | 132 | // MergeMode is how the merge request was merged. MERGE_MODE_UNSPECIFIED | ||
| 88 | // unless state is MERGED. | 133 | // unless state is MERGED. | ||
| 89 | MergeMode merge_mode = 13; | 134 | MergeMode merge_mode = 13; | ||
| 135 | + | // Mergeability tells whether the head can be merged into the target. Set | |||
| 136 | + | // while the merge request is OPEN, with state CHECKING until the server has | |||
| 137 | + | // a result for the current tips; never set once merged or closed. It is a | |||
| 138 | + | // hint: MergeMergeRequest checks again. Set only by servers with the | |||
| 139 | + | // "merge_requests.mergeability" feature. | |||
| 140 | + | Mergeability mergeability = 14; | |||
| 90 | } | 141 | } | ||
| 91 | 142 | ||||
| 92 | // Comment is a note on a merge request, either general or attached to a line | 143 | // Comment is a note on a merge request, either general or attached to a line | ||
| @@ -233,9 +284,12 @@ service MergeRequestService { | |||||
| 233 | // never merged unseen. Fails with invalid_argument if head_id is empty or | 284 | // never merged unseen. Fails with invalid_argument if head_id is empty or | ||
| 234 | // not a commit id, and with failed_precondition if the merge request is not | 285 | // not a commit id, and with failed_precondition if the merge request is not | ||
| 235 | // open, if the source branch no longer points to head_id ("branch moved, | 286 | // open, if the source branch no longer points to head_id ("branch moved, | ||
| 236 | - | // read again"), if the target is not an ancestor of the head (rebase and | 287 | + | // read again"), if the mode is fast-forward and the target is not an |
| 237 | - | // push again), if the mode is not allowed by RepoSettings, or if a check | 288 | + | // ancestor of the head (rebase and push again, or merge with squash or |
| 238 | - | // fails and RepoSettings.failing_checks_block is set. Merges of one | 289 | + | // merge commit), if the mode is squash or merge commit and the head |
| 290 | + | // conflicts with the target or shares no history with it (rebase and push | |||
| 291 | + | // again), if the mode is not allowed by RepoSettings, or if a check fails | |||
| 292 | + | // and RepoSettings.failing_checks_block is set. Merges of one | |||
| 239 | // repository run one at a time. Repeating a call that succeeded fails with | 293 | // repository run one at a time. Repeating a call that succeeded fails with | ||
| 240 | // failed_precondition (not open). On success the server publishes | 294 | // failed_precondition (not open). On success the server publishes | ||
| 241 | // MergeRequestMerged then Pushed for the target branch. | 295 | // MergeRequestMerged then Pushed for the target branch. | ||
M proto/ermite/repo.proto +1 -1
| @@ -38,7 +38,7 @@ message RepoSettings { | |||
| 38 | 38 | // AllowedMergeModes are the modes with which a merge request of the | |
| 39 | 39 | // repository may be merged. It is never empty in a response and has no | |
| 40 | 40 | // duplicate. Both MERGE_MODE_FAST_FORWARD and MERGE_MODE_SQUASH are allowed | |
| 41 | - | // by default. MERGE_MODE_UNSPECIFIED is rejected. | |
| 41 | + | // by default; MERGE_MODE_MERGE_COMMIT is allowed only when listed. MERGE_MODE_UNSPECIFIED is rejected. | |
| 42 | 42 | repeated MergeMode allowed_merge_modes = 1; | |
| 43 | 43 | // FailingChecksBlock says whether a merge request whose checks fail cannot be | |
| 44 | 44 | // merged. It is true at creation of the repository and always stored | |
| @@ -38,7 +38,7 @@ message RepoSettings { | |||||
| 38 | // AllowedMergeModes are the modes with which a merge request of the | 38 | // AllowedMergeModes are the modes with which a merge request of the | ||
| 39 | // repository may be merged. It is never empty in a response and has no | 39 | // repository may be merged. It is never empty in a response and has no | ||
| 40 | // duplicate. Both MERGE_MODE_FAST_FORWARD and MERGE_MODE_SQUASH are allowed | 40 | // duplicate. Both MERGE_MODE_FAST_FORWARD and MERGE_MODE_SQUASH are allowed | ||
| 41 | - | // by default. MERGE_MODE_UNSPECIFIED is rejected. | 41 | + | // by default; MERGE_MODE_MERGE_COMMIT is allowed only when listed. MERGE_MODE_UNSPECIFIED is rejected. |
| 42 | repeated MergeMode allowed_merge_modes = 1; | 42 | repeated MergeMode allowed_merge_modes = 1; | ||
| 43 | // FailingChecksBlock says whether a merge request whose checks fail cannot be | 43 | // FailingChecksBlock says whether a merge request whose checks fail cannot be | ||
| 44 | // merged. It is true at creation of the repository and always stored | 44 | // merged. It is true at creation of the repository and always stored | ||
M proto/ermite/server.proto +5 -2
| @@ -13,7 +13,7 @@ service ServerService { | |||
| 13 | 13 | // it first to check compatibility. | |
| 14 | 14 | rpc GetVersion(GetVersionRequest) returns (GetVersionResponse); | |
| 15 | 15 | // GetSigningKey returns the public key with which the server signs the | |
| 16 | - | // commits it creates (squash merges, see MergeMode). It needs no | |
| 16 | + | // commits it creates (squash and merge commits, see MergeMode). It needs no | |
| 17 | 17 | // authentication: the key is public, and anyone verifying a commit needs it. | |
| 18 | 18 | // Servers that implement it list "signing_key" in | |
| 19 | 19 | // GetVersionResponse.features. | |
| @@ -57,7 +57,10 @@ message GetVersionResponse { | |||
| 57 | 57 | // secrets, vars, environment, permissions and trusted fields and Run.trusted), | |
| 58 | 58 | // "ci.dispatch" (RunService.DispatchWorkflow), "ci.concurrency" | |
| 59 | 59 | // (CI_STATUS_PENDING and RunJob.concurrency_group), "ci.cache" (Job.cache) | |
| 60 | - | // and "ci.artifacts" (JobArtifactService and ArtifactService). | |
| 60 | + | // and "ci.artifacts" (JobArtifactService and ArtifactService). The merge | |
| 61 | + | // request identifier "merge_requests.mergeability" covers | |
| 62 | + | // MergeRequest.mergeability, the MergeRequestMergeability event and | |
| 63 | + | // MERGE_MODE_MERGE_COMMIT. | |
| 61 | 64 | repeated string features = 2; | |
| 62 | 65 | } | |
| 63 | 66 | ||
| @@ -13,7 +13,7 @@ service ServerService { | |||||
| 13 | // it first to check compatibility. | 13 | // it first to check compatibility. | ||
| 14 | rpc GetVersion(GetVersionRequest) returns (GetVersionResponse); | 14 | rpc GetVersion(GetVersionRequest) returns (GetVersionResponse); | ||
| 15 | // GetSigningKey returns the public key with which the server signs the | 15 | // GetSigningKey returns the public key with which the server signs the | ||
| 16 | - | // commits it creates (squash merges, see MergeMode). It needs no | 16 | + | // commits it creates (squash and merge commits, see MergeMode). It needs no |
| 17 | // authentication: the key is public, and anyone verifying a commit needs it. | 17 | // authentication: the key is public, and anyone verifying a commit needs it. | ||
| 18 | // Servers that implement it list "signing_key" in | 18 | // Servers that implement it list "signing_key" in | ||
| 19 | // GetVersionResponse.features. | 19 | // GetVersionResponse.features. | ||
| @@ -57,7 +57,10 @@ message GetVersionResponse { | |||||
| 57 | // secrets, vars, environment, permissions and trusted fields and Run.trusted), | 57 | // secrets, vars, environment, permissions and trusted fields and Run.trusted), | ||
| 58 | // "ci.dispatch" (RunService.DispatchWorkflow), "ci.concurrency" | 58 | // "ci.dispatch" (RunService.DispatchWorkflow), "ci.concurrency" | ||
| 59 | // (CI_STATUS_PENDING and RunJob.concurrency_group), "ci.cache" (Job.cache) | 59 | // (CI_STATUS_PENDING and RunJob.concurrency_group), "ci.cache" (Job.cache) | ||
| 60 | - | // and "ci.artifacts" (JobArtifactService and ArtifactService). | 60 | + | // and "ci.artifacts" (JobArtifactService and ArtifactService). The merge |
| 61 | + | // request identifier "merge_requests.mergeability" covers | |||
| 62 | + | // MergeRequest.mergeability, the MergeRequestMergeability event and | |||
| 63 | + | // MERGE_MODE_MERGE_COMMIT. | |||
| 61 | repeated string features = 2; | 64 | repeated string features = 2; | ||
| 62 | } | 65 | } | ||
| 63 | 66 | ||||
M proto/ermite/types.proto +12 -3
| @@ -40,9 +40,11 @@ message Commit { | |||
| 40 | 40 | CommitVerification verification = 7; | |
| 41 | 41 | } | |
| 42 | 42 | ||
| 43 | - | // MergeMode is how a merge request is merged. Both modes need the target to | |
| 44 | - | // be an ancestor of the head: a branch behind its target is rebased by its | |
| 45 | - | // author and pushed again, the server never rebases nor creates merge commits. | |
| 43 | + | // MergeMode is how a merge request is merged. Fast-forward needs the target | |
| 44 | + | // to be an ancestor of the head. Squash and merge commit need the head to | |
| 45 | + | // merge cleanly into the target, which holds when the branch is behind its | |
| 46 | + | // target without conflict. The server never rebases: a branch that conflicts | |
| 47 | + | // is rebased by its author and pushed again. | |
| 46 | 48 | enum MergeMode { | |
| 47 | 49 | // Not set. In MergeMergeRequestRequest.mode it means fast-forward. Rejected | |
| 48 | 50 | // in RepoSettings.allowed_merge_modes. Returned on a merge request that was | |
| @@ -58,4 +60,11 @@ enum MergeMode { | |||
| 58 | 60 | // title, " (!<number>)", a blank line and the list of the squashed commits' | |
| 59 | 61 | // summaries. | |
| 60 | 62 | MERGE_MODE_SQUASH = 2; | |
| 63 | + | // One new commit is created with two parents, the target tip then the head, | |
| 64 | + | // and the tree of the merge. It is signed by the server's key (see | |
| 65 | + | // ServerService.GetSigningKey); its author and committer are the server | |
| 66 | + | // identity. Its message is "Merge branch '<source>' into <target> (!<n>)", | |
| 67 | + | // a blank line and the title. The signatures of the branch's commits are | |
| 68 | + | // kept. Needs the "merge_requests.mergeability" feature. | |
| 69 | + | MERGE_MODE_MERGE_COMMIT = 3; | |
| 61 | 70 | } | |
| @@ -40,9 +40,11 @@ message Commit { | |||||
| 40 | CommitVerification verification = 7; | 40 | CommitVerification verification = 7; | ||
| 41 | } | 41 | } | ||
| 42 | 42 | ||||
| 43 | - | // MergeMode is how a merge request is merged. Both modes need the target to | 43 | + | // MergeMode is how a merge request is merged. Fast-forward needs the target |
| 44 | - | // be an ancestor of the head: a branch behind its target is rebased by its | 44 | + | // to be an ancestor of the head. Squash and merge commit need the head to |
| 45 | - | // author and pushed again, the server never rebases nor creates merge commits. | 45 | + | // merge cleanly into the target, which holds when the branch is behind its |
| 46 | + | // target without conflict. The server never rebases: a branch that conflicts | |||
| 47 | + | // is rebased by its author and pushed again. | |||
| 46 | enum MergeMode { | 48 | enum MergeMode { | ||
| 47 | // Not set. In MergeMergeRequestRequest.mode it means fast-forward. Rejected | 49 | // Not set. In MergeMergeRequestRequest.mode it means fast-forward. Rejected | ||
| 48 | // in RepoSettings.allowed_merge_modes. Returned on a merge request that was | 50 | // in RepoSettings.allowed_merge_modes. Returned on a merge request that was | ||
| @@ -58,4 +60,11 @@ enum MergeMode { | |||||
| 58 | // title, " (!<number>)", a blank line and the list of the squashed commits' | 60 | // title, " (!<number>)", a blank line and the list of the squashed commits' | ||
| 59 | // summaries. | 61 | // summaries. | ||
| 60 | MERGE_MODE_SQUASH = 2; | 62 | MERGE_MODE_SQUASH = 2; | ||
| 63 | + | // One new commit is created with two parents, the target tip then the head, | |||
| 64 | + | // and the tree of the merge. It is signed by the server's key (see | |||
| 65 | + | // ServerService.GetSigningKey); its author and committer are the server | |||
| 66 | + | // identity. Its message is "Merge branch '<source>' into <target> (!<n>)", | |||
| 67 | + | // a blank line and the title. The signatures of the branch's commits are | |||
| 68 | + | // kept. Needs the "merge_requests.mergeability" feature. | |||
| 69 | + | MERGE_MODE_MERGE_COMMIT = 3; | |||
| 61 | } | 70 | } | ||