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.

231 linesCodeBlameRaw
1---
2title: Forking a repository
3description: Copy a repository into your own workspace, keep it up to date with the one it came from, and propose changes back.
4---
5
6Forking copies a repository into a workspace of yours as a new repository
7that remembers where it came from: its **parent**. The fork is yours. You
8can push to it, change its settings and run its workflows, and the parent
9is untouched until you open a pull request into it and someone there merges
10it.
11
12Fork a repository to contribute to one you cannot push to, or to start your
13own line of work from someone else's code. To work on an issue in a
14repository you can already write to, you do not need a fork: open a pull
15request from a branch, or let it [make a working copy](/concepts/forks/#working-copies-for-pull-requests).
16
17See [Forks](/concepts/forks/) for what a fork is, who can see it and what
18happens to it when its parent changes.
19
20## Who can fork
21
22- **A public repository**: anyone signed in, into any workspace where they
23 can create a public repository.
24- **A private repository**: anyone who can read it, once its admins allow
25 forking (see [Allow forking a private repository](#allow-forking-a-private-repository)),
26 into a workspace where they can create a private repository.
27
28Your email address must be confirmed. An access token made for a workflow
29run or an agent's run cannot fork.
30
31## Fork a repository
32
331. Open the repository and choose **Fork** in its header.
342. Pick the **workspace** to fork it into. Only workspaces where you can
35 create a repository of its kind are listed.
363. Keep its **name**, or give the fork another. Its project starts with
37 the parent project's **description**; change it later on the fork's
38 **Settings → General**.
394. Leave **Copy the `<default>` branch only** on to copy just the default
40 branch, or turn it off to copy every branch and tag.
415. Choose **Create fork**.
42
43You land on the fork. Under its name, its header says **forked from** and
44links to the parent.
45
46From the CLI, `g1t repo fork` forks the current repository, or the one you
47name, into your personal workspace unless you say `--workspace`. With
48`--clone` it clones the fork and adds the parent as the remote `upstream`:
49
50```sh
51g1t repo fork acme/rocket --workspace ada-labs --clone
52```
53
54From the API, call
55[`POST /repos/{owner}/{name}/forks`](/reference/api/repositories/fork-repo/):
56
57```sh
58curl -X POST https://api.g1t.sh/repos/acme/rocket/forks \
59 -H "Authorization: Bearer $G1T_TOKEN" \
60 -H "Content-Type: application/json" \
61 -d '{"workspace": "ada-labs", "default_branch_only": true}'
62```
63
64`workspace`, `name` and `default_branch_only` may each be left out: your
65personal workspace, the parent's name, and the default branch only. Over MCP, it is the `repository` tool's `fork`
66action.
67
68### What the fork gets
69
70| Copied | Not copied |
71| --- | --- |
72| The default branch, or every branch and tag | Issues, pull requests, comments and labels |
73| Its project's description, to the fork's project | Settings, rulesets and branch protection |
74| | Secrets, variables and webhooks |
75| | Environments, projects, deployments and custom domains |
76| | Releases, packages and stars |
77
78Issues are off in a new fork, and so are its workflows: a fork runs none of
79the workflows it copied until someone turns them on (see
80[Turn on workflows](#turn-on-workflows)). Deployments stay off until you set
81up the fork's own project.
82
83### When forking is refused
84
85| Response | Why | What to do |
86| --- | --- | --- |
87| `403 forbidden` | The repository is private and its admins have not allowed forking, or you cannot create a repository of its kind in the workspace. | Ask its admins to allow forking, or pick another workspace. |
88| `409 conflict` | The workspace already has a repository with that name, or a recently deleted one holds it. | Give the fork another `name`. |
89| `402 payment_required` | The fork is private, the workspace is on no plan, and its private repositories would hold more than a free workspace's 1 GB. | Start the g1t plan in the workspace, or fork into another. |
90| `422 invalid` | The name is not valid, no workspace was named and you belong to several, or the repository is a pull request's working copy. | Name a workspace, or fork the repository the working copy belongs to. |
91
92## Sync a fork
93
94A fork does not follow its parent by itself. Syncing brings one of its
95branches up to date with the parent's branch of the same name; the fork's
96default branch follows the parent's default branch, whatever each is
97called.
98
99On the fork's **Code** page, a bar names the parent's branch the branch you
100are looking at follows. Choose **Sync fork**, then **Update branch**; the
101bar then says what happened.
102
103From the CLI, in a clone of the fork:
104
105```sh
106g1t repo sync # the default branch
107g1t repo sync --branch release/2.x
108```
109
110From the API, call
111[`POST /repos/{owner}/{name}/merge-upstream`](/reference/api/repositories/sync-fork/)
112on the fork, with `branch` or without it for the default branch:
113
114```sh
115curl -X POST https://api.g1t.sh/repos/ada-labs/rocket/merge-upstream \
116 -H "Authorization: Bearer $G1T_TOKEN" \
117 -H "Content-Type: application/json" \
118 -d '{"branch": "main"}'
119```
120
121Syncing needs the Write role on the fork and read access to its parent. What
122happens depends on the branch:
123
124| `status` | The branch | What changed |
125| --- | --- | --- |
126| `up_to_date` | Already had every commit of the parent's branch. | Nothing. |
127| `fast_forwarded` | Was only behind. | It now points where the parent's does. |
128| `merged` | Had commits of its own, and the two sides' changes do not clash: different files, or different lines of the same file. | A merge commit joins them. |
129| `conflicted` | Had commits of its own, and both sides changed the same lines (or one deleted a file the other changed, or both changed a binary file), in the files listed in `conflicts`. | Nothing. |
130
131The answer also says how many commits the branch was `behind` and `ahead`.
132A conflicted branch is yours to merge: pull the parent's branch into your
133clone, settle the conflicts and push.
134
135```sh
136git pull upstream main
137git push origin main
138```
139
140Syncing moves the branch on g1t. Pull it into your clone afterwards with
141`git pull origin <branch>`. The fork's rules hold as for any push: a
142protected branch is not moved by syncing.
143
144## Propose changes to the parent
145
146Push a branch to your fork and open a pull request from it into the parent.
147
1481. On the fork's **Code** page, choose **Contribute** on the bar that names
149 the parent's branch.
1502. The base is the parent's default branch; pick another of its branches if
151 you were asked to.
1523. Write a title and description and choose **Create pull request**.
153
154From the CLI, in a clone of the fork whose `upstream` is the parent,
155`g1t pr create` opens the pull request on the parent and pushes the branch
156to your fork (`origin`). `--head-repo OWNER/NAME` names the fork when the
157remotes are set up differently.
158
159```sh
160git switch -c fix-link
161git commit -am "Fix the broken link"
162g1t pr create --fill
163```
164
165From the API, create the pull request on the parent with the fork in
166`head_repo` and its branch in `branch`:
167
168```sh
169curl -X POST https://api.g1t.sh/repos/acme/rocket/pulls \
170 -H "Authorization: Bearer $G1T_TOKEN" \
171 -H "Content-Type: application/json" \
172 -d '{"head_repo": "ada-labs/rocket", "branch": "fix-link", "title": "Fix the broken link"}'
173```
174
175The pull request lives on the parent and is reviewed, checked and merged
176there, under the parent's rules. Its checks are the **parent's** workflows,
177run under the parent's settings, and a pull request from someone outside
178the parent's workspace waits for approval as the parent's
179[approval policy](/guides/actions/#pull-requests-from-outside) says.
180Whoever opened it, its runs get none of the parent's secrets and no token
181that can write to the parent: anyone who can push to the fork can change the
182code they run. Pushing to the branch in your fork updates the pull request.
183
184## Allow forking a private repository
185
186A private repository cannot be forked until its admins allow it.
187
1881. Open the repository's **Settings → Repository**.
1892. Under **Forking**, turn on **Allow forking**.
190
191From the API, send `allow_forking` to
192[`PATCH /repos/{owner}/{name}`](/reference/api/repositories/update-repo/);
193it needs the Admin role. Forks of a private repository are private, and stay
194private. Clearing the setting stops new forks; forks already made stay, but
195a private fork whose maker can no longer read the parent is deleted (and
196can be restored for 30 days by its workspace's owners).
197
198Public repositories can always be forked.
199
200## Turn on workflows
201
202A fork's workflows are off when it is made, so nothing it copied runs on
203your account until you decide it should. In the fork's
204**Settings → Actions**, turn on **Run workflows**. Only someone who manages
205the fork's settings (the Admin role) can. See
206[Turn workflows on or off](/guides/actions/#turn-workflows-on-or-off).
207
208## List a repository's forks
209
210The repository's **Forks** page lists the forks you can see, newest first.
211From the CLI, `g1t repo forks`; from the API,
212[`GET /repos/{owner}/{name}/forks`](/reference/api/repositories/list-forks/).
213
214## Detach a fork
215
216Detaching makes a fork an ordinary repository with no parent. Do it when the
217fork has become its own project, or to change who can see it: a fork stays
218exactly as visible as its parent until it is detached.
219
2201. Open the fork's **Settings → Repository**.
2212. Under **Danger zone**, choose **Detach fork**, type the fork's full name
222 (`<workspace>/<name>`) to confirm, and choose **Detach fork**.
223
224From the CLI, `g1t repo detach`; from the API,
225[`POST /repos/{owner}/{name}/detach`](/reference/api/repositories/detach-fork/).
226It needs the Admin role on the fork.
227
228A detached fork keeps its code, settings and the pull requests it already
229opened into the parent, which stay open there. It can no longer be synced or
230open new pull requests into the parent, and its workflows and issues stay
231off unless someone had turned them on. It cannot be attached again.