Skip to main content
Ephemeral branches give you a disposable ref space for preview environments, CI artifacts, and other short-lived workflows. They never sync to GitHub and stay fully isolated from your normal branches, but you can promote them whenever you’re ready. Under the hood they share the same Git objects as your other branches, keeping storage efficient and fetches fast.

Setup

Create a dedicated remote by inserting +ephemeral before .git in the repository URL:
git remote add ephemeral https://git.example.com/org/repo+ephemeral.git
This remote behaves like any other Git remote—no special tooling required.

Quick start

Push and pull ephemeral branches with standard Git commands:
git push ephemeral feature-branch
git pull ephemeral feature-branch

Promotion (ephemeral → default)

Promote an ephemeral branch to your main remote when it’s ready for production:
git fetch ephemeral feature:feature
git push origin feature

Important notes

  • Isolation: Ephemeral branches never overlap with your default branches until you promote them.
  • GitHub separation: They remain inside Code Storage—they are not mirrored to GitHub.
  • Shared objects: Ephemeral branches reuse existing Git objects for efficient storage.
  • Git protocol only: Access them via Git operations (push/pull/fetch); the REST API does not expose ephemeral refs yet.

SDK Workflows

Create an ephemeral branch

Use ephemeral=True when creating commits, reading files, or listing files in the Python SDK (and ephemeral: true in TypeScript).
// Create an ephemeral branch off of "main"
const preview = await repo
  .createCommit({
    targetBranch: 'preview/pr-123',
    baseBranch: 'main',
    ephemeral: true, // Keep the branch in the ephemeral namespace
    commitMessage: 'Preview environment for PR 123',
    author: { name: 'CI Bot', email: 'ci@example.com' },
  })
  .addFileFromString('index.html', '<h1>Preview</h1>')
  .send();

// Access content from the ephemeral branch
const response = await repo.getFileStream({
  path: 'index.html',
  ref: 'preview/pr-123',
  ephemeral: true, // Read from the ephemeral namespace
});
const html = await response.text();
console.log(html);

// List files that live under the ephemeral branch
const files = await repo.listFiles({
  ref: 'preview/pr-123',
  ephemeral: true,
});
console.log(files.paths);

Branch from an ephemeral base

Use ephemeral_base=True when branching off another ephemeral branch (requires base_branch).
const variant = await repo
  .createCommit({
    targetBranch: 'preview/pr-123-variant',
    baseBranch: 'preview/pr-123',
    ephemeral: true,
    ephemeralBase: true, // Seed from another ephemeral branch
    commitMessage: 'Variant of preview environment',
    author: { name: 'CI Bot', email: 'ci@example.com' },
  })
  .addFileFromString('variant.txt', 'This is a variant\n')
  .send();

Promote an ephemeral branch

Promote an ephemeral branch with promote_ephemeral_branch() / promoteEphemeralBranch(); omit target_branch to keep the same name.
// Promote an ephemeral branch in place
await repo.promoteEphemeralBranch({
  baseBranch: 'preview/pr-123',
});

// Or promote it to a brand-new target name
const result = await repo.promoteEphemeralBranch({
  baseBranch: 'preview/pr-123',
  targetBranch: 'feature/awesome-change',
});
console.log(result.targetBranch);