Skip to content

g1t/apps/docs/src/content/docs/guides/pull-requests.md

230 lines11,013 bytesCodeBlame
1---
2title: Pull requests and checks
3description: What the merge box shows before a pull request can merge, the checks your workflows report and which ones a merge needs, and conflicts found before anyone tries to merge.
4---
5
6At the foot of an open pull request's conversation, the **merge box** says
7what stands between it and its target branch: its checks, its reviews,
8whether it merges cleanly, and the button that merges it. Everything in it
9updates by itself while something is still running.
10
11## Checks
12
13A pull request's checks are the statuses reported on its head commit. Most
14come from the repository's [workflows](/guides/actions/): every workflow
15that runs on `pull_request` runs on every pull request's head, whoever
16opened it, a person or an agent, and reports a check named after the
17workflow. A workflow named `CI` reports the check `CI`; its status context
18is `CI / pull_request`, the workflow's name and the event it ran for. Other
19parts of g1t report under their own names, such as `g1t / deploy` (or
20`g1t / deploy (<project>)`) for a [deployment](/guides/deployments/).
21
22Which checks a merge needs is up to the repository: its
23[required status checks](#required-status-checks). The merge box lists
24those first:
25
26```text
27Required checks: 1 of 2 passing
28 CI failing Details
29 Lint passing Details
30```
31
32Each required check is **passing**, **failing**, **running**, or
33**expected**, "waiting for status to be reported", when nothing has
34reported it on the head commit yet. **Details** opens the run that
35reported it. Below them are all the other checks, workflow runs job by job,
36each with its state and how long it took. A check that is not required is
37shown, but never holds a merge.
38
39A workflow job's **Details** opens its log on the run's page, where every
40step's output is kept.
41
42### Running them again
43
44People with the Write [role](/guides/access-and-roles/) or higher can press
45**Re-run failed jobs** on a workflow run that failed, to run its failed jobs
46again on the same commit. Every push to the pull request runs its workflows
47again on the new head.
48
49### A repository with no checks
50
51When a repository has no workflows, the merge box says **This repository
52has no checks**: nothing proves a change works, for people or for agents.
53**Add CI** writes a starter workflow for you; see
54[add CI](/guides/actions/#add-ci). The same offer is on the
55**Branches and merging** settings page and the **Actions** page.
56
57## Required status checks
58
59Rules for merging belong to the default branch, since every pull request
60merges into it. Someone with the Maintain [role](/guides/access-and-roles/)
61or higher sets them under the repository's **Settings → Branches and
62merging**, in **Branch protection**:
63
64| Setting | Default | What it does |
65| --- | --- | --- |
66| Require a pull request to change the default branch | Off | Refuses pushes to the default branch; changes reach it only by merging. See [protected branches](/guides/git/#protected-branches). |
67| Required status checks | None | The checks that must pass on a pull request's head before it merges. |
68| Required approvals | None | How many reviewers must approve before a merge, 0 to 3 on the page (up to 6 from the API). A reviewer who asked for changes blocks it. |
69| g1t's approval counts | On | Off means approvals have to come from people. |
70| Require branches to be up to date before merging | Off | On means a pull request behind the default branch has to catch up, and its checks run again, before it merges. |
71| Merge through a queue | Off | See [merge queue](/guides/merge-queue/). |
72| Allow bypassing required checks | On | Lets someone who may merge tick **bypass** when merging, to merge without the required checks passing. Off means nobody can. |
73
74### Choosing the checks
75
76**Required status checks** offers the check names reported on the
77repository's commits in the last 30 days, each with the events it was seen
78for, such as `pull_request` and `merge_group`. Pick from the list, or type a
79name that has not reported yet. A repository can require at most 20.
80
81A required check is met by a status of that name on the pull request's head,
82whatever event reported it:
83
84| What reported it | What the merge does |
85| --- | --- |
86| A status that failed | Refused: "The required check CI failed." |
87| A status still pending | Held: "The required check CI is still running." |
88| Nothing yet | Held: "The required check CI has not reported on this commit yet." |
89| Success | Allowed |
90
91The same rule holds wherever a pull request merges: the merge button,
92[`merge_pull_request`](/reference/api/pull-requests/merge-pull-request/),
93a g1t agent's [automatic merge](/guides/working-with-g1t/#merging-automatically)
94and the [merge queue](/guides/merge-queue/). With **Allow bypassing required
95checks** on, the merge button has a **bypass** box, and the API takes
96`ignore_checks: true`.
97
98A check that only exists once a workflow has run, such as `CI` from a
99workflow added in a pull request, appears in the list after that workflow
100has run once.
101
102### From the API
103
104```sh
105curl https://api.g1t.sh/repos/<workspace>/<repo>/check-names \
106 -H "Authorization: Bearer $G1T_TOKEN"
107```
108
109[`list_check_names`](/reference/api/repositories/list-check-names/)
110returns the names seen in the last 30 days, most recent first, each as
111`{name, events, last_seen}`. It needs the `repo:read` scope.
112
113```sh
114curl -X PATCH https://api.g1t.sh/repos/<workspace>/<repo>/settings \
115 -H "Authorization: Bearer $G1T_TOKEN" \
116 -H "Content-Type: application/json" \
117 -d '{"required_checks": ["CI", "g1t / deploy"]}'
118```
119
120[`update_repo_settings`](/reference/api/repositories/update-repo-settings/)
121takes `required_checks`, which replaces the whole list, along with
122`required_approvals`, `count_agent_approvals`, `require_up_to_date`,
123`merge_queue` and `allow_ignoring_checks`;
124[`get_repo_settings`](/reference/api/repositories/get-repo-settings/)
125returns them. On the MCP server they are the `repository` tool's
126`check_names`, `get_settings` and `update_settings` actions.
127
128## Conflicts
129
130g1t works out whether a pull request merges cleanly into its target before
131anyone tries to merge it, and again whenever either side moves: a push to
132the pull request, or anything landing on the target branch.
133
1341. **Without a sandbox.** g1t compares the files the pull request changed
135 since it and the target last agreed with the files the target changed
136 since then. If they share none, the merge cannot conflict, and that is
137 the answer.
1382. **With a short probe.** If they share files, a sandbox merges the two
139 commits without an agent and pushes nothing, and reports the files that
140 conflict. Meanwhile the box says **Checking whether this merges cleanly**,
141 and the merge button waits. Probes are metered as sandbox time; each
142 pair of commits is probed once, and a repository runs at most
143 three at a time, the rest following in turn.
144
145A pull request that conflicts shows **This branch has conflicts that must
146be resolved**, the conflicting files, each linked to its diff, and three
147ways to resolve them:
148
149- **Resolve with g1t.** g1t merges the target branch in,
150 resolves the conflicts keeping what both sides meant, and pushes the
151 result. It is told which files conflict. Available to whoever can push to
152 the pull request: for a pull request's fork, whoever opened it; for a
153 branch, anyone with the Write role or higher.
154- **Resolve in the browser.** Coming soon.
155- **On the command line.** The box lists the commands, each with a copy
156 button. For a pull request from a branch:
157
158 ```sh
159 git fetch origin
160 git checkout my-branch
161 git merge origin/main
162 # fix each conflicting file, then
163 git add -A && git commit --no-edit
164 git push origin my-branch
165 ```
166
167 For a pull request in its own fork, clone the fork and pull `main` into
168 it instead:
169
170 ```sh
171 git clone https://g1t.sh/pulls/<id>.git && cd <id>
172 git pull --no-rebase https://g1t.sh/<owner>/<repo>.git main
173 ```
174
175While it conflicts, it cannot be merged or added to the
176[merge queue](/guides/merge-queue/), and the merge button says so. Once the
177fix is pushed, g1t works it out again.
178
179A pull request that only has fallen behind its target, without conflicts,
180still merges: merging brings it up to date first, unless the repository
181requires pull requests to be up to date.
182
183## Catching up
184
185When the target branch has moved, the merge box says **main has moved since
186this was made**. Whoever can push to the pull request (whoever opened it,
187for one in its own fork; anyone with the Write [role](/guides/access-and-roles/) or higher,
188for a branch) can
189press **Catch up with main now**:
190
1911. **When the two changed different files**, g1t merges `main` in itself,
192 in a few seconds. The merge commit is named **Merge main into
193 *branch***, has the pull request's head and `main`'s head as its
194 parents, and is authored and pushed as you. The box then says **Brought
195 up to date with main**, and the workflows run again on the
196 new commit, as after any push.
1972. **When both changed some of the same files**, a sandbox merges `main` in
198 with git, and [g1t](/guides/working-with-g1t/) resolves any conflict.
199 The box says what is happening (**g1t is resolving conflicts with
200 main** when the merge is known to conflict) with the run's live step and
201 how long it has taken. It usually takes about a minute. When the result
202 is pushed, the box shows the pull request up to date; if the run fails,
203 or nothing has been pushed after five minutes, the box says so and
204 offers **Try again**. Nothing is pushed by a run that fails.
205
206Either way the merge is pushed only if the pull request's branch is still
207where it was when the catch-up started. If someone pushed to it meanwhile,
208the catch-up stops with nothing lost, and you can press it again.
209
210The second case needs g1t's agent enabled for the workspace and is
211[charged](/guides/usage-and-billing/#what-is-charged) as agent work; the
212first is not.
213
214A pull request [g1t](/guides/working-with-g1t/) opened that is found to conflict
215is sent back to resolve it by itself, before it is ready.
216
217## From the API
218
219`GET /repos/{owner}/{name}/pulls/{number}` returns, besides the pull request:
220
221| Field | What it is |
222| --- | --- |
223| `statuses` | What each workflow run, and anything else that reports statuses, said about its head, with a link to the run. |
224| `required_checks` | Each check the default branch requires, as it stands on the head: `name`, `state` (`success`, `failure`, `pending`, or `expected` when nothing has reported it yet), `description` and `target_url`. Empty when none are required. |
225| `checks` | The latest record against its head from g1t itself, such as the merge queue taking it out, with `earlier_checks` before it. |
226| `mergeable` | `clean`, `conflicting`, `checking` or `unknown`. |
227| `conflicts` | When conflicting, the files that conflict. |
228| `behind` | Whether its target has moved on without it. |
229
230An agent sees the same through the `pull_request` tool's `get` action.