Skip to content

g1t/apps/docs/src/content/docs/guides/managing-repositories.md

490 lines21,875 bytesCodeBlame
1---
2title: Managing a repository
3description: What a repository's About shows, and how to rename it or a branch, change its default branch, website and topics, make it public or private, archive it, and delete and restore it.
4---
5
6A repository's details and its lifecycle are managed from its
7**Settings → Repository** page, at
8`g1t.sh/<workspace>/<repo>/settings/repository`, and from the API and MCP
9server. This guide covers each change, who can make it, and what happens
10when you do.
11
12## The About beside the files
13
14A repository's **Code** page shows its files with an **About** beside them,
15the way most code hosts lay it out. On a phone it comes after the files.
16
17| Part | What it shows |
18| --- | --- |
19| Description, website, topics | What you set under [Edit the details](#edit-the-details). |
20| **Readme** | A link to the README shown under the files. |
21| **License** | The license its `LICENSE` file holds, such as **MIT license**, linked to the file. **View license** when the text is not one g1t recognizes. `LICENCE`, `COPYING` and `UNLICENSE` are read too, with or without an extension, and an `SPDX-License-Identifier` line says it outright. |
22| **Security policy** | A link to `SECURITY.md` at the root, or in `.g1t`, `.github` or `docs`. |
23| **Activity** | The repository's [activity](#activity): pushes, merges, new branches and tags. |
24| **Stars**, **watching** | How many people [starred](#stars) it, and how many watch all or some of its activity from the [Watch menu](/guides/inbox/). |
25| **Releases** | How many [releases](/guides/releases/) it has and the latest, or **Create a new release** for people who can push. |
26| **Packages** | [Packages](/guides/packages/) linked to it, or how to publish the first. |
27| **Contributors** | How many people and agents made it, and the most active. See [contributors](#contributors). |
28| **Languages** | The languages it is written in, by bytes. See [languages](#languages). |
29
30The license, security policy, languages and contributors are read from the
31default branch in the background each time it moves, and kept by commit, so
32the page never waits for them. A repository pushed to for the first time
33shows **Reading the default branch…** for a few seconds.
34
35### Languages
36
37The bar counts the bytes of each language's files on the default branch.
38Programming and markup languages count; data such as JSON and YAML, and
39prose such as Markdown, do not. Neither do:
40
41| Files | Such as |
42| --- | --- |
43| Vendored | `node_modules/`, `vendor/`, `third_party/`, minified jQuery, and anything under a dot-directory such as `.github/` |
44| Generated | `dist/`, `*.min.js`, `*.pb.go`, lockfiles |
45| Documentation | `docs/`, `doc/`, `examples/` |
46
47Change what counts with `linguist-*` attributes in the repository's
48`.gitattributes` file at the root. A later line wins over an earlier one.
49
50```text
51vendor/ours/** -linguist-vendored
52*.gen.ts linguist-generated
53docs/** -linguist-documentation
54*.inc linguist-language=PHP
55*.sql linguist-detectable
56```
57
58A repository too large to read in full (more than 10,000 files) counts the
59files read.
60
61### Contributors
62
63**Insights → Contributors** lists everyone whose commits are on the default
64branch, most commits first, with their commits by week, and the
65repository's commits per week over the last year.
66
67| Who | How they are matched |
68| --- | --- |
69| A person | By an address they confirmed on their account, or their noreply address. Several addresses of one account count as one. |
70| g1t | Its own commits, by its address. |
71| Anyone else | By the name on their commits. |
72
73The newest 3,000 commits are counted.
74
75### Activity
76
77**Insights → Activity** lists, newest first, who pushed to which branch,
78created a branch or tag, merged a pull request, renamed a branch or changed
79the default branch, person or agent.
80
81### Stars
82
83Choose **Star** in the repository's header to keep it in your profile's
84**Stars** tab, at `g1t.sh/u/<you>?tab=stars`. The number beside it leads
85to who starred it. Anyone signed in who can read a repository can star it;
86stars on a private repository are seen only by people who can read it.
87
88## The settings page
89
90| Section | What it holds |
91| --- | --- |
92| **Name** | The repository's name, the second part of its address. |
93| **Details** | Its description, website and topics, shown on its page, in [search and Explore](/guides/search/). |
94| **Branches** | The default branch, renaming a branch, and a link to **Branches and merging**: [branch protection](/guides/git/#protected-branches), [required status checks](/guides/pull-requests/#required-status-checks), required approvals, the [merge queue](/guides/merge-queue/) and what agents do. What a sandbox may reach is under **Guardrails**; see [guardrails](/guides/guardrails/). |
95| **Danger zone** | Change visibility, archive, [transfer](/guides/transferring-repositories/) and delete. Shown to people with the Admin role. |
96
97While a repository is [archived](#archive-a-repository), the settings that
98change it are turned off until it is unarchived.
99
100## Who can do what
101
102Each change needs a [role](/guides/access-and-roles/) on the repository.
103Owners of its workspace have Admin on it.
104
105| Change | Needs |
106| --- | --- |
107| Description, website, topics | Maintain |
108| Default branch | Admin |
109| Rename a branch | Write; Admin for the default branch |
110| Rename the repository | Admin |
111| Make it public or private | Admin |
112| Archive or unarchive | Admin |
113| [Transfer](/guides/transferring-repositories/) | An owner of both workspaces |
114| Delete, restore and purge | An owner of its workspace |
115| See the Recently deleted list | An owner of its workspace |
116
117Renaming the repository or its default branch, changing its visibility
118and archiving it are done by a person, not a workspace token.
119g1t's token can never use the tools that make these changes,
120whatever its run. See [credentials](/guides/working-with-g1t/#credentials).
121
122## Edit the details
123
1241. Open the repository's **Settings → Repository**.
1252. Under **Details**, change **Description**, **Website** or **Topics**.
1263. Choose **Save**.
127
128| Field | Rules |
129| --- | --- |
130| Description | Up to 200 characters. Empty clears it. |
131| Website | An http or https address. `https://` is added when you leave the scheme out. Empty clears it. |
132| Topics | Lowercase letters, digits and hyphens, at most 20, each up to 35 characters. Separate them with commas or spaces. |
133
134From the API, call
135[`PATCH /repos/{owner}/{name}`](/reference/api/repositories/update-repo/)
136with the fields to change. Fields you leave out stay as they are.
137
138```sh
139curl -X PATCH https://api.g1t.sh/repos/acme/rocket \
140 -H "Authorization: Bearer $G1T_TOKEN" \
141 -H "Content-Type: application/json" \
142 -d '{"description": "Launches things.", "website": "rocket.acme.dev", "topics": ["cli", "rust"]}'
143```
144
145Over MCP, it is the `repository` tool's `update` action, with `repo` and
146the same fields.
147
148## Change the default branch
149
150The default branch is what the repository opens on, what new clones check
151out, what pull requests target, and what branch protection covers.
152
1531. Open the repository's **Settings → Repository**.
1542. Under **Branches → Default branch**, pick another branch.
1553. Choose **Change default branch**.
156
157The branch must already exist; push it first. When you change it:
158
159- Open pull requests merge into the new default branch.
160- New clones check out the new default branch. Existing clones keep the
161 branches they have; run `git remote set-head origin -a` to update what
162 `origin/HEAD` points at.
163- [Branch protection](/guides/git/#protected-branches) covers the new
164 default branch.
165
166From the API, send `default_branch` to
167[`PATCH /repos/{owner}/{name}`](/reference/api/repositories/update-repo/):
168
169```sh
170curl -X PATCH https://api.g1t.sh/repos/acme/rocket \
171 -H "Authorization: Bearer $G1T_TOKEN" \
172 -H "Content-Type: application/json" \
173 -d '{"default_branch": "trunk"}'
174```
175
176Over MCP, it is the `repository` tool's `update` action, with `repo` and
177`default_branch`. When the
178same call changes other fields, they are changed first.
179
180## Rename a branch
181
1821. Open the repository's **Settings → Repository**.
1832. Under **Branches → Rename a branch**, pick the **Branch** and type its
184 **New name**.
1853. Choose **Rename branch**.
186
187Renaming the default branch needs Admin. It stays the default under its
188new name. When a branch is renamed:
189
190- Open pull requests from it follow it to the new name.
191- Web addresses that name the old branch, such as
192 `g1t.sh/acme/rocket/tree/old-name`, redirect to the new one until a
193 branch with the old name is made again.
194- Git remotes do not follow. In each clone, rename the local branch and
195 track the new one:
196
197```sh
198git branch -m old-name new-name
199git fetch origin
200git branch -u origin/new-name new-name
201git remote set-head origin -a
202```
203
204From the API, call
205[`POST /repos/{owner}/{name}/branches/{branch}/rename`](/reference/api/repositories/rename-branch/)
206with `new_name`. A branch name with slashes goes in the path URL-encoded,
207as one segment: `feature/login` is `feature%2Flogin`.
208
209```sh
210curl -X POST https://api.g1t.sh/repos/acme/rocket/branches/feature%2Flogin/rename \
211 -H "Authorization: Bearer $G1T_TOKEN" \
212 -H "Content-Type: application/json" \
213 -d '{"new_name": "feature/sign-in"}'
214```
215
216Over MCP, it is the `repository` tool's `rename_branch` action, with
217`repo`, `branch` and `new_name`.
218
219## Rename a repository
220
2211. Open the repository's **Settings → Repository**.
2222. Under **Name**, type the new name. It shows the new address.
2233. Choose **Rename**.
224
225A name is lowercase letters, digits, dots, hyphens and underscores, up to
226100 characters. It cannot start with a dot or end in `.git`, and no other
227repository in the workspace may have it, including one that was
228[recently deleted](#restore-a-repository).
229
230Everything stays with the repository: its git data, issues, pull requests,
231workflow runs, deployments, settings, secrets and webhooks. Its old address
232keeps working, the same way as after a
233[transfer](/guides/transferring-repositories/#old-addresses):
234
235| | Behaviour |
236| --- | --- |
237| Web pages | A permanent redirect (`301`) to the same page at the new address. |
238| `git clone`, `fetch`, `pull` and `push` | Redirected to the new remote. Git follows it and prints a warning each time. |
239| API and MCP | A call that names the repository by its old name runs against it under its new name. |
240
241Its project follows: a project that had the repository's name takes the
242new one, unless another project in the workspace already has it, and its
243deployed apps are built again under the new name while the old addresses
244redirect.
245
246A redirect stops as soon as a repository is made at the old address.
247Update your remotes rather than relying on it:
248
249```sh
250git remote set-url origin https://g1t.sh/acme/launcher.git
251```
252
253From the API, call
254[`POST /repos/{owner}/{name}/rename`](/reference/api/repositories/rename-repo/)
255with `name`:
256
257```sh
258curl -X POST https://api.g1t.sh/repos/acme/rocket/rename \
259 -H "Authorization: Bearer $G1T_TOKEN" \
260 -H "Content-Type: application/json" \
261 -d '{"name": "launcher"}'
262```
263
264Over MCP, it is the `repository` tool's `rename` action, with `repo` and
265`name`.
266
267## Change who can see a repository
268
269A public repository can be seen and cloned by anyone, signed in or not. A
270private one can be seen only by people with a
271[role](/guides/access-and-roles/) on it.
272
2731. Open the repository's **Settings → Repository**.
2742. Under **Danger zone → Change visibility**, choose **Make private** or
275 **Make public**.
2763. Read what changes, type the repository's full name (`<workspace>/<repo>`)
277 to confirm, and choose **Make private** or **Make public** again.
278
279| | Making it public | Making it private |
280| --- | --- | --- |
281| Who can see it | Anyone: its code, issues and pull requests, and cloning it, without signing in. | Only people with a role on it: its workspace's owners, its members (unless the [base permission](/guides/access-and-roles/#the-base-permission) is None), and anyone given a role on it. Anyone else gets a page that says it does not exist. |
282| Search and Explore | It is added to [search](/guides/search/) and Explore for everyone. | It leaves search and Explore for everyone outside the workspace. |
283| Link previews | Links to it show a preview card with its name and description. | Links to it stop showing a preview card. |
284| Storage | It stops counting toward the workspace's private storage. | It counts toward the workspace's private storage. A free workspace has 1 GB; making it private is refused when that would go over. See [what is free](/guides/usage-and-billing/#what-is-free). |
285
286Nothing else changes: its address, members, settings, secrets, webhooks
287and deployments stay as they are.
288
289From the API, call
290[`POST /repos/{owner}/{name}/visibility`](/reference/api/repositories/set-repo-visibility/)
291with `private` and its full name in `confirm`:
292
293```sh
294curl -X POST https://api.g1t.sh/repos/acme/rocket/visibility \
295 -H "Authorization: Bearer $G1T_TOKEN" \
296 -H "Content-Type: application/json" \
297 -d '{"private": true, "confirm": "acme/rocket"}'
298```
299
300Over MCP, it is the `repository` tool's `set_visibility` action, with
301`repo`, `private` and `confirm`. `private` on
302[`PATCH /repos/{owner}/{name}`](/reference/api/repositories/update-repo/)
303makes the same change without the confirmation, for people with Admin.
304
305## Archive a repository
306
307Archiving makes a repository read-only. Use it for work that is finished
308but should stay readable.
309
3101. Open the repository's **Settings → Repository**.
3112. Under **Danger zone**, choose **Archive**.
3123. Read what changes and choose **Archive** again.
313
314While it is archived:
315
316| | |
317| --- | --- |
318| Pushes and merges | Refused, whatever your role, and for agents too. |
319| Issues and pull requests | Locked. They stay readable. |
320| Agents and workflows | Do not run. |
321| Settings | The ones that change the repository are turned off. |
322| Deployments | Keep serving. |
323| Who can see it | Unchanged. Anyone who could see it still can, and clone it. |
324
325Its page says it is archived, and so do its project's card on the
326workspace overview and its card on [Explore](/guides/search/#explore),
327with an **archived** label. To undo it, someone with Admin chooses **Unarchive**
328in the same place. Pushes, merges, issues, pull requests, agents and
329workflows work again; nothing that was refused while it was archived runs
330by itself.
331
332From the API, call
333[`POST /repos/{owner}/{name}/archive`](/reference/api/repositories/archive-repo/)
334or
335[`POST /repos/{owner}/{name}/unarchive`](/reference/api/repositories/unarchive-repo/):
336
337```sh
338curl -X POST https://api.g1t.sh/repos/acme/rocket/archive \
339 -H "Authorization: Bearer $G1T_TOKEN"
340```
341
342Over MCP, they are the `repository` tool's `archive` and `unarchive`
343actions, with `repo`. The
344repository's `archived_at` field says when it was archived, and is null
345when it is not.
346
347## Delete a repository
348
349Deleting takes a repository away at once, but an owner can restore it for
35030 days. After that it is purged: removed for good, its git data with it.
351
3521. Open the repository's **Settings → Repository**.
3532. Under **Danger zone**, choose **Delete**.
3543. Read what happens, type the repository's full name
355 (`<workspace>/<repo>`) to confirm, and choose **Delete repository**.
356
357| | While it is deleted | When it is purged |
358| --- | --- | --- |
359| Its pages, git remote and API | Answer as if it did not exist, for everyone. | The same. |
360| Its name | Stays taken: no repository can be made at its address. | Free to use again. |
361| Agents and workflows | Stop, and do not start. | |
362| Deployments | Taken down. Its `g1t.page` addresses stop serving. | Removed. |
363| Custom domains | Kept, and serve nothing. | Removed. |
364| Search | Drops it. | |
365| Webhooks | The workspace's webhooks are sent `repo.deleted`. | Sent `repo.purged`. |
366| Storage | Stops counting toward the workspace's storage. | |
367| Git data, issues, pull requests, settings, secrets | Kept, for restoring. | Removed, and cannot be recovered. |
368
369Its entries in the [audit log](/guides/audit-log/) are kept, as for
370anything else.
371
372From the API, call
373[`DELETE /repos/{owner}/{name}`](/reference/api/repositories/delete-repo/)
374with its full name in `confirm`. It returns the deleted repository with
375`purge_after`, when it will be purged:
376
377```sh
378curl -X DELETE https://api.g1t.sh/repos/acme/rocket \
379 -H "Authorization: Bearer $G1T_TOKEN" \
380 -H "Content-Type: application/json" \
381 -d '{"confirm": "acme/rocket"}'
382```
383
384Over MCP, it is the `repository` tool's `delete` action, with `repo` and
385`confirm`.
386
387To move a repository to another workspace instead of deleting it, see
388[transferring a repository](/guides/transferring-repositories/).
389
390## Restore a repository
391
392A workspace's recently deleted repositories are listed for its owners
393under **Recently deleted** in the workspace's **Settings → Repositories**,
394at `g1t.sh/<workspace>/-/repositories`, each with who deleted it and when
395it will be purged.
396
3971. Open the workspace's **Settings → Repositories**.
3982. Under **Recently deleted**, find the repository and choose **Restore**.
399
400It comes back at the address it had, as it was when it was deleted: git
401data, issues, pull requests, settings, secrets and webhooks. Its
402deployments are built again, and its custom domains serve them once they
403are live. Agents and workflows run again for new work; they do not catch
404up on what they missed.
405
406From the API, list them with
407[`GET /workspaces/{workspace}/repos/deleted`](/reference/api/repositories/list-deleted-repos/)
408(the `repository` tool's `list_deleted` action over MCP), then call
409[`POST /repos/{owner}/{name}/restore`](/reference/api/repositories/restore-repo/)
410with the path it had (the `restore` action):
411
412```sh
413curl https://api.g1t.sh/workspaces/acme/repos/deleted \
414 -H "Authorization: Bearer $G1T_TOKEN"
415
416curl -X POST https://api.g1t.sh/repos/acme/rocket/restore \
417 -H "Authorization: Bearer $G1T_TOKEN"
418```
419
420### Purge a repository now
421
422To remove a deleted repository for good before its 30 days are up, and
423free its name:
424
4251. Open the workspace's **Settings → Repositories**.
4262. Under **Recently deleted**, choose **Delete permanently** beside it.
4273. Type its full name (`<workspace>/<repo>`) to confirm, and choose
428 **Delete permanently** again.
429
430This cannot be undone. From the API, call
431[`POST /repos/{owner}/{name}/purge`](/reference/api/repositories/purge-repo/)
432with its full name in `confirm`:
433
434```sh
435curl -X POST https://api.g1t.sh/repos/acme/rocket/purge \
436 -H "Authorization: Bearer $G1T_TOKEN" \
437 -H "Content-Type: application/json" \
438 -d '{"confirm": "acme/rocket"}'
439```
440
441Over MCP, it is the `repository` tool's `purge` action, with `repo` and
442`confirm`.
443
444A workspace whose only repositories are recently deleted ones can itself
445be [deleted](/guides/workspaces/#delete-a-workspace); they are purged with
446it.
447
448## When a change is refused
449
450| Response | Why | What to do |
451| --- | --- | --- |
452| `401 unauthenticated` | No token, or one that is not valid. | Send a personal access token. |
453| `403 forbidden` | You are not an owner, for a change that needs one; or g1t's token was used. | Ask an owner of the workspace. |
454| `404 not_found` | No such repository or branch, or you cannot see it. For restore and purge: no deleted repository had that path, or it was purged. | Check the path. A deleted repository is named by the path it had. |
455| `409 conflict` | The new name is taken in the workspace, by a repository or a recently deleted one; or a branch with the new name exists. | Pick another name, or purge the deleted repository first. |
456| `422 invalid` | `confirm` is not the repository's full name; the name, branch name or website is not valid; or the new default branch does not exist. | Type `<workspace>/<repo>` exactly; push the branch first. |
457| `402 payment_required` | Making it private would take a free workspace's private storage over 1 GB. | Start [the g1t plan](/guides/usage-and-billing/#the-g1t-plan), or make room first. |
458
459Each refusal comes with a message that says what to do.
460
461## From the API and MCP
462
463| Route | MCP | What it does |
464| --- | --- | --- |
465| [`GET /repos/{owner}/{name}/languages`](/reference/api/repository-insights/get-languages/) | `repository` `languages` | Its languages by bytes, with `color` and `percent`. |
466| [`GET /repos/{owner}/{name}/contributors`](/reference/api/repository-insights/list-contributors/) | `repository` `contributors` | Its contributors with `kind`, `commits` and `weeks`. |
467| [`GET /repos/{owner}/{name}/license`](/reference/api/repository-insights/get-license/) | `repository` `license` | Its license's `spdx_id`, `name` and `path`. |
468| [`GET /repos/{owner}/{name}/stargazers`](/reference/api/stars/list-stargazers/) | `repository` `stargazers` | Who starred it, newest first. |
469| [`PUT /user/starred/{owner}/{name}`](/reference/api/stars/star-repo/) | `repository` `star` | Star it. `DELETE` takes the star back; `GET` says whether you did. |
470| [`GET /user/starred`](/reference/api/stars/list-starred/) | `repository` `list_starred` | What you starred. |
471
472Answers read from the default branch say which `commit` they are for and
473the `head` now; `pending` is true until the first is read. Stars take the
474`account:read` and `account:write` scopes; the rest `repo:read`.
475
476## Events and the audit log
477
478Each change is sent to [webhooks](/guides/webhooks/#events) and recorded
479in the [audit log](/guides/audit-log/):
480
481| Change | Event |
482| --- | --- |
483| Description, website, topics, protection | `repo.updated` |
484| Visibility | `repo.visibility_changed` |
485| Rename | `repo.renamed` |
486| Default branch | `repo.default_branch_changed` |
487| Branch rename | `branch.renamed` |
488| Archive, unarchive | `repo.archived`, `repo.unarchived` |
489| Transfer | `repo.transferred` |
490| Delete, restore, purge | `repo.deleted`, `repo.restored`, `repo.purged` |