Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

g1t.sh

Commit

Merge branch 'g1t-cli'

syntaqxcommitted Parents6a3e03e2de9c5dBrowse files
50 files+19194−3164 files not counted0/50 viewed
+1−1
145145 - name: Check and test
146146 run: cargo test --locked --manifest-path apps/desktop/src-tauri/Cargo.toml --quiet
147147 - name: The release scripts' tests
148− run: node --test scripts/desktop-release.test.mjs scripts/mobile-release.test.mjs
148+ run: node --test scripts/desktop-release.test.mjs scripts/mobile-release.test.mjs scripts/cli-release.test.mjs
+87−0
1+# Releases the g1t CLI (crates/g1t): builds it for Linux and macOS on x64
2+# and arm64 and for Windows on x64, signs the release, and publishes it to
3+# g1t.sh/downloads/cli/ (the g1t-downloads R2 bucket), where g1t.sh/install
4+# and g1t.sh/install.ps1 find it.
5+#
6+# A release is a tag `cli-v<version>`, where the version is the one in
7+# crates/g1t/Cargo.toml; or run it by hand. scripts/cli-release.mjs does the
8+# work, and its header says what a release holds. It is signed with the
9+# runner's release key (RUNNER_RELEASE_KEY, RUNNER_RELEASE_PUBLIC_KEY).
10+#
11+# Every platform builds in one job, in the rust-cross/cargo-zigbuild image:
12+# the macOS builds link Apple's Security framework (the keychain), and that
13+# image carries its SDK. It runs on g1t's own machines (g1t-4core), whose
14+# jobs have a Docker Engine of their own.
15+name: CLI release
16+
17+on:
18+ push:
19+ tags: ["cli-v*"]
20+ workflow_dispatch:
21+
22+permissions:
23+ contents: read
24+
25+concurrency:
26+ group: cli-release
27+ cancel-in-progress: false
28+
29+env:
30+ CLOUDFLARE_ACCOUNT_ID: ${{ vars.CLOUDFLARE_ACCOUNT_ID }}
31+ WRANGLER_SEND_METRICS: "false"
32+
33+jobs:
34+ build:
35+ name: Build every platform
36+ runs-on: g1t-4core
37+ timeout-minutes: 60
38+ steps:
39+ - uses: actions/checkout@v5
40+ - name: The tag names this version
41+ if: startsWith(github.ref, 'refs/tags/cli-v')
42+ run: |
43+ version="$(sed -n 's/^version = "\(.*\)"/\1/p' crates/g1t/Cargo.toml | head -1)"
44+ [ "cli-v$version" = "${GITHUB_REF_NAME}" ] || { echo "::error::The tag is ${GITHUB_REF_NAME}, but crates/g1t is $version"; exit 1; }
45+ - name: Build
46+ run: node scripts/cli-release.mjs build
47+ - uses: actions/upload-artifact@v4
48+ with:
49+ name: cli
50+ path: target/cli-release/
51+ overwrite: true
52+
53+ publish:
54+ name: Sign and publish
55+ needs: build
56+ runs-on: ubuntu-latest
57+ # Production's secrets, without a deployment: a release is not a deploy
58+ # of g1t.sh.
59+ environment:
60+ name: production
61+ deployment: false
62+ timeout-minutes: 30
63+ steps:
64+ - uses: actions/checkout@v5
65+ - uses: actions/download-artifact@v4
66+ with:
67+ name: cli
68+ path: target/cli-release
69+ - name: Sign
70+ env:
71+ RUNNER_RELEASE_KEY: ${{ secrets.RUNNER_RELEASE_KEY }}
72+ G1T_RUNNER_RELEASE_KEY: ${{ vars.RUNNER_RELEASE_PUBLIC_KEY }}
73+ run: |
74+ node scripts/cli-release.mjs sign
75+ node scripts/cli-release.mjs verify
76+ - name: Cache npm's downloads
77+ uses: actions/cache@v4
78+ with:
79+ path: ~/.npm
80+ key: npm-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
81+ restore-keys: npm-${{ runner.os }}-
82+ - name: Install Wrangler
83+ run: npm ci --prefer-offline --workspaces=false --no-audit --no-fund
84+ - name: Publish to g1t.sh/downloads/cli
85+ env:
86+ CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
87+ run: node scripts/cli-release.mjs publish
+11−0
128128 `.g1t/workflows/runner-release.yml` builds, signs and publishes it, and
129129 runners update themselves to it. `scripts/runner-release.mjs` does the
130130 same by hand.
131+- **The g1t CLI** is released the same way: bump `version` in
132+ `crates/g1t/Cargo.toml`, merge, and push a `cli-v<version>` tag.
133+ `.g1t/workflows/cli-release.yml` builds it for every platform, signs
134+ the release with the runner's release key and publishes it to
135+ g1t.sh/downloads/cli/, where g1t.sh/install and g1t.sh/install.ps1
136+ find it. `scripts/cli-release.mjs` does the same by hand. The command
137+ reference in the docs is generated from the CLI
138+ (`G1T_WRITE_DOCS=1 cargo test -p g1t cli_reference`), and its table of
139+ API operations from the OpenAPI document
140+ (`G1T_WRITE_OPS=1 cargo test -p g1t ops_table`); tests fail when either
141+ falls behind. The guide is [The g1t CLI](https://docs.g1t.sh/guides/cli/).
131142 - **The desktop app** is released the same way: bump `version` in
132143 `apps/desktop/src-tauri/Cargo.toml`, merge, and push a
133144 `desktop-v<version>` tag. `.g1t/workflows/desktop-release.yml` builds
+1033−15
A large diff (1,467 lines) is not shown until you ask for it.
+2−0
8181 items: [
8282 { label: 'Quickstart', slug: 'quickstart' },
8383 { label: 'How g1t works', slug: 'concepts/overview' },
84+ { label: 'The g1t CLI', slug: 'guides/cli' },
8485 { label: 'Home', slug: 'guides/home' },
8586 { label: 'Notifications', slug: 'guides/notifications' },
8687 { label: 'The desktop app', slug: 'guides/desktop' },
208209 items: [
209210 { label: 'API overview', slug: 'reference/api' },
210211 { label: 'MCP tools', slug: 'reference/mcp' },
212+ { label: 'CLI commands', slug: 'reference/cli' },
211213 { label: 'Rate limits', slug: 'reference/rate-limits' },
212214 { label: 'Try it in the explorer', link: '/api/reference/', attrs: { target: '_self' } },
213215 { label: 'OpenAPI document', link: 'https://api.g1t.sh/openapi.json' },
+440−0
1+---
2+title: The g1t CLI
3+description: Install the g1t command line, sign in, and work with repositories, issues, pull requests, runs, deployments, secrets and logs from a terminal, a script or an agent.
4+---
5+
6+`g1t` is the command line for g1t. It does the work you would otherwise do on
7+the site: open and review pull requests, wait on checks, read a failing run's
8+logs, set secrets, read a project's logs, and call any operation of the
9+[API](/reference/api/). It is one file with nothing to install alongside it,
10+and it is built to be run by agents as much as by people: every command can
11+print JSON, nothing waits for input unless a person is at the terminal, and
12+exit codes say what happened.
13+
14+```sh
15+g1t issue list --label bug
16+g1t pr create --fill
17+g1t pr checks --watch --fail-fast
18+g1t run logs --failed
19+```
20+
21+Every command and flag is listed in the [command reference](/reference/cli/).
22+
23+## Install
24+
25+On Linux or macOS:
26+
27+```sh
28+curl -fsSL https://g1t.sh/install | sh
29+```
30+
31+On Windows, in PowerShell:
32+
33+```powershell
34+irm https://g1t.sh/install.ps1 | iex
35+```
36+
37+The script picks the build for your system, checks it against the
38+release's `SHA256SUMS`, and puts `g1t` in `~/.local/bin` (Windows:
39+`%LOCALAPPDATA%\g1t\bin`, which it adds to your `PATH`). Set
40+`G1T_INSTALL_DIR` to put it elsewhere, or `G1T_VERSION` to install a
41+version other than the latest. Run it again to update.
42+
43+### Without the script
44+
45+Each release is a single file per platform, at
46+`https://g1t.sh/downloads/cli/latest/`:
47+
48+| Platform | File |
49+| --- | --- |
50+| Linux, x64 | `g1t-linux-x64` |
51+| Linux, ARM | `g1t-linux-arm64` |
52+| macOS, Apple silicon | `g1t-macos-arm64` |
53+| macOS, Intel | `g1t-macos-x64` |
54+| Windows, x64 | `g1t-windows-x64.exe` |
55+
56+```sh
57+curl -fsSLo g1t https://g1t.sh/downloads/cli/latest/g1t-linux-x64
58+chmod +x g1t && mv g1t ~/.local/bin/
59+```
60+
61+Check a download against `https://g1t.sh/downloads/cli/latest/SHA256SUMS`.
62+`latest.json` beside it names the version and each file's SHA-256, and
63+`latest.json.sig` is its signature. A given version's files are at
64+`/downloads/cli/<version>/` and never change.
65+
66+To build it from source, with [Rust](https://www.rust-lang.org/tools/install):
67+
68+```sh
69+git clone https://g1t.sh/flagon-io/g1t
70+cargo install --path g1t/crates/g1t
71+```
72+
73+`g1t --version` prints the version you have.
74+
75+## Sign in
76+
77+```sh
78+g1t auth login
79+```
80+
81+`g1t` shows a one-time code and opens your browser at
82+[g1t.sh/device](https://g1t.sh/device). Sign in there if you are not
83+already, check the code matches, and approve. The command finishes on its
84+own once you have. Where there is no browser (a server, a container, a
85+remote shell), it prints the link instead: open it on any device.
86+
87+To use an [access token](/guides/authentication/#access-tokens) you already
88+have, pipe it in:
89+
90+```sh
91+g1t auth login --with-token < token.txt
92+```
93+
94+The token is kept in your system's credential store: the Keychain on
95+macOS, Credential Manager on Windows, the Secret Service on Linux. Where
96+there is none, as on most servers, it goes in the [config
97+file](#settings-and-environment), readable only by you; `--insecure-storage`
98+puts it there on purpose.
99+
100+| Command | What it does |
101+| --- | --- |
102+| `g1t auth status` | Each account you are signed in as, on each host, whether its token still works, and its scopes. Exits `4` when the active account's token does not work. |
103+| `g1t auth token` | Prints the token in use, for another program. |
104+| `g1t auth logout` | Forgets an account's token. |
105+| `g1t auth switch` | Makes another signed-in account on the same host the active one. |
106+
107+### G1T_TOKEN
108+
109+When `G1T_TOKEN` is set, every command uses it instead of a stored token.
110+This is how to give `g1t` a token in containers, in agents' sandboxes, and
111+in [workflows](/guides/actions/), where the job's own token is
112+`secrets.G1T_TOKEN`:
113+
114+```yaml
115+- run: g1t pr comment ${{ github.event.pull_request.number }} -b "Preview is up."
116+ env:
117+ G1T_TOKEN: ${{ secrets.G1T_TOKEN }}
118+```
119+
120+### Self-hosted g1t
121+
122+`g1t` works with any g1t, not only g1t.sh. Sign in to yours with its
123+address:
124+
125+```sh
126+g1t auth login --hostname git.example.com
127+```
128+
129+`g1t` asks it where its API is (its `/.well-known/g1t.json`), and remembers.
130+After that, commands in a clone of one of its repositories talk to it on
131+their own. Elsewhere, name it with `--hostname` or `G1T_HOST`; the first host
132+you sign in to is the default. You can be signed in to several hosts, and
133+as several accounts on each.
134+
135+## Use it with git
136+
137+```sh
138+g1t auth setup-git
139+```
140+
141+This makes `g1t` git's credential helper for each host you are signed in
142+to, so `git push`, `git fetch` and `git clone` over HTTPS use the same
143+token, with nothing more to type. It changes your global git config only for
144+those hosts' addresses (`credential.https://g1t.sh.helper`). `g1t auth login
145+--git` does both at once. To see the config lines without changing anything,
146+add `--dry-run`.
147+
148+[`g1t push`](/guides/containers/#push-large-layers-with-g1t-push), which sends container
149+images to g1t's registry, uses the same signed-in token.
150+
151+## Which repository
152+
153+Commands about a repository work on the one the current directory is a
154+clone of, found from its git remotes: `upstream` if it is on g1t, then
155+`origin`, then the first one that is. In a pull request's own [working
156+copy](/guides/pull-requests/), they work on the repository the pull request
157+is for.
158+
159+Anywhere else, or to choose another, pass `--repo` (`-R`), or set
160+`G1T_REPO`:
161+
162+```sh
163+g1t issue list -R acme/web
164+g1t pr view 14 -R git.example.com/acme/web
165+```
166+
167+## Everyday work
168+
169+### Issues
170+
171+```sh
172+g1t issue list # open issues, newest first
173+g1t issue list --label bug --assignee @me
174+g1t issue view 12 --comments
175+g1t issue create -t "Greeting should name the caller" -b "Take a name from the first argument."
176+g1t issue comment 12 -b "Fixed in #14."
177+g1t issue edit 12 --add-label p1 --add-assignee @me
178+g1t issue close 12 --reason not_planned
179+```
180+
181+`@me` is you. At a terminal, `g1t issue create` without `--title` asks for
182+one and opens your editor for the body.
183+
184+### Pull requests
185+
186+From a branch with your commits on it:
187+
188+```sh
189+git switch -c greet-by-name
190+# ...commit...
191+g1t pr create --fill --issue 12
192+```
193+
194+`g1t pr create` pushes the branch, then opens the pull request into the
195+default branch (`--base` for another). `--fill` takes the title and body from
196+the branch's commits; `--issue` says which issue it is for; `--draft` opens
197+it as a draft.
198+
199+To start a pull request for an issue without a branch of your own, as g1t's
200+agents do, run it with `--issue` from the default branch. g1t opens a draft
201+with a [working copy](/guides/pull-requests/) of its own and prints the
202+copy's git remote. Push your commits there, then mark it ready with a
203+summary of what changed and why:
204+
205+```sh
206+g1t pr create --issue 12
207+git push https://g1t.sh/pulls/pr_….git HEAD:main
208+g1t pr ready --summary "Reads a name from the first argument."
209+```
210+
211+Then, for any pull request:
212+
213+```sh
214+g1t pr list
215+g1t pr view 14 # the current branch's when left out
216+g1t pr diff 14
217+g1t pr checkout 14 # check its head out locally
218+g1t pr checks 14 --watch
219+g1t pr review 14 --approve -b "Reads well."
220+g1t pr review 14 --request-changes -b "Trim the name first."
221+g1t pr merge 14 --delete-branch
222+```
223+
224+`g1t pr merge` merges the way the repository is set to, once
225+[required checks](/guides/checks/) pass and [rules](/guides/rules/) allow;
226+`--admin` merges past them, with the Admin role.
227+
228+### Checks and runs
229+
230+`g1t pr checks` lists a pull request's checks: g1t Actions jobs, check runs
231+and commit statuses. With `--watch` it waits until they have all finished,
232+redrawing at a terminal and printing a line per change when piped.
233+`--fail-fast` stops at the first failure instead of waiting for the rest. It
234+exits `0` when every check passed, `1` when one failed, and, without
235+`--watch`, `8` while any are still running.
236+
237+```sh
238+g1t run list --branch main
239+g1t run view # the current branch's latest run
240+g1t run watch run_01kpx7b3c6d9e2f5g8h1j4k7mr
241+g1t run logs --failed
242+g1t run rerun --failed
243+```
244+
245+A run is named by its id (`run_…`), its number, or its address; left out,
246+it is the current branch's latest. `g1t run logs --failed` prints only the
247+steps that failed, each with its last 60 lines (`-n` for more or fewer):
248+what you need to see why, without the rest of the log. `g1t run watch`
249+exits `1` if the run fails.
250+
251+### Deployments, logs and secrets
252+
253+```sh
254+g1t deploy list --env production
255+g1t deploy view dep_01kq8m3t5v7x9z1b3d5f7h9k2m
256+
257+g1t logs --since 1h --level error,fatal
258+g1t logs -q '"payment failed"' --follow
259+g1t logs --errors --state open
260+
261+g1t secret list
262+echo "$NPM_TOKEN" | g1t secret set NPM_TOKEN
263+g1t secret set STRIPE_KEY --env production < stripe-key.txt
264+g1t secret set NPM_TOKEN --brokered-host registry.npmjs.org < npm-token.txt
265+g1t secret delete STRIPE_KEY --env preview
266+g1t secret list --workspace acme
267+```
268+
269+`g1t logs` reads the [observability](/guides/observability/) data of the
270+current repository's project, or of `--project WORKSPACE/SLUG`. A secret's
271+value is read from stdin, so it stays out of your shell's history; at a
272+terminal with nothing piped, `g1t` asks for it without echoing. Values are
273+never printed. `--brokered-host` makes it a [brokered
274+secret](/guides/secrets-and-variables/#brokered-secrets).
275+
276+### What needs you
277+
278+```sh
279+g1t status
280+```
281+
282+Your open pull requests and their checks, reviews asked of you, what is
283+assigned to you, and failing checks, across every repository you can see.
284+
285+## Scripting with JSON
286+
287+Every command takes `--json`. Alone, it prints every field the API returns;
288+with a comma-separated list, only those:
289+
290+```sh
291+g1t pr list --json number,title,check_status
292+```
293+
294+```json
295+[{"check_status":"passed","number":14,"title":"Greeting should name the caller"}]
296+```
297+
298+The fields are the API's own, named as in the [API reference](/reference/api/)
299+and always `snake_case`. A field that does not exist is an error that lists
300+the ones that do. Piped, JSON is one compact line with its keys in a fixed
301+order, so the same input gives the same output; at a terminal it is
302+indented.
303+
304+`--jq` runs a [jq](https://jqlang.org/manual/) expression over the JSON,
305+with nothing else to install. Strings come out bare, everything else as
306+JSON:
307+
308+```sh
309+g1t pr list --jq '.[] | select(.check_status == "failed") | .number'
310+g1t run list --jq '.[] | [.id, .conclusion] | @tsv'
311+```
312+
313+Without `--json`, output piped to another program is one record per line,
314+fields separated by tabs, with no header and no color, ready for `cut`,
315+`awk` or `while read`. Lists show 20 entries unless `--limit` (`-L`) says
316+otherwise.
317+
318+### Exit codes
319+
320+| Code | Meaning |
321+| --- | --- |
322+| `0` | It worked. |
323+| `1` | It failed: the API refused it, the network failed, checks or a run failed. |
324+| `2` | The command was used wrongly: an unknown flag, a missing argument, a JSON field that does not exist. |
325+| `4` | Signing in is needed, or the token was refused. |
326+| `8` | Checks are still running (`g1t pr checks` without `--watch`). |
327+
328+An error is one line on stderr, starting `g1t:`. When a token lacks a
329+[scope](/guides/authentication/#scopes) the call needs, the line names it.
330+
331+### No questions when piped
332+
333+`g1t` asks for a missing title, opens an editor for a body, or offers a
334+choice only when stdin and stderr are both a terminal. Anywhere else, and
335+whenever `G1T_PROMPT_DISABLED` is set, a command missing something fails at
336+once with exit code `2` and names the flag that supplies it.
337+
338+## Call any operation
339+
340+`g1t api` calls any operation of the [API](/reference/api/) by its name,
341+with your token, and fills the repository in from where you are:
342+
343+```sh
344+g1t api list_issues -f state=closed --jq '.[].title'
345+g1t api create_label -f name=p1 -f color=d73a4a
346+g1t api get_workflow_run -f id=run_01kpx7b3c6d9e2f5g8h1j4k7mr
347+g1t api --list label # the operations about labels
348+```
349+
350+A path works too, with `{owner}`, `{name}` and `{workspace}` filled in:
351+
352+```sh
353+g1t api /repos/{owner}/{name}/labels
354+g1t api user --jq .username
355+```
356+
357+`-f key=value` sends a string, `-F key=value` sends `true`, `false`, `null`
358+and numbers as JSON and `@file` as a file's contents, and `key[]=value` adds
359+to a list. Fields go in the query of a `GET` and in the JSON body otherwise.
360+`-X` sets the method, `-H` adds a header, and `--input file` sends a file as
361+the body. `--paginate` follows each next page, and with `--slurp` puts every
362+page's items in one array. A request the API refuses prints its error body
363+and exits `1`.
364+
365+In Git Bash on Windows, an argument starting with `/` is turned into a
366+Windows path before `g1t` sees it: leave the leading slash off
367+(`g1t api repos/{owner}/{name}`), or set `MSYS_NO_PATHCONV=1`.
368+
369+## From agents and harnesses
370+
371+An agent with a shell, such as Claude Code, Codex or Cursor, can use `g1t`
372+the way you do. A command and its JSON cost an agent less of its context
373+than a set of tool definitions, and the agent finds what it needs with
374+`--help`. For clients without a shell, use the [MCP server](/reference/mcp/).
375+
376+1. Install `g1t` where the agent runs, as [above](#install).
377+2. Give it a token. Either sign in once with `g1t auth login` as the user
378+ the agent runs as, or set `G1T_TOKEN` in its environment. Make a token
379+ with only the [scopes](/guides/authentication/#scopes) it needs.
380+3. Tell it `g1t` is there. A few lines in the project's `CLAUDE.md` or
381+ `AGENTS.md` are enough:
382+
383+```md
384+This repository is on g1t. Use the `g1t` CLI for issues, pull requests,
385+checks and runs; add `--json` to read results, and see `g1t <command> --help`.
386+
387+- Open a pull request: `g1t pr create --fill --issue <n>`
388+- Wait for checks: `g1t pr checks --watch --fail-fast` (exit 0 passed, 1 failed)
389+- See why a run failed: `g1t run logs --failed`
390+- Anything else: `g1t api --list <word>`, then `g1t api <operation>`
391+```
392+
393+`g1t` never waits for input in an agent's shell, since its stdin is not a
394+terminal. Its JSON is compact and in a stable order, its lists are short
395+by default, and `g1t pr checks --watch --fail-fast` and `g1t run logs
396+--failed` give an agent the one thing it is waiting for, and no more.
397+
398+## Aliases and completion
399+
400+An alias is a shortcut for a command you type often. `$1`, `$2`… take the
401+arguments after it, and the rest go on the end:
402+
403+```sh
404+g1t alias set bugs 'issue list --label bug'
405+g1t alias set co 'pr checkout'
406+g1t alias set mine '!g1t pr list --author @me --json number,title'
407+g1t bugs --limit 5
408+```
409+
410+An alias starting with `!` runs in `sh`. `g1t alias list` lists them, and
411+`g1t alias delete` removes one.
412+
413+`g1t completion <shell>` prints a completion script for `bash`, `zsh`,
414+`fish`, `powershell` or `elvish`:
415+
416+```sh
417+g1t completion bash > ~/.local/share/bash-completion/completions/g1t
418+g1t completion zsh > "${fpath[1]}/_g1t"
419+g1t completion fish > ~/.config/fish/completions/g1t.fish
420+g1t completion powershell >> $PROFILE
421+```
422+
423+## Settings and environment
424+
425+`g1t` keeps the hosts you are signed in to, their accounts and your aliases
426+in `config.json`, in `~/.config/g1t` (`%APPDATA%\g1t` on Windows;
427+`$XDG_CONFIG_HOME/g1t` when that is set).
428+
429+| Variable | |
430+| --- | --- |
431+| `G1T_TOKEN` | A token to use instead of the stored one. |
432+| `G1T_HOST` | The host to use when no repository names one. |
433+| `G1T_REPO` | The repository, as `[HOST/]OWNER/NAME`. |
434+| `G1T_CONFIG_DIR` | Where to keep `config.json`. |
435+| `G1T_KEYRING` | `off` keeps tokens out of the system's credential store. |
436+| `G1T_PROMPT_DISABLED` | Never ask anything. |
437+| `G1T_EDITOR`, `VISUAL`, `EDITOR` | The editor for bodies and summaries. |
438+| `G1T_BROWSER`, `BROWSER` | The browser `--web` and `g1t browse` open. |
439+| `NO_COLOR` | Plain output at a terminal too. |
440+| `G1T_DEBUG` | Print each request's method, address and status on stderr. |
+8−17
178178 1. a token on stdin, with `--token-stdin`
179179 (`echo "$G1T_TOKEN" | g1t push … --token-stdin`);
180180 2. the `G1T_TOKEN` environment variable, as in [workflows](#in-workflows);
181−3. what `docker login g1t.sh` stored, in `~/.docker/config.json` or the
181+3. the account [`g1t auth login`](/guides/cli/#sign-in) signed in to on the
182+ registry's host;
183+4. what `docker login g1t.sh` stored, in `~/.docker/config.json` or the
182184 credential store it names.
183185
184186 | Option | |
192194
193195 ### Getting g1t
194196
195−One file for each platform, from `https://g1t.sh/downloads/cli/latest/`:
197+`g1t push` is part of the [g1t CLI](/guides/cli/). Install it with one line:
196198
197199 ```sh
198−# Linux (x64; use g1t-linux-arm64 on ARM)
199−curl -fsSLo g1t https://g1t.sh/downloads/cli/latest/g1t-linux-x64 && chmod +x g1t
200−# macOS (Apple silicon; use g1t-macos-x64 on Intel)
201−curl -fsSLo g1t https://g1t.sh/downloads/cli/latest/g1t-macos-arm64 && chmod +x g1t
200+curl -fsSL https://g1t.sh/install | sh
202201 ```
203202
204203 ```powershell
205−# Windows
206−Invoke-WebRequest https://g1t.sh/downloads/cli/latest/g1t-windows-x64.exe -OutFile g1t.exe
204+irm https://g1t.sh/install.ps1 | iex
207205 ```
208206
209−Check a download against `https://g1t.sh/downloads/cli/latest/SHA256SUMS`.
210−To build it from source instead, with
211−[Rust](https://www.rust-lang.org/tools/install):
212−
213−```sh
214−git clone https://g1t.sh/flagon-io/g1t
215−cd g1t
216−cargo install --path crates/g1t
217−```
207+[Installing the CLI](/guides/cli/#install) covers the single-file downloads,
208+checking them, and building it from source.
218209
219210 ## Storage and pull limits
220211
+867−0
1+---
2+title: CLI commands
3+description: Every g1t command with its arguments and flags, written from the CLI's own definitions.
4+---
5+
6+<!-- Generated from crates/g1t by `G1T_WRITE_DOCS=1 cargo test -p g1t cli_reference`. Do not edit by hand. -->
7+
8+Every command of the [g1t CLI](/guides/cli/), with its arguments and flags.
9+`g1t <command> --help` prints the same at a terminal. Each command that talks
10+to the API names the operations it calls, which link to the
11+[API reference](/reference/api/); [`g1t api`](#g1t-api) calls any other.
12+
13+## Flags every command takes
14+
15+| Flag | |
16+| --- | --- |
17+| `-R, --repo <[HOST/]OWNER/NAME>` | The repository, as [HOST/]OWNER/NAME, instead of the current directory's. |
18+| `--hostname <HOST>` | The g1t host, such as g1t.sh or git.example.com. |
19+| `--json [FIELDS]` | Print JSON: every field, or only the comma-separated FIELDS. |
20+| `--jq <EXPRESSION>` | Run a jq expression over the JSON and print what it gives. |
21+
22+## g1t auth
23+
24+Sign in, sign out, and set git up to use g1t's credentials.
25+
26+### g1t auth login
27+
28+Sign in to a g1t host.
29+
30+```text
31+g1t auth login [OPTIONS]
32+```
33+
34+| Argument or flag | |
35+| --- | --- |
36+| `--with-token` | Read a token from stdin instead of approving in the browser. |
37+| `--insecure-storage` | Keep the token in the config file, not the system keychain. |
38+| `--no-browser` | Do not open the browser; just print the link. |
39+| `--git` | Also set git up to use g1t's credentials (see `g1t auth setup-git`). |
40+
41+```text
42+Without --with-token, g1t shows a code and a link; approve it in the browser, signed in.
43+With --with-token, the token is read from stdin:
44+ g1t auth login --with-token < token.txt
45+```
46+
47+Calls [`device_code`](/reference/api/accounts/device-code/), [`device_token`](/reference/api/accounts/device-token/), [`whoami`](/reference/api/accounts/whoami/).
48+
49+### g1t auth logout
50+
51+Sign out of an account on a host.
52+
53+```text
54+g1t auth logout [OPTIONS]
55+```
56+
57+| Argument or flag | |
58+| --- | --- |
59+| `-u, --user <USER>` | The account, when more than one is signed in on the host. |
60+
61+### g1t auth status
62+
63+Show which accounts are signed in, and whether their tokens work.
64+
65+```text
66+g1t auth status [OPTIONS]
67+```
68+
69+| Argument or flag | |
70+| --- | --- |
71+| `--show-token` | Print each token too. |
72+
73+Calls [`whoami`](/reference/api/accounts/whoami/).
74+
75+### g1t auth token
76+
77+Print the token in use, for another program.
78+
79+```text
80+g1t auth token [OPTIONS]
81+```
82+
83+| Argument or flag | |
84+| --- | --- |
85+| `-u, --user <USER>` | The account, when more than one is signed in on the host. |
86+
87+### g1t auth switch
88+
89+Make another signed-in account on a host the active one.
90+
91+```text
92+g1t auth switch [OPTIONS]
93+```
94+
95+| Argument or flag | |
96+| --- | --- |
97+| `-u, --user <USER>` | The account, when more than one is signed in on the host. |
98+
99+### g1t auth setup-git
100+
101+Make git use g1t's credentials for pushing and fetching over HTTPS.
102+
103+```text
104+g1t auth setup-git [OPTIONS]
105+```
106+
107+| Argument or flag | |
108+| --- | --- |
109+| `--dry-run` | Print the git config commands instead of running them. |
110+
111+## g1t repo
112+
113+Repositories: view, clone, create, list.
114+
115+### g1t repo view
116+
117+Show a repository.
118+
119+```text
120+g1t repo view [OPTIONS] [REPOSITORY]
121+```
122+
123+| Argument or flag | |
124+| --- | --- |
125+| `[REPOSITORY]` | OWNER/NAME; the current repository when left out. |
126+| `-w, --web` | Open it in the browser. |
127+
128+Calls [`get_repo`](/reference/api/repositories/get-repo/).
129+
130+### g1t repo clone
131+
132+Clone a repository.
133+
134+```text
135+g1t repo clone [OPTIONS] <REPOSITORY> [DIRECTORY] [-- <GIT_FLAGS>...]
136+```
137+
138+| Argument or flag | |
139+| --- | --- |
140+| `<REPOSITORY>` | OWNER/NAME, or NAME for one of your own. |
141+| `[DIRECTORY]` | Where to clone it. |
142+| `[GIT_FLAGS]` | After `--`. Flags for git clone, after --. |
143+
144+Calls [`whoami`](/reference/api/accounts/whoami/).
145+
146+### g1t repo create
147+
148+Make a repository.
149+
150+```text
151+g1t repo create [OPTIONS] [NAME]
152+```
153+
154+| Argument or flag | |
155+| --- | --- |
156+| `[NAME]` | NAME, or WORKSPACE/NAME. |
157+| `--public` | Anyone can see it. Repositories are private unless this is given. |
158+| `--private` | Only people with a role on it can see it (the default). |
159+| `-d, --description <DESCRIPTION>` | |
160+| `-c, --clone` | Clone it once it is made. |
161+| `--source <DIR>` | Add it as a remote of this directory's repository and push it there. |
162+| `--remote <REMOTE>` | The remote's name, with --source. Default: `origin`. |
163+
164+Calls [`create_repo`](/reference/api/repositories/create-repo/).
165+
166+### g1t repo list
167+
168+List repositories you can see.
169+
170+```text
171+g1t repo list [OPTIONS] [WORKSPACE]
172+```
173+
174+| Argument or flag | |
175+| --- | --- |
176+| `[WORKSPACE]` | Only this workspace's. |
177+| `-q, --query <QUERY>` | Only those whose name or description holds this. |
178+| `-L, --limit <LIMIT>` | Default: `20`. |
179+
180+Calls [`list_repos`](/reference/api/repositories/list-repos/).
181+
182+## g1t issue
183+
184+Issues: list, view, create, comment, close, reopen, edit.
185+
186+### g1t issue list
187+
188+List issues.
189+
190+```text
191+g1t issue list [OPTIONS]
192+```
193+
194+| Argument or flag | |
195+| --- | --- |
196+| `-s, --state <STATE>` | One of `open`, `closed`, `all`. Default: `open`. |
197+| `-l, --label <LABEL>` | Only issues with this label. |
198+| `-m, --milestone <MILESTONE>` | Only issues in the milestone of this number. |
199+| `-a, --assignee <ASSIGNEE>` | Only issues assigned to this person (@me for you). |
200+| `-A, --author <AUTHOR>` | Only issues opened by this person (@me for you). |
201+| `-L, --limit <LIMIT>` | Default: `20`. |
202+
203+Calls [`list_issues`](/reference/api/issues/list-issues/).
204+
205+### g1t issue view
206+
207+Show an issue, with its comments.
208+
209+```text
210+g1t issue view [OPTIONS] <NUMBER>
211+```
212+
213+| Argument or flag | |
214+| --- | --- |
215+| `<NUMBER>` | The issue's number. |
216+| `-c, --comments` | Show its comments too. |
217+| `-w, --web` | Open it in the browser. |
218+
219+Calls [`get_issue`](/reference/api/issues/get-issue/).
220+
221+### g1t issue create
222+
223+Open an issue.
224+
225+```text
226+g1t issue create [OPTIONS]
227+```
228+
229+| Argument or flag | |
230+| --- | --- |
231+| `-t, --title <TITLE>` | |
232+| `-b, --body <BODY>` | The text. Markdown. |
233+| `-F, --body-file <FILE>` | Read the text from a file, or - for stdin. |
234+| `-l, --label <LABEL>` | A label; repeat for more. |
235+| `-a, --assignee <ASSIGNEE>` | Someone to assign; repeat for more (@me for you). |
236+| `-m, --milestone <MILESTONE>` | A milestone's number. |
237+| `-w, --web` | Open the new-issue page in the browser instead. |
238+
239+Calls [`create_issue`](/reference/api/issues/create-issue/), [`update_issue`](/reference/api/issues/update-issue/).
240+
241+### g1t issue comment
242+
243+Comment on an issue.
244+
245+```text
246+g1t issue comment [OPTIONS] [NUMBER]
247+```
248+
249+| Argument or flag | |
250+| --- | --- |
251+| `[NUMBER]` | The number; for a pull request, the current branch's when left out. |
252+| `-b, --body <BODY>` | The text. Markdown. |
253+| `-F, --body-file <FILE>` | Read the text from a file, or - for stdin. |
254+
255+Calls [`add_comment`](/reference/api/issues/add-comment/).
256+
257+### g1t issue close
258+
259+Close an issue.
260+
261+```text
262+g1t issue close [OPTIONS] <NUMBER>
263+```
264+
265+| Argument or flag | |
266+| --- | --- |
267+| `<NUMBER>` | |
268+| `-r, --reason <REASON>` | One of `completed`, `not-planned`. |
269+| `-c, --comment <COMMENT>` | Leave a comment as it closes. |
270+
271+Calls [`close_issue`](/reference/api/issues/close-issue/), [`add_comment`](/reference/api/issues/add-comment/).
272+
273+### g1t issue reopen
274+
275+Reopen an issue.
276+
277+```text
278+g1t issue reopen [OPTIONS] <NUMBER>
279+```
280+
281+| Argument or flag | |
282+| --- | --- |
283+| `<NUMBER>` | |
284+| `-c, --comment <COMMENT>` | Leave a comment as it reopens. |
285+
286+Calls [`reopen_issue`](/reference/api/issues/reopen-issue/), [`add_comment`](/reference/api/issues/add-comment/).
287+
288+### g1t issue edit
289+
290+Change an issue's title, body, labels, assignees or milestone.
291+
292+```text
293+g1t issue edit [OPTIONS] <NUMBER>
294+```
295+
296+| Argument or flag | |
297+| --- | --- |
298+| `<NUMBER>` | |
299+| `-t, --title <TITLE>` | |
300+| `-b, --body <BODY>` | The text. Markdown. |
301+| `-F, --body-file <FILE>` | Read the text from a file, or - for stdin. |
302+| `--add-label <LABEL>` | |
303+| `--remove-label <LABEL>` | |
304+| `--add-assignee <LOGIN>` | |
305+| `--remove-assignee <LOGIN>` | |
306+| `-m, --milestone <MILESTONE>` | A milestone's number. |
307+| `--remove-milestone` | Take it out of its milestone. |
308+
309+Calls [`update_issue`](/reference/api/issues/update-issue/), [`get_issue`](/reference/api/issues/get-issue/).
310+
311+## g1t pr
312+
313+Pull requests: list, view, create, check out, diff, checks, review, merge.
314+
315+### g1t pr list
316+
317+List pull requests.
318+
319+```text
320+g1t pr list [OPTIONS]
321+```
322+
323+| Argument or flag | |
324+| --- | --- |
325+| `-s, --state <STATE>` | One of `open`, `closed`, `merged`, `all`. Default: `open`. |
326+| `-B, --base <BASE>` | Only those merging into this branch. |
327+| `-l, --label <LABEL>` | |
328+| `-A, --author <AUTHOR>` | Only those opened by this person (@me for you). |
329+| `-d, --draft` | Only drafts. |
330+| `-L, --limit <LIMIT>` | Default: `20`. |
331+
332+Calls [`list_pull_requests`](/reference/api/pull-requests/list-pull-requests/).
333+
334+### g1t pr view
335+
336+Show a pull request.
337+
338+```text
339+g1t pr view [OPTIONS] [NUMBER]
340+```
341+
342+| Argument or flag | |
343+| --- | --- |
344+| `[NUMBER]` | The number; the current branch's when left out. |
345+| `-c, --comments` | |
346+| `-w, --web` | |
347+
348+Calls [`get_pull_request`](/reference/api/pull-requests/get-pull-request/), [`list_pull_requests`](/reference/api/pull-requests/list-pull-requests/).
349+
350+### g1t pr create
351+
352+Open a pull request from a branch, or start one for an issue.
353+
354+```text
355+g1t pr create [OPTIONS]
356+```
357+
358+| Argument or flag | |
359+| --- | --- |
360+| `-t, --title <TITLE>` | |
361+| `-b, --body <BODY>` | The text. Markdown. |
362+| `-F, --body-file <FILE>` | Read the text from a file, or - for stdin. |
363+| `-B, --base <BASE>` | The branch to merge into; the default branch when left out. |
364+| `-H, --head <HEAD>` | The branch with the changes; the current one when left out. |
365+| `-i, --issue <ISSUE>` | The issue it is for. Without a branch, starts a draft in a working copy of its own. |
366+| `-f, --fill` | Take the title and body from the branch's commits. |
367+| `-d, --draft` | Open it as a draft. |
368+| `--no-push` | Do not push the branch first. |
369+
370+Calls [`create_pull_request`](/reference/api/pull-requests/create-pull-request/), [`get_repo`](/reference/api/repositories/get-repo/), [`convert_pull_request_to_draft`](/reference/api/pull-requests/convert-pull-request-to-draft/).
371+
372+### g1t pr checkout
373+
374+Check a pull request's changes out locally.
375+
376+```text
377+g1t pr checkout [OPTIONS] <NUMBER>
378+```
379+
380+| Argument or flag | |
381+| --- | --- |
382+| `<NUMBER>` | |
383+| `-b, --branch <BRANCH>` | The local branch's name; pr-NUMBER when left out. |
384+| `-f, --force` | Reset the local branch to the pull request's head even if it has other commits. |
385+
386+Calls [`get_pull_request`](/reference/api/pull-requests/get-pull-request/).
387+
388+### g1t pr diff
389+
390+Show a pull request's changes as a diff.
391+
392+```text
393+g1t pr diff [OPTIONS] [NUMBER]
394+```
395+
396+| Argument or flag | |
397+| --- | --- |
398+| `[NUMBER]` | |
399+| `--name-only` | Only the changed files' names. |
400+| `--color <COLOR>` | Color: auto, always or never. Default: `auto`. |
401+
402+Calls [`get_pull_request_changes`](/reference/api/pull-requests/get-pull-request-changes/).
403+
404+### g1t pr checks
405+
406+Show a pull request's checks; --watch waits for them.
407+
408+```text
409+g1t pr checks [OPTIONS] [NUMBER]
410+```
411+
412+| Argument or flag | |
413+| --- | --- |
414+| `[NUMBER]` | |
415+| `-w, --watch` | Wait until every check has finished. |
416+| `--fail-fast` | With --watch, stop at the first failing check. |
417+| `-i, --interval <INTERVAL>` | Seconds between looks, with --watch. Default: `10`. |
418+
419+Calls [`get_pull_request`](/reference/api/pull-requests/get-pull-request/), [`list_check_runs_for_ref`](/reference/api/checks/list-check-runs-for-ref/), [`get_combined_status`](/reference/api/checks/get-combined-status/).
420+
421+### g1t pr review
422+
423+Approve a pull request, or ask for changes.
424+
425+```text
426+g1t pr review [OPTIONS] <--approve|--request-changes|--comment> [NUMBER]
427+```
428+
429+| Argument or flag | |
430+| --- | --- |
431+| `[NUMBER]` | |
432+| `-a, --approve` | |
433+| `-r, --request-changes` | |
434+| `-c, --comment` | Comment without approving or asking for changes. |
435+| `-b, --body <BODY>` | The text. Markdown. |
436+| `-F, --body-file <FILE>` | Read the text from a file, or - for stdin. |
437+
438+Calls [`review_pull_request`](/reference/api/pull-requests/review-pull-request/), [`add_comment`](/reference/api/issues/add-comment/).
439+
440+### g1t pr merge
441+
442+Merge a pull request.
443+
444+```text
445+g1t pr merge [OPTIONS] [NUMBER]
446+```
447+
448+| Argument or flag | |
449+| --- | --- |
450+| `[NUMBER]` | |
451+| `--keep-issue-open` | Leave the issue it is for open. |
452+| `--admin` | Merge past failing required checks and rules (needs the Admin role). |
453+| `-d, --delete-branch` | Delete the local and remote branch afterwards. |
454+
455+Calls [`merge_pull_request`](/reference/api/pull-requests/merge-pull-request/), [`delete_branch`](/reference/api/repositories/delete-branch/).
456+
457+### g1t pr ready
458+
459+Mark a draft ready for review, or turn it back into a draft.
460+
461+```text
462+g1t pr ready [OPTIONS] [NUMBER]
463+```
464+
465+| Argument or flag | |
466+| --- | --- |
467+| `[NUMBER]` | |
468+| `-s, --summary <SUMMARY>` | What changed and why; it becomes the description. The current one when left out. |
469+| `--undo` | Turn it back into a draft. |
470+
471+Calls [`mark_pull_request_ready`](/reference/api/pull-requests/mark-pull-request-ready/), [`convert_pull_request_to_draft`](/reference/api/pull-requests/convert-pull-request-to-draft/).
472+
473+### g1t pr comment
474+
475+Comment on a pull request.
476+
477+```text
478+g1t pr comment [OPTIONS] [NUMBER]
479+```
480+
481+| Argument or flag | |
482+| --- | --- |
483+| `[NUMBER]` | The number; for a pull request, the current branch's when left out. |
484+| `-b, --body <BODY>` | The text. Markdown. |
485+| `-F, --body-file <FILE>` | Read the text from a file, or - for stdin. |
486+
487+Calls [`add_comment`](/reference/api/issues/add-comment/).
488+
489+### g1t pr close
490+
491+Close a pull request without merging it.
492+
493+```text
494+g1t pr close [OPTIONS] [NUMBER]
495+```
496+
497+| Argument or flag | |
498+| --- | --- |
499+| `[NUMBER]` | The number; the current branch's when left out. |
500+
501+Calls [`close_pull_request`](/reference/api/pull-requests/close-pull-request/).
502+
503+### g1t pr reopen
504+
505+Reopen a closed pull request.
506+
507+```text
508+g1t pr reopen [OPTIONS] [NUMBER]
509+```
510+
511+| Argument or flag | |
512+| --- | --- |
513+| `[NUMBER]` | The number; the current branch's when left out. |
514+
515+Calls [`reopen_pull_request`](/reference/api/pull-requests/reopen-pull-request/).
516+
517+## g1t run
518+
519+Workflow runs: list, view, watch, logs, rerun, cancel.
520+
521+### g1t run list
522+
523+List workflow runs, newest first.
524+
525+```text
526+g1t run list [OPTIONS]
527+```
528+
529+| Argument or flag | |
530+| --- | --- |
531+| `-w, --workflow <WORKFLOW>` | Only this workflow's: its file name or id. |
532+| `-b, --branch <BRANCH>` | |
533+| `-e, --event <EVENT>` | Only runs for this event: push, pull_request, schedule... |
534+| `-c, --commit <COMMIT>` | Only runs of this commit. |
535+| `--pr <PR>` | Only runs for this pull request. |
536+| `-L, --limit <LIMIT>` | Default: `20`. |
537+
538+Calls [`list_workflow_runs`](/reference/api/actions/list-workflow-runs/).
539+
540+### g1t run view
541+
542+Show a run's jobs and steps.
543+
544+```text
545+g1t run view [OPTIONS] [RUN]
546+```
547+
548+| Argument or flag | |
549+| --- | --- |
550+| `[RUN]` | |
551+| `-j, --job <JOB>` | Show this job's steps only. |
552+| `--log` | Print the log too. |
553+| `--log-failed` | Print the failing steps' logs too. |
554+| `-w, --web` | |
555+| `--exit-status` | Exit 1 when the run failed. |
556+
557+Calls [`get_workflow_run`](/reference/api/actions/get-workflow-run/), [`get_job_logs`](/reference/api/actions/get-job-logs/).
558+
559+### g1t run watch
560+
561+Follow a run until it finishes; exits 1 if it fails.
562+
563+```text
564+g1t run watch [OPTIONS] [RUN]
565+```
566+
567+| Argument or flag | |
568+| --- | --- |
569+| `[RUN]` | |
570+| `-i, --interval <INTERVAL>` | Seconds between looks. Default: `3`. |
571+
572+Calls [`get_workflow_run`](/reference/api/actions/get-workflow-run/).
573+
574+### g1t run logs
575+
576+Print a run's logs; --failed prints only the failing steps' tails.
577+
578+```text
579+g1t run logs [OPTIONS] [RUN]
580+```
581+
582+| Argument or flag | |
583+| --- | --- |
584+| `[RUN]` | |
585+| `-j, --job <JOB>` | Only this job's (its id, key or name). |
586+| `-f, --failed` | Only the failing steps, and only their last lines. |
587+| `-n, --tail <TAIL>` | How many lines of each failing step to print, with --failed. Default: `60`. |
588+
589+Calls [`get_workflow_run`](/reference/api/actions/get-workflow-run/), [`get_job_logs`](/reference/api/actions/get-job-logs/).
590+
591+### g1t run rerun
592+
593+Run a run again: all of it, its failed jobs, or one job.
594+
595+```text
596+g1t run rerun [OPTIONS] [RUN]
597+```
598+
599+| Argument or flag | |
600+| --- | --- |
601+| `[RUN]` | |
602+| `--failed` | Only the jobs that failed. |
603+| `-j, --job <JOB>` | Only this job (its id). |
604+| `-d, --debug` | With debug logging. |
605+
606+Calls [`rerun_workflow_run`](/reference/api/actions/rerun-workflow-run/), [`rerun_failed_jobs`](/reference/api/actions/rerun-failed-jobs/), [`rerun_job`](/reference/api/actions/rerun-job/).
607+
608+### g1t run cancel
609+
610+Cancel a run.
611+
612+```text
613+g1t run cancel [OPTIONS] [RUN]
614+```
615+
616+| Argument or flag | |
617+| --- | --- |
618+| `[RUN]` | The run's id (run_…) or number; the current branch's latest when left out. |
619+
620+Calls [`cancel_workflow_run`](/reference/api/actions/cancel-workflow-run/).
621+
622+## g1t secret
623+
624+Secrets for workflows and deployments, a repository's or a workspace's.
625+
626+### g1t secret list
627+
628+List secrets' names (never their values).
629+
630+```text
631+g1t secret list [OPTIONS]
632+```
633+
634+| Argument or flag | |
635+| --- | --- |
636+| `-w, --workspace <WORKSPACE>` | A workspace's secrets instead of the repository's. |
637+| `-e, --env <ENVIRONMENT>` | Only the value for this environment (production, preview...). |
638+
639+Calls [`list_actions_secrets`](/reference/api/secrets-and-variables/list-actions-secrets/), [`list_actions_secrets_for_workspace`](/reference/api/secrets-and-variables/list-actions-secrets-for-workspace/).
640+
641+### g1t secret set
642+
643+Set a secret. The value is read from stdin when not given.
644+
645+```text
646+g1t secret set [OPTIONS] <NAME>
647+```
648+
649+| Argument or flag | |
650+| --- | --- |
651+| `<NAME>` | The secret's name; uppercased. |
652+| `-b, --body <BODY>` | The value. Read from stdin when left out, so it stays out of your shell's history. |
653+| `-w, --workspace <WORKSPACE>` | A workspace's secrets instead of the repository's. |
654+| `-e, --env <ENVIRONMENT>` | Only the value for this environment (production, preview...). |
655+| `--available-to <WHO>` | Who can read it: workflows, deployments, or both (repeat). |
656+| `--brokered-host <HOST>` | Broker it: jobs get a stand-in, and g1t fills the value in only on requests to this host. Repeat for more. |
657+| `--note <NOTE>` | A note for whoever reads the list. |
658+
659+Calls [`set_actions_secret`](/reference/api/secrets-and-variables/set-actions-secret/), [`set_actions_secret_for_workspace`](/reference/api/secrets-and-variables/set-actions-secret-for-workspace/).
660+
661+### g1t secret delete
662+
663+Delete a secret.
664+
665+```text
666+g1t secret delete [OPTIONS] <NAME>
667+```
668+
669+| Argument or flag | |
670+| --- | --- |
671+| `<NAME>` | |
672+| `-w, --workspace <WORKSPACE>` | A workspace's secrets instead of the repository's. |
673+| `-e, --env <ENVIRONMENT>` | Only the value for this environment (production, preview...). |
674+
675+Calls [`delete_actions_secret`](/reference/api/secrets-and-variables/delete-actions-secret/), [`delete_actions_secret_for_workspace`](/reference/api/secrets-and-variables/delete-actions-secret-for-workspace/).
676+
677+## g1t deploy
678+
679+Deployments: list and view.
680+
681+### g1t deploy list
682+
683+List deployments, newest first.
684+
685+```text
686+g1t deploy list [OPTIONS]
687+```
688+
689+| Argument or flag | |
690+| --- | --- |
691+| `-e, --env <ENV>` | |
692+| `-s, --state <STATE>` | queued, in_progress, success, failure, error or inactive. |
693+| `--source <SOURCE>` | api, actions or g1t_page. |
694+| `-L, --limit <LIMIT>` | Default: `20`. |
695+
696+Calls [`list_deployments`](/reference/api/deployments/list-deployments/).
697+
698+### g1t deploy view
699+
700+Show a deployment and its statuses.
701+
702+```text
703+g1t deploy view [OPTIONS] <ID>
704+```
705+
706+| Argument or flag | |
707+| --- | --- |
708+| `<ID>` | |
709+| `-w, --web` | |
710+
711+Calls [`get_deployment`](/reference/api/deployments/get-deployment/).
712+
713+## g1t logs
714+
715+A project's logs and errors.
716+
717+```text
718+g1t logs [OPTIONS]
719+```
720+
721+| Argument or flag | |
722+| --- | --- |
723+| `-p, --project <PROJECT>` | The project; the current repository's when left out. |
724+| `--errors` | Grouped errors instead of log lines. |
725+| `-q, --query <QUERY>` | Lines holding all of these words, or a "quoted phrase". |
726+| `-l, --level <LEVEL>` | Levels: trace, debug, info, warn, error, fatal (comma-separated). |
727+| `-e, --env <ENV>` | |
728+| `--service <SERVICE>` | |
729+| `-s, --since <SINCE>` | How far back: 15m, 2h, 1d, or a time like 2026-10-12T09:00:00Z. |
730+| `--state <STATE>` | With --errors: open, resolved or ignored. |
731+| `-f, --follow` | Keep printing new lines as they come. |
732+| `-L, --limit <LIMIT>` | Default: `50`. |
733+
734+Calls [`list_logs`](/reference/api/observability/list-logs/), [`list_errors`](/reference/api/observability/list-errors/), [`list_projects`](/reference/api/projects/list-projects/), [`get_repo`](/reference/api/repositories/get-repo/).
735+
736+## g1t status
737+
738+What needs you: your pull requests, reviews asked of you, your issues, failing checks.
739+
740+```text
741+g1t status [OPTIONS]
742+```
743+
744+Calls [`search`](/reference/api/search/search/), [`list_notifications`](/reference/api/notifications/list-notifications/), [`get_pull_request`](/reference/api/pull-requests/get-pull-request/).
745+
746+## g1t api
747+
748+Call any API operation or path, with your token.
749+
750+```text
751+g1t api [OPTIONS] [ENDPOINT]
752+```
753+
754+| Argument or flag | |
755+| --- | --- |
756+| `[ENDPOINT]` | An operation's name, or a path. |
757+| `--list [QUERY]` | List the operations, or those matching this word. |
758+| `-X, --method <METHOD>` | The HTTP method: GET unless fields are given, then POST. |
759+| `-f, --raw-field <KEY=VALUE>` | A string field, key=value. key[]=value adds to a list. |
760+| `-F, --field <KEY=VALUE>` | A typed field: true, false, null and numbers become JSON; @file reads a file. |
761+| `-H, --header <KEY:VALUE>` | A request header, key:value. |
762+| `--input <FILE>` | The request body, from a file or - for stdin. |
763+| `--paginate` | Follow next pages until there are none. |
764+| `--slurp` | With --paginate, put every page's items into one array. |
765+| `-i, --include` | Print the status line and headers too. |
766+| `--silent` | Print nothing on success. |
767+
768+```text
769+ENDPOINT is an operation's name (list_issues) or a path (/repos/{owner}/{name}/issues).
770+{owner}, {name}, {repo} and {workspace} are filled in from the current repository,
771+and an operation's other path parameters from -f/-F fields of the same name.
772+
773+Examples:
774+ g1t api list_issues -f state=closed
775+ g1t api /user --jq .username
776+ g1t api create_issue -f title='Broken link' -f labels[]=docs
777+ g1t api list_workflow_runs --paginate --jq '.[].conclusion'
778+ g1t api --list issue
779+```
780+
781+## g1t browse
782+
783+Open the repository, an issue or a pull request in the browser.
784+
785+```text
786+g1t browse [OPTIONS] [TARGET]
787+```
788+
789+| Argument or flag | |
790+| --- | --- |
791+| `[TARGET]` | An issue or pull request number, a file path (path:line), or a commit. |
792+| `-b, --branch <BRANCH>` | The branch to show files on. |
793+| `-s, --settings` | |
794+| `--issues` | |
795+| `--pulls` | |
796+| `--actions` | |
797+| `-n, --no-browser` | Print the address instead of opening it. |
798+
799+## g1t alias
800+
801+Shortcuts for commands you type often.
802+
803+### g1t alias set
804+
805+Make an alias: g1t alias set co 'pr checkout'. Start it with ! to run it through the shell.
806+
807+```text
808+g1t alias set [OPTIONS] <NAME> <EXPANSION>
809+```
810+
811+| Argument or flag | |
812+| --- | --- |
813+| `<NAME>` | |
814+| `<EXPANSION>` | What it expands to. $1, $2... take the arguments after it. |
815+
816+### g1t alias list
817+
818+List aliases.
819+
820+```text
821+g1t alias list [OPTIONS]
822+```
823+
824+### g1t alias delete
825+
826+Delete an alias.
827+
828+```text
829+g1t alias delete [OPTIONS] <NAME>
830+```
831+
832+| Argument or flag | |
833+| --- | --- |
834+| `<NAME>` | |
835+
836+## g1t completion
837+
838+Print a shell completion script.
839+
840+```text
841+g1t completion [OPTIONS] <SHELL>
842+```
843+
844+| Argument or flag | |
845+| --- | --- |
846+| `<SHELL>` | One of `bash`, `elvish`, `fish`, `powershell`, `zsh`. |
847+
848+## g1t push
849+
850+Push a local container image to g1t's registry, in chunks.
851+
852+```text
853+g1t push [OPTIONS] [IMAGE]
854+```
855+
856+| Argument or flag | |
857+| --- | --- |
858+| `[IMAGE]` | The local image, [REGISTRY/]NAME[:TAG]. |
859+| `--as <ADDRESS>` | Where to push, when the image's own name is not an address on g1t.sh. The tag defaults to latest. |
860+| `--chunk-size <SIZE>` | How much of a layer each request carries: 5MB to 95MB. Default: `90MB`. |
861+| `--token-stdin` | Read the g1t token from stdin. |
862+| `--archive <FILE>` | Push a tarball `docker save` wrote, instead of asking docker for the image. |
863+
864+```text
865+The token is the first of: --token-stdin, G1T_TOKEN, the account `g1t auth login`
866+signed in for the registry's host, or what `docker login g1t.sh` stored.
867+```
+57−0
1+# Installs the g1t CLI on Windows:
2+#
3+# irm https://g1t.sh/install.ps1 | iex
4+#
5+# It downloads the build from g1t.sh/downloads/cli, checks it against the
6+# release's SHA256SUMS, puts it in %LOCALAPPDATA%\g1t\bin, and adds that to
7+# your PATH.
8+#
9+# G1T_INSTALL_DIR where to put g1t.exe
10+# G1T_VERSION a version to install, such as 0.2.0 (default: the latest)
11+#
12+# Docs: https://docs.g1t.sh/guides/cli/
13+$ErrorActionPreference = 'Stop'
14+$ProgressPreference = 'SilentlyContinue'
15+
16+$base = if ($env:G1T_DOWNLOAD_URL) { $env:G1T_DOWNLOAD_URL } else { 'https://g1t.sh/downloads/cli' }
17+$version = if ($env:G1T_VERSION) { $env:G1T_VERSION.TrimStart('v') } else { 'latest' }
18+$dir = if ($env:G1T_INSTALL_DIR) { $env:G1T_INSTALL_DIR } else { Join-Path $env:LOCALAPPDATA 'g1t\bin' }
19+
20+$arch = $env:PROCESSOR_ARCHITECTURE
21+if ($arch -ne 'AMD64' -and $arch -ne 'ARM64') { throw "g1t install: there is no build for $arch." }
22+# Windows on ARM runs the x64 build.
23+$file = 'g1t-windows-x64.exe'
24+
25+[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12
26+$tmp = Join-Path ([IO.Path]::GetTempPath()) ('g1t-' + [Guid]::NewGuid())
27+New-Item -ItemType Directory -Path $tmp | Out-Null
28+try {
29+ Write-Host "Downloading g1t ($version, windows x64)..."
30+ $exe = Join-Path $tmp 'g1t.exe'
31+ Invoke-WebRequest -UseBasicParsing -Uri "$base/$version/$file" -OutFile $exe
32+ $sumsFile = Join-Path $tmp 'SHA256SUMS'
33+ Invoke-WebRequest -UseBasicParsing -Uri "$base/$version/SHA256SUMS" -OutFile $sumsFile
34+ $want = Get-Content $sumsFile |
35+ Where-Object { ($_ -split '\s+')[1] -eq $file } |
36+ ForEach-Object { ($_ -split '\s+')[0] } |
37+ Select-Object -First 1
38+ if (-not $want) { throw "g1t install: SHA256SUMS names no $file." }
39+ $have = (Get-FileHash -Algorithm SHA256 -Path $exe).Hash.ToLower()
40+ if ($have -ne $want.ToLower()) { throw "g1t install: the download's SHA-256 is $have, not $want. Nothing was installed." }
41+ New-Item -ItemType Directory -Force -Path $dir | Out-Null
42+ Move-Item -Force -Path $exe -Destination (Join-Path $dir 'g1t.exe')
43+}
44+finally {
45+ Remove-Item -Recurse -Force -Path $tmp -ErrorAction SilentlyContinue
46+}
47+
48+$userPath = [Environment]::GetEnvironmentVariable('Path', 'User')
49+if (-not (($userPath -split ';') -contains $dir)) {
50+ $joined = if ($userPath) { "$userPath;$dir" } else { $dir }
51+ [Environment]::SetEnvironmentVariable('Path', $joined, 'User')
52+ $env:Path = "$env:Path;$dir"
53+ Write-Host "Added $dir to your PATH; terminals opened from now on have it."
54+}
55+$installed = & (Join-Path $dir 'g1t.exe') --version
56+Write-Host "Installed $installed to $dir\g1t.exe"
57+Write-Host 'Next: g1t auth login'
+79−0
1+#!/bin/sh
2+# Installs the g1t CLI on Linux or macOS:
3+#
4+# curl -fsSL https://g1t.sh/install | sh
5+#
6+# It downloads the build for this system from g1t.sh/downloads/cli, checks it
7+# against the release's SHA256SUMS, and puts it in ~/.local/bin.
8+#
9+# G1T_INSTALL_DIR where to put g1t (default: ~/.local/bin)
10+# G1T_VERSION a version to install, such as 0.2.0 (default: the latest)
11+#
12+# Docs: https://docs.g1t.sh/guides/cli/
13+set -eu
14+
15+base="${G1T_DOWNLOAD_URL:-https://g1t.sh/downloads/cli}"
16+version="${G1T_VERSION:-latest}"
17+version="${version#v}"
18+dir="${G1T_INSTALL_DIR:-$HOME/.local/bin}"
19+
20+say() { printf '%s\n' "$*" >&2; }
21+fail() {
22+ say "g1t install: $*"
23+ exit 1
24+}
25+
26+case "$(uname -s)" in
27+Linux) os=linux ;;
28+Darwin) os=macos ;;
29+MINGW* | MSYS* | CYGWIN*) fail "on Windows, run this in PowerShell instead: irm https://g1t.sh/install.ps1 | iex" ;;
30+*) fail "there is no build for $(uname -s)." ;;
31+esac
32+case "$(uname -m)" in
33+x86_64 | amd64) arch=x64 ;;
34+arm64 | aarch64) arch=arm64 ;;
35+*) fail "there is no build for $(uname -m)." ;;
36+esac
37+# An Intel shell on Apple silicon (Rosetta) gets the native build.
38+if [ "$os" = macos ] && [ "$arch" = x64 ] && [ "$(sysctl -n sysctl.proc_translated 2>/dev/null || echo 0)" = 1 ]; then
39+ arch=arm64
40+fi
41+file="g1t-$os-$arch"
42+
43+if command -v curl >/dev/null 2>&1; then
44+ get() { curl -fsSL --retry 3 -o "$2" "$1"; }
45+elif command -v wget >/dev/null 2>&1; then
46+ get() { wget -q -O "$2" "$1"; }
47+else
48+ fail "this needs curl or wget."
49+fi
50+
51+tmp="$(mktemp -d)"
52+trap 'rm -rf "$tmp"' EXIT INT TERM
53+
54+say "Downloading g1t ($version, $os $arch)..."
55+get "$base/$version/$file" "$tmp/g1t" || fail "could not download $base/$version/$file."
56+get "$base/$version/SHA256SUMS" "$tmp/SHA256SUMS" || fail "could not download $base/$version/SHA256SUMS."
57+
58+# A name may carry sha256sum's binary-mode `*`.
59+want="$(awk -v f="$file" '{ sub(/^[*]/, "", $2) } $2 == f { print $1 }' "$tmp/SHA256SUMS")"
60+[ -n "$want" ] || fail "SHA256SUMS names no $file."
61+if command -v sha256sum >/dev/null 2>&1; then
62+ have="$(sha256sum "$tmp/g1t" | awk '{ print $1 }')"
63+elif command -v shasum >/dev/null 2>&1; then
64+ have="$(shasum -a 256 "$tmp/g1t" | awk '{ print $1 }')"
65+else
66+ fail "this needs sha256sum or shasum to check the download."
67+fi
68+[ "$want" = "$have" ] || fail "the download's SHA-256 is $have, not $want. Nothing was installed."
69+
70+chmod +x "$tmp/g1t"
71+mkdir -p "$dir" || fail "could not make $dir. Set G1T_INSTALL_DIR to a directory you can write to."
72+mv "$tmp/g1t" "$dir/g1t" || fail "could not write $dir/g1t. Set G1T_INSTALL_DIR to a directory you can write to."
73+
74+say "Installed $("$dir/g1t" --version) to $dir/g1t"
75+case ":$PATH:" in
76+*":$dir:"*) ;;
77+*) say "$dir is not on your PATH. Add it to your shell's profile: export PATH=\"$dir:\$PATH\"" ;;
78+esac
79+say "Next: g1t auth login"
+3−0
9595 route("download", "routes/download.tsx"),
9696 // Releases of the desktop app, the self-hosted runner and the g1t CLI, from R2.
9797 route("downloads/:tool/*", "routes/downloads-runner.ts"),
98+ // The g1t CLI's install scripts, for Linux and macOS and for Windows. `install` is reserved.
99+ route("install", "routes/install-script.ts", { id: "routes/install-sh" }),
100+ route("install.ps1", "routes/install-script.ts", { id: "routes/install-ps1" }),
98101 // A workspace's own pages sit under `-`, which no repository can be named.
99102 route(":owner", "routes/workspace/layout.tsx", [
100103 index("routes/workspace/overview.tsx"),
+22−0
1+/**
2+ * The g1t CLI's install scripts: g1t.sh/install for Linux and macOS
3+ * (`curl -fsSL https://g1t.sh/install | sh`) and g1t.sh/install.ps1 for
4+ * Windows (`irm https://g1t.sh/install.ps1 | iex`). Each downloads the newest
5+ * release from g1t.sh/downloads/cli/ (scripts/cli-release.mjs), checks it
6+ * against the release's SHA256SUMS, and installs it. `install` is a
7+ * reserved name.
8+ */
9+import type { Route } from "./+types/install-script";
10+import sh from "../content/install/install.sh?raw";
11+import ps1 from "../content/install/install.ps1?raw";
12+
13+export function loader({ request }: Route.LoaderArgs) {
14+ const windows = new URL(request.url).pathname.endsWith(".ps1");
15+ return new Response(windows ? ps1 : sh, {
16+ headers: {
17+ "content-type": "text/plain; charset=utf-8",
18+ "cache-control": "public, max-age=300",
19+ "x-content-type-options": "nosniff",
20+ },
21+ });
22+}
+17−2
11 [package]
22 name = "g1t"
3−version = "0.1.0"
3+version = "0.2.0"
44 edition.workspace = true
55 license.workspace = true
66 repository.workspace = true
7−description = "The g1t command line: g1t push sends a local image to g1t.sh in chunks, so a layer can be any size."
7+description = "The g1t command line: repositories, issues, pull requests, workflow runs, deployments, secrets and logs on g1t, from a terminal or an agent's shell."
8+
9+[[bin]]
10+name = "g1t"
11+path = "src/main.rs"
812
913 [dependencies]
14+anstyle-query = "1.1"
1015 base64 = "0.22"
16+clap = { version = "4.6", features = ["derive", "env", "wrap_help"] }
17+clap_complete = "4.6"
1118 flate2 = "1"
1219 hex = "0.4"
20+jaq-core = "3.1"
21+jaq-json = "2.0"
22+jaq-std = "3.0"
23+keyring = "4.2"
24+rpassword = "7"
25+serde = { workspace = true }
1326 serde_json = { workspace = true }
1427 sha2 = "0.10"
1528 tar = { version = "0.4", default-features = false }
29+terminal_size = "0.4"
1630 ureq = { version = "2", default-features = false, features = ["tls"] }
31+
+354−0
Loading the diff…
+1−0
Loading the diff…
+909−0
Loading the diff…
+330−0
Loading the diff…
+228−0
Loading the diff…
+611−0
Loading the diff…
+536−0
Loading the diff…
+132−0
Loading the diff…
+126−0
Loading the diff…
+500−0
Loading the diff…
+279−0
Loading the diff…
+69−0
Loading the diff…
+969−0
Loading the diff…
+181−0
Loading the diff…
+616−0
Loading the diff…
+239−0
Loading the diff…
+155−0
Loading the diff…
+155−0
Loading the diff…
+164−0
Loading the diff…
+9−3
Loading the diff…
+216−0
Loading the diff…
+98−0
Loading the diff…
+90−0
Loading the diff…
+106−0
Loading the diff…
+73−278
Loading the diff…
+369−0
Loading the diff…
+264−0
Loading the diff…
+6912−0
A large diff (6,912 lines) is not shown until you ask for it.
+404−0
Loading the diff…
+153−0
Loading the diff…
+226−0
Loading the diff…
+199−0
Loading the diff…
+894−0
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…