detached 7348bb2

feat(web): offer ignore checks on the merge form, document mr ready and the merge check rules

commit
7348bb24aef518be69e5d94fc53f100cacbe62f2
author
brice · · 2026-10-21 13:27 UTC
parent
5d0c190
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
9 files · +419 -350
M docs/ci.md +1 -1
@@ -44,7 +44,7 @@ Like `gh workflow disable`: a disabled workflow starts no run for any event (`pu
4444 - A disabled **reusable** workflow (`on: workflow_call`) can still be called with `uses:` from an enabled workflow: it then runs inside the caller's run, not as a run of its own, as on GitHub. Disable the caller to stop it.
4545 - The state is checked again in the transaction that stores a run, so a disable takes effect for every run not yet stored, even one being planned at that moment.
4646
47-The **Actions** tab of a repository shows the same. With `failing_checks_block` on (default), a merge waits for every check to pass. Turn it off with `ermite repo edit <repo> --failing-checks-block=false`.
47+The **Actions** tab of a repository shows the same. A merge needs passing checks on the head: none failed, queued or running. A head with no checks can merge. `ermite mr merge <repo> <n> --head <id> --ignore-checks` bypasses checks, needs `mr:force-merge`, and cannot be combined with `--auto`.
4848
4949 ## Trust
5050
@@ -44,7 +44,7 @@ Like `gh workflow disable`: a disabled workflow starts no run for any event (`pu
44 - A disabled **reusable** workflow (`on: workflow_call`) can still be called with `uses:` from an enabled workflow: it then runs inside the caller's run, not as a run of its own, as on GitHub. Disable the caller to stop it.44 - A disabled **reusable** workflow (`on: workflow_call`) can still be called with `uses:` from an enabled workflow: it then runs inside the caller's run, not as a run of its own, as on GitHub. Disable the caller to stop it.
45 - The state is checked again in the transaction that stores a run, so a disable takes effect for every run not yet stored, even one being planned at that moment.45 - The state is checked again in the transaction that stores a run, so a disable takes effect for every run not yet stored, even one being planned at that moment.
46 46
47-The **Actions** tab of a repository shows the same. With `failing_checks_block` on (default), a merge waits for every check to pass. Turn it off with `ermite repo edit <repo> --failing-checks-block=false`.47+The **Actions** tab of a repository shows the same. A merge needs passing checks on the head: none failed, queued or running. A head with no checks can merge. `ermite mr merge <repo> <n> --head <id> --ignore-checks` bypasses checks, needs `mr:force-merge`, and cannot be combined with `--auto`.
48 48
49 ## Trust49 ## Trust
50 50
M docs/cli.md +4 -2
@@ -48,7 +48,7 @@ It does not run:
4848
4949 ```sh
5050 ermite repo list | show <name> | create <name> [--description …] [--visibility public]
51-ermite repo edit <name> [--description …] [--visibility …] [--default-branch …] [--merge-modes …] [--failing-checks-block=false] [--allow-auto-merge] [--issues off|owner|public]
51+ermite repo edit <name> [--description …] [--visibility …] [--default-branch …] [--merge-modes …] [--allow-auto-merge] [--issues off|owner|public]
5252 ermite repo delete <name> [--yes]
5353
5454 ermite token create <label> [--preset cli|agent|ci|runner] [--scope …] [--repo …] [--branch-prefix …] [--expires 30d]
@@ -57,7 +57,8 @@ ermite token list | revoke <id>
5757 ermite mr create <repo> --source <branch> --title … | list <repo> | show <repo> <n> [--diff] # show prints the mergeability: up to date, behind, conflict
5858 ermite mr comment <repo> <n> -m … [--path … --line N|A-B --side old|new] [--reply <id>] [--approve|--request-changes]
5959 ermite mr resolve <repo> <n> <comment> | edit-comment <repo> <n> <comment> -m … | delete-comment <repo> <n> <comment>
60-ermite mr merge <repo> <n> --head <id> [--mode fast-forward|squash|merge] [--delete-branch] | merge <repo> <n> --head <id> --auto [--mode …] | merge <repo> <n> --cancel-auto | close <repo> <n>
60+ermite mr ready <repo> <n> # removes WIP:/[WIP], needs mr:write
61+ermite mr merge <repo> <n> --head <id> [--mode fast-forward|squash|merge] [--delete-branch] [--ignore-checks] | merge <repo> <n> --head <id> --auto [--mode …] | merge <repo> <n> --cancel-auto | close <repo> <n>
6162
6263 ermite issue create <repo> --title … [--body … | --body-file …] | list <repo> [--state open|closed|all]
6364 ermite issue show <repo> <n> | comment <repo> <n> -m … | close <repo> <n> | reopen <repo> <n>
@@ -99,6 +100,7 @@ Mirrors push repositories to a remote over SSH, never forcing. See [Push mirror]
99100
100101 - `--json` prints stable field names (listed in each `--help`) on `repo list|show|create|edit`, `issue create|list|show|comment|close|reopen`, `token create|list`, `run list|view|cancel|rerun`, `runner list`, `mirror key|config|status` and `version`.
101102 - `watch --json` prints one object per line. `merge_request_mergeability` events carry `mergeability` (`state`, `behind`, `conflict_paths`…) and print as `repo!n mergeability: behind by 2`.
103+- A merge needs passing checks on the head (no failed, queued or running checks); a head with no checks can merge. `mr merge --ignore-checks` bypasses this, needs `mr:force-merge`, and cannot be combined with `--auto` or `--cancel-auto`. The `cli` preset includes `mr:force-merge`; `agent` does not. Adding `--scope mr:merge` lets an agent merge only with passing checks.
102104 - `mr merge --mode squash|merge` creates a commit signed by the server's own key (generated on first start); the output names its fingerprint, `ermite signing-key show` prints the key. Every mode is allowed by default; `repo edit --merge-modes fast-forward,squash` disables `merge`.
103105 - `mr merge --auto` makes the server merge once CI passed on the head (`repo edit --allow-auto-merge` first); `--cancel-auto` cancels it; both are exclusive with each other and `--auto` with `--delete-branch`. `watch --json` adds `merge_request_auto_merge_enabled`, `merge_request_auto_merge_cancelled` (with `reason`), and `auto` (true) on `merge_request_merged` after an auto-merge. See [Merge requests](merge-requests.md#auto-merge).
104106 - Errors are one line on stderr (`ermite: …`) with exit status 1.
@@ -48,7 +48,7 @@ It does not run:
48 48
49 ```sh49 ```sh
50 ermite repo list | show <name> | create <name> [--description …] [--visibility public]50 ermite repo list | show <name> | create <name> [--description …] [--visibility public]
51-ermite repo edit <name> [--description …] [--visibility …] [--default-branch …] [--merge-modes …] [--failing-checks-block=false] [--allow-auto-merge] [--issues off|owner|public]51+ermite repo edit <name> [--description …] [--visibility …] [--default-branch …] [--merge-modes …] [--allow-auto-merge] [--issues off|owner|public]
52 ermite repo delete <name> [--yes]52 ermite repo delete <name> [--yes]
53 53
54 ermite token create <label> [--preset cli|agent|ci|runner] [--scope …] [--repo …] [--branch-prefix …] [--expires 30d]54 ermite token create <label> [--preset cli|agent|ci|runner] [--scope …] [--repo …] [--branch-prefix …] [--expires 30d]
@@ -57,7 +57,8 @@ ermite token list | revoke <id>
57 ermite mr create <repo> --source <branch> --title … | list <repo> | show <repo> <n> [--diff] # show prints the mergeability: up to date, behind, conflict57 ermite mr create <repo> --source <branch> --title … | list <repo> | show <repo> <n> [--diff] # show prints the mergeability: up to date, behind, conflict
58 ermite mr comment <repo> <n> -m … [--path … --line N|A-B --side old|new] [--reply <id>] [--approve|--request-changes]58 ermite mr comment <repo> <n> -m … [--path … --line N|A-B --side old|new] [--reply <id>] [--approve|--request-changes]
59 ermite mr resolve <repo> <n> <comment> | edit-comment <repo> <n> <comment> -m … | delete-comment <repo> <n> <comment>59 ermite mr resolve <repo> <n> <comment> | edit-comment <repo> <n> <comment> -m … | delete-comment <repo> <n> <comment>
60-ermite mr merge <repo> <n> --head <id> [--mode fast-forward|squash|merge] [--delete-branch] | merge <repo> <n> --head <id> --auto [--mode …] | merge <repo> <n> --cancel-auto | close <repo> <n>60+ermite mr ready <repo> <n> # removes WIP:/[WIP], needs mr:write
61+ermite mr merge <repo> <n> --head <id> [--mode fast-forward|squash|merge] [--delete-branch] [--ignore-checks] | merge <repo> <n> --head <id> --auto [--mode …] | merge <repo> <n> --cancel-auto | close <repo> <n>
61 62
62 ermite issue create <repo> --title … [--body … | --body-file …] | list <repo> [--state open|closed|all]63 ermite issue create <repo> --title … [--body … | --body-file …] | list <repo> [--state open|closed|all]
63 ermite issue show <repo> <n> | comment <repo> <n> -m … | close <repo> <n> | reopen <repo> <n>64 ermite issue show <repo> <n> | comment <repo> <n> -m … | close <repo> <n> | reopen <repo> <n>
@@ -99,6 +100,7 @@ Mirrors push repositories to a remote over SSH, never forcing. See [Push mirror]
99 100
100 - `--json` prints stable field names (listed in each `--help`) on `repo list|show|create|edit`, `issue create|list|show|comment|close|reopen`, `token create|list`, `run list|view|cancel|rerun`, `runner list`, `mirror key|config|status` and `version`.101 - `--json` prints stable field names (listed in each `--help`) on `repo list|show|create|edit`, `issue create|list|show|comment|close|reopen`, `token create|list`, `run list|view|cancel|rerun`, `runner list`, `mirror key|config|status` and `version`.
101 - `watch --json` prints one object per line. `merge_request_mergeability` events carry `mergeability` (`state`, `behind`, `conflict_paths`…) and print as `repo!n mergeability: behind by 2`.102 - `watch --json` prints one object per line. `merge_request_mergeability` events carry `mergeability` (`state`, `behind`, `conflict_paths`…) and print as `repo!n mergeability: behind by 2`.
103+- A merge needs passing checks on the head (no failed, queued or running checks); a head with no checks can merge. `mr merge --ignore-checks` bypasses this, needs `mr:force-merge`, and cannot be combined with `--auto` or `--cancel-auto`. The `cli` preset includes `mr:force-merge`; `agent` does not. Adding `--scope mr:merge` lets an agent merge only with passing checks.
102 - `mr merge --mode squash|merge` creates a commit signed by the server's own key (generated on first start); the output names its fingerprint, `ermite signing-key show` prints the key. Every mode is allowed by default; `repo edit --merge-modes fast-forward,squash` disables `merge`.104 - `mr merge --mode squash|merge` creates a commit signed by the server's own key (generated on first start); the output names its fingerprint, `ermite signing-key show` prints the key. Every mode is allowed by default; `repo edit --merge-modes fast-forward,squash` disables `merge`.
103 - `mr merge --auto` makes the server merge once CI passed on the head (`repo edit --allow-auto-merge` first); `--cancel-auto` cancels it; both are exclusive with each other and `--auto` with `--delete-branch`. `watch --json` adds `merge_request_auto_merge_enabled`, `merge_request_auto_merge_cancelled` (with `reason`), and `auto` (true) on `merge_request_merged` after an auto-merge. See [Merge requests](merge-requests.md#auto-merge).105 - `mr merge --auto` makes the server merge once CI passed on the head (`repo edit --allow-auto-merge` first); `--cancel-auto` cancels it; both are exclusive with each other and `--auto` with `--delete-branch`. `watch --json` adds `merge_request_auto_merge_enabled`, `merge_request_auto_merge_cancelled` (with `reason`), and `auto` (true) on `merge_request_merged` after an auto-merge. See [Merge requests](merge-requests.md#auto-merge).
104 - Errors are one line on stderr (`ermite: …`) with exit status 1.106 - Errors are one line on stderr (`ermite: …`) with exit status 1.
M docs/merge-requests.md +5 -3
@@ -14,6 +14,8 @@ Naming an issue with `#N` links it, and `Fixes #N` closes it on merge: see [issu
1414 merge request web URL on its own line. With `--json`, merge request objects
1515 (create, show, list, close and merge) include `url` alongside the other fields.
1616
17+A draft cannot merge. `ermite mr ready <repo> <n>` removes the `WIP:` or `[WIP]` title prefix; it needs `mr:write` and an open draft.
18+
1719 ## Merge modes
1820
1921 | Mode | Result | Needs |
@@ -25,10 +27,10 @@ merge request web URL on its own line. With `--json`, merge request objects
2527 - The server never rebases. A branch behind its target merges with `squash` or `merge`, or is rebased and pushed again for a fast-forward.
2628 - The server checks the mode again when it merges, whatever the badge showed, and refuses with the reason (the target moved, a conflict with the paths).
2729 - The merge is also refused when the branch moved since the reviewed `--head`.
28-- With `failing_checks_block` on (default), the merge is refused while a check of the head failed or is still running.
30+- A merge needs passing checks on the head: no failed, queued or running checks. A head with no checks can merge. `--ignore-checks` bypasses this, needs `mr:force-merge`, and cannot be combined with `--auto` or `--cancel-auto`. The owner web merge form offers **Ignore checks** when checks fail or are pending.
2931 - The merge answers as soon as the target has moved. `--delete-branch` then deletes the source branch right after, in the background (unless it is the default branch or another open request uses it); if the branch moved meanwhile, it is kept.
3032 - Every mode is allowed by default, including in repositories that had only `fast-forward` and `squash` before `merge` existed: those gain `merge`. Disable a mode per repository with `ermite repo edit <repo> --merge-modes fast-forward,squash` (list the modes to keep).
31-- Scopes: `mr:write` to open and comment, `mr:review` to give a verdict, `mr:merge` to merge.
33+- Scopes: `mr:write` to open and comment, `mr:review` to give a verdict, `mr:merge` to merge, `mr:force-merge` to bypass checks. The `cli` preset includes the bypass scope; `agent` does not. Adding `--scope mr:merge` lets an agent merge only with passing checks.
3234
3335 ## Signed commits
3436
@@ -47,7 +49,7 @@ A merge request can merge by itself once its checks passed.
4749
4850 - The repository setting `allow_auto_merge` is off by default: `ermite repo edit <repo> --allow-auto-merge` (`=false` to turn it off).
4951 - Enable it with `ermite mr merge <repo> <n> --head <commit> --auto --mode squash` (`--head` is required, as for a plain merge; a head that moved is refused with "branch moved"), or with **Merge when ready** in the web merge box. Its separate mode choice offers every repository-allowed mode, even while the head conflicts or is behind. Auto-merge keeps the source branch; the delete-source checkbox applies only to an immediate merge. It needs `mr:merge` and a server with CI. Re-enabling replaces the previous mode and enabler.
50-- The server merges when CI has settled on the head with every run complete and at least one check passed. A failing or unfinished check always blocks, whatever `failing_checks_block` says. The mode must still be allowed.
52+- The server merges when CI has settled on the head with every run complete and at least one check passed. A failing or unfinished check always blocks. The mode must still be allowed.
5153 - The merge is made as the person who enabled it. Their token is checked at every evaluation, even while checks are pending, and again at merge time under the merge lock: it must still be valid and allow `mr:merge` on the repository and the target branch. A token that no longer qualifies cancels the auto-merge.
5254 - A pending auto-merge shows in `mr show` (`auto_merge`), in the web merge box and as `merge_request_auto_merge_enabled` in `ermite watch`. A merge request merged this way has `auto_merged` true.
5355 - A failing, unfinished or conflicting head waits with auto-merge still on. A re-run or a target fix can make it pass; pushing a new source head cancels the recorded intent (the reason names the new head).
@@ -14,6 +14,8 @@ Naming an issue with `#N` links it, and `Fixes #N` closes it on merge: see [issu
14 merge request web URL on its own line. With `--json`, merge request objects14 merge request web URL on its own line. With `--json`, merge request objects
15 (create, show, list, close and merge) include `url` alongside the other fields.15 (create, show, list, close and merge) include `url` alongside the other fields.
16 16
17+A draft cannot merge. `ermite mr ready <repo> <n>` removes the `WIP:` or `[WIP]` title prefix; it needs `mr:write` and an open draft.
18+
17 ## Merge modes19 ## Merge modes
18 20
19 | Mode | Result | Needs |21 | Mode | Result | Needs |
@@ -25,10 +27,10 @@ merge request web URL on its own line. With `--json`, merge request objects
25 - The server never rebases. A branch behind its target merges with `squash` or `merge`, or is rebased and pushed again for a fast-forward.27 - The server never rebases. A branch behind its target merges with `squash` or `merge`, or is rebased and pushed again for a fast-forward.
26 - The server checks the mode again when it merges, whatever the badge showed, and refuses with the reason (the target moved, a conflict with the paths).28 - The server checks the mode again when it merges, whatever the badge showed, and refuses with the reason (the target moved, a conflict with the paths).
27 - The merge is also refused when the branch moved since the reviewed `--head`.29 - The merge is also refused when the branch moved since the reviewed `--head`.
28-- With `failing_checks_block` on (default), the merge is refused while a check of the head failed or is still running.30+- A merge needs passing checks on the head: no failed, queued or running checks. A head with no checks can merge. `--ignore-checks` bypasses this, needs `mr:force-merge`, and cannot be combined with `--auto` or `--cancel-auto`. The owner web merge form offers **Ignore checks** when checks fail or are pending.
29 - The merge answers as soon as the target has moved. `--delete-branch` then deletes the source branch right after, in the background (unless it is the default branch or another open request uses it); if the branch moved meanwhile, it is kept.31 - The merge answers as soon as the target has moved. `--delete-branch` then deletes the source branch right after, in the background (unless it is the default branch or another open request uses it); if the branch moved meanwhile, it is kept.
30 - Every mode is allowed by default, including in repositories that had only `fast-forward` and `squash` before `merge` existed: those gain `merge`. Disable a mode per repository with `ermite repo edit <repo> --merge-modes fast-forward,squash` (list the modes to keep).32 - Every mode is allowed by default, including in repositories that had only `fast-forward` and `squash` before `merge` existed: those gain `merge`. Disable a mode per repository with `ermite repo edit <repo> --merge-modes fast-forward,squash` (list the modes to keep).
31-- Scopes: `mr:write` to open and comment, `mr:review` to give a verdict, `mr:merge` to merge.33+- Scopes: `mr:write` to open and comment, `mr:review` to give a verdict, `mr:merge` to merge, `mr:force-merge` to bypass checks. The `cli` preset includes the bypass scope; `agent` does not. Adding `--scope mr:merge` lets an agent merge only with passing checks.
32 34
33 ## Signed commits35 ## Signed commits
34 36
@@ -47,7 +49,7 @@ A merge request can merge by itself once its checks passed.
47 49
48 - The repository setting `allow_auto_merge` is off by default: `ermite repo edit <repo> --allow-auto-merge` (`=false` to turn it off).50 - The repository setting `allow_auto_merge` is off by default: `ermite repo edit <repo> --allow-auto-merge` (`=false` to turn it off).
49 - Enable it with `ermite mr merge <repo> <n> --head <commit> --auto --mode squash` (`--head` is required, as for a plain merge; a head that moved is refused with "branch moved"), or with **Merge when ready** in the web merge box. Its separate mode choice offers every repository-allowed mode, even while the head conflicts or is behind. Auto-merge keeps the source branch; the delete-source checkbox applies only to an immediate merge. It needs `mr:merge` and a server with CI. Re-enabling replaces the previous mode and enabler.51 - Enable it with `ermite mr merge <repo> <n> --head <commit> --auto --mode squash` (`--head` is required, as for a plain merge; a head that moved is refused with "branch moved"), or with **Merge when ready** in the web merge box. Its separate mode choice offers every repository-allowed mode, even while the head conflicts or is behind. Auto-merge keeps the source branch; the delete-source checkbox applies only to an immediate merge. It needs `mr:merge` and a server with CI. Re-enabling replaces the previous mode and enabler.
50-- The server merges when CI has settled on the head with every run complete and at least one check passed. A failing or unfinished check always blocks, whatever `failing_checks_block` says. The mode must still be allowed.52+- The server merges when CI has settled on the head with every run complete and at least one check passed. A failing or unfinished check always blocks. The mode must still be allowed.
51 - The merge is made as the person who enabled it. Their token is checked at every evaluation, even while checks are pending, and again at merge time under the merge lock: it must still be valid and allow `mr:merge` on the repository and the target branch. A token that no longer qualifies cancels the auto-merge.53 - The merge is made as the person who enabled it. Their token is checked at every evaluation, even while checks are pending, and again at merge time under the merge lock: it must still be valid and allow `mr:merge` on the repository and the target branch. A token that no longer qualifies cancels the auto-merge.
52 - A pending auto-merge shows in `mr show` (`auto_merge`), in the web merge box and as `merge_request_auto_merge_enabled` in `ermite watch`. A merge request merged this way has `auto_merged` true.54 - A pending auto-merge shows in `mr show` (`auto_merge`), in the web merge box and as `merge_request_auto_merge_enabled` in `ermite watch`. A merge request merged this way has `auto_merged` true.
53 - A failing, unfinished or conflicting head waits with auto-merge still on. A re-run or a target fix can make it pass; pushing a new source head cancels the recorded intent (the reason names the new head).55 - A failing, unfinished or conflicting head waits with auto-merge still on. A re-run or a target fix can make it pass; pushing a new source head cancels the recorded intent (the reason names the new head).
M internal/adapters/web/mr.templ +5 -1
@@ -545,6 +545,10 @@ templ mergeMenu(p MRPage) {
545545 </label>
546546 }
547547 </fieldset>
548+ if p.ChecksSum.Kind == "bad" || p.ChecksSum.Kind == "running" {
549+ <p class="d-note">{ p.ChecksSum.State + ": a failing or unfinished check blocks the merge." }</p>
550+ <label class="d-check"><input type="checkbox" name="ignore_checks"/> Ignore checks</label>
551+ }
548552 if p.Box.CanDeleteBranch {
549553 <label class="d-check"><input type="checkbox" name="delete_branch" value="1"/> delete { p.Source } after the merge <kbd aria-hidden="true">D</kbd></label>
550554 }
@@ -634,7 +638,7 @@ templ moreMenu(p MRPage) {
634638 <dt>checks</dt>
635639 <dd>
636640 if p.ChecksBlock {
637- failing ones block the merge
641+ failing or unfinished checks block the merge
638642 } else {
639643 do not block the merge
640644 }
@@ -545,6 +545,10 @@ templ mergeMenu(p MRPage) {
545 </label>545 </label>
546 }546 }
547 </fieldset>547 </fieldset>
548+ if p.ChecksSum.Kind == "bad" || p.ChecksSum.Kind == "running" {
549+ <p class="d-note">{ p.ChecksSum.State + ": a failing or unfinished check blocks the merge." }</p>
550+ <label class="d-check"><input type="checkbox" name="ignore_checks"/> Ignore checks</label>
551+ }
548 if p.Box.CanDeleteBranch {552 if p.Box.CanDeleteBranch {
549 <label class="d-check"><input type="checkbox" name="delete_branch" value="1"/> delete { p.Source } after the merge <kbd aria-hidden="true">D</kbd></label>553 <label class="d-check"><input type="checkbox" name="delete_branch" value="1"/> delete { p.Source } after the merge <kbd aria-hidden="true">D</kbd></label>
550 }554 }
@@ -634,7 +638,7 @@ templ moreMenu(p MRPage) {
634 <dt>checks</dt>638 <dt>checks</dt>
635 <dd>639 <dd>
636 if p.ChecksBlock {640 if p.ChecksBlock {
637- failing ones block the merge641+ failing or unfinished checks block the merge
638 } else {642 } else {
639 do not block the merge643 do not block the merge
640 }644 }
M internal/adapters/web/mr_post.go +1 -0
@@ -377,6 +377,7 @@ func (s *Server) mrMerge(ctx context.Context, r *http.Request) (string, string,
377377 }
378378 res, err := s.cfg.MergeRequests.Merge(ctx, principal(ctx), name, n, ports.MergeParams{
379379 Mode: mode, HeadID: head, DeleteSource: r.PostFormValue("delete_branch") == "1",
380+ IgnoreChecks: r.PostFormValue("ignore_checks") == "on",
380381 })
381382 switch {
382383 case errors.Is(err, domain.ErrPreconditionFailed), errors.Is(err, domain.ErrConflict):
@@ -377,6 +377,7 @@ func (s *Server) mrMerge(ctx context.Context, r *http.Request) (string, string,
377 }377 }
378 res, err := s.cfg.MergeRequests.Merge(ctx, principal(ctx), name, n, ports.MergeParams{378 res, err := s.cfg.MergeRequests.Merge(ctx, principal(ctx), name, n, ports.MergeParams{
379 Mode: mode, HeadID: head, DeleteSource: r.PostFormValue("delete_branch") == "1",379 Mode: mode, HeadID: head, DeleteSource: r.PostFormValue("delete_branch") == "1",
380+ IgnoreChecks: r.PostFormValue("ignore_checks") == "on",
380 })381 })
381 switch {382 switch {
382 case errors.Is(err, domain.ErrPreconditionFailed), errors.Is(err, domain.ErrConflict):383 case errors.Is(err, domain.ErrPreconditionFailed), errors.Is(err, domain.ErrConflict):
M internal/adapters/web/mr_templ.go +354 -335
@@ -2805,155 +2805,174 @@ func mergeMenu(p MRPage) templ.Component {
28052805 if templ_7745c5c3_Err != nil {
28062806 return templ_7745c5c3_Err
28072807 }
2808- if p.Box.CanDeleteBranch {
2809- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 264, "<label class=\"d-check\"><input type=\"checkbox\" name=\"delete_branch\" value=\"1\"> delete ")
2808+ if p.ChecksSum.Kind == "bad" || p.ChecksSum.Kind == "running" {
2809+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 264, "<p class=\"d-note\">")
28102810 if templ_7745c5c3_Err != nil {
28112811 return templ_7745c5c3_Err
28122812 }
28132813 var templ_7745c5c3_Var134 string
2814- templ_7745c5c3_Var134, templ_7745c5c3_Err = templ.JoinStringErrs(p.Source)
2814+ templ_7745c5c3_Var134, templ_7745c5c3_Err = templ.JoinStringErrs(p.ChecksSum.State + ": a failing or unfinished check blocks the merge.")
28152815 if templ_7745c5c3_Err != nil {
2816- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 549, Col: 102}
2816+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 549, Col: 97}
28172817 }
28182818 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var134))
28192819 if templ_7745c5c3_Err != nil {
28202820 return templ_7745c5c3_Err
28212821 }
2822- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 265, " after the merge <kbd aria-hidden=\"true\">D</kbd></label>")
2822+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 265, "</p><label class=\"d-check\"><input type=\"checkbox\" name=\"ignore_checks\"> Ignore checks</label> ")
28232823 if templ_7745c5c3_Err != nil {
28242824 return templ_7745c5c3_Err
28252825 }
28262826 }
2827- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 266, "<div class=\"d-btns\"><button type=\"submit\" class=\"btn primary\" data-default")
2827+ if p.Box.CanDeleteBranch {
2828+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 266, "<label class=\"d-check\"><input type=\"checkbox\" name=\"delete_branch\" value=\"1\"> delete ")
2829+ if templ_7745c5c3_Err != nil {
2830+ return templ_7745c5c3_Err
2831+ }
2832+ var templ_7745c5c3_Var135 string
2833+ templ_7745c5c3_Var135, templ_7745c5c3_Err = templ.JoinStringErrs(p.Source)
2834+ if templ_7745c5c3_Err != nil {
2835+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 553, Col: 102}
2836+ }
2837+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var135))
2838+ if templ_7745c5c3_Err != nil {
2839+ return templ_7745c5c3_Err
2840+ }
2841+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 267, " after the merge <kbd aria-hidden=\"true\">D</kbd></label>")
2842+ if templ_7745c5c3_Err != nil {
2843+ return templ_7745c5c3_Err
2844+ }
2845+ }
2846+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 268, "<div class=\"d-btns\"><button type=\"submit\" class=\"btn primary\" data-default")
28282847 if templ_7745c5c3_Err != nil {
28292848 return templ_7745c5c3_Err
28302849 }
28312850 if !p.Box.CanMerge() {
2832- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 267, " disabled")
2851+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 269, " disabled")
28332852 if templ_7745c5c3_Err != nil {
28342853 return templ_7745c5c3_Err
28352854 }
28362855 }
2837- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 268, " title=\"")
2856+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 270, " title=\"")
28382857 if templ_7745c5c3_Err != nil {
28392858 return templ_7745c5c3_Err
28402859 }
2841- var templ_7745c5c3_Var135 string
2842- templ_7745c5c3_Var135, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Box.MergeTitle())
2860+ var templ_7745c5c3_Var136 string
2861+ templ_7745c5c3_Var136, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Box.MergeTitle())
28432862 if templ_7745c5c3_Err != nil {
2844- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 557, Col: 33}
2863+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 561, Col: 33}
28452864 }
2846- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var135)
2865+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var136)
28472866 if templ_7745c5c3_Err != nil {
28482867 return templ_7745c5c3_Err
28492868 }
2850- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 269, "\" :disabled=\"!this.form.querySelector('input[name=mode]:checked:not(:disabled)')\" :title=\"(this.form.querySelector('input[name=mode]:checked') || {}).title || ''\">Merge into ")
2869+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 271, "\" :disabled=\"!this.form.querySelector('input[name=mode]:checked:not(:disabled)')\" :title=\"(this.form.querySelector('input[name=mode]:checked') || {}).title || ''\">Merge into ")
28512870 if templ_7745c5c3_Err != nil {
28522871 return templ_7745c5c3_Err
28532872 }
2854- var templ_7745c5c3_Var136 string
2855- templ_7745c5c3_Var136, templ_7745c5c3_Err = templ.JoinStringErrs(p.Target)
2873+ var templ_7745c5c3_Var137 string
2874+ templ_7745c5c3_Var137, templ_7745c5c3_Err = templ.JoinStringErrs(p.Target)
28562875 if templ_7745c5c3_Err != nil {
2857- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 560, Col: 28}
2876+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 564, Col: 28}
28582877 }
2859- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var136))
2878+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var137))
28602879 if templ_7745c5c3_Err != nil {
28612880 return templ_7745c5c3_Err
28622881 }
2863- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 270, "</button></div></form>")
2882+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 272, "</button></div></form>")
28642883 if templ_7745c5c3_Err != nil {
28652884 return templ_7745c5c3_Err
28662885 }
28672886 if p.Box.CanAutoMerge {
2868- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 271, "<form class=\"d-acts\" method=\"post\" action=\"")
2887+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 273, "<form class=\"d-acts\" method=\"post\" action=\"")
28692888 if templ_7745c5c3_Err != nil {
28702889 return templ_7745c5c3_Err
28712890 }
2872- var templ_7745c5c3_Var137 templ.SafeURL
2873- templ_7745c5c3_Var137, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Box.AutoAction))
2891+ var templ_7745c5c3_Var138 templ.SafeURL
2892+ templ_7745c5c3_Var138, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Box.AutoAction))
28742893 if templ_7745c5c3_Err != nil {
2875- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 564, Col: 80}
2894+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 568, Col: 80}
28762895 }
2877- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var137))
2896+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var138))
28782897 if templ_7745c5c3_Err != nil {
28792898 return templ_7745c5c3_Err
28802899 }
2881- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 272, "\"><input type=\"hidden\" name=\"head_id\" value=\"")
2900+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 274, "\"><input type=\"hidden\" name=\"head_id\" value=\"")
28822901 if templ_7745c5c3_Err != nil {
28832902 return templ_7745c5c3_Err
28842903 }
2885- var templ_7745c5c3_Var138 string
2886- templ_7745c5c3_Var138, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Box.Head)
2904+ var templ_7745c5c3_Var139 string
2905+ templ_7745c5c3_Var139, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Box.Head)
28872906 if templ_7745c5c3_Err != nil {
2888- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 565, Col: 60}
2907+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 569, Col: 60}
28892908 }
2890- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var138)
2909+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var139)
28912910 if templ_7745c5c3_Err != nil {
28922911 return templ_7745c5c3_Err
28932912 }
2894- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 273, "\"><fieldset class=\"d-modes\"><legend>Auto-merge mode</legend> ")
2913+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 275, "\"><fieldset class=\"d-modes\"><legend>Auto-merge mode</legend> ")
28952914 if templ_7745c5c3_Err != nil {
28962915 return templ_7745c5c3_Err
28972916 }
28982917 for i, m := range p.Box.Modes {
2899- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 274, "<label><input type=\"radio\" name=\"mode\" value=\"")
2918+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 276, "<label><input type=\"radio\" name=\"mode\" value=\"")
29002919 if templ_7745c5c3_Err != nil {
29012920 return templ_7745c5c3_Err
29022921 }
2903- var templ_7745c5c3_Var139 string
2904- templ_7745c5c3_Var139, templ_7745c5c3_Err = templ.ResolveAttributeValue(m.Value)
2922+ var templ_7745c5c3_Var140 string
2923+ templ_7745c5c3_Var140, templ_7745c5c3_Err = templ.ResolveAttributeValue(m.Value)
29052924 if templ_7745c5c3_Err != nil {
2906- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 569, Col: 62}
2925+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 573, Col: 62}
29072926 }
2908- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var139)
2927+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var140)
29092928 if templ_7745c5c3_Err != nil {
29102929 return templ_7745c5c3_Err
29112930 }
2912- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 275, "\"")
2931+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 277, "\"")
29132932 if templ_7745c5c3_Err != nil {
29142933 return templ_7745c5c3_Err
29152934 }
29162935 if i == 0 {
2917- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 276, " checked")
2936+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 278, " checked")
29182937 if templ_7745c5c3_Err != nil {
29192938 return templ_7745c5c3_Err
29202939 }
29212940 }
2922- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 277, "> ")
2941+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 279, "> ")
29232942 if templ_7745c5c3_Err != nil {
29242943 return templ_7745c5c3_Err
29252944 }
2926- var templ_7745c5c3_Var140 string
2927- templ_7745c5c3_Var140, templ_7745c5c3_Err = templ.JoinStringErrs(m.Label)
2945+ var templ_7745c5c3_Var141 string
2946+ templ_7745c5c3_Var141, templ_7745c5c3_Err = templ.JoinStringErrs(m.Label)
29282947 if templ_7745c5c3_Err != nil {
2929- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 569, Col: 96}
2948+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 573, Col: 96}
29302949 }
2931- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var140))
2950+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var141))
29322951 if templ_7745c5c3_Err != nil {
29332952 return templ_7745c5c3_Err
29342953 }
2935- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 278, "</label>")
2954+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 280, "</label>")
29362955 if templ_7745c5c3_Err != nil {
29372956 return templ_7745c5c3_Err
29382957 }
29392958 }
2940- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 279, "</fieldset><div class=\"d-btns\"><button type=\"submit\" class=\"btn\"")
2959+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 281, "</fieldset><div class=\"d-btns\"><button type=\"submit\" class=\"btn\"")
29412960 if templ_7745c5c3_Err != nil {
29422961 return templ_7745c5c3_Err
29432962 }
29442963 if len(p.Box.Modes) == 0 {
2945- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 280, " disabled")
2964+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 282, " disabled")
29462965 if templ_7745c5c3_Err != nil {
29472966 return templ_7745c5c3_Err
29482967 }
29492968 }
2950- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 281, " title=\"merge once the checks pass\">Merge when ready</button></div></form>")
2969+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 283, " title=\"merge once the checks pass\">Merge when ready</button></div></form>")
29512970 if templ_7745c5c3_Err != nil {
29522971 return templ_7745c5c3_Err
29532972 }
29542973 }
29552974 }
2956- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 282, "</div></details>")
2975+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 284, "</div></details>")
29572976 if templ_7745c5c3_Err != nil {
29582977 return templ_7745c5c3_Err
29592978 }
@@ -2979,182 +2998,182 @@ func MRMergeability(v MergeabilityView) templ.Component {
29792998 }()
29802999 }
29813000 ctx = templ.InitializeContext(ctx)
2982- templ_7745c5c3_Var141 := templ.GetChildren(ctx)
2983- if templ_7745c5c3_Var141 == nil {
2984- templ_7745c5c3_Var141 = templ.NopComponent
3001+ templ_7745c5c3_Var142 := templ.GetChildren(ctx)
3002+ if templ_7745c5c3_Var142 == nil {
3003+ templ_7745c5c3_Var142 = templ.NopComponent
29853004 }
29863005 ctx = templ.ClearChildren(ctx)
2987- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 283, "<span data-mergeability data-state=\"")
2988- if templ_7745c5c3_Err != nil {
2989- return templ_7745c5c3_Err
2990- }
2991- var templ_7745c5c3_Var142 string
2992- templ_7745c5c3_Var142, templ_7745c5c3_Err = templ.ResolveAttributeValue(v.State)
2993- if templ_7745c5c3_Err != nil {
2994- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 587, Col: 22}
2995- }
2996- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var142)
2997- if templ_7745c5c3_Err != nil {
2998- return templ_7745c5c3_Err
2999- }
3000- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 284, "\" data-ff-ok=\"")
3006+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 285, "<span data-mergeability data-state=\"")
30013007 if templ_7745c5c3_Err != nil {
30023008 return templ_7745c5c3_Err
30033009 }
30043010 var templ_7745c5c3_Var143 string
3005- templ_7745c5c3_Var143, templ_7745c5c3_Err = templ.ResolveAttributeValue(strconv.FormatBool(v.FFOk))
3011+ templ_7745c5c3_Var143, templ_7745c5c3_Err = templ.ResolveAttributeValue(v.State)
30063012 if templ_7745c5c3_Err != nil {
3007- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 588, Col: 41}
3013+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 591, Col: 22}
30083014 }
30093015 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var143)
30103016 if templ_7745c5c3_Err != nil {
30113017 return templ_7745c5c3_Err
30123018 }
3013- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 285, "\" data-merge-ok=\"")
3019+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 286, "\" data-ff-ok=\"")
30143020 if templ_7745c5c3_Err != nil {
30153021 return templ_7745c5c3_Err
30163022 }
30173023 var templ_7745c5c3_Var144 string
3018- templ_7745c5c3_Var144, templ_7745c5c3_Err = templ.ResolveAttributeValue(strconv.FormatBool(v.MergeOk))
3024+ templ_7745c5c3_Var144, templ_7745c5c3_Err = templ.ResolveAttributeValue(strconv.FormatBool(v.FFOk))
30193025 if templ_7745c5c3_Err != nil {
3020- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 589, Col: 47}
3026+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 592, Col: 41}
30213027 }
30223028 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var144)
30233029 if templ_7745c5c3_Err != nil {
30243030 return templ_7745c5c3_Err
30253031 }
3026- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 286, "\" data-ff-reason=\"")
3032+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 287, "\" data-merge-ok=\"")
30273033 if templ_7745c5c3_Err != nil {
30283034 return templ_7745c5c3_Err
30293035 }
30303036 var templ_7745c5c3_Var145 string
3031- templ_7745c5c3_Var145, templ_7745c5c3_Err = templ.ResolveAttributeValue(v.FFReason)
3037+ templ_7745c5c3_Var145, templ_7745c5c3_Err = templ.ResolveAttributeValue(strconv.FormatBool(v.MergeOk))
30323038 if templ_7745c5c3_Err != nil {
3033- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 590, Col: 29}
3039+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 593, Col: 47}
30343040 }
30353041 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var145)
30363042 if templ_7745c5c3_Err != nil {
30373043 return templ_7745c5c3_Err
30383044 }
3039- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 287, "\" data-merge-reason=\"")
3045+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 288, "\" data-ff-reason=\"")
30403046 if templ_7745c5c3_Err != nil {
30413047 return templ_7745c5c3_Err
30423048 }
30433049 var templ_7745c5c3_Var146 string
3044- templ_7745c5c3_Var146, templ_7745c5c3_Err = templ.ResolveAttributeValue(v.MergeReason)
3050+ templ_7745c5c3_Var146, templ_7745c5c3_Err = templ.ResolveAttributeValue(v.FFReason)
30453051 if templ_7745c5c3_Err != nil {
3046- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 591, Col: 35}
3052+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 594, Col: 29}
30473053 }
30483054 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var146)
30493055 if templ_7745c5c3_Err != nil {
30503056 return templ_7745c5c3_Err
30513057 }
3052- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 288, "\"><span class=\"badge\" data-state=\"")
3058+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 289, "\" data-merge-reason=\"")
30533059 if templ_7745c5c3_Err != nil {
30543060 return templ_7745c5c3_Err
30553061 }
30563062 var templ_7745c5c3_Var147 string
3057- templ_7745c5c3_Var147, templ_7745c5c3_Err = templ.ResolveAttributeValue(v.State)
3063+ templ_7745c5c3_Var147, templ_7745c5c3_Err = templ.ResolveAttributeValue(v.MergeReason)
30583064 if templ_7745c5c3_Err != nil {
3059- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 593, Col: 42}
3065+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 595, Col: 35}
30603066 }
30613067 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var147)
30623068 if templ_7745c5c3_Err != nil {
30633069 return templ_7745c5c3_Err
30643070 }
3065- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 289, "\">")
3071+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 290, "\"><span class=\"badge\" data-state=\"")
30663072 if templ_7745c5c3_Err != nil {
30673073 return templ_7745c5c3_Err
30683074 }
30693075 var templ_7745c5c3_Var148 string
3070- templ_7745c5c3_Var148, templ_7745c5c3_Err = templ.JoinStringErrs(v.Label)
3076+ templ_7745c5c3_Var148, templ_7745c5c3_Err = templ.ResolveAttributeValue(v.State)
30713077 if templ_7745c5c3_Err != nil {
3072- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 593, Col: 54}
3078+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 597, Col: 42}
30733079 }
3074- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var148))
3080+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var148)
30753081 if templ_7745c5c3_Err != nil {
30763082 return templ_7745c5c3_Err
30773083 }
3078- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 290, "</span> ")
3084+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 291, "\">")
3085+ if templ_7745c5c3_Err != nil {
3086+ return templ_7745c5c3_Err
3087+ }
3088+ var templ_7745c5c3_Var149 string
3089+ templ_7745c5c3_Var149, templ_7745c5c3_Err = templ.JoinStringErrs(v.Label)
3090+ if templ_7745c5c3_Err != nil {
3091+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 597, Col: 54}
3092+ }
3093+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var149))
3094+ if templ_7745c5c3_Err != nil {
3095+ return templ_7745c5c3_Err
3096+ }
3097+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 292, "</span> ")
30793098 if templ_7745c5c3_Err != nil {
30803099 return templ_7745c5c3_Err
30813100 }
30823101 if v.Detail != "" {
3083- var templ_7745c5c3_Var149 string
3084- templ_7745c5c3_Var149, templ_7745c5c3_Err = templ.JoinStringErrs(" ")
3102+ var templ_7745c5c3_Var150 string
3103+ templ_7745c5c3_Var150, templ_7745c5c3_Err = templ.JoinStringErrs(" ")
30853104 if templ_7745c5c3_Err != nil {
3086- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 595, Col: 8}
3105+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 599, Col: 8}
30873106 }
3088- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var149))
3107+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var150))
30893108 if templ_7745c5c3_Err != nil {
30903109 return templ_7745c5c3_Err
30913110 }
3092- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 291, "<span class=\"dim\">")
3111+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 293, "<span class=\"dim\">")
30933112 if templ_7745c5c3_Err != nil {
30943113 return templ_7745c5c3_Err
30953114 }
3096- var templ_7745c5c3_Var150 string
3097- templ_7745c5c3_Var150, templ_7745c5c3_Err = templ.JoinStringErrs(v.Detail)
3115+ var templ_7745c5c3_Var151 string
3116+ templ_7745c5c3_Var151, templ_7745c5c3_Err = templ.JoinStringErrs(v.Detail)
30983117 if templ_7745c5c3_Err != nil {
3099- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 595, Col: 38}
3118+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 599, Col: 38}
31003119 }
3101- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var150))
3120+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var151))
31023121 if templ_7745c5c3_Err != nil {
31033122 return templ_7745c5c3_Err
31043123 }
3105- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 292, "</span>")
3124+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 294, "</span>")
31063125 if templ_7745c5c3_Err != nil {
31073126 return templ_7745c5c3_Err
31083127 }
31093128 }
3110- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 293, "</span> ")
3129+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 295, "</span> ")
31113130 if templ_7745c5c3_Err != nil {
31123131 return templ_7745c5c3_Err
31133132 }
31143133 if len(v.Paths) > 0 {
3115- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 294, "<ul class=\"mg-paths\" aria-label=\"conflicting files\">")
3134+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 296, "<ul class=\"mg-paths\" aria-label=\"conflicting files\">")
31163135 if templ_7745c5c3_Err != nil {
31173136 return templ_7745c5c3_Err
31183137 }
31193138 for _, path := range v.Paths {
3120- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 295, "<li><code>")
3139+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 297, "<li><code>")
31213140 if templ_7745c5c3_Err != nil {
31223141 return templ_7745c5c3_Err
31233142 }
3124- var templ_7745c5c3_Var151 string
3125- templ_7745c5c3_Var151, templ_7745c5c3_Err = templ.JoinStringErrs(path)
3143+ var templ_7745c5c3_Var152 string
3144+ templ_7745c5c3_Var152, templ_7745c5c3_Err = templ.JoinStringErrs(path)
31263145 if templ_7745c5c3_Err != nil {
3127- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 601, Col: 20}
3146+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 605, Col: 20}
31283147 }
3129- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var151))
3148+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var152))
31303149 if templ_7745c5c3_Err != nil {
31313150 return templ_7745c5c3_Err
31323151 }
3133- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 296, "</code></li>")
3152+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 298, "</code></li>")
31343153 if templ_7745c5c3_Err != nil {
31353154 return templ_7745c5c3_Err
31363155 }
31373156 }
3138- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 297, "</ul>")
3157+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 299, "</ul>")
31393158 if templ_7745c5c3_Err != nil {
31403159 return templ_7745c5c3_Err
31413160 }
31423161 }
31433162 if v.PathsNote != "" {
3144- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 298, "<p class=\"dim\">")
3163+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 300, "<p class=\"dim\">")
31453164 if templ_7745c5c3_Err != nil {
31463165 return templ_7745c5c3_Err
31473166 }
3148- var templ_7745c5c3_Var152 string
3149- templ_7745c5c3_Var152, templ_7745c5c3_Err = templ.JoinStringErrs(v.PathsNote)
3167+ var templ_7745c5c3_Var153 string
3168+ templ_7745c5c3_Var153, templ_7745c5c3_Err = templ.JoinStringErrs(v.PathsNote)
31503169 if templ_7745c5c3_Err != nil {
3151- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 606, Col: 30}
3170+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 610, Col: 30}
31523171 }
3153- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var152))
3172+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var153))
31543173 if templ_7745c5c3_Err != nil {
31553174 return templ_7745c5c3_Err
31563175 }
3157- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 299, "</p>")
3176+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 301, "</p>")
31583177 if templ_7745c5c3_Err != nil {
31593178 return templ_7745c5c3_Err
31603179 }
@@ -3181,12 +3200,12 @@ func mrMergeabilitySlot(v MergeabilityView) templ.Component {
31813200 }()
31823201 }
31833202 ctx = templ.InitializeContext(ctx)
3184- templ_7745c5c3_Var153 := templ.GetChildren(ctx)
3185- if templ_7745c5c3_Var153 == nil {
3186- templ_7745c5c3_Var153 = templ.NopComponent
3203+ templ_7745c5c3_Var154 := templ.GetChildren(ctx)
3204+ if templ_7745c5c3_Var154 == nil {
3205+ templ_7745c5c3_Var154 = templ.NopComponent
31873206 }
31883207 ctx = templ.ClearChildren(ctx)
3189- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 300, "<div id=\"mr-mergeability\" class=\"live-slot\" role=\"status\" data-slot>")
3208+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 302, "<div id=\"mr-mergeability\" class=\"live-slot\" role=\"status\" data-slot>")
31903209 if templ_7745c5c3_Err != nil {
31913210 return templ_7745c5c3_Err
31923211 }
@@ -3194,7 +3213,7 @@ func mrMergeabilitySlot(v MergeabilityView) templ.Component {
31943213 if templ_7745c5c3_Err != nil {
31953214 return templ_7745c5c3_Err
31963215 }
3197- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 301, "</div>")
3216+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 303, "</div>")
31983217 if templ_7745c5c3_Err != nil {
31993218 return templ_7745c5c3_Err
32003219 }
@@ -3219,9 +3238,9 @@ func MRMergeabilityFragment(v MergeabilityView) templ.Component {
32193238 }()
32203239 }
32213240 ctx = templ.InitializeContext(ctx)
3222- templ_7745c5c3_Var154 := templ.GetChildren(ctx)
3223- if templ_7745c5c3_Var154 == nil {
3224- templ_7745c5c3_Var154 = templ.NopComponent
3241+ templ_7745c5c3_Var155 := templ.GetChildren(ctx)
3242+ if templ_7745c5c3_Var155 == nil {
3243+ templ_7745c5c3_Var155 = templ.NopComponent
32253244 }
32263245 ctx = templ.ClearChildren(ctx)
32273246 templ_7745c5c3_Err = mrMergeabilitySlot(v).Render(ctx, templ_7745c5c3_Buffer)
@@ -3250,128 +3269,128 @@ func moreMenu(p MRPage) templ.Component {
32503269 }()
32513270 }
32523271 ctx = templ.InitializeContext(ctx)
3253- templ_7745c5c3_Var155 := templ.GetChildren(ctx)
3254- if templ_7745c5c3_Var155 == nil {
3255- templ_7745c5c3_Var155 = templ.NopComponent
3272+ templ_7745c5c3_Var156 := templ.GetChildren(ctx)
3273+ if templ_7745c5c3_Var156 == nil {
3274+ templ_7745c5c3_Var156 = templ.NopComponent
32563275 }
32573276 ctx = templ.ClearChildren(ctx)
3258- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 302, "<details class=\"menu omenu\"><summary class=\"btn icon\" aria-label=\"More actions\" title=\"more actions\">⋯</summary><div class=\"menu-pop\" role=\"group\" aria-label=\"More actions\"><section class=\"merge-settings\"><h2>Merge settings</h2><dl class=\"kv\"><dt>modes</dt><dd>")
3277+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 304, "<details class=\"menu omenu\"><summary class=\"btn icon\" aria-label=\"More actions\" title=\"more actions\">⋯</summary><div class=\"menu-pop\" role=\"group\" aria-label=\"More actions\"><section class=\"merge-settings\"><h2>Merge settings</h2><dl class=\"kv\"><dt>modes</dt><dd>")
32593278 if templ_7745c5c3_Err != nil {
32603279 return templ_7745c5c3_Err
32613280 }
3262- var templ_7745c5c3_Var156 string
3263- templ_7745c5c3_Var156, templ_7745c5c3_Err = templ.JoinStringErrs(strings.Join(p.Modes, ", "))
3281+ var templ_7745c5c3_Var157 string
3282+ templ_7745c5c3_Var157, templ_7745c5c3_Err = templ.JoinStringErrs(strings.Join(p.Modes, ", "))
32643283 if templ_7745c5c3_Err != nil {
3265- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 633, Col: 38}
3284+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 637, Col: 38}
32663285 }
3267- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var156))
3286+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var157))
32683287 if templ_7745c5c3_Err != nil {
32693288 return templ_7745c5c3_Err
32703289 }
3271- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 303, "</dd><dt>checks</dt><dd>")
3290+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 305, "</dd><dt>checks</dt><dd>")
32723291 if templ_7745c5c3_Err != nil {
32733292 return templ_7745c5c3_Err
32743293 }
32753294 if p.ChecksBlock {
3276- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 304, "failing ones block the merge")
3295+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 306, "failing or unfinished checks block the merge")
32773296 if templ_7745c5c3_Err != nil {
32783297 return templ_7745c5c3_Err
32793298 }
32803299 } else {
3281- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 305, "do not block the merge")
3300+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 307, "do not block the merge")
32823301 if templ_7745c5c3_Err != nil {
32833302 return templ_7745c5c3_Err
32843303 }
32853304 }
3286- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 306, "</dd></dl></section>")
3305+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 308, "</dd></dl></section>")
32873306 if templ_7745c5c3_Err != nil {
32883307 return templ_7745c5c3_Err
32893308 }
32903309 if p.Box != nil {
32913310 if p.Box.Signed {
3292- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 307, "<p class=\"d-note\" id=\"mr-signing\">squash and merge commits are signed with ermite's own key (generated on first start). ")
3311+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 309, "<p class=\"d-note\" id=\"mr-signing\">squash and merge commits are signed with ermite's own key (generated on first start). ")
32933312 if templ_7745c5c3_Err != nil {
32943313 return templ_7745c5c3_Err
32953314 }
32963315 if p.Box.Fingerprint != "" {
3297- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 308, "fingerprint <code>")
3316+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 310, "fingerprint <code>")
32983317 if templ_7745c5c3_Err != nil {
32993318 return templ_7745c5c3_Err
33003319 }
3301- var templ_7745c5c3_Var157 string
3302- templ_7745c5c3_Var157, templ_7745c5c3_Err = templ.JoinStringErrs(p.Box.Fingerprint)
3320+ var templ_7745c5c3_Var158 string
3321+ templ_7745c5c3_Var158, templ_7745c5c3_Err = templ.JoinStringErrs(p.Box.Fingerprint)
33033322 if templ_7745c5c3_Err != nil {
3304- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 649, Col: 44}
3323+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 653, Col: 44}
33053324 }
3306- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var157))
3325+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var158))
33073326 if templ_7745c5c3_Err != nil {
33083327 return templ_7745c5c3_Err
33093328 }
3310- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 309, "</code> ")
3329+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 311, "</code> ")
33113330 if templ_7745c5c3_Err != nil {
33123331 return templ_7745c5c3_Err
33133332 }
33143333 }
3315- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 310, "<code>ermite signing-key show</code> prints it.</p>")
3334+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 312, "<code>ermite signing-key show</code> prints it.</p>")
33163335 if templ_7745c5c3_Err != nil {
33173336 return templ_7745c5c3_Err
33183337 }
33193338 }
3320- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 311, " ")
3339+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 313, " ")
33213340 if templ_7745c5c3_Err != nil {
33223341 return templ_7745c5c3_Err
33233342 }
33243343 if p.Box.CanMarkRead {
3325- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 312, "<form method=\"post\" action=\"")
3344+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 314, "<form method=\"post\" action=\"")
33263345 if templ_7745c5c3_Err != nil {
33273346 return templ_7745c5c3_Err
33283347 }
3329- var templ_7745c5c3_Var158 templ.SafeURL
3330- templ_7745c5c3_Var158, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Box.ReadAction))
3348+ var templ_7745c5c3_Var159 templ.SafeURL
3349+ templ_7745c5c3_Var159, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Box.ReadAction))
33313350 if templ_7745c5c3_Err != nil {
3332- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 655, Col: 65}
3351+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 659, Col: 65}
33333352 }
3334- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var158))
3353+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var159))
33353354 if templ_7745c5c3_Err != nil {
33363355 return templ_7745c5c3_Err
33373356 }
3338- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 313, "\"><input type=\"hidden\" name=\"head_id\" value=\"")
3357+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 315, "\"><input type=\"hidden\" name=\"head_id\" value=\"")
33393358 if templ_7745c5c3_Err != nil {
33403359 return templ_7745c5c3_Err
33413360 }
3342- var templ_7745c5c3_Var159 string
3343- templ_7745c5c3_Var159, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Box.Head)
3361+ var templ_7745c5c3_Var160 string
3362+ templ_7745c5c3_Var160, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Box.Head)
33443363 if templ_7745c5c3_Err != nil {
3345- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 656, Col: 60}
3364+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 660, Col: 60}
33463365 }
3347- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var159)
3366+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var160)
33483367 if templ_7745c5c3_Err != nil {
33493368 return templ_7745c5c3_Err
33503369 }
3351- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 314, "\"> <button type=\"submit\" title=\"the next visit can show only what changed after this head\" class=\"btn\" aria-keyshortcuts=\"Shift+R\" data-read>Mark read <kbd aria-hidden=\"true\">R</kbd></button></form>")
3370+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 316, "\"> <button type=\"submit\" title=\"the next visit can show only what changed after this head\" class=\"btn\" aria-keyshortcuts=\"Shift+R\" data-read>Mark read <kbd aria-hidden=\"true\">R</kbd></button></form>")
33523371 if templ_7745c5c3_Err != nil {
33533372 return templ_7745c5c3_Err
33543373 }
33553374 }
3356- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 315, " <form method=\"post\" action=\"")
3375+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 317, " <form method=\"post\" action=\"")
33573376 if templ_7745c5c3_Err != nil {
33583377 return templ_7745c5c3_Err
33593378 }
3360- var templ_7745c5c3_Var160 templ.SafeURL
3361- templ_7745c5c3_Var160, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Box.CloseAction))
3379+ var templ_7745c5c3_Var161 templ.SafeURL
3380+ templ_7745c5c3_Var161, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Box.CloseAction))
33623381 if templ_7745c5c3_Err != nil {
3363- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 660, Col: 65}
3382+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 664, Col: 65}
33643383 }
3365- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var160))
3384+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var161))
33663385 if templ_7745c5c3_Err != nil {
33673386 return templ_7745c5c3_Err
33683387 }
3369- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 316, "\"><button type=\"submit\" title=\"close without merging; the branch is kept\" class=\"btn danger\">Close</button></form>")
3388+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 318, "\"><button type=\"submit\" title=\"close without merging; the branch is kept\" class=\"btn danger\">Close</button></form>")
33703389 if templ_7745c5c3_Err != nil {
33713390 return templ_7745c5c3_Err
33723391 }
33733392 if !p.Box.HeadGone && p.Box.ReadyAction == "" {
3374- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 317, "<details class=\"d-or\"><summary class=\"mute\">or from a terminal</summary>")
3393+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 319, "<details class=\"d-or\"><summary class=\"mute\">or from a terminal</summary>")
33753394 if templ_7745c5c3_Err != nil {
33763395 return templ_7745c5c3_Err
33773396 }
@@ -3379,13 +3398,13 @@ func moreMenu(p MRPage) templ.Component {
33793398 if templ_7745c5c3_Err != nil {
33803399 return templ_7745c5c3_Err
33813400 }
3382- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 318, "</details>")
3401+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 320, "</details>")
33833402 if templ_7745c5c3_Err != nil {
33843403 return templ_7745c5c3_Err
33853404 }
33863405 }
33873406 }
3388- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 319, "</div></details>")
3407+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 321, "</div></details>")
33893408 if templ_7745c5c3_Err != nil {
33903409 return templ_7745c5c3_Err
33913410 }
@@ -3409,12 +3428,12 @@ func Compare(l Layout, p ComparePage) templ.Component {
34093428 }()
34103429 }
34113430 ctx = templ.InitializeContext(ctx)
3412- templ_7745c5c3_Var161 := templ.GetChildren(ctx)
3413- if templ_7745c5c3_Var161 == nil {
3414- templ_7745c5c3_Var161 = templ.NopComponent
3431+ templ_7745c5c3_Var162 := templ.GetChildren(ctx)
3432+ if templ_7745c5c3_Var162 == nil {
3433+ templ_7745c5c3_Var162 = templ.NopComponent
34153434 }
34163435 ctx = templ.ClearChildren(ctx)
3417- templ_7745c5c3_Var162 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
3436+ templ_7745c5c3_Var163 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
34183437 templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
34193438 templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
34203439 if !templ_7745c5c3_IsBuffer {
@@ -3426,263 +3445,263 @@ func Compare(l Layout, p ComparePage) templ.Component {
34263445 }()
34273446 }
34283447 ctx = templ.InitializeContext(ctx)
3429- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 320, "<header class=\"show mr-h\"><h1>")
3430- if templ_7745c5c3_Err != nil {
3431- return templ_7745c5c3_Err
3432- }
3433- var templ_7745c5c3_Var163 string
3434- templ_7745c5c3_Var163, templ_7745c5c3_Err = templ.JoinStringErrs(p.Source)
3435- if templ_7745c5c3_Err != nil {
3436- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 677, Col: 17}
3437- }
3438- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var163))
3439- if templ_7745c5c3_Err != nil {
3440- return templ_7745c5c3_Err
3441- }
3442- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 321, " → ")
3448+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 322, "<header class=\"show mr-h\"><h1>")
34433449 if templ_7745c5c3_Err != nil {
34443450 return templ_7745c5c3_Err
34453451 }
34463452 var templ_7745c5c3_Var164 string
3447- templ_7745c5c3_Var164, templ_7745c5c3_Err = templ.JoinStringErrs(p.Target)
3453+ templ_7745c5c3_Var164, templ_7745c5c3_Err = templ.JoinStringErrs(p.Source)
34483454 if templ_7745c5c3_Err != nil {
3449- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 677, Col: 34}
3455+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 681, Col: 17}
34503456 }
34513457 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var164))
34523458 if templ_7745c5c3_Err != nil {
34533459 return templ_7745c5c3_Err
34543460 }
3455- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 322, "</h1><dl class=\"kv show-kv\"><dt>branch</dt><dd><a href=\"")
3461+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 323, " → ")
34563462 if templ_7745c5c3_Err != nil {
34573463 return templ_7745c5c3_Err
34583464 }
3459- var templ_7745c5c3_Var165 templ.SafeURL
3460- templ_7745c5c3_Var165, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.SourceHref))
3465+ var templ_7745c5c3_Var165 string
3466+ templ_7745c5c3_Var165, templ_7745c5c3_Err = templ.JoinStringErrs(p.Target)
34613467 if templ_7745c5c3_Err != nil {
3462- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 680, Col: 45}
3468+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 681, Col: 34}
34633469 }
34643470 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var165))
34653471 if templ_7745c5c3_Err != nil {
34663472 return templ_7745c5c3_Err
34673473 }
3468- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 323, "\">")
3474+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 324, "</h1><dl class=\"kv show-kv\"><dt>branch</dt><dd><a href=\"")
34693475 if templ_7745c5c3_Err != nil {
34703476 return templ_7745c5c3_Err
34713477 }
3472- var templ_7745c5c3_Var166 string
3473- templ_7745c5c3_Var166, templ_7745c5c3_Err = templ.JoinStringErrs(p.Source)
3478+ var templ_7745c5c3_Var166 templ.SafeURL
3479+ templ_7745c5c3_Var166, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.SourceHref))
34743480 if templ_7745c5c3_Err != nil {
3475- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 680, Col: 58}
3481+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 684, Col: 45}
34763482 }
34773483 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var166))
34783484 if templ_7745c5c3_Err != nil {
34793485 return templ_7745c5c3_Err
34803486 }
3481- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 324, "</a></dd><dt>target</dt><dd><a href=\"")
3487+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 325, "\">")
34823488 if templ_7745c5c3_Err != nil {
34833489 return templ_7745c5c3_Err
34843490 }
3485- var templ_7745c5c3_Var167 templ.SafeURL
3486- templ_7745c5c3_Var167, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.TargetHref))
3491+ var templ_7745c5c3_Var167 string
3492+ templ_7745c5c3_Var167, templ_7745c5c3_Err = templ.JoinStringErrs(p.Source)
34873493 if templ_7745c5c3_Err != nil {
3488- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 682, Col: 45}
3494+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 684, Col: 58}
34893495 }
34903496 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var167))
34913497 if templ_7745c5c3_Err != nil {
34923498 return templ_7745c5c3_Err
34933499 }
3494- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 325, "\">")
3500+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 326, "</a></dd><dt>target</dt><dd><a href=\"")
34953501 if templ_7745c5c3_Err != nil {
34963502 return templ_7745c5c3_Err
34973503 }
3498- var templ_7745c5c3_Var168 string
3499- templ_7745c5c3_Var168, templ_7745c5c3_Err = templ.JoinStringErrs(p.Target)
3504+ var templ_7745c5c3_Var168 templ.SafeURL
3505+ templ_7745c5c3_Var168, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.TargetHref))
35003506 if templ_7745c5c3_Err != nil {
3501- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 682, Col: 58}
3507+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 686, Col: 45}
35023508 }
35033509 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var168))
35043510 if templ_7745c5c3_Err != nil {
35053511 return templ_7745c5c3_Err
35063512 }
3507- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 326, "</a></dd><dt>ahead</dt><dd>")
3513+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 327, "\">")
35083514 if templ_7745c5c3_Err != nil {
35093515 return templ_7745c5c3_Err
35103516 }
35113517 var templ_7745c5c3_Var169 string
3512- templ_7745c5c3_Var169, templ_7745c5c3_Err = templ.JoinStringErrs(p.AheadText)
3518+ templ_7745c5c3_Var169, templ_7745c5c3_Err = templ.JoinStringErrs(p.Target)
35133519 if templ_7745c5c3_Err != nil {
3514- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 684, Col: 21}
3520+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 686, Col: 58}
35153521 }
35163522 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var169))
35173523 if templ_7745c5c3_Err != nil {
35183524 return templ_7745c5c3_Err
35193525 }
3520- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 327, "</dd></dl></header>")
3526+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 328, "</a></dd><dt>ahead</dt><dd>")
3527+ if templ_7745c5c3_Err != nil {
3528+ return templ_7745c5c3_Err
3529+ }
3530+ var templ_7745c5c3_Var170 string
3531+ templ_7745c5c3_Var170, templ_7745c5c3_Err = templ.JoinStringErrs(p.AheadText)
3532+ if templ_7745c5c3_Err != nil {
3533+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 688, Col: 21}
3534+ }
3535+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var170))
3536+ if templ_7745c5c3_Err != nil {
3537+ return templ_7745c5c3_Err
3538+ }
3539+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 329, "</dd></dl></header>")
35213540 if templ_7745c5c3_Err != nil {
35223541 return templ_7745c5c3_Err
35233542 }
35243543 if p.Note != "" {
3525- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 328, "<p class=\"notice\">")
3544+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 330, "<p class=\"notice\">")
35263545 if templ_7745c5c3_Err != nil {
35273546 return templ_7745c5c3_Err
35283547 }
3529- var templ_7745c5c3_Var170 string
3530- templ_7745c5c3_Var170, templ_7745c5c3_Err = templ.JoinStringErrs(p.Note)
3548+ var templ_7745c5c3_Var171 string
3549+ templ_7745c5c3_Var171, templ_7745c5c3_Err = templ.JoinStringErrs(p.Note)
35313550 if templ_7745c5c3_Err != nil {
3532- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 688, Col: 29}
3551+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 692, Col: 29}
35333552 }
3534- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var170))
3553+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var171))
35353554 if templ_7745c5c3_Err != nil {
35363555 return templ_7745c5c3_Err
35373556 }
3538- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 329, "</p>")
3557+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 331, "</p>")
35393558 if templ_7745c5c3_Err != nil {
35403559 return templ_7745c5c3_Err
35413560 }
35423561 }
3543- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 330, " ")
3562+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 332, " ")
35443563 if templ_7745c5c3_Err != nil {
35453564 return templ_7745c5c3_Err
35463565 }
35473566 if p.Existing != nil {
3548- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 331, "<p class=\"notice\">an open merge request already covers these branches: <a href=\"")
3567+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 333, "<p class=\"notice\">an open merge request already covers these branches: <a href=\"")
35493568 if templ_7745c5c3_Err != nil {
35503569 return templ_7745c5c3_Err
35513570 }
3552- var templ_7745c5c3_Var171 templ.SafeURL
3553- templ_7745c5c3_Var171, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Existing.Href))
3571+ var templ_7745c5c3_Var172 templ.SafeURL
3572+ templ_7745c5c3_Var172, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Existing.Href))
35543573 if templ_7745c5c3_Err != nil {
3555- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 691, Col: 114}
3574+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 695, Col: 114}
35563575 }
3557- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var171))
3576+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var172))
35583577 if templ_7745c5c3_Err != nil {
35593578 return templ_7745c5c3_Err
35603579 }
3561- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 332, "\">")
3580+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 334, "\">")
35623581 if templ_7745c5c3_Err != nil {
35633582 return templ_7745c5c3_Err
35643583 }
3565- var templ_7745c5c3_Var172 string
3566- templ_7745c5c3_Var172, templ_7745c5c3_Err = templ.JoinStringErrs(p.Existing.Label)
3584+ var templ_7745c5c3_Var173 string
3585+ templ_7745c5c3_Var173, templ_7745c5c3_Err = templ.JoinStringErrs(p.Existing.Label)
35673586 if templ_7745c5c3_Err != nil {
3568- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 691, Col: 135}
3587+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 695, Col: 135}
35693588 }
3570- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var172))
3589+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var173))
35713590 if templ_7745c5c3_Err != nil {
35723591 return templ_7745c5c3_Err
35733592 }
3574- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 333, "</a></p>")
3593+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 335, "</a></p>")
35753594 if templ_7745c5c3_Err != nil {
35763595 return templ_7745c5c3_Err
35773596 }
35783597 }
3579- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 334, " ")
3598+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 336, " ")
35803599 if templ_7745c5c3_Err != nil {
35813600 return templ_7745c5c3_Err
35823601 }
35833602 if p.Create != nil {
3584- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 335, "<form class=\"cform create\" method=\"post\" action=\"")
3603+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 337, "<form class=\"cform create\" method=\"post\" action=\"")
35853604 if templ_7745c5c3_Err != nil {
35863605 return templ_7745c5c3_Err
35873606 }
3588- var templ_7745c5c3_Var173 templ.SafeURL
3589- templ_7745c5c3_Var173, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Create.Action))
3607+ var templ_7745c5c3_Var174 templ.SafeURL
3608+ templ_7745c5c3_Var174, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Create.Action))
35903609 if templ_7745c5c3_Err != nil {
3591- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 694, Col: 83}
3610+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 698, Col: 83}
35923611 }
3593- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var173))
3612+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var174))
35943613 if templ_7745c5c3_Err != nil {
35953614 return templ_7745c5c3_Err
35963615 }
3597- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 336, "\"><input type=\"hidden\" name=\"source\" value=\"")
3616+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 338, "\"><input type=\"hidden\" name=\"source\" value=\"")
35983617 if templ_7745c5c3_Err != nil {
35993618 return templ_7745c5c3_Err
36003619 }
3601- var templ_7745c5c3_Var174 string
3602- templ_7745c5c3_Var174, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Create.Source)
3620+ var templ_7745c5c3_Var175 string
3621+ templ_7745c5c3_Var175, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Create.Source)
36033622 if templ_7745c5c3_Err != nil {
3604- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 695, Col: 62}
3623+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 699, Col: 62}
36053624 }
3606- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var174)
3625+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var175)
36073626 if templ_7745c5c3_Err != nil {
36083627 return templ_7745c5c3_Err
36093628 }
3610- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 337, "\"> <input type=\"hidden\" name=\"target\" value=\"")
3629+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 339, "\"> <input type=\"hidden\" name=\"target\" value=\"")
36113630 if templ_7745c5c3_Err != nil {
36123631 return templ_7745c5c3_Err
36133632 }
3614- var templ_7745c5c3_Var175 string
3615- templ_7745c5c3_Var175, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Create.Target)
3633+ var templ_7745c5c3_Var176 string
3634+ templ_7745c5c3_Var176, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Create.Target)
36163635 if templ_7745c5c3_Err != nil {
3617- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 696, Col: 62}
3636+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 700, Col: 62}
36183637 }
3619- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var175)
3638+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var176)
36203639 if templ_7745c5c3_Err != nil {
36213640 return templ_7745c5c3_Err
36223641 }
3623- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 338, "\"> <label for=\"mr-title\">title</label> <input id=\"mr-title\" name=\"title\" type=\"text\" maxlength=\"120\" required value=\"")
3642+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 340, "\"> <label for=\"mr-title\">title</label> <input id=\"mr-title\" name=\"title\" type=\"text\" maxlength=\"120\" required value=\"")
36243643 if templ_7745c5c3_Err != nil {
36253644 return templ_7745c5c3_Err
36263645 }
3627- var templ_7745c5c3_Var176 string
3628- templ_7745c5c3_Var176, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Create.Title)
3646+ var templ_7745c5c3_Var177 string
3647+ templ_7745c5c3_Var177, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Create.Title)
36293648 if templ_7745c5c3_Err != nil {
3630- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 698, Col: 97}
3649+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 702, Col: 97}
36313650 }
3632- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var176)
3651+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var177)
36333652 if templ_7745c5c3_Err != nil {
36343653 return templ_7745c5c3_Err
36353654 }
3636- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 339, "\" autocomplete=\"off\"> <label for=\"mr-desc\">description</label> <textarea id=\"mr-desc\" name=\"description\" rows=\"4\" maxlength=\"8000\" placeholder=\"Markdown, optional\"></textarea><div class=\"f-btns\"><button type=\"submit\" class=\"btn primary\">Create merge request</button></div></form>")
3655+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 341, "\" autocomplete=\"off\"> <label for=\"mr-desc\">description</label> <textarea id=\"mr-desc\" name=\"description\" rows=\"4\" maxlength=\"8000\" placeholder=\"Markdown, optional\"></textarea><div class=\"f-btns\"><button type=\"submit\" class=\"btn primary\">Create merge request</button></div></form>")
36373656 if templ_7745c5c3_Err != nil {
36383657 return templ_7745c5c3_Err
36393658 }
36403659 }
3641- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 340, " ")
3660+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 342, " ")
36423661 if templ_7745c5c3_Err != nil {
36433662 return templ_7745c5c3_Err
36443663 }
36453664 if p.HasDiff {
3646- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 341, "<div class=\"diff-tools\" role=\"group\" aria-label=\"Diff view\"><span class=\"dim\">")
3665+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 343, "<div class=\"diff-tools\" role=\"group\" aria-label=\"Diff view\"><span class=\"dim\">")
36473666 if templ_7745c5c3_Err != nil {
36483667 return templ_7745c5c3_Err
36493668 }
3650- var templ_7745c5c3_Var177 string
3651- templ_7745c5c3_Var177, templ_7745c5c3_Err = templ.JoinStringErrs(plural(p.NFiles, "file", "files"))
3669+ var templ_7745c5c3_Var178 string
3670+ templ_7745c5c3_Var178, templ_7745c5c3_Err = templ.JoinStringErrs(plural(p.NFiles, "file", "files"))
36523671 if templ_7745c5c3_Err != nil {
3653- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 708, Col: 57}
3672+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 712, Col: 57}
36543673 }
3655- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var177))
3674+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var178))
36563675 if templ_7745c5c3_Err != nil {
36573676 return templ_7745c5c3_Err
36583677 }
3659- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 342, " · <span class=\"plus\">+")
3678+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 344, " · <span class=\"plus\">+")
36603679 if templ_7745c5c3_Err != nil {
36613680 return templ_7745c5c3_Err
36623681 }
3663- var templ_7745c5c3_Var178 string
3664- templ_7745c5c3_Var178, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(p.Adds))
3682+ var templ_7745c5c3_Var179 string
3683+ templ_7745c5c3_Var179, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(p.Adds))
36653684 if templ_7745c5c3_Err != nil {
3666- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 708, Col: 97}
3685+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 712, Col: 97}
36673686 }
3668- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var178))
3687+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var179))
36693688 if templ_7745c5c3_Err != nil {
36703689 return templ_7745c5c3_Err
36713690 }
3672- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 343, "</span> <span class=\"minus\">-")
3691+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 345, "</span> <span class=\"minus\">-")
36733692 if templ_7745c5c3_Err != nil {
36743693 return templ_7745c5c3_Err
36753694 }
3676- var templ_7745c5c3_Var179 string
3677- templ_7745c5c3_Var179, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(p.Dels))
3695+ var templ_7745c5c3_Var180 string
3696+ templ_7745c5c3_Var180, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(p.Dels))
36783697 if templ_7745c5c3_Err != nil {
3679- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 708, Col: 142}
3698+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 712, Col: 142}
36803699 }
3681- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var179))
3700+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var180))
36823701 if templ_7745c5c3_Err != nil {
36833702 return templ_7745c5c3_Err
36843703 }
3685- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 344, "</span></span> <span class=\"grow\"></span>")
3704+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 346, "</span></span> <span class=\"grow\"></span>")
36863705 if templ_7745c5c3_Err != nil {
36873706 return templ_7745c5c3_Err
36883707 }
@@ -3690,64 +3709,64 @@ func Compare(l Layout, p ComparePage) templ.Component {
36903709 if templ_7745c5c3_Err != nil {
36913710 return templ_7745c5c3_Err
36923711 }
3693- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 345, "</div>")
3712+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 347, "</div>")
36943713 if templ_7745c5c3_Err != nil {
36953714 return templ_7745c5c3_Err
36963715 }
36973716 if p.Invisible {
3698- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 346, "<p class=\"notice\">this diff holds invisible characters (direction controls, zero-width characters). They are shown as <span class=\"inv\">&lt;U+XXXX&gt;</span> markers, never applied.</p>")
3717+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 348, "<p class=\"notice\">this diff holds invisible characters (direction controls, zero-width characters). They are shown as <span class=\"inv\">&lt;U+XXXX&gt;</span> markers, never applied.</p>")
36993718 if templ_7745c5c3_Err != nil {
37003719 return templ_7745c5c3_Err
37013720 }
37023721 }
3703- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 347, " <div id=\"diffs\"")
3722+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 349, " <div id=\"diffs\"")
37043723 if templ_7745c5c3_Err != nil {
37053724 return templ_7745c5c3_Err
37063725 }
37073726 if p.Both {
3708- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 348, " data-diff=\"")
3727+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 350, " data-diff=\"")
37093728 if templ_7745c5c3_Err != nil {
37103729 return templ_7745c5c3_Err
37113730 }
3712- var templ_7745c5c3_Var180 string
3713- templ_7745c5c3_Var180, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.View)
3731+ var templ_7745c5c3_Var181 string
3732+ templ_7745c5c3_Var181, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.View)
37143733 if templ_7745c5c3_Err != nil {
3715- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 721, Col: 23}
3734+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 725, Col: 23}
37163735 }
3717- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var180)
3736+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var181)
37183737 if templ_7745c5c3_Err != nil {
37193738 return templ_7745c5c3_Err
37203739 }
3721- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 349, "\"")
3740+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 351, "\"")
37223741 if templ_7745c5c3_Err != nil {
37233742 return templ_7745c5c3_Err
37243743 }
37253744 } else {
3726- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 350, " data-view=\"")
3745+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 352, " data-view=\"")
37273746 if templ_7745c5c3_Err != nil {
37283747 return templ_7745c5c3_Err
37293748 }
3730- var templ_7745c5c3_Var181 string
3731- templ_7745c5c3_Var181, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.View)
3749+ var templ_7745c5c3_Var182 string
3750+ templ_7745c5c3_Var182, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.View)
37323751 if templ_7745c5c3_Err != nil {
3733- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 723, Col: 23}
3752+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 727, Col: 23}
37343753 }
3735- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var181)
3754+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var182)
37363755 if templ_7745c5c3_Err != nil {
37373756 return templ_7745c5c3_Err
37383757 }
3739- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 351, "\"")
3758+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 353, "\"")
37403759 if templ_7745c5c3_Err != nil {
37413760 return templ_7745c5c3_Err
37423761 }
37433762 }
37443763 if p.Both && !p.Pinned {
3745- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 352, " hx-live=\"this.dataset.diff = sessionStorage.getItem('diff') || this.dataset.diff\"")
3764+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 354, " hx-live=\"this.dataset.diff = sessionStorage.getItem('diff') || this.dataset.diff\"")
37463765 if templ_7745c5c3_Err != nil {
37473766 return templ_7745c5c3_Err
37483767 }
37493768 }
3750- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 353, ">")
3769+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 355, ">")
37513770 if templ_7745c5c3_Err != nil {
37523771 return templ_7745c5c3_Err
37533772 }
@@ -3757,14 +3776,14 @@ func Compare(l Layout, p ComparePage) templ.Component {
37573776 return templ_7745c5c3_Err
37583777 }
37593778 }
3760- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 354, "</div>")
3779+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 356, "</div>")
37613780 if templ_7745c5c3_Err != nil {
37623781 return templ_7745c5c3_Err
37633782 }
37643783 }
37653784 return nil
37663785 })
3767- templ_7745c5c3_Err = Shell(l, compareRail(p)).Render(templ.WithChildren(ctx, templ_7745c5c3_Var162), templ_7745c5c3_Buffer)
3786+ templ_7745c5c3_Err = Shell(l, compareRail(p)).Render(templ.WithChildren(ctx, templ_7745c5c3_Var163), templ_7745c5c3_Buffer)
37683787 if templ_7745c5c3_Err != nil {
37693788 return templ_7745c5c3_Err
37703789 }
@@ -3788,173 +3807,173 @@ func compareRail(p ComparePage) templ.Component {
37883807 }()
37893808 }
37903809 ctx = templ.InitializeContext(ctx)
3791- templ_7745c5c3_Var182 := templ.GetChildren(ctx)
3792- if templ_7745c5c3_Var182 == nil {
3793- templ_7745c5c3_Var182 = templ.NopComponent
3810+ templ_7745c5c3_Var183 := templ.GetChildren(ctx)
3811+ if templ_7745c5c3_Var183 == nil {
3812+ templ_7745c5c3_Var183 = templ.NopComponent
37943813 }
37953814 ctx = templ.ClearChildren(ctx)
3796- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 355, "<section aria-labelledby=\"r-ahead\"><h2 id=\"r-ahead\">Commits <span class=\"count\">")
3815+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 357, "<section aria-labelledby=\"r-ahead\"><h2 id=\"r-ahead\">Commits <span class=\"count\">")
37973816 if templ_7745c5c3_Err != nil {
37983817 return templ_7745c5c3_Err
37993818 }
3800- var templ_7745c5c3_Var183 string
3801- templ_7745c5c3_Var183, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(len(p.Ahead)))
3819+ var templ_7745c5c3_Var184 string
3820+ templ_7745c5c3_Var184, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(len(p.Ahead)))
38023821 if templ_7745c5c3_Err != nil {
3803- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 739, Col: 67}
3822+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 743, Col: 67}
38043823 }
3805- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var183))
3824+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var184))
38063825 if templ_7745c5c3_Err != nil {
38073826 return templ_7745c5c3_Err
38083827 }
3809- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 356, "</span></h2><ul class=\"pcommits\">")
3828+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 358, "</span></h2><ul class=\"pcommits\">")
38103829 if templ_7745c5c3_Err != nil {
38113830 return templ_7745c5c3_Err
38123831 }
38133832 for _, c := range p.Ahead {
3814- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 357, "<li><a href=\"")
3833+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 359, "<li><a href=\"")
38153834 if templ_7745c5c3_Err != nil {
38163835 return templ_7745c5c3_Err
38173836 }
3818- var templ_7745c5c3_Var184 templ.SafeURL
3819- templ_7745c5c3_Var184, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(c.CHref))
3837+ var templ_7745c5c3_Var185 templ.SafeURL
3838+ templ_7745c5c3_Var185, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(c.CHref))
38203839 if templ_7745c5c3_Err != nil {
3821- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 743, Col: 37}
3840+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 747, Col: 37}
38223841 }
3823- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var184))
3842+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var185))
38243843 if templ_7745c5c3_Err != nil {
38253844 return templ_7745c5c3_Err
38263845 }
3827- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 358, "\">")
3846+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 360, "\">")
38283847 if templ_7745c5c3_Err != nil {
38293848 return templ_7745c5c3_Err
38303849 }
3831- var templ_7745c5c3_Var185 string
3832- templ_7745c5c3_Var185, templ_7745c5c3_Err = templ.JoinStringErrs(c.Short)
3850+ var templ_7745c5c3_Var186 string
3851+ templ_7745c5c3_Var186, templ_7745c5c3_Err = templ.JoinStringErrs(c.Short)
38333852 if templ_7745c5c3_Err != nil {
3834- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 743, Col: 49}
3853+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 747, Col: 49}
38353854 }
3836- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var185))
3855+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var186))
38373856 if templ_7745c5c3_Err != nil {
38383857 return templ_7745c5c3_Err
38393858 }
3840- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 359, "</a> <span class=\"s\">")
3859+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 361, "</a> <span class=\"s\">")
38413860 if templ_7745c5c3_Err != nil {
38423861 return templ_7745c5c3_Err
38433862 }
3844- var templ_7745c5c3_Var186 string
3845- templ_7745c5c3_Var186, templ_7745c5c3_Err = templ.JoinStringErrs(c.Subject)
3863+ var templ_7745c5c3_Var187 string
3864+ templ_7745c5c3_Var187, templ_7745c5c3_Err = templ.JoinStringErrs(c.Subject)
38463865 if templ_7745c5c3_Err != nil {
3847- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 744, Col: 32}
3866+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 748, Col: 32}
38483867 }
3849- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var186))
3868+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var187))
38503869 if templ_7745c5c3_Err != nil {
38513870 return templ_7745c5c3_Err
38523871 }
3853- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 360, "</span> <span class=\"mute\">")
3872+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 362, "</span> <span class=\"mute\">")
38543873 if templ_7745c5c3_Err != nil {
38553874 return templ_7745c5c3_Err
38563875 }
3857- var templ_7745c5c3_Var187 string
3858- templ_7745c5c3_Var187, templ_7745c5c3_Err = templ.JoinStringErrs(c.Author)
3876+ var templ_7745c5c3_Var188 string
3877+ templ_7745c5c3_Var188, templ_7745c5c3_Err = templ.JoinStringErrs(c.Author)
38593878 if templ_7745c5c3_Err != nil {
3860- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 746, Col: 16}
3879+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 750, Col: 16}
38613880 }
3862- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var187))
3881+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var188))
38633882 if templ_7745c5c3_Err != nil {
38643883 return templ_7745c5c3_Err
38653884 }
3866- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 361, " ")
3885+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 363, " ")
38673886 if templ_7745c5c3_Err != nil {
38683887 return templ_7745c5c3_Err
38693888 }
38703889 if c.WhenAt != "" {
3871- var templ_7745c5c3_Var188 string
3872- templ_7745c5c3_Var188, templ_7745c5c3_Err = templ.JoinStringErrs(" · ")
3890+ var templ_7745c5c3_Var189 string
3891+ templ_7745c5c3_Var189, templ_7745c5c3_Err = templ.JoinStringErrs(" · ")
38733892 if templ_7745c5c3_Err != nil {
3874- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 748, Col: 15}
3893+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 752, Col: 15}
38753894 }
3876- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var188))
3895+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var189))
38773896 if templ_7745c5c3_Err != nil {
38783897 return templ_7745c5c3_Err
38793898 }
3880- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 362, "<time datetime=\"")
3899+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 364, "<time datetime=\"")
38813900 if templ_7745c5c3_Err != nil {
38823901 return templ_7745c5c3_Err
38833902 }
3884- var templ_7745c5c3_Var189 string
3885- templ_7745c5c3_Var189, templ_7745c5c3_Err = templ.ResolveAttributeValue(c.WhenAt)
3903+ var templ_7745c5c3_Var190 string
3904+ templ_7745c5c3_Var190, templ_7745c5c3_Err = templ.ResolveAttributeValue(c.WhenAt)
38863905 if templ_7745c5c3_Err != nil {
3887- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 748, Col: 42}
3906+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 752, Col: 42}
38883907 }
3889- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var189)
3908+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var190)
38903909 if templ_7745c5c3_Err != nil {
38913910 return templ_7745c5c3_Err
38923911 }
3893- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 363, "\">")
3912+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 365, "\">")
38943913 if templ_7745c5c3_Err != nil {
38953914 return templ_7745c5c3_Err
38963915 }
3897- var templ_7745c5c3_Var190 string
3898- templ_7745c5c3_Var190, templ_7745c5c3_Err = templ.JoinStringErrs(c.When)
3916+ var templ_7745c5c3_Var191 string
3917+ templ_7745c5c3_Var191, templ_7745c5c3_Err = templ.JoinStringErrs(c.When)
38993918 if templ_7745c5c3_Err != nil {
3900- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 748, Col: 53}
3919+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 752, Col: 53}
39013920 }
3902- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var190))
3921+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var191))
39033922 if templ_7745c5c3_Err != nil {
39043923 return templ_7745c5c3_Err
39053924 }
3906- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 364, "</time>")
3925+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 366, "</time>")
39073926 if templ_7745c5c3_Err != nil {
39083927 return templ_7745c5c3_Err
39093928 }
39103929 }
3911- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 365, "</span></li>")
3930+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 367, "</span></li>")
39123931 if templ_7745c5c3_Err != nil {
39133932 return templ_7745c5c3_Err
39143933 }
39153934 }
3916- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 366, "</ul>")
3935+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 368, "</ul>")
39173936 if templ_7745c5c3_Err != nil {
39183937 return templ_7745c5c3_Err
39193938 }
39203939 if len(p.Ahead) == 0 {
3921- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 367, "<p class=\"dim\">no commit ahead of ")
3940+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 369, "<p class=\"dim\">no commit ahead of ")
39223941 if templ_7745c5c3_Err != nil {
39233942 return templ_7745c5c3_Err
39243943 }
3925- var templ_7745c5c3_Var191 string
3926- templ_7745c5c3_Var191, templ_7745c5c3_Err = templ.JoinStringErrs(p.Target)
3944+ var templ_7745c5c3_Var192 string
3945+ templ_7745c5c3_Var192, templ_7745c5c3_Err = templ.JoinStringErrs(p.Target)
39273946 if templ_7745c5c3_Err != nil {
3928- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 755, Col: 47}
3947+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 759, Col: 47}
39293948 }
3930- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var191))
3949+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var192))
39313950 if templ_7745c5c3_Err != nil {
39323951 return templ_7745c5c3_Err
39333952 }
3934- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 368, ".</p>")
3953+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 370, ".</p>")
39353954 if templ_7745c5c3_Err != nil {
39363955 return templ_7745c5c3_Err
39373956 }
39383957 }
3939- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 369, "</section>")
3958+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 371, "</section>")
39403959 if templ_7745c5c3_Err != nil {
39413960 return templ_7745c5c3_Err
39423961 }
39433962 if p.HasDiff {
3944- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 370, "<section aria-labelledby=\"r-files\"><h2 id=\"r-files\">Files <span class=\"count\">")
3963+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 372, "<section aria-labelledby=\"r-files\"><h2 id=\"r-files\">Files <span class=\"count\">")
39453964 if templ_7745c5c3_Err != nil {
39463965 return templ_7745c5c3_Err
39473966 }
3948- var templ_7745c5c3_Var192 string
3949- templ_7745c5c3_Var192, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(len(p.Files)))
3967+ var templ_7745c5c3_Var193 string
3968+ templ_7745c5c3_Var193, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(len(p.Files)))
39503969 if templ_7745c5c3_Err != nil {
3951- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 760, Col: 66}
3970+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 764, Col: 66}
39523971 }
3953- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var192))
3972+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var193))
39543973 if templ_7745c5c3_Err != nil {
39553974 return templ_7745c5c3_Err
39563975 }
3957- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 371, "</span></h2>")
3976+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 373, "</span></h2>")
39583977 if templ_7745c5c3_Err != nil {
39593978 return templ_7745c5c3_Err
39603979 }
@@ -3962,12 +3981,12 @@ func compareRail(p ComparePage) templ.Component {
39623981 if templ_7745c5c3_Err != nil {
39633982 return templ_7745c5c3_Err
39643983 }
3965- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 372, "</section>")
3984+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 374, "</section>")
39663985 if templ_7745c5c3_Err != nil {
39673986 return templ_7745c5c3_Err
39683987 }
39693988 }
3970- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 373, "<section aria-labelledby=\"r-cli\"><h2 id=\"r-cli\">From a terminal</h2>")
3989+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 375, "<section aria-labelledby=\"r-cli\"><h2 id=\"r-cli\">From a terminal</h2>")
39713990 if templ_7745c5c3_Err != nil {
39723991 return templ_7745c5c3_Err
39733992 }
@@ -3975,7 +3994,7 @@ func compareRail(p ComparePage) templ.Component {
39753994 if templ_7745c5c3_Err != nil {
39763995 return templ_7745c5c3_Err
39773996 }
3978- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 374, "</section>")
3997+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 376, "</section>")
39793998 if templ_7745c5c3_Err != nil {
39803999 return templ_7745c5c3_Err
39814000 }
@@ -2805,155 +2805,174 @@ func mergeMenu(p MRPage) templ.Component {
2805 if templ_7745c5c3_Err != nil {2805 if templ_7745c5c3_Err != nil {
2806 return templ_7745c5c3_Err2806 return templ_7745c5c3_Err
2807 }2807 }
2808- if p.Box.CanDeleteBranch {2808+ if p.ChecksSum.Kind == "bad" || p.ChecksSum.Kind == "running" {
2809- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 264, "<label class=\"d-check\"><input type=\"checkbox\" name=\"delete_branch\" value=\"1\"> delete ")2809+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 264, "<p class=\"d-note\">")
2810 if templ_7745c5c3_Err != nil {2810 if templ_7745c5c3_Err != nil {
2811 return templ_7745c5c3_Err2811 return templ_7745c5c3_Err
2812 }2812 }
2813 var templ_7745c5c3_Var134 string2813 var templ_7745c5c3_Var134 string
2814- templ_7745c5c3_Var134, templ_7745c5c3_Err = templ.JoinStringErrs(p.Source)2814+ templ_7745c5c3_Var134, templ_7745c5c3_Err = templ.JoinStringErrs(p.ChecksSum.State + ": a failing or unfinished check blocks the merge.")
2815 if templ_7745c5c3_Err != nil {2815 if templ_7745c5c3_Err != nil {
2816- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 549, Col: 102}2816+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 549, Col: 97}
2817 }2817 }
2818 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var134))2818 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var134))
2819 if templ_7745c5c3_Err != nil {2819 if templ_7745c5c3_Err != nil {
2820 return templ_7745c5c3_Err2820 return templ_7745c5c3_Err
2821 }2821 }
2822- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 265, " after the merge <kbd aria-hidden=\"true\">D</kbd></label>")2822+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 265, "</p><label class=\"d-check\"><input type=\"checkbox\" name=\"ignore_checks\"> Ignore checks</label> ")
2823 if templ_7745c5c3_Err != nil {2823 if templ_7745c5c3_Err != nil {
2824 return templ_7745c5c3_Err2824 return templ_7745c5c3_Err
2825 }2825 }
2826 }2826 }
2827- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 266, "<div class=\"d-btns\"><button type=\"submit\" class=\"btn primary\" data-default")2827+ if p.Box.CanDeleteBranch {
2828+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 266, "<label class=\"d-check\"><input type=\"checkbox\" name=\"delete_branch\" value=\"1\"> delete ")
2829+ if templ_7745c5c3_Err != nil {
2830+ return templ_7745c5c3_Err
2831+ }
2832+ var templ_7745c5c3_Var135 string
2833+ templ_7745c5c3_Var135, templ_7745c5c3_Err = templ.JoinStringErrs(p.Source)
2834+ if templ_7745c5c3_Err != nil {
2835+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 553, Col: 102}
2836+ }
2837+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var135))
2838+ if templ_7745c5c3_Err != nil {
2839+ return templ_7745c5c3_Err
2840+ }
2841+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 267, " after the merge <kbd aria-hidden=\"true\">D</kbd></label>")
2842+ if templ_7745c5c3_Err != nil {
2843+ return templ_7745c5c3_Err
2844+ }
2845+ }
2846+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 268, "<div class=\"d-btns\"><button type=\"submit\" class=\"btn primary\" data-default")
2828 if templ_7745c5c3_Err != nil {2847 if templ_7745c5c3_Err != nil {
2829 return templ_7745c5c3_Err2848 return templ_7745c5c3_Err
2830 }2849 }
2831 if !p.Box.CanMerge() {2850 if !p.Box.CanMerge() {
2832- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 267, " disabled")2851+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 269, " disabled")
2833 if templ_7745c5c3_Err != nil {2852 if templ_7745c5c3_Err != nil {
2834 return templ_7745c5c3_Err2853 return templ_7745c5c3_Err
2835 }2854 }
2836 }2855 }
2837- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 268, " title=\"")2856+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 270, " title=\"")
2838 if templ_7745c5c3_Err != nil {2857 if templ_7745c5c3_Err != nil {
2839 return templ_7745c5c3_Err2858 return templ_7745c5c3_Err
2840 }2859 }
2841- var templ_7745c5c3_Var135 string2860+ var templ_7745c5c3_Var136 string
2842- templ_7745c5c3_Var135, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Box.MergeTitle())2861+ templ_7745c5c3_Var136, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Box.MergeTitle())
2843 if templ_7745c5c3_Err != nil {2862 if templ_7745c5c3_Err != nil {
2844- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 557, Col: 33}2863+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 561, Col: 33}
2845 }2864 }
2846- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var135)2865+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var136)
2847 if templ_7745c5c3_Err != nil {2866 if templ_7745c5c3_Err != nil {
2848 return templ_7745c5c3_Err2867 return templ_7745c5c3_Err
2849 }2868 }
2850- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 269, "\" :disabled=\"!this.form.querySelector('input[name=mode]:checked:not(:disabled)')\" :title=\"(this.form.querySelector('input[name=mode]:checked') || {}).title || ''\">Merge into ")2869+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 271, "\" :disabled=\"!this.form.querySelector('input[name=mode]:checked:not(:disabled)')\" :title=\"(this.form.querySelector('input[name=mode]:checked') || {}).title || ''\">Merge into ")
2851 if templ_7745c5c3_Err != nil {2870 if templ_7745c5c3_Err != nil {
2852 return templ_7745c5c3_Err2871 return templ_7745c5c3_Err
2853 }2872 }
2854- var templ_7745c5c3_Var136 string2873+ var templ_7745c5c3_Var137 string
2855- templ_7745c5c3_Var136, templ_7745c5c3_Err = templ.JoinStringErrs(p.Target)2874+ templ_7745c5c3_Var137, templ_7745c5c3_Err = templ.JoinStringErrs(p.Target)
2856 if templ_7745c5c3_Err != nil {2875 if templ_7745c5c3_Err != nil {
2857- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 560, Col: 28}2876+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 564, Col: 28}
2858 }2877 }
2859- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var136))2878+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var137))
2860 if templ_7745c5c3_Err != nil {2879 if templ_7745c5c3_Err != nil {
2861 return templ_7745c5c3_Err2880 return templ_7745c5c3_Err
2862 }2881 }
2863- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 270, "</button></div></form>")2882+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 272, "</button></div></form>")
2864 if templ_7745c5c3_Err != nil {2883 if templ_7745c5c3_Err != nil {
2865 return templ_7745c5c3_Err2884 return templ_7745c5c3_Err
2866 }2885 }
2867 if p.Box.CanAutoMerge {2886 if p.Box.CanAutoMerge {
2868- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 271, "<form class=\"d-acts\" method=\"post\" action=\"")2887+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 273, "<form class=\"d-acts\" method=\"post\" action=\"")
2869 if templ_7745c5c3_Err != nil {2888 if templ_7745c5c3_Err != nil {
2870 return templ_7745c5c3_Err2889 return templ_7745c5c3_Err
2871 }2890 }
2872- var templ_7745c5c3_Var137 templ.SafeURL2891+ var templ_7745c5c3_Var138 templ.SafeURL
2873- templ_7745c5c3_Var137, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Box.AutoAction))2892+ templ_7745c5c3_Var138, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Box.AutoAction))
2874 if templ_7745c5c3_Err != nil {2893 if templ_7745c5c3_Err != nil {
2875- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 564, Col: 80}2894+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 568, Col: 80}
2876 }2895 }
2877- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var137))2896+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var138))
2878 if templ_7745c5c3_Err != nil {2897 if templ_7745c5c3_Err != nil {
2879 return templ_7745c5c3_Err2898 return templ_7745c5c3_Err
2880 }2899 }
2881- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 272, "\"><input type=\"hidden\" name=\"head_id\" value=\"")2900+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 274, "\"><input type=\"hidden\" name=\"head_id\" value=\"")
2882 if templ_7745c5c3_Err != nil {2901 if templ_7745c5c3_Err != nil {
2883 return templ_7745c5c3_Err2902 return templ_7745c5c3_Err
2884 }2903 }
2885- var templ_7745c5c3_Var138 string2904+ var templ_7745c5c3_Var139 string
2886- templ_7745c5c3_Var138, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Box.Head)2905+ templ_7745c5c3_Var139, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Box.Head)
2887 if templ_7745c5c3_Err != nil {2906 if templ_7745c5c3_Err != nil {
2888- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 565, Col: 60}2907+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 569, Col: 60}
2889 }2908 }
2890- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var138)2909+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var139)
2891 if templ_7745c5c3_Err != nil {2910 if templ_7745c5c3_Err != nil {
2892 return templ_7745c5c3_Err2911 return templ_7745c5c3_Err
2893 }2912 }
2894- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 273, "\"><fieldset class=\"d-modes\"><legend>Auto-merge mode</legend> ")2913+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 275, "\"><fieldset class=\"d-modes\"><legend>Auto-merge mode</legend> ")
2895 if templ_7745c5c3_Err != nil {2914 if templ_7745c5c3_Err != nil {
2896 return templ_7745c5c3_Err2915 return templ_7745c5c3_Err
2897 }2916 }
2898 for i, m := range p.Box.Modes {2917 for i, m := range p.Box.Modes {
2899- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 274, "<label><input type=\"radio\" name=\"mode\" value=\"")2918+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 276, "<label><input type=\"radio\" name=\"mode\" value=\"")
2900 if templ_7745c5c3_Err != nil {2919 if templ_7745c5c3_Err != nil {
2901 return templ_7745c5c3_Err2920 return templ_7745c5c3_Err
2902 }2921 }
2903- var templ_7745c5c3_Var139 string2922+ var templ_7745c5c3_Var140 string
2904- templ_7745c5c3_Var139, templ_7745c5c3_Err = templ.ResolveAttributeValue(m.Value)2923+ templ_7745c5c3_Var140, templ_7745c5c3_Err = templ.ResolveAttributeValue(m.Value)
2905 if templ_7745c5c3_Err != nil {2924 if templ_7745c5c3_Err != nil {
2906- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 569, Col: 62}2925+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 573, Col: 62}
2907 }2926 }
2908- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var139)2927+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var140)
2909 if templ_7745c5c3_Err != nil {2928 if templ_7745c5c3_Err != nil {
2910 return templ_7745c5c3_Err2929 return templ_7745c5c3_Err
2911 }2930 }
2912- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 275, "\"")2931+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 277, "\"")
2913 if templ_7745c5c3_Err != nil {2932 if templ_7745c5c3_Err != nil {
2914 return templ_7745c5c3_Err2933 return templ_7745c5c3_Err
2915 }2934 }
2916 if i == 0 {2935 if i == 0 {
2917- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 276, " checked")2936+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 278, " checked")
2918 if templ_7745c5c3_Err != nil {2937 if templ_7745c5c3_Err != nil {
2919 return templ_7745c5c3_Err2938 return templ_7745c5c3_Err
2920 }2939 }
2921 }2940 }
2922- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 277, "> ")2941+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 279, "> ")
2923 if templ_7745c5c3_Err != nil {2942 if templ_7745c5c3_Err != nil {
2924 return templ_7745c5c3_Err2943 return templ_7745c5c3_Err
2925 }2944 }
2926- var templ_7745c5c3_Var140 string2945+ var templ_7745c5c3_Var141 string
2927- templ_7745c5c3_Var140, templ_7745c5c3_Err = templ.JoinStringErrs(m.Label)2946+ templ_7745c5c3_Var141, templ_7745c5c3_Err = templ.JoinStringErrs(m.Label)
2928 if templ_7745c5c3_Err != nil {2947 if templ_7745c5c3_Err != nil {
2929- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 569, Col: 96}2948+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 573, Col: 96}
2930 }2949 }
2931- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var140))2950+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var141))
2932 if templ_7745c5c3_Err != nil {2951 if templ_7745c5c3_Err != nil {
2933 return templ_7745c5c3_Err2952 return templ_7745c5c3_Err
2934 }2953 }
2935- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 278, "</label>")2954+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 280, "</label>")
2936 if templ_7745c5c3_Err != nil {2955 if templ_7745c5c3_Err != nil {
2937 return templ_7745c5c3_Err2956 return templ_7745c5c3_Err
2938 }2957 }
2939 }2958 }
2940- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 279, "</fieldset><div class=\"d-btns\"><button type=\"submit\" class=\"btn\"")2959+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 281, "</fieldset><div class=\"d-btns\"><button type=\"submit\" class=\"btn\"")
2941 if templ_7745c5c3_Err != nil {2960 if templ_7745c5c3_Err != nil {
2942 return templ_7745c5c3_Err2961 return templ_7745c5c3_Err
2943 }2962 }
2944 if len(p.Box.Modes) == 0 {2963 if len(p.Box.Modes) == 0 {
2945- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 280, " disabled")2964+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 282, " disabled")
2946 if templ_7745c5c3_Err != nil {2965 if templ_7745c5c3_Err != nil {
2947 return templ_7745c5c3_Err2966 return templ_7745c5c3_Err
2948 }2967 }
2949 }2968 }
2950- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 281, " title=\"merge once the checks pass\">Merge when ready</button></div></form>")2969+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 283, " title=\"merge once the checks pass\">Merge when ready</button></div></form>")
2951 if templ_7745c5c3_Err != nil {2970 if templ_7745c5c3_Err != nil {
2952 return templ_7745c5c3_Err2971 return templ_7745c5c3_Err
2953 }2972 }
2954 }2973 }
2955 }2974 }
2956- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 282, "</div></details>")2975+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 284, "</div></details>")
2957 if templ_7745c5c3_Err != nil {2976 if templ_7745c5c3_Err != nil {
2958 return templ_7745c5c3_Err2977 return templ_7745c5c3_Err
2959 }2978 }
@@ -2979,182 +2998,182 @@ func MRMergeability(v MergeabilityView) templ.Component {
2979 }()2998 }()
2980 }2999 }
2981 ctx = templ.InitializeContext(ctx)3000 ctx = templ.InitializeContext(ctx)
2982- templ_7745c5c3_Var141 := templ.GetChildren(ctx)3001+ templ_7745c5c3_Var142 := templ.GetChildren(ctx)
2983- if templ_7745c5c3_Var141 == nil {3002+ if templ_7745c5c3_Var142 == nil {
2984- templ_7745c5c3_Var141 = templ.NopComponent3003+ templ_7745c5c3_Var142 = templ.NopComponent
2985 }3004 }
2986 ctx = templ.ClearChildren(ctx)3005 ctx = templ.ClearChildren(ctx)
2987- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 283, "<span data-mergeability data-state=\"")3006+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 285, "<span data-mergeability data-state=\"")
2988- if templ_7745c5c3_Err != nil {
2989- return templ_7745c5c3_Err
2990- }
2991- var templ_7745c5c3_Var142 string
2992- templ_7745c5c3_Var142, templ_7745c5c3_Err = templ.ResolveAttributeValue(v.State)
2993- if templ_7745c5c3_Err != nil {
2994- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 587, Col: 22}
2995- }
2996- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var142)
2997- if templ_7745c5c3_Err != nil {
2998- return templ_7745c5c3_Err
2999- }
3000- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 284, "\" data-ff-ok=\"")
3001 if templ_7745c5c3_Err != nil {3007 if templ_7745c5c3_Err != nil {
3002 return templ_7745c5c3_Err3008 return templ_7745c5c3_Err
3003 }3009 }
3004 var templ_7745c5c3_Var143 string3010 var templ_7745c5c3_Var143 string
3005- templ_7745c5c3_Var143, templ_7745c5c3_Err = templ.ResolveAttributeValue(strconv.FormatBool(v.FFOk))3011+ templ_7745c5c3_Var143, templ_7745c5c3_Err = templ.ResolveAttributeValue(v.State)
3006 if templ_7745c5c3_Err != nil {3012 if templ_7745c5c3_Err != nil {
3007- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 588, Col: 41}3013+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 591, Col: 22}
3008 }3014 }
3009 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var143)3015 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var143)
3010 if templ_7745c5c3_Err != nil {3016 if templ_7745c5c3_Err != nil {
3011 return templ_7745c5c3_Err3017 return templ_7745c5c3_Err
3012 }3018 }
3013- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 285, "\" data-merge-ok=\"")3019+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 286, "\" data-ff-ok=\"")
3014 if templ_7745c5c3_Err != nil {3020 if templ_7745c5c3_Err != nil {
3015 return templ_7745c5c3_Err3021 return templ_7745c5c3_Err
3016 }3022 }
3017 var templ_7745c5c3_Var144 string3023 var templ_7745c5c3_Var144 string
3018- templ_7745c5c3_Var144, templ_7745c5c3_Err = templ.ResolveAttributeValue(strconv.FormatBool(v.MergeOk))3024+ templ_7745c5c3_Var144, templ_7745c5c3_Err = templ.ResolveAttributeValue(strconv.FormatBool(v.FFOk))
3019 if templ_7745c5c3_Err != nil {3025 if templ_7745c5c3_Err != nil {
3020- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 589, Col: 47}3026+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 592, Col: 41}
3021 }3027 }
3022 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var144)3028 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var144)
3023 if templ_7745c5c3_Err != nil {3029 if templ_7745c5c3_Err != nil {
3024 return templ_7745c5c3_Err3030 return templ_7745c5c3_Err
3025 }3031 }
3026- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 286, "\" data-ff-reason=\"")3032+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 287, "\" data-merge-ok=\"")
3027 if templ_7745c5c3_Err != nil {3033 if templ_7745c5c3_Err != nil {
3028 return templ_7745c5c3_Err3034 return templ_7745c5c3_Err
3029 }3035 }
3030 var templ_7745c5c3_Var145 string3036 var templ_7745c5c3_Var145 string
3031- templ_7745c5c3_Var145, templ_7745c5c3_Err = templ.ResolveAttributeValue(v.FFReason)3037+ templ_7745c5c3_Var145, templ_7745c5c3_Err = templ.ResolveAttributeValue(strconv.FormatBool(v.MergeOk))
3032 if templ_7745c5c3_Err != nil {3038 if templ_7745c5c3_Err != nil {
3033- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 590, Col: 29}3039+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 593, Col: 47}
3034 }3040 }
3035 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var145)3041 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var145)
3036 if templ_7745c5c3_Err != nil {3042 if templ_7745c5c3_Err != nil {
3037 return templ_7745c5c3_Err3043 return templ_7745c5c3_Err
3038 }3044 }
3039- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 287, "\" data-merge-reason=\"")3045+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 288, "\" data-ff-reason=\"")
3040 if templ_7745c5c3_Err != nil {3046 if templ_7745c5c3_Err != nil {
3041 return templ_7745c5c3_Err3047 return templ_7745c5c3_Err
3042 }3048 }
3043 var templ_7745c5c3_Var146 string3049 var templ_7745c5c3_Var146 string
3044- templ_7745c5c3_Var146, templ_7745c5c3_Err = templ.ResolveAttributeValue(v.MergeReason)3050+ templ_7745c5c3_Var146, templ_7745c5c3_Err = templ.ResolveAttributeValue(v.FFReason)
3045 if templ_7745c5c3_Err != nil {3051 if templ_7745c5c3_Err != nil {
3046- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 591, Col: 35}3052+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 594, Col: 29}
3047 }3053 }
3048 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var146)3054 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var146)
3049 if templ_7745c5c3_Err != nil {3055 if templ_7745c5c3_Err != nil {
3050 return templ_7745c5c3_Err3056 return templ_7745c5c3_Err
3051 }3057 }
3052- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 288, "\"><span class=\"badge\" data-state=\"")3058+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 289, "\" data-merge-reason=\"")
3053 if templ_7745c5c3_Err != nil {3059 if templ_7745c5c3_Err != nil {
3054 return templ_7745c5c3_Err3060 return templ_7745c5c3_Err
3055 }3061 }
3056 var templ_7745c5c3_Var147 string3062 var templ_7745c5c3_Var147 string
3057- templ_7745c5c3_Var147, templ_7745c5c3_Err = templ.ResolveAttributeValue(v.State)3063+ templ_7745c5c3_Var147, templ_7745c5c3_Err = templ.ResolveAttributeValue(v.MergeReason)
3058 if templ_7745c5c3_Err != nil {3064 if templ_7745c5c3_Err != nil {
3059- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 593, Col: 42}3065+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 595, Col: 35}
3060 }3066 }
3061 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var147)3067 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var147)
3062 if templ_7745c5c3_Err != nil {3068 if templ_7745c5c3_Err != nil {
3063 return templ_7745c5c3_Err3069 return templ_7745c5c3_Err
3064 }3070 }
3065- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 289, "\">")3071+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 290, "\"><span class=\"badge\" data-state=\"")
3066 if templ_7745c5c3_Err != nil {3072 if templ_7745c5c3_Err != nil {
3067 return templ_7745c5c3_Err3073 return templ_7745c5c3_Err
3068 }3074 }
3069 var templ_7745c5c3_Var148 string3075 var templ_7745c5c3_Var148 string
3070- templ_7745c5c3_Var148, templ_7745c5c3_Err = templ.JoinStringErrs(v.Label)3076+ templ_7745c5c3_Var148, templ_7745c5c3_Err = templ.ResolveAttributeValue(v.State)
3071 if templ_7745c5c3_Err != nil {3077 if templ_7745c5c3_Err != nil {
3072- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 593, Col: 54}3078+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 597, Col: 42}
3073 }3079 }
3074- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var148))3080+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var148)
3075 if templ_7745c5c3_Err != nil {3081 if templ_7745c5c3_Err != nil {
3076 return templ_7745c5c3_Err3082 return templ_7745c5c3_Err
3077 }3083 }
3078- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 290, "</span> ")3084+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 291, "\">")
3085+ if templ_7745c5c3_Err != nil {
3086+ return templ_7745c5c3_Err
3087+ }
3088+ var templ_7745c5c3_Var149 string
3089+ templ_7745c5c3_Var149, templ_7745c5c3_Err = templ.JoinStringErrs(v.Label)
3090+ if templ_7745c5c3_Err != nil {
3091+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 597, Col: 54}
3092+ }
3093+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var149))
3094+ if templ_7745c5c3_Err != nil {
3095+ return templ_7745c5c3_Err
3096+ }
3097+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 292, "</span> ")
3079 if templ_7745c5c3_Err != nil {3098 if templ_7745c5c3_Err != nil {
3080 return templ_7745c5c3_Err3099 return templ_7745c5c3_Err
3081 }3100 }
3082 if v.Detail != "" {3101 if v.Detail != "" {
3083- var templ_7745c5c3_Var149 string3102+ var templ_7745c5c3_Var150 string
3084- templ_7745c5c3_Var149, templ_7745c5c3_Err = templ.JoinStringErrs(" ")3103+ templ_7745c5c3_Var150, templ_7745c5c3_Err = templ.JoinStringErrs(" ")
3085 if templ_7745c5c3_Err != nil {3104 if templ_7745c5c3_Err != nil {
3086- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 595, Col: 8}3105+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 599, Col: 8}
3087 }3106 }
3088- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var149))3107+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var150))
3089 if templ_7745c5c3_Err != nil {3108 if templ_7745c5c3_Err != nil {
3090 return templ_7745c5c3_Err3109 return templ_7745c5c3_Err
3091 }3110 }
3092- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 291, "<span class=\"dim\">")3111+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 293, "<span class=\"dim\">")
3093 if templ_7745c5c3_Err != nil {3112 if templ_7745c5c3_Err != nil {
3094 return templ_7745c5c3_Err3113 return templ_7745c5c3_Err
3095 }3114 }
3096- var templ_7745c5c3_Var150 string3115+ var templ_7745c5c3_Var151 string
3097- templ_7745c5c3_Var150, templ_7745c5c3_Err = templ.JoinStringErrs(v.Detail)3116+ templ_7745c5c3_Var151, templ_7745c5c3_Err = templ.JoinStringErrs(v.Detail)
3098 if templ_7745c5c3_Err != nil {3117 if templ_7745c5c3_Err != nil {
3099- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 595, Col: 38}3118+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 599, Col: 38}
3100 }3119 }
3101- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var150))3120+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var151))
3102 if templ_7745c5c3_Err != nil {3121 if templ_7745c5c3_Err != nil {
3103 return templ_7745c5c3_Err3122 return templ_7745c5c3_Err
3104 }3123 }
3105- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 292, "</span>")3124+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 294, "</span>")
3106 if templ_7745c5c3_Err != nil {3125 if templ_7745c5c3_Err != nil {
3107 return templ_7745c5c3_Err3126 return templ_7745c5c3_Err
3108 }3127 }
3109 }3128 }
3110- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 293, "</span> ")3129+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 295, "</span> ")
3111 if templ_7745c5c3_Err != nil {3130 if templ_7745c5c3_Err != nil {
3112 return templ_7745c5c3_Err3131 return templ_7745c5c3_Err
3113 }3132 }
3114 if len(v.Paths) > 0 {3133 if len(v.Paths) > 0 {
3115- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 294, "<ul class=\"mg-paths\" aria-label=\"conflicting files\">")3134+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 296, "<ul class=\"mg-paths\" aria-label=\"conflicting files\">")
3116 if templ_7745c5c3_Err != nil {3135 if templ_7745c5c3_Err != nil {
3117 return templ_7745c5c3_Err3136 return templ_7745c5c3_Err
3118 }3137 }
3119 for _, path := range v.Paths {3138 for _, path := range v.Paths {
3120- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 295, "<li><code>")3139+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 297, "<li><code>")
3121 if templ_7745c5c3_Err != nil {3140 if templ_7745c5c3_Err != nil {
3122 return templ_7745c5c3_Err3141 return templ_7745c5c3_Err
3123 }3142 }
3124- var templ_7745c5c3_Var151 string3143+ var templ_7745c5c3_Var152 string
3125- templ_7745c5c3_Var151, templ_7745c5c3_Err = templ.JoinStringErrs(path)3144+ templ_7745c5c3_Var152, templ_7745c5c3_Err = templ.JoinStringErrs(path)
3126 if templ_7745c5c3_Err != nil {3145 if templ_7745c5c3_Err != nil {
3127- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 601, Col: 20}3146+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 605, Col: 20}
3128 }3147 }
3129- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var151))3148+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var152))
3130 if templ_7745c5c3_Err != nil {3149 if templ_7745c5c3_Err != nil {
3131 return templ_7745c5c3_Err3150 return templ_7745c5c3_Err
3132 }3151 }
3133- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 296, "</code></li>")3152+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 298, "</code></li>")
3134 if templ_7745c5c3_Err != nil {3153 if templ_7745c5c3_Err != nil {
3135 return templ_7745c5c3_Err3154 return templ_7745c5c3_Err
3136 }3155 }
3137 }3156 }
3138- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 297, "</ul>")3157+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 299, "</ul>")
3139 if templ_7745c5c3_Err != nil {3158 if templ_7745c5c3_Err != nil {
3140 return templ_7745c5c3_Err3159 return templ_7745c5c3_Err
3141 }3160 }
3142 }3161 }
3143 if v.PathsNote != "" {3162 if v.PathsNote != "" {
3144- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 298, "<p class=\"dim\">")3163+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 300, "<p class=\"dim\">")
3145 if templ_7745c5c3_Err != nil {3164 if templ_7745c5c3_Err != nil {
3146 return templ_7745c5c3_Err3165 return templ_7745c5c3_Err
3147 }3166 }
3148- var templ_7745c5c3_Var152 string3167+ var templ_7745c5c3_Var153 string
3149- templ_7745c5c3_Var152, templ_7745c5c3_Err = templ.JoinStringErrs(v.PathsNote)3168+ templ_7745c5c3_Var153, templ_7745c5c3_Err = templ.JoinStringErrs(v.PathsNote)
3150 if templ_7745c5c3_Err != nil {3169 if templ_7745c5c3_Err != nil {
3151- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 606, Col: 30}3170+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 610, Col: 30}
3152 }3171 }
3153- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var152))3172+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var153))
3154 if templ_7745c5c3_Err != nil {3173 if templ_7745c5c3_Err != nil {
3155 return templ_7745c5c3_Err3174 return templ_7745c5c3_Err
3156 }3175 }
3157- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 299, "</p>")3176+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 301, "</p>")
3158 if templ_7745c5c3_Err != nil {3177 if templ_7745c5c3_Err != nil {
3159 return templ_7745c5c3_Err3178 return templ_7745c5c3_Err
3160 }3179 }
@@ -3181,12 +3200,12 @@ func mrMergeabilitySlot(v MergeabilityView) templ.Component {
3181 }()3200 }()
3182 }3201 }
3183 ctx = templ.InitializeContext(ctx)3202 ctx = templ.InitializeContext(ctx)
3184- templ_7745c5c3_Var153 := templ.GetChildren(ctx)3203+ templ_7745c5c3_Var154 := templ.GetChildren(ctx)
3185- if templ_7745c5c3_Var153 == nil {3204+ if templ_7745c5c3_Var154 == nil {
3186- templ_7745c5c3_Var153 = templ.NopComponent3205+ templ_7745c5c3_Var154 = templ.NopComponent
3187 }3206 }
3188 ctx = templ.ClearChildren(ctx)3207 ctx = templ.ClearChildren(ctx)
3189- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 300, "<div id=\"mr-mergeability\" class=\"live-slot\" role=\"status\" data-slot>")3208+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 302, "<div id=\"mr-mergeability\" class=\"live-slot\" role=\"status\" data-slot>")
3190 if templ_7745c5c3_Err != nil {3209 if templ_7745c5c3_Err != nil {
3191 return templ_7745c5c3_Err3210 return templ_7745c5c3_Err
3192 }3211 }
@@ -3194,7 +3213,7 @@ func mrMergeabilitySlot(v MergeabilityView) templ.Component {
3194 if templ_7745c5c3_Err != nil {3213 if templ_7745c5c3_Err != nil {
3195 return templ_7745c5c3_Err3214 return templ_7745c5c3_Err
3196 }3215 }
3197- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 301, "</div>")3216+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 303, "</div>")
3198 if templ_7745c5c3_Err != nil {3217 if templ_7745c5c3_Err != nil {
3199 return templ_7745c5c3_Err3218 return templ_7745c5c3_Err
3200 }3219 }
@@ -3219,9 +3238,9 @@ func MRMergeabilityFragment(v MergeabilityView) templ.Component {
3219 }()3238 }()
3220 }3239 }
3221 ctx = templ.InitializeContext(ctx)3240 ctx = templ.InitializeContext(ctx)
3222- templ_7745c5c3_Var154 := templ.GetChildren(ctx)3241+ templ_7745c5c3_Var155 := templ.GetChildren(ctx)
3223- if templ_7745c5c3_Var154 == nil {3242+ if templ_7745c5c3_Var155 == nil {
3224- templ_7745c5c3_Var154 = templ.NopComponent3243+ templ_7745c5c3_Var155 = templ.NopComponent
3225 }3244 }
3226 ctx = templ.ClearChildren(ctx)3245 ctx = templ.ClearChildren(ctx)
3227 templ_7745c5c3_Err = mrMergeabilitySlot(v).Render(ctx, templ_7745c5c3_Buffer)3246 templ_7745c5c3_Err = mrMergeabilitySlot(v).Render(ctx, templ_7745c5c3_Buffer)
@@ -3250,128 +3269,128 @@ func moreMenu(p MRPage) templ.Component {
3250 }()3269 }()
3251 }3270 }
3252 ctx = templ.InitializeContext(ctx)3271 ctx = templ.InitializeContext(ctx)
3253- templ_7745c5c3_Var155 := templ.GetChildren(ctx)3272+ templ_7745c5c3_Var156 := templ.GetChildren(ctx)
3254- if templ_7745c5c3_Var155 == nil {3273+ if templ_7745c5c3_Var156 == nil {
3255- templ_7745c5c3_Var155 = templ.NopComponent3274+ templ_7745c5c3_Var156 = templ.NopComponent
3256 }3275 }
3257 ctx = templ.ClearChildren(ctx)3276 ctx = templ.ClearChildren(ctx)
3258- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 302, "<details class=\"menu omenu\"><summary class=\"btn icon\" aria-label=\"More actions\" title=\"more actions\">⋯</summary><div class=\"menu-pop\" role=\"group\" aria-label=\"More actions\"><section class=\"merge-settings\"><h2>Merge settings</h2><dl class=\"kv\"><dt>modes</dt><dd>")3277+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 304, "<details class=\"menu omenu\"><summary class=\"btn icon\" aria-label=\"More actions\" title=\"more actions\">⋯</summary><div class=\"menu-pop\" role=\"group\" aria-label=\"More actions\"><section class=\"merge-settings\"><h2>Merge settings</h2><dl class=\"kv\"><dt>modes</dt><dd>")
3259 if templ_7745c5c3_Err != nil {3278 if templ_7745c5c3_Err != nil {
3260 return templ_7745c5c3_Err3279 return templ_7745c5c3_Err
3261 }3280 }
3262- var templ_7745c5c3_Var156 string3281+ var templ_7745c5c3_Var157 string
3263- templ_7745c5c3_Var156, templ_7745c5c3_Err = templ.JoinStringErrs(strings.Join(p.Modes, ", "))3282+ templ_7745c5c3_Var157, templ_7745c5c3_Err = templ.JoinStringErrs(strings.Join(p.Modes, ", "))
3264 if templ_7745c5c3_Err != nil {3283 if templ_7745c5c3_Err != nil {
3265- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 633, Col: 38}3284+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 637, Col: 38}
3266 }3285 }
3267- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var156))3286+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var157))
3268 if templ_7745c5c3_Err != nil {3287 if templ_7745c5c3_Err != nil {
3269 return templ_7745c5c3_Err3288 return templ_7745c5c3_Err
3270 }3289 }
3271- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 303, "</dd><dt>checks</dt><dd>")3290+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 305, "</dd><dt>checks</dt><dd>")
3272 if templ_7745c5c3_Err != nil {3291 if templ_7745c5c3_Err != nil {
3273 return templ_7745c5c3_Err3292 return templ_7745c5c3_Err
3274 }3293 }
3275 if p.ChecksBlock {3294 if p.ChecksBlock {
3276- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 304, "failing ones block the merge")3295+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 306, "failing or unfinished checks block the merge")
3277 if templ_7745c5c3_Err != nil {3296 if templ_7745c5c3_Err != nil {
3278 return templ_7745c5c3_Err3297 return templ_7745c5c3_Err
3279 }3298 }
3280 } else {3299 } else {
3281- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 305, "do not block the merge")3300+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 307, "do not block the merge")
3282 if templ_7745c5c3_Err != nil {3301 if templ_7745c5c3_Err != nil {
3283 return templ_7745c5c3_Err3302 return templ_7745c5c3_Err
3284 }3303 }
3285 }3304 }
3286- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 306, "</dd></dl></section>")3305+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 308, "</dd></dl></section>")
3287 if templ_7745c5c3_Err != nil {3306 if templ_7745c5c3_Err != nil {
3288 return templ_7745c5c3_Err3307 return templ_7745c5c3_Err
3289 }3308 }
3290 if p.Box != nil {3309 if p.Box != nil {
3291 if p.Box.Signed {3310 if p.Box.Signed {
3292- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 307, "<p class=\"d-note\" id=\"mr-signing\">squash and merge commits are signed with ermite's own key (generated on first start). ")3311+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 309, "<p class=\"d-note\" id=\"mr-signing\">squash and merge commits are signed with ermite's own key (generated on first start). ")
3293 if templ_7745c5c3_Err != nil {3312 if templ_7745c5c3_Err != nil {
3294 return templ_7745c5c3_Err3313 return templ_7745c5c3_Err
3295 }3314 }
3296 if p.Box.Fingerprint != "" {3315 if p.Box.Fingerprint != "" {
3297- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 308, "fingerprint <code>")3316+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 310, "fingerprint <code>")
3298 if templ_7745c5c3_Err != nil {3317 if templ_7745c5c3_Err != nil {
3299 return templ_7745c5c3_Err3318 return templ_7745c5c3_Err
3300 }3319 }
3301- var templ_7745c5c3_Var157 string3320+ var templ_7745c5c3_Var158 string
3302- templ_7745c5c3_Var157, templ_7745c5c3_Err = templ.JoinStringErrs(p.Box.Fingerprint)3321+ templ_7745c5c3_Var158, templ_7745c5c3_Err = templ.JoinStringErrs(p.Box.Fingerprint)
3303 if templ_7745c5c3_Err != nil {3322 if templ_7745c5c3_Err != nil {
3304- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 649, Col: 44}3323+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 653, Col: 44}
3305 }3324 }
3306- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var157))3325+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var158))
3307 if templ_7745c5c3_Err != nil {3326 if templ_7745c5c3_Err != nil {
3308 return templ_7745c5c3_Err3327 return templ_7745c5c3_Err
3309 }3328 }
3310- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 309, "</code> ")3329+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 311, "</code> ")
3311 if templ_7745c5c3_Err != nil {3330 if templ_7745c5c3_Err != nil {
3312 return templ_7745c5c3_Err3331 return templ_7745c5c3_Err
3313 }3332 }
3314 }3333 }
3315- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 310, "<code>ermite signing-key show</code> prints it.</p>")3334+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 312, "<code>ermite signing-key show</code> prints it.</p>")
3316 if templ_7745c5c3_Err != nil {3335 if templ_7745c5c3_Err != nil {
3317 return templ_7745c5c3_Err3336 return templ_7745c5c3_Err
3318 }3337 }
3319 }3338 }
3320- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 311, " ")3339+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 313, " ")
3321 if templ_7745c5c3_Err != nil {3340 if templ_7745c5c3_Err != nil {
3322 return templ_7745c5c3_Err3341 return templ_7745c5c3_Err
3323 }3342 }
3324 if p.Box.CanMarkRead {3343 if p.Box.CanMarkRead {
3325- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 312, "<form method=\"post\" action=\"")3344+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 314, "<form method=\"post\" action=\"")
3326 if templ_7745c5c3_Err != nil {3345 if templ_7745c5c3_Err != nil {
3327 return templ_7745c5c3_Err3346 return templ_7745c5c3_Err
3328 }3347 }
3329- var templ_7745c5c3_Var158 templ.SafeURL3348+ var templ_7745c5c3_Var159 templ.SafeURL
3330- templ_7745c5c3_Var158, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Box.ReadAction))3349+ templ_7745c5c3_Var159, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Box.ReadAction))
3331 if templ_7745c5c3_Err != nil {3350 if templ_7745c5c3_Err != nil {
3332- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 655, Col: 65}3351+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 659, Col: 65}
3333 }3352 }
3334- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var158))3353+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var159))
3335 if templ_7745c5c3_Err != nil {3354 if templ_7745c5c3_Err != nil {
3336 return templ_7745c5c3_Err3355 return templ_7745c5c3_Err
3337 }3356 }
3338- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 313, "\"><input type=\"hidden\" name=\"head_id\" value=\"")3357+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 315, "\"><input type=\"hidden\" name=\"head_id\" value=\"")
3339 if templ_7745c5c3_Err != nil {3358 if templ_7745c5c3_Err != nil {
3340 return templ_7745c5c3_Err3359 return templ_7745c5c3_Err
3341 }3360 }
3342- var templ_7745c5c3_Var159 string3361+ var templ_7745c5c3_Var160 string
3343- templ_7745c5c3_Var159, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Box.Head)3362+ templ_7745c5c3_Var160, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Box.Head)
3344 if templ_7745c5c3_Err != nil {3363 if templ_7745c5c3_Err != nil {
3345- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 656, Col: 60}3364+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 660, Col: 60}
3346 }3365 }
3347- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var159)3366+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var160)
3348 if templ_7745c5c3_Err != nil {3367 if templ_7745c5c3_Err != nil {
3349 return templ_7745c5c3_Err3368 return templ_7745c5c3_Err
3350 }3369 }
3351- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 314, "\"> <button type=\"submit\" title=\"the next visit can show only what changed after this head\" class=\"btn\" aria-keyshortcuts=\"Shift+R\" data-read>Mark read <kbd aria-hidden=\"true\">R</kbd></button></form>")3370+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 316, "\"> <button type=\"submit\" title=\"the next visit can show only what changed after this head\" class=\"btn\" aria-keyshortcuts=\"Shift+R\" data-read>Mark read <kbd aria-hidden=\"true\">R</kbd></button></form>")
3352 if templ_7745c5c3_Err != nil {3371 if templ_7745c5c3_Err != nil {
3353 return templ_7745c5c3_Err3372 return templ_7745c5c3_Err
3354 }3373 }
3355 }3374 }
3356- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 315, " <form method=\"post\" action=\"")3375+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 317, " <form method=\"post\" action=\"")
3357 if templ_7745c5c3_Err != nil {3376 if templ_7745c5c3_Err != nil {
3358 return templ_7745c5c3_Err3377 return templ_7745c5c3_Err
3359 }3378 }
3360- var templ_7745c5c3_Var160 templ.SafeURL3379+ var templ_7745c5c3_Var161 templ.SafeURL
3361- templ_7745c5c3_Var160, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Box.CloseAction))3380+ templ_7745c5c3_Var161, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Box.CloseAction))
3362 if templ_7745c5c3_Err != nil {3381 if templ_7745c5c3_Err != nil {
3363- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 660, Col: 65}3382+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 664, Col: 65}
3364 }3383 }
3365- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var160))3384+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var161))
3366 if templ_7745c5c3_Err != nil {3385 if templ_7745c5c3_Err != nil {
3367 return templ_7745c5c3_Err3386 return templ_7745c5c3_Err
3368 }3387 }
3369- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 316, "\"><button type=\"submit\" title=\"close without merging; the branch is kept\" class=\"btn danger\">Close</button></form>")3388+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 318, "\"><button type=\"submit\" title=\"close without merging; the branch is kept\" class=\"btn danger\">Close</button></form>")
3370 if templ_7745c5c3_Err != nil {3389 if templ_7745c5c3_Err != nil {
3371 return templ_7745c5c3_Err3390 return templ_7745c5c3_Err
3372 }3391 }
3373 if !p.Box.HeadGone && p.Box.ReadyAction == "" {3392 if !p.Box.HeadGone && p.Box.ReadyAction == "" {
3374- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 317, "<details class=\"d-or\"><summary class=\"mute\">or from a terminal</summary>")3393+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 319, "<details class=\"d-or\"><summary class=\"mute\">or from a terminal</summary>")
3375 if templ_7745c5c3_Err != nil {3394 if templ_7745c5c3_Err != nil {
3376 return templ_7745c5c3_Err3395 return templ_7745c5c3_Err
3377 }3396 }
@@ -3379,13 +3398,13 @@ func moreMenu(p MRPage) templ.Component {
3379 if templ_7745c5c3_Err != nil {3398 if templ_7745c5c3_Err != nil {
3380 return templ_7745c5c3_Err3399 return templ_7745c5c3_Err
3381 }3400 }
3382- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 318, "</details>")3401+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 320, "</details>")
3383 if templ_7745c5c3_Err != nil {3402 if templ_7745c5c3_Err != nil {
3384 return templ_7745c5c3_Err3403 return templ_7745c5c3_Err
3385 }3404 }
3386 }3405 }
3387 }3406 }
3388- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 319, "</div></details>")3407+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 321, "</div></details>")
3389 if templ_7745c5c3_Err != nil {3408 if templ_7745c5c3_Err != nil {
3390 return templ_7745c5c3_Err3409 return templ_7745c5c3_Err
3391 }3410 }
@@ -3409,12 +3428,12 @@ func Compare(l Layout, p ComparePage) templ.Component {
3409 }()3428 }()
3410 }3429 }
3411 ctx = templ.InitializeContext(ctx)3430 ctx = templ.InitializeContext(ctx)
3412- templ_7745c5c3_Var161 := templ.GetChildren(ctx)3431+ templ_7745c5c3_Var162 := templ.GetChildren(ctx)
3413- if templ_7745c5c3_Var161 == nil {3432+ if templ_7745c5c3_Var162 == nil {
3414- templ_7745c5c3_Var161 = templ.NopComponent3433+ templ_7745c5c3_Var162 = templ.NopComponent
3415 }3434 }
3416 ctx = templ.ClearChildren(ctx)3435 ctx = templ.ClearChildren(ctx)
3417- templ_7745c5c3_Var162 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {3436+ templ_7745c5c3_Var163 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
3418 templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context3437 templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
3419 templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)3438 templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
3420 if !templ_7745c5c3_IsBuffer {3439 if !templ_7745c5c3_IsBuffer {
@@ -3426,263 +3445,263 @@ func Compare(l Layout, p ComparePage) templ.Component {
3426 }()3445 }()
3427 }3446 }
3428 ctx = templ.InitializeContext(ctx)3447 ctx = templ.InitializeContext(ctx)
3429- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 320, "<header class=\"show mr-h\"><h1>")3448+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 322, "<header class=\"show mr-h\"><h1>")
3430- if templ_7745c5c3_Err != nil {
3431- return templ_7745c5c3_Err
3432- }
3433- var templ_7745c5c3_Var163 string
3434- templ_7745c5c3_Var163, templ_7745c5c3_Err = templ.JoinStringErrs(p.Source)
3435- if templ_7745c5c3_Err != nil {
3436- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 677, Col: 17}
3437- }
3438- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var163))
3439- if templ_7745c5c3_Err != nil {
3440- return templ_7745c5c3_Err
3441- }
3442- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 321, " → ")
3443 if templ_7745c5c3_Err != nil {3449 if templ_7745c5c3_Err != nil {
3444 return templ_7745c5c3_Err3450 return templ_7745c5c3_Err
3445 }3451 }
3446 var templ_7745c5c3_Var164 string3452 var templ_7745c5c3_Var164 string
3447- templ_7745c5c3_Var164, templ_7745c5c3_Err = templ.JoinStringErrs(p.Target)3453+ templ_7745c5c3_Var164, templ_7745c5c3_Err = templ.JoinStringErrs(p.Source)
3448 if templ_7745c5c3_Err != nil {3454 if templ_7745c5c3_Err != nil {
3449- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 677, Col: 34}3455+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 681, Col: 17}
3450 }3456 }
3451 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var164))3457 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var164))
3452 if templ_7745c5c3_Err != nil {3458 if templ_7745c5c3_Err != nil {
3453 return templ_7745c5c3_Err3459 return templ_7745c5c3_Err
3454 }3460 }
3455- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 322, "</h1><dl class=\"kv show-kv\"><dt>branch</dt><dd><a href=\"")3461+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 323, " → ")
3456 if templ_7745c5c3_Err != nil {3462 if templ_7745c5c3_Err != nil {
3457 return templ_7745c5c3_Err3463 return templ_7745c5c3_Err
3458 }3464 }
3459- var templ_7745c5c3_Var165 templ.SafeURL3465+ var templ_7745c5c3_Var165 string
3460- templ_7745c5c3_Var165, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.SourceHref))3466+ templ_7745c5c3_Var165, templ_7745c5c3_Err = templ.JoinStringErrs(p.Target)
3461 if templ_7745c5c3_Err != nil {3467 if templ_7745c5c3_Err != nil {
3462- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 680, Col: 45}3468+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 681, Col: 34}
3463 }3469 }
3464 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var165))3470 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var165))
3465 if templ_7745c5c3_Err != nil {3471 if templ_7745c5c3_Err != nil {
3466 return templ_7745c5c3_Err3472 return templ_7745c5c3_Err
3467 }3473 }
3468- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 323, "\">")3474+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 324, "</h1><dl class=\"kv show-kv\"><dt>branch</dt><dd><a href=\"")
3469 if templ_7745c5c3_Err != nil {3475 if templ_7745c5c3_Err != nil {
3470 return templ_7745c5c3_Err3476 return templ_7745c5c3_Err
3471 }3477 }
3472- var templ_7745c5c3_Var166 string3478+ var templ_7745c5c3_Var166 templ.SafeURL
3473- templ_7745c5c3_Var166, templ_7745c5c3_Err = templ.JoinStringErrs(p.Source)3479+ templ_7745c5c3_Var166, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.SourceHref))
3474 if templ_7745c5c3_Err != nil {3480 if templ_7745c5c3_Err != nil {
3475- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 680, Col: 58}3481+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 684, Col: 45}
3476 }3482 }
3477 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var166))3483 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var166))
3478 if templ_7745c5c3_Err != nil {3484 if templ_7745c5c3_Err != nil {
3479 return templ_7745c5c3_Err3485 return templ_7745c5c3_Err
3480 }3486 }
3481- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 324, "</a></dd><dt>target</dt><dd><a href=\"")3487+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 325, "\">")
3482 if templ_7745c5c3_Err != nil {3488 if templ_7745c5c3_Err != nil {
3483 return templ_7745c5c3_Err3489 return templ_7745c5c3_Err
3484 }3490 }
3485- var templ_7745c5c3_Var167 templ.SafeURL3491+ var templ_7745c5c3_Var167 string
3486- templ_7745c5c3_Var167, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.TargetHref))3492+ templ_7745c5c3_Var167, templ_7745c5c3_Err = templ.JoinStringErrs(p.Source)
3487 if templ_7745c5c3_Err != nil {3493 if templ_7745c5c3_Err != nil {
3488- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 682, Col: 45}3494+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 684, Col: 58}
3489 }3495 }
3490 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var167))3496 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var167))
3491 if templ_7745c5c3_Err != nil {3497 if templ_7745c5c3_Err != nil {
3492 return templ_7745c5c3_Err3498 return templ_7745c5c3_Err
3493 }3499 }
3494- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 325, "\">")3500+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 326, "</a></dd><dt>target</dt><dd><a href=\"")
3495 if templ_7745c5c3_Err != nil {3501 if templ_7745c5c3_Err != nil {
3496 return templ_7745c5c3_Err3502 return templ_7745c5c3_Err
3497 }3503 }
3498- var templ_7745c5c3_Var168 string3504+ var templ_7745c5c3_Var168 templ.SafeURL
3499- templ_7745c5c3_Var168, templ_7745c5c3_Err = templ.JoinStringErrs(p.Target)3505+ templ_7745c5c3_Var168, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.TargetHref))
3500 if templ_7745c5c3_Err != nil {3506 if templ_7745c5c3_Err != nil {
3501- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 682, Col: 58}3507+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 686, Col: 45}
3502 }3508 }
3503 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var168))3509 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var168))
3504 if templ_7745c5c3_Err != nil {3510 if templ_7745c5c3_Err != nil {
3505 return templ_7745c5c3_Err3511 return templ_7745c5c3_Err
3506 }3512 }
3507- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 326, "</a></dd><dt>ahead</dt><dd>")3513+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 327, "\">")
3508 if templ_7745c5c3_Err != nil {3514 if templ_7745c5c3_Err != nil {
3509 return templ_7745c5c3_Err3515 return templ_7745c5c3_Err
3510 }3516 }
3511 var templ_7745c5c3_Var169 string3517 var templ_7745c5c3_Var169 string
3512- templ_7745c5c3_Var169, templ_7745c5c3_Err = templ.JoinStringErrs(p.AheadText)3518+ templ_7745c5c3_Var169, templ_7745c5c3_Err = templ.JoinStringErrs(p.Target)
3513 if templ_7745c5c3_Err != nil {3519 if templ_7745c5c3_Err != nil {
3514- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 684, Col: 21}3520+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 686, Col: 58}
3515 }3521 }
3516 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var169))3522 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var169))
3517 if templ_7745c5c3_Err != nil {3523 if templ_7745c5c3_Err != nil {
3518 return templ_7745c5c3_Err3524 return templ_7745c5c3_Err
3519 }3525 }
3520- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 327, "</dd></dl></header>")3526+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 328, "</a></dd><dt>ahead</dt><dd>")
3527+ if templ_7745c5c3_Err != nil {
3528+ return templ_7745c5c3_Err
3529+ }
3530+ var templ_7745c5c3_Var170 string
3531+ templ_7745c5c3_Var170, templ_7745c5c3_Err = templ.JoinStringErrs(p.AheadText)
3532+ if templ_7745c5c3_Err != nil {
3533+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 688, Col: 21}
3534+ }
3535+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var170))
3536+ if templ_7745c5c3_Err != nil {
3537+ return templ_7745c5c3_Err
3538+ }
3539+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 329, "</dd></dl></header>")
3521 if templ_7745c5c3_Err != nil {3540 if templ_7745c5c3_Err != nil {
3522 return templ_7745c5c3_Err3541 return templ_7745c5c3_Err
3523 }3542 }
3524 if p.Note != "" {3543 if p.Note != "" {
3525- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 328, "<p class=\"notice\">")3544+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 330, "<p class=\"notice\">")
3526 if templ_7745c5c3_Err != nil {3545 if templ_7745c5c3_Err != nil {
3527 return templ_7745c5c3_Err3546 return templ_7745c5c3_Err
3528 }3547 }
3529- var templ_7745c5c3_Var170 string3548+ var templ_7745c5c3_Var171 string
3530- templ_7745c5c3_Var170, templ_7745c5c3_Err = templ.JoinStringErrs(p.Note)3549+ templ_7745c5c3_Var171, templ_7745c5c3_Err = templ.JoinStringErrs(p.Note)
3531 if templ_7745c5c3_Err != nil {3550 if templ_7745c5c3_Err != nil {
3532- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 688, Col: 29}3551+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 692, Col: 29}
3533 }3552 }
3534- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var170))3553+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var171))
3535 if templ_7745c5c3_Err != nil {3554 if templ_7745c5c3_Err != nil {
3536 return templ_7745c5c3_Err3555 return templ_7745c5c3_Err
3537 }3556 }
3538- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 329, "</p>")3557+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 331, "</p>")
3539 if templ_7745c5c3_Err != nil {3558 if templ_7745c5c3_Err != nil {
3540 return templ_7745c5c3_Err3559 return templ_7745c5c3_Err
3541 }3560 }
3542 }3561 }
3543- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 330, " ")3562+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 332, " ")
3544 if templ_7745c5c3_Err != nil {3563 if templ_7745c5c3_Err != nil {
3545 return templ_7745c5c3_Err3564 return templ_7745c5c3_Err
3546 }3565 }
3547 if p.Existing != nil {3566 if p.Existing != nil {
3548- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 331, "<p class=\"notice\">an open merge request already covers these branches: <a href=\"")3567+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 333, "<p class=\"notice\">an open merge request already covers these branches: <a href=\"")
3549 if templ_7745c5c3_Err != nil {3568 if templ_7745c5c3_Err != nil {
3550 return templ_7745c5c3_Err3569 return templ_7745c5c3_Err
3551 }3570 }
3552- var templ_7745c5c3_Var171 templ.SafeURL3571+ var templ_7745c5c3_Var172 templ.SafeURL
3553- templ_7745c5c3_Var171, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Existing.Href))3572+ templ_7745c5c3_Var172, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Existing.Href))
3554 if templ_7745c5c3_Err != nil {3573 if templ_7745c5c3_Err != nil {
3555- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 691, Col: 114}3574+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 695, Col: 114}
3556 }3575 }
3557- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var171))3576+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var172))
3558 if templ_7745c5c3_Err != nil {3577 if templ_7745c5c3_Err != nil {
3559 return templ_7745c5c3_Err3578 return templ_7745c5c3_Err
3560 }3579 }
3561- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 332, "\">")3580+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 334, "\">")
3562 if templ_7745c5c3_Err != nil {3581 if templ_7745c5c3_Err != nil {
3563 return templ_7745c5c3_Err3582 return templ_7745c5c3_Err
3564 }3583 }
3565- var templ_7745c5c3_Var172 string3584+ var templ_7745c5c3_Var173 string
3566- templ_7745c5c3_Var172, templ_7745c5c3_Err = templ.JoinStringErrs(p.Existing.Label)3585+ templ_7745c5c3_Var173, templ_7745c5c3_Err = templ.JoinStringErrs(p.Existing.Label)
3567 if templ_7745c5c3_Err != nil {3586 if templ_7745c5c3_Err != nil {
3568- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 691, Col: 135}3587+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 695, Col: 135}
3569 }3588 }
3570- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var172))3589+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var173))
3571 if templ_7745c5c3_Err != nil {3590 if templ_7745c5c3_Err != nil {
3572 return templ_7745c5c3_Err3591 return templ_7745c5c3_Err
3573 }3592 }
3574- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 333, "</a></p>")3593+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 335, "</a></p>")
3575 if templ_7745c5c3_Err != nil {3594 if templ_7745c5c3_Err != nil {
3576 return templ_7745c5c3_Err3595 return templ_7745c5c3_Err
3577 }3596 }
3578 }3597 }
3579- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 334, " ")3598+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 336, " ")
3580 if templ_7745c5c3_Err != nil {3599 if templ_7745c5c3_Err != nil {
3581 return templ_7745c5c3_Err3600 return templ_7745c5c3_Err
3582 }3601 }
3583 if p.Create != nil {3602 if p.Create != nil {
3584- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 335, "<form class=\"cform create\" method=\"post\" action=\"")3603+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 337, "<form class=\"cform create\" method=\"post\" action=\"")
3585 if templ_7745c5c3_Err != nil {3604 if templ_7745c5c3_Err != nil {
3586 return templ_7745c5c3_Err3605 return templ_7745c5c3_Err
3587 }3606 }
3588- var templ_7745c5c3_Var173 templ.SafeURL3607+ var templ_7745c5c3_Var174 templ.SafeURL
3589- templ_7745c5c3_Var173, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Create.Action))3608+ templ_7745c5c3_Var174, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Create.Action))
3590 if templ_7745c5c3_Err != nil {3609 if templ_7745c5c3_Err != nil {
3591- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 694, Col: 83}3610+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 698, Col: 83}
3592 }3611 }
3593- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var173))3612+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var174))
3594 if templ_7745c5c3_Err != nil {3613 if templ_7745c5c3_Err != nil {
3595 return templ_7745c5c3_Err3614 return templ_7745c5c3_Err
3596 }3615 }
3597- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 336, "\"><input type=\"hidden\" name=\"source\" value=\"")3616+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 338, "\"><input type=\"hidden\" name=\"source\" value=\"")
3598 if templ_7745c5c3_Err != nil {3617 if templ_7745c5c3_Err != nil {
3599 return templ_7745c5c3_Err3618 return templ_7745c5c3_Err
3600 }3619 }
3601- var templ_7745c5c3_Var174 string3620+ var templ_7745c5c3_Var175 string
3602- templ_7745c5c3_Var174, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Create.Source)3621+ templ_7745c5c3_Var175, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Create.Source)
3603 if templ_7745c5c3_Err != nil {3622 if templ_7745c5c3_Err != nil {
3604- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 695, Col: 62}3623+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 699, Col: 62}
3605 }3624 }
3606- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var174)3625+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var175)
3607 if templ_7745c5c3_Err != nil {3626 if templ_7745c5c3_Err != nil {
3608 return templ_7745c5c3_Err3627 return templ_7745c5c3_Err
3609 }3628 }
3610- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 337, "\"> <input type=\"hidden\" name=\"target\" value=\"")3629+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 339, "\"> <input type=\"hidden\" name=\"target\" value=\"")
3611 if templ_7745c5c3_Err != nil {3630 if templ_7745c5c3_Err != nil {
3612 return templ_7745c5c3_Err3631 return templ_7745c5c3_Err
3613 }3632 }
3614- var templ_7745c5c3_Var175 string3633+ var templ_7745c5c3_Var176 string
3615- templ_7745c5c3_Var175, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Create.Target)3634+ templ_7745c5c3_Var176, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Create.Target)
3616 if templ_7745c5c3_Err != nil {3635 if templ_7745c5c3_Err != nil {
3617- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 696, Col: 62}3636+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 700, Col: 62}
3618 }3637 }
3619- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var175)3638+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var176)
3620 if templ_7745c5c3_Err != nil {3639 if templ_7745c5c3_Err != nil {
3621 return templ_7745c5c3_Err3640 return templ_7745c5c3_Err
3622 }3641 }
3623- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 338, "\"> <label for=\"mr-title\">title</label> <input id=\"mr-title\" name=\"title\" type=\"text\" maxlength=\"120\" required value=\"")3642+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 340, "\"> <label for=\"mr-title\">title</label> <input id=\"mr-title\" name=\"title\" type=\"text\" maxlength=\"120\" required value=\"")
3624 if templ_7745c5c3_Err != nil {3643 if templ_7745c5c3_Err != nil {
3625 return templ_7745c5c3_Err3644 return templ_7745c5c3_Err
3626 }3645 }
3627- var templ_7745c5c3_Var176 string3646+ var templ_7745c5c3_Var177 string
3628- templ_7745c5c3_Var176, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Create.Title)3647+ templ_7745c5c3_Var177, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Create.Title)
3629 if templ_7745c5c3_Err != nil {3648 if templ_7745c5c3_Err != nil {
3630- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 698, Col: 97}3649+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 702, Col: 97}
3631 }3650 }
3632- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var176)3651+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var177)
3633 if templ_7745c5c3_Err != nil {3652 if templ_7745c5c3_Err != nil {
3634 return templ_7745c5c3_Err3653 return templ_7745c5c3_Err
3635 }3654 }
3636- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 339, "\" autocomplete=\"off\"> <label for=\"mr-desc\">description</label> <textarea id=\"mr-desc\" name=\"description\" rows=\"4\" maxlength=\"8000\" placeholder=\"Markdown, optional\"></textarea><div class=\"f-btns\"><button type=\"submit\" class=\"btn primary\">Create merge request</button></div></form>")3655+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 341, "\" autocomplete=\"off\"> <label for=\"mr-desc\">description</label> <textarea id=\"mr-desc\" name=\"description\" rows=\"4\" maxlength=\"8000\" placeholder=\"Markdown, optional\"></textarea><div class=\"f-btns\"><button type=\"submit\" class=\"btn primary\">Create merge request</button></div></form>")
3637 if templ_7745c5c3_Err != nil {3656 if templ_7745c5c3_Err != nil {
3638 return templ_7745c5c3_Err3657 return templ_7745c5c3_Err
3639 }3658 }
3640 }3659 }
3641- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 340, " ")3660+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 342, " ")
3642 if templ_7745c5c3_Err != nil {3661 if templ_7745c5c3_Err != nil {
3643 return templ_7745c5c3_Err3662 return templ_7745c5c3_Err
3644 }3663 }
3645 if p.HasDiff {3664 if p.HasDiff {
3646- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 341, "<div class=\"diff-tools\" role=\"group\" aria-label=\"Diff view\"><span class=\"dim\">")3665+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 343, "<div class=\"diff-tools\" role=\"group\" aria-label=\"Diff view\"><span class=\"dim\">")
3647 if templ_7745c5c3_Err != nil {3666 if templ_7745c5c3_Err != nil {
3648 return templ_7745c5c3_Err3667 return templ_7745c5c3_Err
3649 }3668 }
3650- var templ_7745c5c3_Var177 string3669+ var templ_7745c5c3_Var178 string
3651- templ_7745c5c3_Var177, templ_7745c5c3_Err = templ.JoinStringErrs(plural(p.NFiles, "file", "files"))3670+ templ_7745c5c3_Var178, templ_7745c5c3_Err = templ.JoinStringErrs(plural(p.NFiles, "file", "files"))
3652 if templ_7745c5c3_Err != nil {3671 if templ_7745c5c3_Err != nil {
3653- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 708, Col: 57}3672+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 712, Col: 57}
3654 }3673 }
3655- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var177))3674+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var178))
3656 if templ_7745c5c3_Err != nil {3675 if templ_7745c5c3_Err != nil {
3657 return templ_7745c5c3_Err3676 return templ_7745c5c3_Err
3658 }3677 }
3659- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 342, " · <span class=\"plus\">+")3678+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 344, " · <span class=\"plus\">+")
3660 if templ_7745c5c3_Err != nil {3679 if templ_7745c5c3_Err != nil {
3661 return templ_7745c5c3_Err3680 return templ_7745c5c3_Err
3662 }3681 }
3663- var templ_7745c5c3_Var178 string3682+ var templ_7745c5c3_Var179 string
3664- templ_7745c5c3_Var178, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(p.Adds))3683+ templ_7745c5c3_Var179, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(p.Adds))
3665 if templ_7745c5c3_Err != nil {3684 if templ_7745c5c3_Err != nil {
3666- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 708, Col: 97}3685+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 712, Col: 97}
3667 }3686 }
3668- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var178))3687+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var179))
3669 if templ_7745c5c3_Err != nil {3688 if templ_7745c5c3_Err != nil {
3670 return templ_7745c5c3_Err3689 return templ_7745c5c3_Err
3671 }3690 }
3672- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 343, "</span> <span class=\"minus\">-")3691+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 345, "</span> <span class=\"minus\">-")
3673 if templ_7745c5c3_Err != nil {3692 if templ_7745c5c3_Err != nil {
3674 return templ_7745c5c3_Err3693 return templ_7745c5c3_Err
3675 }3694 }
3676- var templ_7745c5c3_Var179 string3695+ var templ_7745c5c3_Var180 string
3677- templ_7745c5c3_Var179, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(p.Dels))3696+ templ_7745c5c3_Var180, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(p.Dels))
3678 if templ_7745c5c3_Err != nil {3697 if templ_7745c5c3_Err != nil {
3679- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 708, Col: 142}3698+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 712, Col: 142}
3680 }3699 }
3681- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var179))3700+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var180))
3682 if templ_7745c5c3_Err != nil {3701 if templ_7745c5c3_Err != nil {
3683 return templ_7745c5c3_Err3702 return templ_7745c5c3_Err
3684 }3703 }
3685- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 344, "</span></span> <span class=\"grow\"></span>")3704+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 346, "</span></span> <span class=\"grow\"></span>")
3686 if templ_7745c5c3_Err != nil {3705 if templ_7745c5c3_Err != nil {
3687 return templ_7745c5c3_Err3706 return templ_7745c5c3_Err
3688 }3707 }
@@ -3690,64 +3709,64 @@ func Compare(l Layout, p ComparePage) templ.Component {
3690 if templ_7745c5c3_Err != nil {3709 if templ_7745c5c3_Err != nil {
3691 return templ_7745c5c3_Err3710 return templ_7745c5c3_Err
3692 }3711 }
3693- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 345, "</div>")3712+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 347, "</div>")
3694 if templ_7745c5c3_Err != nil {3713 if templ_7745c5c3_Err != nil {
3695 return templ_7745c5c3_Err3714 return templ_7745c5c3_Err
3696 }3715 }
3697 if p.Invisible {3716 if p.Invisible {
3698- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 346, "<p class=\"notice\">this diff holds invisible characters (direction controls, zero-width characters). They are shown as <span class=\"inv\">&lt;U+XXXX&gt;</span> markers, never applied.</p>")3717+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 348, "<p class=\"notice\">this diff holds invisible characters (direction controls, zero-width characters). They are shown as <span class=\"inv\">&lt;U+XXXX&gt;</span> markers, never applied.</p>")
3699 if templ_7745c5c3_Err != nil {3718 if templ_7745c5c3_Err != nil {
3700 return templ_7745c5c3_Err3719 return templ_7745c5c3_Err
3701 }3720 }
3702 }3721 }
3703- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 347, " <div id=\"diffs\"")3722+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 349, " <div id=\"diffs\"")
3704 if templ_7745c5c3_Err != nil {3723 if templ_7745c5c3_Err != nil {
3705 return templ_7745c5c3_Err3724 return templ_7745c5c3_Err
3706 }3725 }
3707 if p.Both {3726 if p.Both {
3708- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 348, " data-diff=\"")3727+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 350, " data-diff=\"")
3709 if templ_7745c5c3_Err != nil {3728 if templ_7745c5c3_Err != nil {
3710 return templ_7745c5c3_Err3729 return templ_7745c5c3_Err
3711 }3730 }
3712- var templ_7745c5c3_Var180 string3731+ var templ_7745c5c3_Var181 string
3713- templ_7745c5c3_Var180, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.View)3732+ templ_7745c5c3_Var181, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.View)
3714 if templ_7745c5c3_Err != nil {3733 if templ_7745c5c3_Err != nil {
3715- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 721, Col: 23}3734+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 725, Col: 23}
3716 }3735 }
3717- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var180)3736+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var181)
3718 if templ_7745c5c3_Err != nil {3737 if templ_7745c5c3_Err != nil {
3719 return templ_7745c5c3_Err3738 return templ_7745c5c3_Err
3720 }3739 }
3721- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 349, "\"")3740+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 351, "\"")
3722 if templ_7745c5c3_Err != nil {3741 if templ_7745c5c3_Err != nil {
3723 return templ_7745c5c3_Err3742 return templ_7745c5c3_Err
3724 }3743 }
3725 } else {3744 } else {
3726- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 350, " data-view=\"")3745+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 352, " data-view=\"")
3727 if templ_7745c5c3_Err != nil {3746 if templ_7745c5c3_Err != nil {
3728 return templ_7745c5c3_Err3747 return templ_7745c5c3_Err
3729 }3748 }
3730- var templ_7745c5c3_Var181 string3749+ var templ_7745c5c3_Var182 string
3731- templ_7745c5c3_Var181, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.View)3750+ templ_7745c5c3_Var182, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.View)
3732 if templ_7745c5c3_Err != nil {3751 if templ_7745c5c3_Err != nil {
3733- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 723, Col: 23}3752+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 727, Col: 23}
3734 }3753 }
3735- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var181)3754+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var182)
3736 if templ_7745c5c3_Err != nil {3755 if templ_7745c5c3_Err != nil {
3737 return templ_7745c5c3_Err3756 return templ_7745c5c3_Err
3738 }3757 }
3739- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 351, "\"")3758+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 353, "\"")
3740 if templ_7745c5c3_Err != nil {3759 if templ_7745c5c3_Err != nil {
3741 return templ_7745c5c3_Err3760 return templ_7745c5c3_Err
3742 }3761 }
3743 }3762 }
3744 if p.Both && !p.Pinned {3763 if p.Both && !p.Pinned {
3745- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 352, " hx-live=\"this.dataset.diff = sessionStorage.getItem('diff') || this.dataset.diff\"")3764+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 354, " hx-live=\"this.dataset.diff = sessionStorage.getItem('diff') || this.dataset.diff\"")
3746 if templ_7745c5c3_Err != nil {3765 if templ_7745c5c3_Err != nil {
3747 return templ_7745c5c3_Err3766 return templ_7745c5c3_Err
3748 }3767 }
3749 }3768 }
3750- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 353, ">")3769+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 355, ">")
3751 if templ_7745c5c3_Err != nil {3770 if templ_7745c5c3_Err != nil {
3752 return templ_7745c5c3_Err3771 return templ_7745c5c3_Err
3753 }3772 }
@@ -3757,14 +3776,14 @@ func Compare(l Layout, p ComparePage) templ.Component {
3757 return templ_7745c5c3_Err3776 return templ_7745c5c3_Err
3758 }3777 }
3759 }3778 }
3760- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 354, "</div>")3779+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 356, "</div>")
3761 if templ_7745c5c3_Err != nil {3780 if templ_7745c5c3_Err != nil {
3762 return templ_7745c5c3_Err3781 return templ_7745c5c3_Err
3763 }3782 }
3764 }3783 }
3765 return nil3784 return nil
3766 })3785 })
3767- templ_7745c5c3_Err = Shell(l, compareRail(p)).Render(templ.WithChildren(ctx, templ_7745c5c3_Var162), templ_7745c5c3_Buffer)3786+ templ_7745c5c3_Err = Shell(l, compareRail(p)).Render(templ.WithChildren(ctx, templ_7745c5c3_Var163), templ_7745c5c3_Buffer)
3768 if templ_7745c5c3_Err != nil {3787 if templ_7745c5c3_Err != nil {
3769 return templ_7745c5c3_Err3788 return templ_7745c5c3_Err
3770 }3789 }
@@ -3788,173 +3807,173 @@ func compareRail(p ComparePage) templ.Component {
3788 }()3807 }()
3789 }3808 }
3790 ctx = templ.InitializeContext(ctx)3809 ctx = templ.InitializeContext(ctx)
3791- templ_7745c5c3_Var182 := templ.GetChildren(ctx)3810+ templ_7745c5c3_Var183 := templ.GetChildren(ctx)
3792- if templ_7745c5c3_Var182 == nil {3811+ if templ_7745c5c3_Var183 == nil {
3793- templ_7745c5c3_Var182 = templ.NopComponent3812+ templ_7745c5c3_Var183 = templ.NopComponent
3794 }3813 }
3795 ctx = templ.ClearChildren(ctx)3814 ctx = templ.ClearChildren(ctx)
3796- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 355, "<section aria-labelledby=\"r-ahead\"><h2 id=\"r-ahead\">Commits <span class=\"count\">")3815+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 357, "<section aria-labelledby=\"r-ahead\"><h2 id=\"r-ahead\">Commits <span class=\"count\">")
3797 if templ_7745c5c3_Err != nil {3816 if templ_7745c5c3_Err != nil {
3798 return templ_7745c5c3_Err3817 return templ_7745c5c3_Err
3799 }3818 }
3800- var templ_7745c5c3_Var183 string3819+ var templ_7745c5c3_Var184 string
3801- templ_7745c5c3_Var183, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(len(p.Ahead)))3820+ templ_7745c5c3_Var184, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(len(p.Ahead)))
3802 if templ_7745c5c3_Err != nil {3821 if templ_7745c5c3_Err != nil {
3803- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 739, Col: 67}3822+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 743, Col: 67}
3804 }3823 }
3805- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var183))3824+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var184))
3806 if templ_7745c5c3_Err != nil {3825 if templ_7745c5c3_Err != nil {
3807 return templ_7745c5c3_Err3826 return templ_7745c5c3_Err
3808 }3827 }
3809- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 356, "</span></h2><ul class=\"pcommits\">")3828+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 358, "</span></h2><ul class=\"pcommits\">")
3810 if templ_7745c5c3_Err != nil {3829 if templ_7745c5c3_Err != nil {
3811 return templ_7745c5c3_Err3830 return templ_7745c5c3_Err
3812 }3831 }
3813 for _, c := range p.Ahead {3832 for _, c := range p.Ahead {
3814- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 357, "<li><a href=\"")3833+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 359, "<li><a href=\"")
3815 if templ_7745c5c3_Err != nil {3834 if templ_7745c5c3_Err != nil {
3816 return templ_7745c5c3_Err3835 return templ_7745c5c3_Err
3817 }3836 }
3818- var templ_7745c5c3_Var184 templ.SafeURL3837+ var templ_7745c5c3_Var185 templ.SafeURL
3819- templ_7745c5c3_Var184, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(c.CHref))3838+ templ_7745c5c3_Var185, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(c.CHref))
3820 if templ_7745c5c3_Err != nil {3839 if templ_7745c5c3_Err != nil {
3821- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 743, Col: 37}3840+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 747, Col: 37}
3822 }3841 }
3823- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var184))3842+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var185))
3824 if templ_7745c5c3_Err != nil {3843 if templ_7745c5c3_Err != nil {
3825 return templ_7745c5c3_Err3844 return templ_7745c5c3_Err
3826 }3845 }
3827- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 358, "\">")3846+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 360, "\">")
3828 if templ_7745c5c3_Err != nil {3847 if templ_7745c5c3_Err != nil {
3829 return templ_7745c5c3_Err3848 return templ_7745c5c3_Err
3830 }3849 }
3831- var templ_7745c5c3_Var185 string3850+ var templ_7745c5c3_Var186 string
3832- templ_7745c5c3_Var185, templ_7745c5c3_Err = templ.JoinStringErrs(c.Short)3851+ templ_7745c5c3_Var186, templ_7745c5c3_Err = templ.JoinStringErrs(c.Short)
3833 if templ_7745c5c3_Err != nil {3852 if templ_7745c5c3_Err != nil {
3834- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 743, Col: 49}3853+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 747, Col: 49}
3835 }3854 }
3836- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var185))3855+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var186))
3837 if templ_7745c5c3_Err != nil {3856 if templ_7745c5c3_Err != nil {
3838 return templ_7745c5c3_Err3857 return templ_7745c5c3_Err
3839 }3858 }
3840- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 359, "</a> <span class=\"s\">")3859+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 361, "</a> <span class=\"s\">")
3841 if templ_7745c5c3_Err != nil {3860 if templ_7745c5c3_Err != nil {
3842 return templ_7745c5c3_Err3861 return templ_7745c5c3_Err
3843 }3862 }
3844- var templ_7745c5c3_Var186 string3863+ var templ_7745c5c3_Var187 string
3845- templ_7745c5c3_Var186, templ_7745c5c3_Err = templ.JoinStringErrs(c.Subject)3864+ templ_7745c5c3_Var187, templ_7745c5c3_Err = templ.JoinStringErrs(c.Subject)
3846 if templ_7745c5c3_Err != nil {3865 if templ_7745c5c3_Err != nil {
3847- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 744, Col: 32}3866+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 748, Col: 32}
3848 }3867 }
3849- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var186))3868+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var187))
3850 if templ_7745c5c3_Err != nil {3869 if templ_7745c5c3_Err != nil {
3851 return templ_7745c5c3_Err3870 return templ_7745c5c3_Err
3852 }3871 }
3853- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 360, "</span> <span class=\"mute\">")3872+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 362, "</span> <span class=\"mute\">")
3854 if templ_7745c5c3_Err != nil {3873 if templ_7745c5c3_Err != nil {
3855 return templ_7745c5c3_Err3874 return templ_7745c5c3_Err
3856 }3875 }
3857- var templ_7745c5c3_Var187 string3876+ var templ_7745c5c3_Var188 string
3858- templ_7745c5c3_Var187, templ_7745c5c3_Err = templ.JoinStringErrs(c.Author)3877+ templ_7745c5c3_Var188, templ_7745c5c3_Err = templ.JoinStringErrs(c.Author)
3859 if templ_7745c5c3_Err != nil {3878 if templ_7745c5c3_Err != nil {
3860- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 746, Col: 16}3879+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 750, Col: 16}
3861 }3880 }
3862- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var187))3881+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var188))
3863 if templ_7745c5c3_Err != nil {3882 if templ_7745c5c3_Err != nil {
3864 return templ_7745c5c3_Err3883 return templ_7745c5c3_Err
3865 }3884 }
3866- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 361, " ")3885+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 363, " ")
3867 if templ_7745c5c3_Err != nil {3886 if templ_7745c5c3_Err != nil {
3868 return templ_7745c5c3_Err3887 return templ_7745c5c3_Err
3869 }3888 }
3870 if c.WhenAt != "" {3889 if c.WhenAt != "" {
3871- var templ_7745c5c3_Var188 string3890+ var templ_7745c5c3_Var189 string
3872- templ_7745c5c3_Var188, templ_7745c5c3_Err = templ.JoinStringErrs(" · ")3891+ templ_7745c5c3_Var189, templ_7745c5c3_Err = templ.JoinStringErrs(" · ")
3873 if templ_7745c5c3_Err != nil {3892 if templ_7745c5c3_Err != nil {
3874- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 748, Col: 15}3893+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 752, Col: 15}
3875 }3894 }
3876- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var188))3895+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var189))
3877 if templ_7745c5c3_Err != nil {3896 if templ_7745c5c3_Err != nil {
3878 return templ_7745c5c3_Err3897 return templ_7745c5c3_Err
3879 }3898 }
3880- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 362, "<time datetime=\"")3899+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 364, "<time datetime=\"")
3881 if templ_7745c5c3_Err != nil {3900 if templ_7745c5c3_Err != nil {
3882 return templ_7745c5c3_Err3901 return templ_7745c5c3_Err
3883 }3902 }
3884- var templ_7745c5c3_Var189 string3903+ var templ_7745c5c3_Var190 string
3885- templ_7745c5c3_Var189, templ_7745c5c3_Err = templ.ResolveAttributeValue(c.WhenAt)3904+ templ_7745c5c3_Var190, templ_7745c5c3_Err = templ.ResolveAttributeValue(c.WhenAt)
3886 if templ_7745c5c3_Err != nil {3905 if templ_7745c5c3_Err != nil {
3887- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 748, Col: 42}3906+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 752, Col: 42}
3888 }3907 }
3889- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var189)3908+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var190)
3890 if templ_7745c5c3_Err != nil {3909 if templ_7745c5c3_Err != nil {
3891 return templ_7745c5c3_Err3910 return templ_7745c5c3_Err
3892 }3911 }
3893- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 363, "\">")3912+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 365, "\">")
3894 if templ_7745c5c3_Err != nil {3913 if templ_7745c5c3_Err != nil {
3895 return templ_7745c5c3_Err3914 return templ_7745c5c3_Err
3896 }3915 }
3897- var templ_7745c5c3_Var190 string3916+ var templ_7745c5c3_Var191 string
3898- templ_7745c5c3_Var190, templ_7745c5c3_Err = templ.JoinStringErrs(c.When)3917+ templ_7745c5c3_Var191, templ_7745c5c3_Err = templ.JoinStringErrs(c.When)
3899 if templ_7745c5c3_Err != nil {3918 if templ_7745c5c3_Err != nil {
3900- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 748, Col: 53}3919+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 752, Col: 53}
3901 }3920 }
3902- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var190))3921+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var191))
3903 if templ_7745c5c3_Err != nil {3922 if templ_7745c5c3_Err != nil {
3904 return templ_7745c5c3_Err3923 return templ_7745c5c3_Err
3905 }3924 }
3906- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 364, "</time>")3925+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 366, "</time>")
3907 if templ_7745c5c3_Err != nil {3926 if templ_7745c5c3_Err != nil {
3908 return templ_7745c5c3_Err3927 return templ_7745c5c3_Err
3909 }3928 }
3910 }3929 }
3911- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 365, "</span></li>")3930+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 367, "</span></li>")
3912 if templ_7745c5c3_Err != nil {3931 if templ_7745c5c3_Err != nil {
3913 return templ_7745c5c3_Err3932 return templ_7745c5c3_Err
3914 }3933 }
3915 }3934 }
3916- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 366, "</ul>")3935+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 368, "</ul>")
3917 if templ_7745c5c3_Err != nil {3936 if templ_7745c5c3_Err != nil {
3918 return templ_7745c5c3_Err3937 return templ_7745c5c3_Err
3919 }3938 }
3920 if len(p.Ahead) == 0 {3939 if len(p.Ahead) == 0 {
3921- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 367, "<p class=\"dim\">no commit ahead of ")3940+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 369, "<p class=\"dim\">no commit ahead of ")
3922 if templ_7745c5c3_Err != nil {3941 if templ_7745c5c3_Err != nil {
3923 return templ_7745c5c3_Err3942 return templ_7745c5c3_Err
3924 }3943 }
3925- var templ_7745c5c3_Var191 string3944+ var templ_7745c5c3_Var192 string
3926- templ_7745c5c3_Var191, templ_7745c5c3_Err = templ.JoinStringErrs(p.Target)3945+ templ_7745c5c3_Var192, templ_7745c5c3_Err = templ.JoinStringErrs(p.Target)
3927 if templ_7745c5c3_Err != nil {3946 if templ_7745c5c3_Err != nil {
3928- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 755, Col: 47}3947+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 759, Col: 47}
3929 }3948 }
3930- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var191))3949+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var192))
3931 if templ_7745c5c3_Err != nil {3950 if templ_7745c5c3_Err != nil {
3932 return templ_7745c5c3_Err3951 return templ_7745c5c3_Err
3933 }3952 }
3934- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 368, ".</p>")3953+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 370, ".</p>")
3935 if templ_7745c5c3_Err != nil {3954 if templ_7745c5c3_Err != nil {
3936 return templ_7745c5c3_Err3955 return templ_7745c5c3_Err
3937 }3956 }
3938 }3957 }
3939- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 369, "</section>")3958+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 371, "</section>")
3940 if templ_7745c5c3_Err != nil {3959 if templ_7745c5c3_Err != nil {
3941 return templ_7745c5c3_Err3960 return templ_7745c5c3_Err
3942 }3961 }
3943 if p.HasDiff {3962 if p.HasDiff {
3944- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 370, "<section aria-labelledby=\"r-files\"><h2 id=\"r-files\">Files <span class=\"count\">")3963+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 372, "<section aria-labelledby=\"r-files\"><h2 id=\"r-files\">Files <span class=\"count\">")
3945 if templ_7745c5c3_Err != nil {3964 if templ_7745c5c3_Err != nil {
3946 return templ_7745c5c3_Err3965 return templ_7745c5c3_Err
3947 }3966 }
3948- var templ_7745c5c3_Var192 string3967+ var templ_7745c5c3_Var193 string
3949- templ_7745c5c3_Var192, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(len(p.Files)))3968+ templ_7745c5c3_Var193, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(len(p.Files)))
3950 if templ_7745c5c3_Err != nil {3969 if templ_7745c5c3_Err != nil {
3951- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 760, Col: 66}3970+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 764, Col: 66}
3952 }3971 }
3953- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var192))3972+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var193))
3954 if templ_7745c5c3_Err != nil {3973 if templ_7745c5c3_Err != nil {
3955 return templ_7745c5c3_Err3974 return templ_7745c5c3_Err
3956 }3975 }
3957- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 371, "</span></h2>")3976+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 373, "</span></h2>")
3958 if templ_7745c5c3_Err != nil {3977 if templ_7745c5c3_Err != nil {
3959 return templ_7745c5c3_Err3978 return templ_7745c5c3_Err
3960 }3979 }
@@ -3962,12 +3981,12 @@ func compareRail(p ComparePage) templ.Component {
3962 if templ_7745c5c3_Err != nil {3981 if templ_7745c5c3_Err != nil {
3963 return templ_7745c5c3_Err3982 return templ_7745c5c3_Err
3964 }3983 }
3965- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 372, "</section>")3984+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 374, "</section>")
3966 if templ_7745c5c3_Err != nil {3985 if templ_7745c5c3_Err != nil {
3967 return templ_7745c5c3_Err3986 return templ_7745c5c3_Err
3968 }3987 }
3969 }3988 }
3970- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 373, "<section aria-labelledby=\"r-cli\"><h2 id=\"r-cli\">From a terminal</h2>")3989+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 375, "<section aria-labelledby=\"r-cli\"><h2 id=\"r-cli\">From a terminal</h2>")
3971 if templ_7745c5c3_Err != nil {3990 if templ_7745c5c3_Err != nil {
3972 return templ_7745c5c3_Err3991 return templ_7745c5c3_Err
3973 }3992 }
@@ -3975,7 +3994,7 @@ func compareRail(p ComparePage) templ.Component {
3975 if templ_7745c5c3_Err != nil {3994 if templ_7745c5c3_Err != nil {
3976 return templ_7745c5c3_Err3995 return templ_7745c5c3_Err
3977 }3996 }
3978- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 374, "</section>")3997+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 376, "</section>")
3979 if templ_7745c5c3_Err != nil {3998 if templ_7745c5c3_Err != nil {
3980 return templ_7745c5c3_Err3999 return templ_7745c5c3_Err
3981 }4000 }
M internal/adapters/web/mr_test.go +34 -1
@@ -161,7 +161,7 @@ func TestMRPanelsAndMenus(t *testing.T) {
161161 assert.NotContains(t, rail, text)
162162 }
163163 more := renderToString(t, moreMenu(p))
164- for _, text := range []string{"Merge settings", "squash, merge", "failing ones block", `id="mr-signing"`, "fingerprint", "ermite signing-key show"} {
164+ for _, text := range []string{"Merge settings", "squash, merge", "failing or unfinished checks block", `id="mr-signing"`, "fingerprint", "ermite signing-key show"} {
165165 assert.Contains(t, more, text)
166166 }
167167 merge := renderToString(t, mergeMenu(p))
@@ -297,3 +297,36 @@ func TestAutoMergeLiveEvents(t *testing.T) {
297297 assert.True(t, liveEvent(watchOf(domain.MergeRequestAutoMergeEnabled{})))
298298 assert.True(t, liveEvent(watchOf(domain.MergeRequestAutoMergeCancelled{})))
299299 }
300+
301+func TestMergeIgnoreChecks(t *testing.T) {
302+ t.Parallel()
303+ for _, kind := range []string{"bad", "running", "ok", ""} {
304+ t.Run(kind, func(t *testing.T) {
305+ box := (&Server{}).mergeBox(&repoData{repo: repoWithModes(domain.MergeModes()...)}, 3, "feat", "abc", true, mergeabilityView(domain.Mergeability{State: domain.MergeabilityUpToDate}, "main"))
306+ html := renderToString(t, mergeMenu(MRPage{Box: box, ChecksSum: ChecksSummary{Kind: kind}}))
307+ if kind == "bad" || kind == "running" {
308+ assert.Contains(t, html, `name="ignore_checks"`)
309+ assert.Contains(t, html, "Ignore checks")
310+ } else {
311+ assert.NotContains(t, html, `name="ignore_checks"`)
312+ }
313+ assert.True(t, box.CanMerge())
314+ })
315+ }
316+ name, err := domain.ParseRepoName("demo")
317+ require.NoError(t, err)
318+ head, err := domain.ParseObjectID(strings.Repeat("a", domain.ObjectIDLen))
319+ require.NoError(t, err)
320+ for _, ignore := range []bool{false, true} {
321+ svc := mocks.NewMergeRequestService(t)
322+ svc.EXPECT().Merge(mock.Anything, mock.Anything, name, int64(3), ports.MergeParams{Mode: domain.MergeModeSquash, HeadID: head, IgnoreChecks: ignore}).Return(ports.MergeResult{}, nil).Once()
323+ body := "mode=squash&head_id=" + head.String()
324+ if ignore {
325+ body += "&ignore_checks=on"
326+ }
327+ s := &Server{cfg: Config{MergeRequests: svc}}
328+ to, _, err := s.mrMerge(context.Background(), autoMergeRequest("/demo/merge-requests/3/merge", body))
329+ require.NoError(t, err)
330+ assert.Equal(t, mrHref("demo", 3), to)
331+ }
332+}
@@ -161,7 +161,7 @@ func TestMRPanelsAndMenus(t *testing.T) {
161 assert.NotContains(t, rail, text)161 assert.NotContains(t, rail, text)
162 }162 }
163 more := renderToString(t, moreMenu(p))163 more := renderToString(t, moreMenu(p))
164- for _, text := range []string{"Merge settings", "squash, merge", "failing ones block", `id="mr-signing"`, "fingerprint", "ermite signing-key show"} {164+ for _, text := range []string{"Merge settings", "squash, merge", "failing or unfinished checks block", `id="mr-signing"`, "fingerprint", "ermite signing-key show"} {
165 assert.Contains(t, more, text)165 assert.Contains(t, more, text)
166 }166 }
167 merge := renderToString(t, mergeMenu(p))167 merge := renderToString(t, mergeMenu(p))
@@ -297,3 +297,36 @@ func TestAutoMergeLiveEvents(t *testing.T) {
297 assert.True(t, liveEvent(watchOf(domain.MergeRequestAutoMergeEnabled{})))297 assert.True(t, liveEvent(watchOf(domain.MergeRequestAutoMergeEnabled{})))
298 assert.True(t, liveEvent(watchOf(domain.MergeRequestAutoMergeCancelled{})))298 assert.True(t, liveEvent(watchOf(domain.MergeRequestAutoMergeCancelled{})))
299 }299 }
300+
301+func TestMergeIgnoreChecks(t *testing.T) {
302+ t.Parallel()
303+ for _, kind := range []string{"bad", "running", "ok", ""} {
304+ t.Run(kind, func(t *testing.T) {
305+ box := (&Server{}).mergeBox(&repoData{repo: repoWithModes(domain.MergeModes()...)}, 3, "feat", "abc", true, mergeabilityView(domain.Mergeability{State: domain.MergeabilityUpToDate}, "main"))
306+ html := renderToString(t, mergeMenu(MRPage{Box: box, ChecksSum: ChecksSummary{Kind: kind}}))
307+ if kind == "bad" || kind == "running" {
308+ assert.Contains(t, html, `name="ignore_checks"`)
309+ assert.Contains(t, html, "Ignore checks")
310+ } else {
311+ assert.NotContains(t, html, `name="ignore_checks"`)
312+ }
313+ assert.True(t, box.CanMerge())
314+ })
315+ }
316+ name, err := domain.ParseRepoName("demo")
317+ require.NoError(t, err)
318+ head, err := domain.ParseObjectID(strings.Repeat("a", domain.ObjectIDLen))
319+ require.NoError(t, err)
320+ for _, ignore := range []bool{false, true} {
321+ svc := mocks.NewMergeRequestService(t)
322+ svc.EXPECT().Merge(mock.Anything, mock.Anything, name, int64(3), ports.MergeParams{Mode: domain.MergeModeSquash, HeadID: head, IgnoreChecks: ignore}).Return(ports.MergeResult{}, nil).Once()
323+ body := "mode=squash&head_id=" + head.String()
324+ if ignore {
325+ body += "&ignore_checks=on"
326+ }
327+ s := &Server{cfg: Config{MergeRequests: svc}}
328+ to, _, err := s.mrMerge(context.Background(), autoMergeRequest("/demo/merge-requests/3/merge", body))
329+ require.NoError(t, err)
330+ assert.Equal(t, mrHref("demo", 3), to)
331+ }
332+}
M skills/ermite/CLI.md +10 -4
@@ -11,10 +11,10 @@ Errors are one line on standard error (`ermite: ...`) with exit status 1. `--jso
1111 | `repo list [--json]` | none | repositories you can see |
1212 | `repo show <name> [--json]` | none | |
1313 | `repo create <name> [--description TEXT] [--visibility public]` | `repo:write` | private by default |
14-| `repo edit <name> [--description TEXT] [--visibility V] [--default-branch B] [--merge-modes fast-forward,squash,merge] [--failing-checks-block=false] [--allow-auto-merge]` | `repo:admin` | only the given flags change; every merge mode is allowed by default, list the ones to keep; `--description ""` clears it; the branch must exist |
14+| `repo edit <name> [--description TEXT] [--visibility V] [--default-branch B] [--merge-modes fast-forward,squash,merge] [--allow-auto-merge]` | `repo:admin` | only the given flags change; every merge mode is allowed by default, list the ones to keep; `--description ""` clears it; the branch must exist |
1515 | `repo delete <name> [--yes]` | `repo:admin` | |
1616
17-Repository JSON: `name`, `description`, `visibility`, `default_branch`, `created_at`, `pushed_at` (null before the first push), `merge_modes`, `failing_checks_block`, `allow_auto_merge`.
17+Repository JSON: `name`, `description`, `visibility`, `default_branch`, `created_at`, `pushed_at` (null before the first push), `merge_modes`, `allow_auto_merge`.
1818
1919 ## Tokens
2020
@@ -28,7 +28,7 @@ Presets add up with `--scope` (repeatable or comma-separated):
2828
2929 | Preset | Scopes |
3030 |---|---|
31-| `cli` | every scope (including `mr:review`), for the owner's daily use; a token created before `mr:review` existed lacks it and loses owner rights: recreate it with `--preset cli` using the root token or from a signed-in owner web session (an old token lacking `mr:review` cannot grant it), then replace the stored CLI secret and revoke the old token |
31+| `cli` | every scope, including `mr:review` and `mr:force-merge`, for the owner's daily use |
3232 | `agent` | `repo:write`, `mr:write` |
3333 | `ci` | `repo:read` |
3434
@@ -42,6 +42,7 @@ Scopes:
4242 | `mr:write` | open, comment on, reply, edit and delete own notes, resolve, close, mark read |
4343 | `mr:review` | give a verdict (`--approve`, `--request-changes`) |
4444 | `mr:merge` | merge, and delete the merged source branch with `--delete-branch` |
45+| `mr:force-merge` | bypass failing or unfinished checks with `--ignore-checks` |
4546 | `issue:write` | open, comment on, close and reopen issues |
4647 | `token:admin` | create, list and revoke tokens |
4748 | `ci:write`, `secrets:write`, `runner:register` | reserved for CI |
@@ -50,6 +51,8 @@ A token can never grant more than the token that creates it. `--repo` (repeatabl
5051
5152 `--branch-prefix` (repeatable, up to 8, each ending with `/`, for example `agent/claude/`) limits the branches the token may write; the default is all. A limited token pushes, force-pushes and deletes only `refs/heads/<prefix>…`: any other ref (`main`, tags, notes) refuses the whole push, naming the ref. It cannot create or delete a repository or change its settings (`repo edit`: default branch, visibility, description, merge modes), merges only into branches under its prefixes (and deletes only a source branch under them), never has owner rights, and creates only tokens within its own prefixes. A token for an agent: `ermite token create claude --preset agent --scope repo:read --repo <repo> --branch-prefix agent/claude/`. If you hold such a token, work on a branch under your prefix and open a merge request; do not try `main` or tags.
5253
54+The `agent` preset lacks `mr:force-merge`; adding `--scope mr:merge` lets an agent merge only with passing checks.
55+
5356 ## Merge requests
5457
5558 | Command | Scope | Notes |
@@ -61,10 +64,13 @@ A token can never grant more than the token that creates it. `--repo` (repeatabl
6164 | `mr edit-comment <repo> <n> <comment-id> -m TEXT\|-` | `mr:write` | author only, open merge request; the verdict is unchanged |
6265 | `mr delete-comment <repo> <n> <comment-id>` | `mr:write` | author only; the text is lost, the verdict is kept |
6366 | `mr resolve <repo> <n> <comment-id> [--undo]` | `mr:write` | on the thread root, covers its replies; doing it twice is not an error |
64-| `mr merge <repo> <n> --head <full-id> [--mode fast-forward\|squash\|merge] [--delete-branch]` | `mr:merge` | refused if the branch moved, if `fast-forward` and the target is not an ancestor of the head (behind: use `squash` or `merge`), or if `squash`/`merge` conflict; squash and merge commits are signed by the server key (`signing-key show`); answers once the target moved; `--delete-branch` deletes the source after the merge (refused for the default branch or a branch another open request uses; JSON adds `source_branch_deleted`) |
67+| `mr merge <repo> <n> --head <full-id> [--mode fast-forward\|squash\|merge] [--delete-branch] [--ignore-checks]` | `mr:merge` | refused if the branch moved, if `fast-forward` and the target is not an ancestor of the head (behind: use `squash` or `merge`), or if `squash`/`merge` conflict; squash and merge commits are signed by the server key (`signing-key show`); answers once the target moved; `--delete-branch` deletes the source after the merge (refused for the default branch or a branch another open request uses; JSON adds `source_branch_deleted`) |
6568 | `mr merge <repo> <n> --head <full-id> --auto [--mode M]` / `mr merge <repo> <n> --cancel-auto` | `mr:merge` | the server merges as you once CI settled on the head with a passed check and no failing one; needs `repo edit --allow-auto-merge`; failing checks or conflicts wait with auto-merge on; a new head cancels it, as do a deleted source, a disallowed mode, the setting turned off or your token losing merge rights; a manual merge supersedes it (`merge_request_merged`, `auto=false`, no cancelled event); a manual close clears it (`merge_request_closed` then cancelled with reason `closed`); JSON `auto_merge` (null unless pending), `auto_merged` |
69+| `mr ready <repo> <n>` | `mr:write` | removes the `WIP:` or `[WIP]` title prefix; needs an open draft |
6670 | `mr close <repo> <n>` | `mr:write` | a closed merge request cannot be reopened |
6771
72+A merge needs passing checks on the head: none failed, queued or running. A head with no checks can merge. `mr merge --ignore-checks` bypasses checks, needs `mr:force-merge`, and cannot be combined with `--auto` or `--cancel-auto`.
73+
6874 `ermite mr create` and `ermite mr close` print a confirmation followed by the full
6975 merge request web URL on its own line. With `--json`, merge request objects
7076 (create, show, list, close and merge) include `url` alongside the other fields.
@@ -11,10 +11,10 @@ Errors are one line on standard error (`ermite: ...`) with exit status 1. `--jso
11 | `repo list [--json]` | none | repositories you can see |11 | `repo list [--json]` | none | repositories you can see |
12 | `repo show <name> [--json]` | none | |12 | `repo show <name> [--json]` | none | |
13 | `repo create <name> [--description TEXT] [--visibility public]` | `repo:write` | private by default |13 | `repo create <name> [--description TEXT] [--visibility public]` | `repo:write` | private by default |
14-| `repo edit <name> [--description TEXT] [--visibility V] [--default-branch B] [--merge-modes fast-forward,squash,merge] [--failing-checks-block=false] [--allow-auto-merge]` | `repo:admin` | only the given flags change; every merge mode is allowed by default, list the ones to keep; `--description ""` clears it; the branch must exist |14+| `repo edit <name> [--description TEXT] [--visibility V] [--default-branch B] [--merge-modes fast-forward,squash,merge] [--allow-auto-merge]` | `repo:admin` | only the given flags change; every merge mode is allowed by default, list the ones to keep; `--description ""` clears it; the branch must exist |
15 | `repo delete <name> [--yes]` | `repo:admin` | |15 | `repo delete <name> [--yes]` | `repo:admin` | |
16 16
17-Repository JSON: `name`, `description`, `visibility`, `default_branch`, `created_at`, `pushed_at` (null before the first push), `merge_modes`, `failing_checks_block`, `allow_auto_merge`.17+Repository JSON: `name`, `description`, `visibility`, `default_branch`, `created_at`, `pushed_at` (null before the first push), `merge_modes`, `allow_auto_merge`.
18 18
19 ## Tokens19 ## Tokens
20 20
@@ -28,7 +28,7 @@ Presets add up with `--scope` (repeatable or comma-separated):
28 28
29 | Preset | Scopes |29 | Preset | Scopes |
30 |---|---|30 |---|---|
31-| `cli` | every scope (including `mr:review`), for the owner's daily use; a token created before `mr:review` existed lacks it and loses owner rights: recreate it with `--preset cli` using the root token or from a signed-in owner web session (an old token lacking `mr:review` cannot grant it), then replace the stored CLI secret and revoke the old token |31+| `cli` | every scope, including `mr:review` and `mr:force-merge`, for the owner's daily use |
32 | `agent` | `repo:write`, `mr:write` |32 | `agent` | `repo:write`, `mr:write` |
33 | `ci` | `repo:read` |33 | `ci` | `repo:read` |
34 34
@@ -42,6 +42,7 @@ Scopes:
42 | `mr:write` | open, comment on, reply, edit and delete own notes, resolve, close, mark read |42 | `mr:write` | open, comment on, reply, edit and delete own notes, resolve, close, mark read |
43 | `mr:review` | give a verdict (`--approve`, `--request-changes`) |43 | `mr:review` | give a verdict (`--approve`, `--request-changes`) |
44 | `mr:merge` | merge, and delete the merged source branch with `--delete-branch` |44 | `mr:merge` | merge, and delete the merged source branch with `--delete-branch` |
45+| `mr:force-merge` | bypass failing or unfinished checks with `--ignore-checks` |
45 | `issue:write` | open, comment on, close and reopen issues |46 | `issue:write` | open, comment on, close and reopen issues |
46 | `token:admin` | create, list and revoke tokens |47 | `token:admin` | create, list and revoke tokens |
47 | `ci:write`, `secrets:write`, `runner:register` | reserved for CI |48 | `ci:write`, `secrets:write`, `runner:register` | reserved for CI |
@@ -50,6 +51,8 @@ A token can never grant more than the token that creates it. `--repo` (repeatabl
50 51
51 `--branch-prefix` (repeatable, up to 8, each ending with `/`, for example `agent/claude/`) limits the branches the token may write; the default is all. A limited token pushes, force-pushes and deletes only `refs/heads/<prefix>…`: any other ref (`main`, tags, notes) refuses the whole push, naming the ref. It cannot create or delete a repository or change its settings (`repo edit`: default branch, visibility, description, merge modes), merges only into branches under its prefixes (and deletes only a source branch under them), never has owner rights, and creates only tokens within its own prefixes. A token for an agent: `ermite token create claude --preset agent --scope repo:read --repo <repo> --branch-prefix agent/claude/`. If you hold such a token, work on a branch under your prefix and open a merge request; do not try `main` or tags.52 `--branch-prefix` (repeatable, up to 8, each ending with `/`, for example `agent/claude/`) limits the branches the token may write; the default is all. A limited token pushes, force-pushes and deletes only `refs/heads/<prefix>…`: any other ref (`main`, tags, notes) refuses the whole push, naming the ref. It cannot create or delete a repository or change its settings (`repo edit`: default branch, visibility, description, merge modes), merges only into branches under its prefixes (and deletes only a source branch under them), never has owner rights, and creates only tokens within its own prefixes. A token for an agent: `ermite token create claude --preset agent --scope repo:read --repo <repo> --branch-prefix agent/claude/`. If you hold such a token, work on a branch under your prefix and open a merge request; do not try `main` or tags.
52 53
54+The `agent` preset lacks `mr:force-merge`; adding `--scope mr:merge` lets an agent merge only with passing checks.
55+
53 ## Merge requests56 ## Merge requests
54 57
55 | Command | Scope | Notes |58 | Command | Scope | Notes |
@@ -61,10 +64,13 @@ A token can never grant more than the token that creates it. `--repo` (repeatabl
61 | `mr edit-comment <repo> <n> <comment-id> -m TEXT\|-` | `mr:write` | author only, open merge request; the verdict is unchanged |64 | `mr edit-comment <repo> <n> <comment-id> -m TEXT\|-` | `mr:write` | author only, open merge request; the verdict is unchanged |
62 | `mr delete-comment <repo> <n> <comment-id>` | `mr:write` | author only; the text is lost, the verdict is kept |65 | `mr delete-comment <repo> <n> <comment-id>` | `mr:write` | author only; the text is lost, the verdict is kept |
63 | `mr resolve <repo> <n> <comment-id> [--undo]` | `mr:write` | on the thread root, covers its replies; doing it twice is not an error |66 | `mr resolve <repo> <n> <comment-id> [--undo]` | `mr:write` | on the thread root, covers its replies; doing it twice is not an error |
64-| `mr merge <repo> <n> --head <full-id> [--mode fast-forward\|squash\|merge] [--delete-branch]` | `mr:merge` | refused if the branch moved, if `fast-forward` and the target is not an ancestor of the head (behind: use `squash` or `merge`), or if `squash`/`merge` conflict; squash and merge commits are signed by the server key (`signing-key show`); answers once the target moved; `--delete-branch` deletes the source after the merge (refused for the default branch or a branch another open request uses; JSON adds `source_branch_deleted`) |67+| `mr merge <repo> <n> --head <full-id> [--mode fast-forward\|squash\|merge] [--delete-branch] [--ignore-checks]` | `mr:merge` | refused if the branch moved, if `fast-forward` and the target is not an ancestor of the head (behind: use `squash` or `merge`), or if `squash`/`merge` conflict; squash and merge commits are signed by the server key (`signing-key show`); answers once the target moved; `--delete-branch` deletes the source after the merge (refused for the default branch or a branch another open request uses; JSON adds `source_branch_deleted`) |
65 | `mr merge <repo> <n> --head <full-id> --auto [--mode M]` / `mr merge <repo> <n> --cancel-auto` | `mr:merge` | the server merges as you once CI settled on the head with a passed check and no failing one; needs `repo edit --allow-auto-merge`; failing checks or conflicts wait with auto-merge on; a new head cancels it, as do a deleted source, a disallowed mode, the setting turned off or your token losing merge rights; a manual merge supersedes it (`merge_request_merged`, `auto=false`, no cancelled event); a manual close clears it (`merge_request_closed` then cancelled with reason `closed`); JSON `auto_merge` (null unless pending), `auto_merged` |68 | `mr merge <repo> <n> --head <full-id> --auto [--mode M]` / `mr merge <repo> <n> --cancel-auto` | `mr:merge` | the server merges as you once CI settled on the head with a passed check and no failing one; needs `repo edit --allow-auto-merge`; failing checks or conflicts wait with auto-merge on; a new head cancels it, as do a deleted source, a disallowed mode, the setting turned off or your token losing merge rights; a manual merge supersedes it (`merge_request_merged`, `auto=false`, no cancelled event); a manual close clears it (`merge_request_closed` then cancelled with reason `closed`); JSON `auto_merge` (null unless pending), `auto_merged` |
69+| `mr ready <repo> <n>` | `mr:write` | removes the `WIP:` or `[WIP]` title prefix; needs an open draft |
66 | `mr close <repo> <n>` | `mr:write` | a closed merge request cannot be reopened |70 | `mr close <repo> <n>` | `mr:write` | a closed merge request cannot be reopened |
67 71
72+A merge needs passing checks on the head: none failed, queued or running. A head with no checks can merge. `mr merge --ignore-checks` bypasses checks, needs `mr:force-merge`, and cannot be combined with `--auto` or `--cancel-auto`.
73+
68 `ermite mr create` and `ermite mr close` print a confirmation followed by the full74 `ermite mr create` and `ermite mr close` print a confirmation followed by the full
69 merge request web URL on its own line. With `--json`, merge request objects75 merge request web URL on its own line. With `--json`, merge request objects
70 (create, show, list, close and merge) include `url` alongside the other fields.76 (create, show, list, close and merge) include `url` alongside the other fields.
M skills/ermite/SKILL.md +5 -3
@@ -37,9 +37,11 @@ git push https://git.example.com/<repo>.git main # password = token,
3737 2. Read: `ermite mr show <repo> <n> --diff --json`. Keep `head_id`; take line numbers from the hunks.
3838 3. Comment on a line: `ermite mr comment <repo> <n> -m "text" --path <file> --line <n> --side new`; `--line 10-14` covers a range on one side. Without `--path` the comment is general. The line must appear in the diff. Notes are Markdown; `^N` refers to note N.
3939 4. End a review with a verdict (needs `mr:review`): `--approve` or `--request-changes`, alone or with a message. Verdicts are informative and cannot be edited; a new verdict replaces the previous one.
40-5. Merge only when asked: `ermite mr merge <repo> <n> --head <head_id>`, with `--mode squash` for one commit or `--mode merge` for a merge commit (both signed by the server's key, see `ermite signing-key show`) and `--delete-branch` to delete the source branch afterwards.
40+5. Merge only when the human asks explicitly. If the request is a draft, run `ermite mr ready <repo> <n>` first (removes the `WIP:` or `[WIP]` prefix; needs `mr:write`). Merge: `ermite mr merge <repo> <n> --head <head_id>`, with `--mode squash` for one commit or `--mode merge` for a merge commit (both signed by the server's key, see `ermite signing-key show`) and `--delete-branch` to delete the source branch afterwards.
4141
42-To merge once CI passed instead of now, add `--auto` (`ermite mr merge <repo> <n> --head <head_id> --auto --mode squash`; needs `repo edit --allow-auto-merge`); `--cancel-auto` cancels it.
42+To merge once CI passed automatically, add `--auto` (`ermite mr merge <repo> <n> --head <head_id> --auto --mode squash`; needs `repo edit --allow-auto-merge`); `--cancel-auto` cancels it.
43+
44+A merge needs passing checks on the head (none failed, queued or running); a head with no checks can merge. Never use `--ignore-checks` unless the human asks for it. It needs `mr:force-merge` and cannot be combined with `--auto` or `--cancel-auto`.
4345
4446 The merge is refused when the branch moved since `head_id` (review again) or, for `fast-forward`, when the target is not an ancestor of the head (rebase and push again, or use `squash`/`merge`), or when `squash`/`merge` conflict. `ermite mr show` prints the `mergeability` line (up to date, behind by N, conflict with paths). The repository may allow only some merge modes.
4547
@@ -63,7 +65,7 @@ Open one: `ermite mr create <repo> --source <branch> --title "..."`. After new p
6365 ermite token create my-agent --preset agent --repo <repo> --expires 30d
6466 ```
6567
66-The secret is printed once. Presets: `agent` (push, open and comment on merge requests; no verdicts), `ci` (read), `cli` (everything). Add `--scope mr:review` to let an agent give verdicts, `--scope mr:merge` to let it merge. A token can never grant more than the token that creates it. Full scope list: [CLI.md](CLI.md).
68+The secret is printed once. Presets: `agent` (push, open and comment on merge requests; no verdicts), `ci` (read), `cli` (every scope, including `mr:force-merge`). Add `--scope mr:review` to let an agent give verdicts, `--scope mr:merge` to let it merge only with passing checks. The `agent` preset does not include `mr:force-merge`. A token can never grant more than the token that creates it. Full scope list: [CLI.md](CLI.md).
6769
6870 ## Follow events
6971
@@ -37,9 +37,11 @@ git push https://git.example.com/<repo>.git main # password = token,
37 2. Read: `ermite mr show <repo> <n> --diff --json`. Keep `head_id`; take line numbers from the hunks.37 2. Read: `ermite mr show <repo> <n> --diff --json`. Keep `head_id`; take line numbers from the hunks.
38 3. Comment on a line: `ermite mr comment <repo> <n> -m "text" --path <file> --line <n> --side new`; `--line 10-14` covers a range on one side. Without `--path` the comment is general. The line must appear in the diff. Notes are Markdown; `^N` refers to note N.38 3. Comment on a line: `ermite mr comment <repo> <n> -m "text" --path <file> --line <n> --side new`; `--line 10-14` covers a range on one side. Without `--path` the comment is general. The line must appear in the diff. Notes are Markdown; `^N` refers to note N.
39 4. End a review with a verdict (needs `mr:review`): `--approve` or `--request-changes`, alone or with a message. Verdicts are informative and cannot be edited; a new verdict replaces the previous one.39 4. End a review with a verdict (needs `mr:review`): `--approve` or `--request-changes`, alone or with a message. Verdicts are informative and cannot be edited; a new verdict replaces the previous one.
40-5. Merge only when asked: `ermite mr merge <repo> <n> --head <head_id>`, with `--mode squash` for one commit or `--mode merge` for a merge commit (both signed by the server's key, see `ermite signing-key show`) and `--delete-branch` to delete the source branch afterwards.40+5. Merge only when the human asks explicitly. If the request is a draft, run `ermite mr ready <repo> <n>` first (removes the `WIP:` or `[WIP]` prefix; needs `mr:write`). Merge: `ermite mr merge <repo> <n> --head <head_id>`, with `--mode squash` for one commit or `--mode merge` for a merge commit (both signed by the server's key, see `ermite signing-key show`) and `--delete-branch` to delete the source branch afterwards.
41 41
42-To merge once CI passed instead of now, add `--auto` (`ermite mr merge <repo> <n> --head <head_id> --auto --mode squash`; needs `repo edit --allow-auto-merge`); `--cancel-auto` cancels it.42+To merge once CI passed automatically, add `--auto` (`ermite mr merge <repo> <n> --head <head_id> --auto --mode squash`; needs `repo edit --allow-auto-merge`); `--cancel-auto` cancels it.
43+
44+A merge needs passing checks on the head (none failed, queued or running); a head with no checks can merge. Never use `--ignore-checks` unless the human asks for it. It needs `mr:force-merge` and cannot be combined with `--auto` or `--cancel-auto`.
43 45
44 The merge is refused when the branch moved since `head_id` (review again) or, for `fast-forward`, when the target is not an ancestor of the head (rebase and push again, or use `squash`/`merge`), or when `squash`/`merge` conflict. `ermite mr show` prints the `mergeability` line (up to date, behind by N, conflict with paths). The repository may allow only some merge modes.46 The merge is refused when the branch moved since `head_id` (review again) or, for `fast-forward`, when the target is not an ancestor of the head (rebase and push again, or use `squash`/`merge`), or when `squash`/`merge` conflict. `ermite mr show` prints the `mergeability` line (up to date, behind by N, conflict with paths). The repository may allow only some merge modes.
45 47
@@ -63,7 +65,7 @@ Open one: `ermite mr create <repo> --source <branch> --title "..."`. After new p
63 ermite token create my-agent --preset agent --repo <repo> --expires 30d65 ermite token create my-agent --preset agent --repo <repo> --expires 30d
64 ```66 ```
65 67
66-The secret is printed once. Presets: `agent` (push, open and comment on merge requests; no verdicts), `ci` (read), `cli` (everything). Add `--scope mr:review` to let an agent give verdicts, `--scope mr:merge` to let it merge. A token can never grant more than the token that creates it. Full scope list: [CLI.md](CLI.md).68+The secret is printed once. Presets: `agent` (push, open and comment on merge requests; no verdicts), `ci` (read), `cli` (every scope, including `mr:force-merge`). Add `--scope mr:review` to let an agent give verdicts, `--scope mr:merge` to let it merge only with passing checks. The `agent` preset does not include `mr:force-merge`. A token can never grant more than the token that creates it. Full scope list: [CLI.md](CLI.md).
67 69
68 ## Follow events70 ## Follow events
69 71

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 2

Tags 42

↑↓ moveenter openesc close