1# Source control
2
3T3 Code integrates with GitHub, GitLab, Forgejo, Gitea, Bitbucket, Azure DevOps, GitCafe, and Cursor
4Origin to clone and publish repositories, create pull requests, and review changes.
5
6## Review turn changes
7
8A turn's changed files and diff show only the turn's own work. When a turn pulls, merges, or
9rebases, the files Git brought in are left out. A file stays in the list when the turn edited it,
10committed it, or fixed a conflict in it. Use the branch comparison to review everything that changed
11against your base branch. Restore still returns the complete saved workspace.
12
13On web and desktop, open the Diff pane source picker and choose **Commits** to review one local
14commit at a time. The list shows the newest 100 commits in the branch comparison. A merge commit
15shows its changes against its first parent.
16
17A commit link from a supported code host opens in the Diff pane when the thread's repository has
18that commit locally, on any branch. Otherwise a pull request commit link opens the pull request. Other
19commit links follow your **Open links in** setting; on web, when that opens a new tab, T3 Code first
20shows an **Open link** button. Command/Ctrl+Click always opens the link in your browser. Commit links follow the **Open pull requests in T3 Code**
21setting in **Settings → Diffs**.
22
23## Connect an account
24
25Install Git and configure authentication on the machine running your T3 Code server. For a remote
26environment, do this on the remote machine. After signing in, open **Settings → Source control**
27and choose **Rescan**.
28
29### GitHub
30
31T3 Code talks to GitHub's API directly and only needs a token. Any of these works, in this
32order of precedence:
33
341. A token saved in **Settings → Source control → GitHub**. It is kept in the server's secret
35 store, and works without the GitHub CLI.
362. `GH_TOKEN` (`GH_ENTERPRISE_TOKEN` with `GH_HOST` for GitHub Enterprise Server) in the
37 server's environment.
383. [GitHub CLI](https://cli.github.com/) 2.81.0 or newer, signed in with `gh auth login`.
39
40If `gh` is signed in to several accounts or hosts, expand **GitHub** in the same place to pick
41the account each host uses or turn a host off. A saved token or `GH_TOKEN` takes precedence
42over that choice; a host turned off stays off either way.
43
44For GitHub Enterprise, sign in with `gh auth login --hostname YOUR_HOST`. T3 Code treats a
45custom server name as GitHub once it has a credential for that host.
46
47### Forgejo and Gitea
48
49Install [Forgejo CLI (`fj`)](https://codeberg.org/forgejo-contrib/forgejo-cli) or
50[Gitea CLI (`tea`)](https://gitea.com/gitea/tea) 0.16 or later on your T3 Code server.
51Sign in with `fj --host https://your-server auth add-token` or `tea login add`.
52Repeat for each server you use, including Codeberg.
53
54T3 Code prefers a matching `fj` login and falls back to `tea` when `fj` is unavailable
55or has no login for that server. Once an account is selected, failed actions stay on that
56account. Settings shows the detected CLI. Forgejo and Gitea share one integration entry.
57Servers hosted under a URL subpath, such as `https://example.com/forgejo`, use `tea` because
58fj 0.6 does not preserve the subpath when checking its account.
59
60When cloning or publishing, use a full repository URL to select a specific server.
61You can use `owner/repo` when only one fj server is configured, or with your default `tea`
62login when fj is unavailable or unconfigured. With multiple fj servers, use the full URL.
63If you have multiple `tea` accounts on one server, select one with
64`tea login default <login-name>`. Git push and clone also need Git credentials or an SSH key
65for that server.
66
67### GitLab
68
69Install [GitLab CLI](https://gitlab.com/gitlab-org/cli), then sign in:
70
71```bash
72glab auth login
73```
74
75### Bitbucket
76
77Open **Settings → Source control**, expand **Bitbucket**, and enter one of:
78
79- **Access token**: a token created for one repository, project, or workspace. It can only reach
80 what it was created for.
81- **Atlassian account email** and **API token**: an Atlassian API token for your account. It can
82 reach every repository you can. Give it read/write access to repositories and pull requests, plus
83 user read access (`read:user:bitbucket`).
84
85A field saves when you leave it, and applies right away. The access token wins when both are saved.
86Credentials are saved on the environment's server, so select a remote environment to configure
87it. Saved tokens can't be viewed again; enter a new one to replace it, or choose **Remove** to clear
88everything saved for Bitbucket.
89
90If no credentials are saved, T3 Code falls back to these variables in the server's environment.
91Restart the server after changing them:
92
93```bash
94export T3CODE_BITBUCKET_ACCESS_TOKEN="your-access-token"
95# or
96export T3CODE_BITBUCKET_EMAIL="you@example.com"
97export T3CODE_BITBUCKET_API_TOKEN="your-token"
98```
99
100For a background service, put these `KEY=VALUE` entries in
101[`service.env`](./background-service.md#configure-the-service-environment)
102under T3 home, then run `t3 service restart`. Service installation and updates
103preserve that file.
104
105### Azure DevOps
106
107Install [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/), add the DevOps extension, and sign in:
108
109```bash
110az extension add --name azure-devops
111az login
112```
113
114### GitCafe
115
116Install the GitCafe CLI and sign in:
117
118```bash
119bun install -g @gitcafe/cli
120cafe auth login --host https://git.cafe/api
121```
122
123Alternatively, open **Settings → Source control**, expand **GitCafe**, and enter a token. It is
124kept in the server's secret store, applies right away, and is used before `CAFE_TOKEN` and the
125`cafe` login. Or set `CAFE_TOKEN` in the server's environment and restart it. Both tokens are only
126sent to `git.cafe`; `CAFE_TOKEN` follows `CAFE_HOST` if you set it. Repositories on
127`staging.git.cafe` need their own login with `--host https://staging.git.cafe/api`.
128
129Line comments are not available for GitCafe pull requests yet.
130Merging a stack lands it through GitCafe, and updating a branch restacks the layers above it.
131
132### Cursor Origin
133
134Install the [Origin CLI](https://cursor.com/docs/origin/cli) and sign in. Signing in also sets up Git
135credentials for `origin.cursor.com`:
136
137```bash
138curl -fsSL https://downloads.cursor.com/origin/install.sh | sh
139origin auth login
140```
141
142If cloning or pushing asks for a username, run `origin auth setup-git` to point Git at the CLI's
143credentials again. Origin repositories use HTTPS and are published privately. Repositories mirrored
144from GitHub keep their pull requests on GitHub; open those from the GitHub remote.
145
146## Start, clone, or publish a project
147
148To start from nothing, choose **New project** in the command palette (`Cmd/Ctrl+K`), or
149**New project** under **Add Project** on any client, and type a name. T3 Code makes a Git
150repository in `~/.t3/projects` (the `projects` folder of your T3 data directory) with a README,
151an icon, and a first commit, then opens a new thread in it. Until the project has a thread, new
152threads work in its folder, even when your default is a new worktree. The folder is named after the project,
153like `pinball-stats` for "Pinball Stats". Turn on **Create private repository on GitHub** to also
154publish it. If Git has no name or email on that machine, the project is created without the
155first commit.
156
157Use **Add Project** in the command palette (`Cmd/Ctrl+K`) to clone a repository. Choose a hosting
158provider or paste a Git URL, then choose where to save it. Only GitHub is listed at first. To list
159another provider here and in **Publish Repository**, turn on its switch under
160**Settings → Source control**. A branch or file page copied from GitHub,
161GitLab, GitCafe, Codeberg or Bitbucket also works: T3 Code clones that repository's default branch.
162On other hosts, paste the repository's clone URL. The project opens right away while the
163clone runs in the background: you can write your first prompt, and sending waits until the files
164are in place. A toast tracks progress and lets you cancel; if the clone fails, retry it from the
165toast or from the banner above the composer. When the host refuses the machine's SSH key, T3 Code
166clones over HTTPS with Git's credentials for that host instead, and the project's remote uses the
167HTTPS URL.
168
169To lay clones out like [ghq](https://github.com/x-motemen/ghq), turn on **Clone into host folders**
170under **Settings → Threads** (or **Source control** on mobile). Clones then default to
171`<host>/<owner>/<repo>` under **Add project starts in**, so set that to `~/ghq` to share ghq's
172folders. You can still change the destination before cloning.
173
174For a local Git repository without a remote, **Publish Repository** creates a hosted repository,
175adds it as `origin`, and pushes your commits. If there are no commits yet, it creates the remote;
176make your first commit before pushing.
177
178## Create a pull request
179
180Use a thread's Git actions to commit, push, and create a pull request. T3 Code can generate commit
181messages, review titles, and descriptions from your changes. Descriptions also draw on the work in
182the thread, including the checks it ran.
183
184An existing fork PR can appear beside the branch even if you pushed without setting an upstream.
185If its badge is missing because several remotes hold that branch, set the branch's upstream to
186the intended remote with `git branch --set-upstream-to=<remote>/<branch>`.
187
188Choose how commit messages and pull request titles and descriptions are written in
189**Settings → Source control → Commits & pull requests**. **Repository conventions** uses the
190project's instructions and recent commit subjects. **Custom instructions** applies your own
191instructions to commits and pull requests.
192
193## Review and merge
194
195Open **Pull requests** to review changes and comments, request reviewers, check out a branch,
196or merge. You can edit review titles and descriptions and your own comments where the host allows it.
197Where you can edit a description, you can also tick its checkboxes from the Summary tab
198(the Overview tab on mobile).
199GitLab calls these merge requests.
200
201A link to part of a pull request opens that part: a comment or review is marked in the activity, a
202changed-line link opens the file at those lines, a checks link opens the checks, and a commit link
203opens that commit's changes. On web and desktop, hovering a comment or commit link previews it.
204
205On mobile, **Pull requests** lists reviews across your connected environments. Open a review
206to read its description, activity, commits, and changed files. Line comments stay as drafts
207until you submit the review. **Work on PR** opens a chat with the review attached; sending
208the first message prepares a worktree from the review's branch.
209
210Previously loaded lists, review details, guides, and diff pages remain readable on mobile
211without a connection, including after restarting the app. Saved content refreshes when the
212environment reconnects; submitting changes requires a connection.
213
214Enable **Remove agent credits when merging** in Settings → Source control to remove recognized
215agent co-author and generated-by lines from GitHub merge and squash commit messages. Human
216co-authors stay credited. The setting is off by default and projects can override it. It also
217applies to auto-merge, but not merge queues or native stack merges. Original commits keep their
218messages, so merge and rebase can still retain agent credits in those commits.
219
220On web and desktop, hold **Shift** in the GitHub pull request list for quick actions.
221To close several, press **Close**, drag across the rows in the same group, and release.
222Press **Escape** before releasing to cancel. Failed closes stay in the list so you can retry them.
223
224GitHub, GitLab, and Azure DevOps support auto-merge while checks are outstanding. GitHub also
225supports approving waiting fork workflows and opening a revert pull request for a merged change.
226
227Pull request sharing is off by default. In Settings → Environments → Pull request sharing (Pull
228request routing under Environments on mobile), choose **Read PRs** or **Read and act** for each
229environment you trust to share its source control access.
230Enable both the original environment and the environment answering its requests on this client.
231**Read and act** can use broader permissions than the original environment's credential;
232only enable it for environments you control and trust. Changing a saved endpoint or removing an
233environment clears its permission.
234
235Review details, linked PR status, and permitted review actions can then use another connected
236environment signed in to the same account on the same host. Each needs a project on that host.
237A connected local environment is preferred for actions and can answer slow or failed reads.
238Browsers and mobile clients need a paired environment to use its GitHub credentials.
239Credentials stay on their machines. Previously verified credentials remain usable for routing
240for ten minutes during a GitHub outage; new credentials must be verified first. An action with
241an uncertain result is never automatically retried elsewhere. Listings, diffs, and checkout or
242PR creation from Git actions continue to use the project's environment.
243
244For Azure DevOps, use the host website to change comments. Bitbucket does not support reopening a
245declined pull request.
246
247### Review guides
248
249Review guides are in beta. Turn on **Review guides** in Settings → Source control to add the
250**Guide** tab to pull requests on that server. On mobile, move between stops with **Next**
251and the back button; a stale guide offers a rewrite and hides excerpts that no longer match
252the current change.
253
254The **Guide** tab gives you a tour of a pull request without reading it line by line: stops
255through the change in reading order. Each stop points at the lines worth reading, and a stop marked
256**Look closely** has a call only a maintainer can make. Mechanical changes such as renames and
257snapshots are grouped at the end, and every changed file appears somewhere on the tour.
258Conversations already resolved in review are left out. For a pull request in a stack, the guide
259covers that layer only, and may point out what a lower layer introduced or what a higher one uses.
260
261Choose **Write guide** to have the review guide model from Settings → Source control read the
262change in a temporary checkout; without one set, the source control writer model is used. Nothing
263in the checkout is changed, and a large pull request takes a few minutes; you can go elsewhere in
264the app. On web, you are told when the guide is ready; on mobile, return to the guide to check
265its progress. Claude and Codex can write guides. The guide is
266kept for everyone using this server. To write it again, for example after a push or after changing
267the model or instructions, choose **Rewrite guide** from the pull request's **⋯** menu.
268
269On web, while reading a stop, select lines in an excerpt to add a comment to your review or ask an agent
270about them; comments wait with the ones from the **Code** tab until you send the review. Choose a
271suggested question, or **Ask about this stop**, to open a thread that already knows which stop you
272are on. **Finish review** on the last stop opens the review with everything you collected.
273
274Agents can write guides too: ask one to prepare guides for a set of pull requests, and it starts
275them for you. Each is read through the project whose checkout has that repository.
276
277To shape guides to your taste, write **Review guide instructions** in Settings → Source control,
278such as what to show first or what to skip; projects can override them. They change emphasis and
279ordering, not the guide's layout or which files it covers.
280
281### Mark files as viewed
282
283Tick a file off in the **Code** tab once you have read it and it collapses; the toolbar keeps a
284running count. A tick belongs to the pull request rather than to a commit, so scoping the tab to a
285single commit keeps them. A file pushed to after you cleared it comes back marked **Changed**.
286
287On GitHub these are GitHub's own viewed marks, so a review carries between T3 Code and github.com
288in either direction. Forgejo, GitLab, Bitbucket, Azure DevOps, and Cursor Origin expose no record
289T3 Code can read, so the server you are connected to keeps them instead: they follow you across the
290apps connected to that server, but the host's own site will not show them, and the count reads **viewed in T3 Code**.
291
292On mobile, open a changed file and mark it viewed from its header. Viewed files collapse,
293and their marks follow the same rules as on web and desktop.
294
295## Troubleshooting
296
297- **Not authenticated:** run the provider's login command on the server, then rescan. For Bitbucket,
298 check the credentials saved in Settings → Source control, or confirm the running server received
299 the environment variables.
300- **GitHub sign-in cannot be verified:** update GitHub CLI to at least 2.81.0, or save a token in Settings → Source control.
301- **Push fails despite a connected account:** check the Git remote's credentials. SSH and HTTPS
302 remotes can require separate setup from the hosting provider's API access.
303- **A review cannot load:** open it on the host website while resolving connectivity, permissions,
304 or rate limits.
305
306## Linked pull requests
307
308A thread can hold several pull requests, including reviews from another repository on the same host.
309Use **Link pull request** in the command palette or **Linked pull requests** panel, or right-click a
310pull request link in the conversation. Creating a pull request from Git actions links it automatically,
311and so does an agent creating one with `gh pr create` or `glab mr create`. Agents can link other
312pull requests with the `link_pull_request` tool.
313
314Use **Link pull request to thread** in the command palette to keep a pull request with the thread. From a review
315on the Pull requests page, **Link to thread** lets you search for an active thread. The review header
316also lists the threads that link to it, including archived threads, so you can return to their context.
317
318Thread badges show a stack's layer count or the current review number with a count of additional
319links. Clicking a badge with more than one review opens the **Linked pull requests** panel. On mobile, the Git overview lists linked reviews and their stacks; tap a review to open it.
320Linking and unlinking are available in the web and desktop clients.
321
322The **Linked pull requests** panel lists every review and groups stacks. Unlink a review from its
323row menu. An unlinked stack layer stays out of later syncs. Open linked reviews refresh on the server;
324closed reviews refresh periodically so reopening one on the host is detected. Merged reviews refresh
325when requested. Settling a thread refreshes its open and closed reviews once; after that they stop refreshing until you unsettle it. With **Auto-settle merged threads** enabled, a thread can settle after every linked
326review is terminal. An open or unsynced link keeps it active.
327
328Ask the agent to watch, monitor, or babysit a pull request and it calls `watch_pull_request`. While
329the thread is active, the server checks the pull request every two minutes and wakes the agent when a
330check fails or waits for a maintainer's approval, the required checks pass, someone else comments or reviews, or the branch starts to
331conflict. On github.com it also wakes the agent, with GitHub's reason, when the merge queue drops
332the pull request without merging it. Threads in a project that watch the same pull request share one check. On GitHub, a check
333first asks whether anything changed and reads the pull request only when it did, which keeps
334watching inside GitHub's rate limit. Comments from your own account do not wake it. Watching ends
335when the pull request merges or closes, after 10 wakes in a row that bring only comments, after 8
336failed reads in a row, or when you press Stop on the thread. A rate limit only pauses watching.
337Settling or archiving a thread also ends all its watches. Unsettle the thread before starting a new
338watch. Watching a pull request again does not repeat check or conflict news its last
339watch already reported; unlinking the pull request clears that. Subagents cannot watch pull requests; the thread that delegated to them does. To start or stop
340it yourself, use the row menu in the **Linked pull requests** panel. In the thread details card, a
341watched pull request shows an eye; click it to stop watching.
342
343A watched thread counts as working while the pull request still has checks running, so it stays in
344the **Working** section, including after the agent pushes a fix. Once every check has finished,
345including review bots that report as checks, the thread returns to your inbox: what happens next is
346up to a person. That includes a workflow waiting for a maintainer to approve it, which runs only
347once someone does. The watch stays on and still wakes the agent on new comments, failed checks or
348conflicts, and a watched thread never auto-settles.
349
350Cross-repository links use a project on the same host. Azure DevOps reviews require a project checked
351out from the matching organization and repository.
352
353## GitHub stacks
354
355The Pull requests page shows each PR's position in its GitHub stack. Open the stack badge in a
356review to navigate its layers. **Merge stack** submits the selected pull request and every unmerged
357layer below it to GitHub together, respecting branch rules and merge queues. The confirmation shows
358the scope and merge strategy. GitHub rebases the remaining stack after merging.
359
360**Rebase stack** updates remote branches from bottom to top without changing your local checkout.
361It can rewrite history and restart checks. If a layer fails, earlier updates remain; resolve that
362layer before retrying. GitHub may require manual conflict resolution after a lower layer is amended,
363even when its changes look independent. Stack actions require an environment that supports them.