The See the migration guide for more examples.
sandbox.git module is deprecated. It still works today, but it will be removed in the next major version of the JavaScript and Python SDKs. Run git through the commands module instead:// Deprecated
await sandbox.git.clone('https://github.com/e2b-dev/E2B.git', { path: 'repo' })
// Use instead
await sandbox.commands.run('git clone https://github.com/e2b-dev/E2B.git repo')
# Deprecated
sandbox.git.clone("https://github.com/e2b-dev/E2B.git", path="repo")
# Use instead
sandbox.commands.run("git clone https://github.com/e2b-dev/E2B.git repo")
Authentication and Identity
Passing credentials inline
For private repositories over HTTP(S), passusername and password (token) directly to commands that need authentication. A username is required whenever you pass a password/token.
const repoPath = '/home/user/repo'
await sandbox.git.push(repoPath, {
username: process.env.GIT_USERNAME,
password: process.env.GIT_TOKEN,
})
await sandbox.git.pull(repoPath, {
username: process.env.GIT_USERNAME,
password: process.env.GIT_TOKEN,
})
import os
repo_path = "/home/user/repo"
sandbox.git.push(
repo_path,
username=os.environ.get("GIT_USERNAME"),
password=os.environ.get("GIT_TOKEN"),
)
sandbox.git.pull(
repo_path,
username=os.environ.get("GIT_USERNAME"),
password=os.environ.get("GIT_TOKEN"),
)
Credential helper (authenticate once)
To avoid passing credentials on each command, store them in the git credential helper inside the sandbox usingdangerouslyAuthenticate() / dangerously_authenticate().
Stores credentials on disk inside the sandbox. Any process or agent with access to the sandbox can read them. Use only when you understand the risk.
// Default (GitHub)
await sandbox.git.dangerouslyAuthenticate({
username: process.env.GIT_USERNAME,
password: process.env.GIT_TOKEN,
})
// Custom host (self-hosted)
await sandbox.git.dangerouslyAuthenticate({
username: process.env.GIT_USERNAME,
password: process.env.GIT_TOKEN,
host: 'git.example.com',
protocol: 'https',
})
// After this, HTTPS git operations use the stored credentials
await sandbox.git.clone('https://git.example.com/org/repo.git', { path: '/home/user/repo' })
await sandbox.git.push('/home/user/repo')
import os
# Default (GitHub)
sandbox.git.dangerously_authenticate(
username=os.environ.get("GIT_USERNAME"),
password=os.environ.get("GIT_TOKEN"),
)
# Custom host (self-hosted)
sandbox.git.dangerously_authenticate(
username=os.environ.get("GIT_USERNAME"),
password=os.environ.get("GIT_TOKEN"),
host="git.example.com",
protocol="https",
)
# After this, HTTPS git operations use the stored credentials
sandbox.git.clone("https://git.example.com/org/repo.git", path="/home/user/repo")
sandbox.git.push("/home/user/repo")
Keep credentials in the remote URL
By default, credentials are stripped from the remote URL after cloning. To keep credentials in the remote URL (stored in.git/config), set dangerouslyStoreCredentials / dangerously_store_credentials.
Storing credentials in the remote URL persists them in the repo config. Any process or agent with access to the sandbox can read them. Only use this when required.
// Default: credentials are stripped from the remote URL
await sandbox.git.clone('https://git.example.com/org/repo.git', {
path: '/home/user/repo',
username: process.env.GIT_USERNAME,
password: process.env.GIT_TOKEN,
})
// Keep credentials in the remote URL
await sandbox.git.clone('https://git.example.com/org/repo.git', {
path: '/home/user/repo',
username: process.env.GIT_USERNAME,
password: process.env.GIT_TOKEN,
dangerouslyStoreCredentials: true,
})
import os
# Default: credentials are stripped from the remote URL
sandbox.git.clone(
"https://git.example.com/org/repo.git",
path="/home/user/repo",
username=os.environ.get("GIT_USERNAME"),
password=os.environ.get("GIT_TOKEN"),
)
# Keep credentials in the remote URL
sandbox.git.clone(
"https://git.example.com/org/repo.git",
path="/home/user/repo",
username=os.environ.get("GIT_USERNAME"),
password=os.environ.get("GIT_TOKEN"),
dangerously_store_credentials=True,
)
Configure git identity
Set the git author name and email for commits. Configure globally or per-repository.const repoPath = '/home/user/repo'
// Global config
await sandbox.git.configureUser('E2B Bot', 'bot@example.com')
// Repo-local config
await sandbox.git.configureUser('E2B Bot', 'bot@example.com', {
scope: 'local',
path: repoPath
})
repo_path = "/home/user/repo"
# Global config
sandbox.git.configure_user("E2B Bot", "bot@example.com")
# Repo-local config
sandbox.git.configure_user(
"E2B Bot",
"bot@example.com",
scope="local",
path=repo_path
)
Clone a repository
See Authentication and Identity for how to authenticate with private repositories.const repoUrl = 'https://git.example.com/org/repo.git'
const repoPath = '/home/user/repo'
// Default clone
await sandbox.git.clone(repoUrl, { path: repoPath })
// Clone a specific branch
await sandbox.git.clone(repoUrl, { path: repoPath, branch: 'main' })
// Shallow clone
await sandbox.git.clone(repoUrl, { path: repoPath, depth: 1 })
repo_url = "https://git.example.com/org/repo.git"
repo_path = "/home/user/repo"
# Default clone
sandbox.git.clone(repo_url, path=repo_path)
# Clone a specific branch
sandbox.git.clone(repo_url, path=repo_path, branch="main")
# Shallow clone
sandbox.git.clone(repo_url, path=repo_path, depth=1)
Check status and branches
status() returns a structured object with branch, ahead/behind, and file status details. branches() returns the branch list and the current branch.
const repoPath = '/home/user/repo'
const status = await sandbox.git.status(repoPath)
console.log(status.currentBranch, status.ahead, status.behind)
console.log(status.fileStatus)
const branches = await sandbox.git.branches(repoPath)
console.log(branches.currentBranch)
console.log(branches.branches)
repo_path = "/home/user/repo"
status = sandbox.git.status(repo_path)
print(status.current_branch, status.ahead, status.behind)
print(status.file_status)
branches = sandbox.git.branches(repo_path)
print(branches.current_branch)
print(branches.branches)
Create and manage branches
const repoPath = '/home/user/repo'
// Create and switch to a new branch
await sandbox.git.createBranch(repoPath, 'feature/new-docs')
// Check out an existing branch
await sandbox.git.checkoutBranch(repoPath, 'main')
// Delete a branch
await sandbox.git.deleteBranch(repoPath, 'feature/old-docs')
// Force delete a branch
await sandbox.git.deleteBranch(repoPath, 'feature/stale-docs', { force: true })
repo_path = "/home/user/repo"
# Create and switch to a new branch
sandbox.git.create_branch(repo_path, "feature/new-docs")
# Check out an existing branch
sandbox.git.checkout_branch(repo_path, "main")
# Delete a branch
sandbox.git.delete_branch(repo_path, "feature/old-docs")
# Force delete a branch
sandbox.git.delete_branch(repo_path, "feature/stale-docs", force=True)
Stage and commit
const repoPath = '/home/user/repo'
// Default: stage all changes, commit with repo config
await sandbox.git.add(repoPath)
await sandbox.git.commit(repoPath, 'Initial commit')
// Stage specific files
await sandbox.git.add(repoPath, { files: ['README.md', 'src/index.ts'] })
// Allow empty commit and override author
await sandbox.git.commit(repoPath, 'Docs sync', {
authorName: 'E2B Bot',
authorEmail: 'bot@example.com',
allowEmpty: true,
})
repo_path = "/home/user/repo"
# Default: stage all changes, commit with repo config
sandbox.git.add(repo_path)
sandbox.git.commit(repo_path, "Initial commit")
# Stage specific files
sandbox.git.add(repo_path, files=["README.md", "src/index.ts"])
# Allow empty commit and override author
sandbox.git.commit(
repo_path,
"Docs sync",
author_name="E2B Bot",
author_email="bot@example.com",
allow_empty=True,
)
Pull and push
See Authentication and Identity for how to authenticate with private repositories.const repoPath = '/home/user/repo'
// Default (uses upstream when set)
await sandbox.git.push(repoPath)
await sandbox.git.pull(repoPath)
// Target a specific remote/branch and set upstream
await sandbox.git.push(repoPath, {
remote: 'origin',
branch: 'main',
setUpstream: true,
})
await sandbox.git.pull(repoPath, {
remote: 'origin',
branch: 'main',
})
repo_path = "/home/user/repo"
# Default (uses upstream when set)
sandbox.git.push(repo_path)
sandbox.git.pull(repo_path)
# Target a specific remote/branch and set upstream
sandbox.git.push(
repo_path,
remote="origin",
branch="main",
set_upstream=True,
)
sandbox.git.pull(
repo_path,
remote="origin",
branch="main",
)
Manage remotes
const repoPath = '/home/user/repo'
const repoUrl = 'https://git.example.com/org/repo.git'
// Default
await sandbox.git.remoteAdd(repoPath, 'origin', repoUrl)
// Fetch after adding the remote
await sandbox.git.remoteAdd(repoPath, 'origin', repoUrl, { fetch: true })
// Overwrite the remote URL if it already exists
await sandbox.git.remoteAdd(repoPath, 'origin', repoUrl, { overwrite: true })
repo_path = "/home/user/repo"
repo_url = "https://git.example.com/org/repo.git"
# Default
sandbox.git.remote_add(repo_path, "origin", repo_url)
# Fetch after adding the remote
sandbox.git.remote_add(repo_path, "origin", repo_url, fetch=True)
# Overwrite the remote URL if it already exists
sandbox.git.remote_add(repo_path, "origin", repo_url, overwrite=True)
Git config
Set and get git configuration values. See Configure git identity for configuring the commit author.const repoPath = '/home/user/repo'
// Global config
await sandbox.git.setConfig('pull.rebase', 'false')
const rebase = await sandbox.git.getConfig('pull.rebase')
// Repo-local config
await sandbox.git.setConfig('pull.rebase', 'false', { scope: 'local', path: repoPath })
const localRebase = await sandbox.git.getConfig('pull.rebase', { scope: 'local', path: repoPath })
repo_path = "/home/user/repo"
# Global config
sandbox.git.set_config("pull.rebase", "false")
rebase = sandbox.git.get_config("pull.rebase")
# Repo-local config
sandbox.git.set_config("pull.rebase", "false", scope="local", path=repo_path)
local_rebase = sandbox.git.get_config("pull.rebase", scope="local", path=repo_path)