> ## Documentation Index
> Fetch the complete documentation index at: https://code.storage/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Repository Forks

> Create independent repository copies for experiments, templates, and isolated development.

A fork is an independent copy of an existing Code Storage repository. It starts from one source
commit and has its own branches and access. After the copy, a change in one repository does not
reach the other.

## When to use a fork

* **Templates**: Create new projects from a starter template
* **Experiments**: Test changes in an independent repository
* **Snapshots**: Capture a repository's state at a specific commit or branch
* **Isolation**: Separate work across a trust or tenant boundary, or give each user an independent
  project of their own

For per-agent and per-task isolation inside a single repository, use the
[ephemeral namespace](/docs/guides/ephemeral-branches) instead. Those branches share the repository's Git
objects and its access, and you can promote the work you keep.

## Quick start

<CodeGroup>
  ```typescript TypeScript theme={null} theme={"theme":{"light":"github-light","dark":"min-dark"}}
  import { GitStorage } from '@pierre/storage';

  const store = new GitStorage({
    name: 'your-org',
    key: process.env.PIERRE_PRIVATE_KEY,
  });

  // Fork at the latest commit (HEAD)
  const fork = await store.createRepo({
    id: 'my-fork',
    baseRepo: {
      id: 'template-repo', // Source repository ID
    },
  });

  // Fork at a specific branch
  const branchFork = await store.createRepo({
    id: 'feature-fork',
    baseRepo: {
      id: 'template-repo',
      ref: 'develop', // Fork from tip of 'develop' branch
    },
  });

  // Fork at a specific commit
  const commitFork = await store.createRepo({
    id: 'snapshot-fork',
    baseRepo: {
      id: 'template-repo',
      sha: 'abc123def456...', // Fork at exact commit
    },
  });
  ```

  ```python Python theme={null} theme={"theme":{"light":"github-light","dark":"min-dark"}}
  import os
  from pierre_storage import GitStorage

  storage = GitStorage({
      "name": "your-org",
      "key": os.environ["PIERRE_PRIVATE_KEY"],
  })

  # Fork at the latest commit (HEAD)
  fork = await storage.create_repo(
      id="my-fork",
      base_repo={
          "id": "template-repo",  # Source repository ID
      },
  )

  # Fork at a specific branch
  branch_fork = await storage.create_repo(
      id="feature-fork",
      base_repo={
          "id": "template-repo",
          "ref": "develop",  # Fork from tip of 'develop' branch
      },
  )

  # Fork at a specific commit
  commit_fork = await storage.create_repo(
      id="snapshot-fork",
      base_repo={
          "id": "template-repo",
          "sha": "abc123def456...",  # Fork at exact commit
      },
  )
  ```

  ```go Go theme={null} theme={"theme":{"light":"github-light","dark":"min-dark"}}
  ctx := context.Background()

  // Fork at the latest commit (HEAD)
  fork, err := client.CreateRepo(ctx, storage.CreateRepoOptions{
  	ID: "my-fork",
  	BaseRepo: storage.ForkBaseRepo{
  		ID: "template-repo",
  	},
  })

  // Fork at a specific branch
  branchFork, err := client.CreateRepo(ctx, storage.CreateRepoOptions{
  	ID: "feature-fork",
  	BaseRepo: storage.ForkBaseRepo{
  		ID:  "template-repo",
  		Ref: "develop",
  	},
  })

  // Fork at a specific commit
  commitFork, err := client.CreateRepo(ctx, storage.CreateRepoOptions{
  	ID: "snapshot-fork",
  	BaseRepo: storage.ForkBaseRepo{
  		ID:  "template-repo",
  		SHA: "abc123def456...",
  	},
  })
  ```
</CodeGroup>

`baseRepo` takes `id`, `ref`, and `sha`. See [`createRepo()`](/docs/reference/sdk/create-repo) for the
full parameter list and resolution order. That page also explains which default branch the fork
inherits.

## Use cases

### Project templates

Create new projects from a starter template:

<CodeGroup>
  ```typescript TypeScript theme={null} theme={"theme":{"light":"github-light","dark":"min-dark"}}
  async function createProjectFromTemplate(templateId: string, projectName: string, userId: string) {
    const project = await store.createRepo({
      id: `${userId}/${projectName}`,
      baseRepo: { id: templateId },
    });

    // Customize the new project
    await project
      .createCommit({
        targetBranch: 'main',
        commitMessage: 'Initialize project',
        author: { name: 'System', email: 'system@example.com' },
      })
      .addFileFromString('README.md', `# ${projectName}\n\nCreated by ${userId}`)
      .send();

    return project;
  }

  // Usage
  const project = await createProjectFromTemplate(
    'templates/react-starter',
    'my-new-app',
    'user-123',
  );
  ```

  ```python Python theme={null} theme={"theme":{"light":"github-light","dark":"min-dark"}}
  async def create_project_from_template(
      template_id: str,
      project_name: str,
      user_id: str
  ):
      project = await storage.create_repo(
          id=f"{user_id}/{project_name}",
          base_repo={"id": template_id},
      )

      # Customize the new project
      commit = project.create_commit(
          target_branch="main",
          commit_message="Initialize project",
          author={"name": "System", "email": "system@example.com"},
      )
      commit.add_file_from_string(
          "README.md",
          f"# {project_name}\n\nCreated by {user_id}"
      )
      await commit.send()

      return project

  # Usage
  project = await create_project_from_template(
      "templates/react-starter",
      "my-new-app",
      "user-123"
  )
  ```

  ```go Go theme={null} theme={"theme":{"light":"github-light","dark":"min-dark"}}
  func createProjectFromTemplate(ctx context.Context, templateID, projectName, userID string) (*storage.Repo, error) {
  	// Fork the template repo
  	project, err := client.CreateRepo(ctx, storage.CreateRepoOptions{
  		ID:       userID + "/" + projectName,
  		BaseRepo: storage.ForkBaseRepo{ID: templateID},
  	})
  	if err != nil {
  		return nil, err
  	}

  	// Customize the new project
  	builder, err := project.CreateCommit(storage.CommitOptions{
  		TargetBranch:  "main",
  		CommitMessage: "Initialize project",
  		Author:        storage.CommitSignature{Name: "System", Email: "system@example.com"},
  	})
  	if err != nil {
  		return nil, err
  	}

  	_, err = builder.AddFileFromString(
  		"README.md",
  		"# "+projectName+"\n\nCreated by "+userID,
  		nil,
  	).Send(ctx)
  	if err != nil {
  		return nil, err
  	}

  	return project, nil
  }

  // Usage
  project, err := createProjectFromTemplate(context.Background(), "templates/react-starter", "my-new-app", "user-123")
  ```
</CodeGroup>

### Point-in-time snapshots

Capture a repository's state before you make risky changes:

<CodeGroup>
  ```typescript TypeScript theme={null} theme={"theme":{"light":"github-light","dark":"min-dark"}}
  async function createSnapshot(repoId: string, label: string) {
    const source = await store.findOne({ id: repoId });
    const commits = await source.listCommits({ limit: 1 });
    const headSha = commits.commits[0].sha;

    const snapshot = await store.createRepo({
      id: `snapshots/${repoId}/${label}`,
      baseRepo: {
        id: repoId,
        sha: headSha,
      },
    });

    return snapshot;
  }

  // Before a major refactor
  const backup = await createSnapshot('my-project', 'pre-refactor-2024-01');
  ```

  ```python Python theme={null} theme={"theme":{"light":"github-light","dark":"min-dark"}}
  async def create_snapshot(repo_id: str, label: str):
      source = await storage.find_one(id=repo_id)
      commits = await source.list_commits(limit=1)
      head_sha = commits["commits"][0]["sha"]

      snapshot = await storage.create_repo(
          id=f"snapshots/{repo_id}/{label}",
          base_repo={
              "id": repo_id,
              "sha": head_sha,
          },
      )

      return snapshot

  # Before a major refactor
  backup = await create_snapshot("my-project", "pre-refactor-2024-01")
  ```

  ```go Go theme={null} theme={"theme":{"light":"github-light","dark":"min-dark"}}
  func createSnapshot(ctx context.Context, repoID, label string) (*storage.Repo, error) {
  	// Capture the current HEAD SHA
  	source, err := client.FindOne(ctx, storage.FindOneOptions{ID: repoID})
  	if err != nil {
  		return nil, err
  	}
  	commits, err := source.ListCommits(ctx, storage.ListCommitsOptions{Limit: 1})
  	if err != nil {
  		return nil, err
  	}
  	headSHA := commits.Commits[0].SHA

  	// Fork at the captured commit
  	return client.CreateRepo(ctx, storage.CreateRepoOptions{
  		ID: "snapshots/" + repoID + "/" + label,
  		BaseRepo: storage.ForkBaseRepo{
  			ID:  repoID,
  			SHA: headSHA,
  		},
  	})
  }

  // Before a major refactor
  backup, err := createSnapshot(context.Background(), "my-project", "pre-refactor-2024-01")
  ```
</CodeGroup>

## Fork or sync

| `operation`                   | Source                    | Ongoing connection | Best for                               |
| ----------------------------- | ------------------------- | ------------------ | -------------------------------------- |
| `fork`                        | A Code Storage repository | No                 | Templates, snapshots, isolated copies  |
| [`sync`](/docs/guides/github-sync) | An external Git provider  | Yes                | Repositories that should stay mirrored |

## Limitations

* **Same organization**: You can only fork repositories within your own organization
* **No relationship tracking**: Forks are independent. Code Storage keeps no "parent" reference
  after creation. No route merges a fork back into its source
* **No upstream**: A fork records no upstream, so [`pullUpstream()`](/docs/reference/sdk/pull-upstream)
  on a fork returns HTTP `400` with `repository has no upstream configured`. To get later changes,
  add the source repository as a second Git remote. Fetch and merge the changes
* **Full copy**: Forks include all branches and history up to the fork point
