From b8a314057a67e175ef1b8701686f1389f1a851a8 Mon Sep 17 00:00:00 2001 From: Matt Brockman Date: Tue, 27 Jan 2026 18:04:27 -0800 Subject: [PATCH 01/15] docs for git operations --- docs.json | 10 ++- docs/git/authentication.mdx | 123 +++++++++++++++++++++++++++++ docs/git/clone.mdx | 151 ++++++++++++++++++++++++++++++++++++ docs/git/create-repo.mdx | 126 ++++++++++++++++++++++++++++++ 4 files changed, 409 insertions(+), 1 deletion(-) create mode 100644 docs/git/authentication.mdx create mode 100644 docs/git/clone.mdx create mode 100644 docs/git/create-repo.mdx diff --git a/docs.json b/docs.json index 4254115..97e5e24 100644 --- a/docs.json +++ b/docs.json @@ -151,6 +151,14 @@ "docs/commands/background" ] }, + { + "group": "Git", + "pages": [ + "docs/git/authentication", + "docs/git/clone", + "docs/git/create-repo" + ] + }, { "group": "MCP Gateway", "pages": [ @@ -323,4 +331,4 @@ "permanent": true } ] -} \ No newline at end of file +} diff --git a/docs/git/authentication.mdx b/docs/git/authentication.mdx new file mode 100644 index 0000000..d06a144 --- /dev/null +++ b/docs/git/authentication.mdx @@ -0,0 +1,123 @@ +--- +title: "Git authentication" +sidebarTitle: Authentication +--- + +Use the `sandbox.git` helper to authenticate for private repositories. The helper does not perform interactive prompts, so pass credentials explicitly or store them. + + +Git is available in the default sandbox template. If you’re using a custom or minimal template without git, install it first. See the [install custom packages](/docs/quickstart/install-custom-packages) guide or add git in your [template definition](/docs/template/defining-template). + + +## Authenticate per command + +For HTTP(S) repositories, pass `username` and `password` (token) to the command that needs it. A username is required whenever you pass a password/token. + + +```js JavaScript & TypeScript +import { Sandbox } from '@e2b/code-interpreter' + +const sandbox = await Sandbox.create() + +await sandbox.git.push('/workspace/repo', { + remote: 'origin', + branch: 'main', + setUpstream: true, + username: process.env.GIT_USERNAME, + password: process.env.GIT_TOKEN, +}) + +await sandbox.git.pull('/workspace/repo', { + remote: 'origin', + branch: 'main', + username: process.env.GIT_USERNAME, + password: process.env.GIT_TOKEN, +}) +``` +```python Python +import os +from e2b_code_interpreter import Sandbox + +sandbox = Sandbox.create() + +sandbox.git.push( + '/workspace/repo', + remote='origin', + branch='main', + set_upstream=True, + username=os.environ.get('GIT_USERNAME'), + password=os.environ.get('GIT_TOKEN'), +) + +sandbox.git.pull( + '/workspace/repo', + remote='origin', + branch='main', + username=os.environ.get('GIT_USERNAME'), + password=os.environ.get('GIT_TOKEN'), +) +``` + + +## Authenticate once (credential helper) + +If you want to avoid passing credentials on each command, you can store them in the git credential helper inside the sandbox. + + +`dangerouslyAuthenticate()` / `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. + + + +```js JavaScript & TypeScript +import { Sandbox } from '@e2b/code-interpreter' + +const sandbox = await Sandbox.create() + +await sandbox.git.dangerouslyAuthenticate({ + username: process.env.GIT_USERNAME, + password: process.env.GIT_TOKEN, + host: 'github.com', + protocol: 'https', +}) + +// After this, HTTPS git operations can use the stored credentials. +await sandbox.git.clone('https://github.com/org/private-repo.git', { + path: '/workspace/repo', +}) +await sandbox.git.push('/workspace/repo', { remote: 'origin', branch: 'main' }) +``` +```python Python +import os +from e2b_code_interpreter import Sandbox + +sandbox = Sandbox.create() + +sandbox.git.dangerously_authenticate( + username=os.environ.get('GIT_USERNAME'), + password=os.environ.get('GIT_TOKEN'), + host='github.com', + protocol='https', +) + +# After this, HTTPS git operations can use the stored credentials. +sandbox.git.clone('https://github.com/org/private-repo.git', path='/workspace/repo') +sandbox.git.push('/workspace/repo', remote='origin', branch='main') +``` + + +## Configure identity and config + +Set the global git author and other config values as needed. + + +```js JavaScript & TypeScript +await sandbox.git.configureUser('E2B Bot', 'bot@example.com') +await sandbox.git.configSet('pull.rebase', 'false') +const rebase = await sandbox.git.configGet('pull.rebase') +``` +```python Python +sandbox.git.configure_user('E2B Bot', 'bot@example.com') +sandbox.git.config_set('pull.rebase', 'false') +rebase = sandbox.git.config_get('pull.rebase') +``` + diff --git a/docs/git/clone.mdx b/docs/git/clone.mdx new file mode 100644 index 0000000..779c504 --- /dev/null +++ b/docs/git/clone.mdx @@ -0,0 +1,151 @@ +--- +title: "Clone a repository" +sidebarTitle: Clone +--- + +Use the `sandbox.git` helper to clone repositories into the sandbox. + + +Git is available in the default sandbox template. If you’re using a custom or minimal template without git, install it first. See the [install custom packages](/docs/quickstart/install-custom-packages) guide or add git in your [template definition](/docs/template/defining-template). + + +## Basic clone + + +```js JavaScript & TypeScript +import { Sandbox } from '@e2b/code-interpreter' + +const sandbox = await Sandbox.create() + +await sandbox.git.clone('https://github.com/org/repo.git', { + path: '/workspace/repo', + branch: 'main', + depth: 1, +}) +``` +```python Python +from e2b_code_interpreter import Sandbox + +sandbox = Sandbox.create() + +sandbox.git.clone( + 'https://github.com/org/repo.git', + path='/workspace/repo', + branch='main', + depth=1, +) +``` + + +## Clone with credentials + +For private repos over HTTP(S), pass `username` and `password` (token). By default, credentials are stripped from the remote URL after cloning. + + +```js JavaScript & TypeScript +await sandbox.git.clone('https://github.com/org/private-repo.git', { + path: '/workspace/private-repo', + username: process.env.GIT_USERNAME, + password: process.env.GIT_TOKEN, +}) +``` +```python Python +import os + +sandbox.git.clone( + 'https://github.com/org/private-repo.git', + path='/workspace/private-repo', + username=os.environ.get('GIT_USERNAME'), + password=os.environ.get('GIT_TOKEN'), +) +``` + + +## Keep credentials in the remote URL + +If you intentionally want to keep credentials in the cloned repository, set the `dangerouslyStoreCredentials` / `dangerously_store_credentials` flag. + + +Storing credentials in the repository remote persists them in the repo config. Any process or agent with access to the sandbox can read them. Only use this when required. + + + +```js JavaScript & TypeScript +await sandbox.git.clone('https://github.com/org/private-repo.git', { + username: process.env.GIT_USERNAME, + password: process.env.GIT_TOKEN, + dangerouslyStoreCredentials: true, +}) +``` +```python Python +import os + +sandbox.git.clone( + 'https://github.com/org/private-repo.git', + username=os.environ.get('GIT_USERNAME'), + password=os.environ.get('GIT_TOKEN'), + dangerously_store_credentials=True, +) +``` + + +## 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. + + +```js JavaScript & TypeScript +const status = await sandbox.git.status('/workspace/repo') +console.log(status.currentBranch, status.ahead, status.behind) +console.log(status.fileStatus) + +const branches = await sandbox.git.branches('/workspace/repo') +console.log(branches.currentBranch) +console.log(branches.branches) +``` +```python Python +status = sandbox.git.status('/workspace/repo') +print(status.current_branch, status.ahead, status.behind) +print(status.file_status) + +branches = sandbox.git.branches('/workspace/repo') +print(branches.current_branch) +print(branches.branches) +``` + + +## Manage branches + + +```js JavaScript & TypeScript +await sandbox.git.createBranch('/workspace/repo', 'feature/new-docs') +await sandbox.git.checkoutBranch('/workspace/repo', 'main') +await sandbox.git.deleteBranch('/workspace/repo', 'feature/old-docs', { force: true }) +``` +```python Python +sandbox.git.create_branch('/workspace/repo', 'feature/new-docs') +sandbox.git.checkout_branch('/workspace/repo', 'main') +sandbox.git.delete_branch('/workspace/repo', 'feature/old-docs', force=True) +``` + + +## Stage and commit + + +```js JavaScript & TypeScript +await sandbox.git.add('/workspace/repo', { all: true }) +await sandbox.git.commit('/workspace/repo', 'Initial commit', { + authorName: 'E2B Bot', + authorEmail: 'bot@example.com', +}) +``` +```python Python +sandbox.git.add('/workspace/repo', all=True) +sandbox.git.commit( + '/workspace/repo', + 'Initial commit', + author_name='E2B Bot', + author_email='bot@example.com', +) +``` + diff --git a/docs/git/create-repo.mdx b/docs/git/create-repo.mdx new file mode 100644 index 0000000..c3dad85 --- /dev/null +++ b/docs/git/create-repo.mdx @@ -0,0 +1,126 @@ +--- +title: "Create a GitHub repository" +sidebarTitle: Create repo +--- + +Use the `sandbox.git` helper to create GitHub repositories via the GitHub API and wire them up as remotes. + + +Git is available in the default sandbox template. If you’re using a custom or minimal template without git, install it first. See the [install custom packages](/docs/quickstart/install-custom-packages) guide or add git in your [template definition](/docs/template/defining-template). + + +## Create a repository (remote only) + +You can pass a token explicitly or set `GITHUB_PAT`, `GITHUB_TOKEN`, or `GH_TOKEN` in the environment. + + +```js JavaScript & TypeScript +import { Sandbox } from '@e2b/code-interpreter' + +const sandbox = await Sandbox.create() + +const repo = await sandbox.git.createGitHubRepo({ + name: 'demo-repo', + private: true, + token: process.env.GITHUB_TOKEN, + description: 'Docs example', +}) + +console.log(repo.cloneUrl) +``` +```python Python +import os +from e2b_code_interpreter import Sandbox + +sandbox = Sandbox.create() + +repo = sandbox.git.create_github_repo( + name='demo-repo', + private=True, + token=os.environ.get('GITHUB_TOKEN'), + description='Docs example', +) + +print(repo['clone_url']) +``` + + +## Create and add as a remote + +When you already have a local repository in the sandbox, you can add the created GitHub repo as a remote in one step. + + +```js JavaScript & TypeScript +const repo = await sandbox.git.createGitHubRepo({ + name: 'demo-repo', + private: true, + token: process.env.GITHUB_TOKEN, + addRemote: { + path: '/workspace/repo', + remoteName: 'origin', + fetch: true, + overwrite: true, + }, +}) + +console.log(repo.cloneUrl) +``` +```python Python +import os + +repo = sandbox.git.create_github_repo( + name='demo-repo', + private=True, + token=os.environ.get('GITHUB_TOKEN'), + add_remote_path='/workspace/repo', + add_remote_name='origin', + add_remote_fetch=True, + add_remote_overwrite=True, +) + +print(repo['clone_url']) +``` + + +## Add or update a remote manually + + +```js JavaScript & TypeScript +await sandbox.git.remoteAdd('/workspace/repo', 'origin', 'https://github.com/org/repo.git', { + fetch: true, + overwrite: true, +}) +``` +```python Python +sandbox.git.remote_add( + '/workspace/repo', + 'origin', + 'https://github.com/org/repo.git', + fetch=True, + overwrite=True, +) +``` + + +## GitHub Enterprise + +Use `apiBaseUrl` / `api_base_url` to target GitHub Enterprise. + + +```js JavaScript & TypeScript +await sandbox.git.createGitHubRepo({ + name: 'demo-repo', + token: process.env.GITHUB_TOKEN, + apiBaseUrl: 'https://github.example.com/api/v3', +}) +``` +```python Python +import os + +sandbox.git.create_github_repo( + name='demo-repo', + token=os.environ.get('GITHUB_TOKEN'), + api_base_url='https://github.example.com/api/v3', +) +``` + From 16f5d009d884ad7a3caeffbdf6bdd62619f91352 Mon Sep 17 00:00:00 2001 From: Matt Brockman Date: Wed, 28 Jan 2026 11:24:09 -0800 Subject: [PATCH 02/15] rm the github specific git commands (create repo) --- docs.json | 4 +- docs/git.mdx | 248 ++++++++++++++++++++++++++++++++++++ docs/git/authentication.mdx | 123 ------------------ docs/git/clone.mdx | 151 ---------------------- docs/git/create-repo.mdx | 126 ------------------ 5 files changed, 249 insertions(+), 403 deletions(-) create mode 100644 docs/git.mdx delete mode 100644 docs/git/authentication.mdx delete mode 100644 docs/git/clone.mdx delete mode 100644 docs/git/create-repo.mdx diff --git a/docs.json b/docs.json index 97e5e24..e6e6af5 100644 --- a/docs.json +++ b/docs.json @@ -154,9 +154,7 @@ { "group": "Git", "pages": [ - "docs/git/authentication", - "docs/git/clone", - "docs/git/create-repo" + "docs/git" ] }, { diff --git a/docs/git.mdx b/docs/git.mdx new file mode 100644 index 0000000..b514a48 --- /dev/null +++ b/docs/git.mdx @@ -0,0 +1,248 @@ +--- +title: "Git" +sidebarTitle: Overview +--- + +Use the `sandbox.git` helper to run common git operations inside a sandbox. The helper is non-interactive, so pass credentials explicitly or store them. + + +Git is available in the default sandbox template. If you're using a custom or minimal template without git, install it first. See the [install custom packages](/docs/quickstart/install-custom-packages) guide or add git in your [template definition](/docs/template/defining-template). + + +All examples below assume you already created a `sandbox` instance. + +## Clone a repository + + +```js JavaScript & TypeScript +import { Sandbox } from '@e2b/code-interpreter' + +const sandbox = await Sandbox.create() + +await sandbox.git.clone('https://git.example.com/org/repo.git', { + path: '/workspace/repo', + branch: 'main', + depth: 1, +}) +``` +```python Python +from e2b_code_interpreter import Sandbox + +sandbox = Sandbox.create() + +sandbox.git.clone( + 'https://git.example.com/org/repo.git', + path='/workspace/repo', + branch='main', + 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. + + +```js JavaScript & TypeScript +const status = await sandbox.git.status('/workspace/repo') +console.log(status.currentBranch, status.ahead, status.behind) +console.log(status.fileStatus) + +const branches = await sandbox.git.branches('/workspace/repo') +console.log(branches.currentBranch) +console.log(branches.branches) +``` +```python Python +status = sandbox.git.status('/workspace/repo') +print(status.current_branch, status.ahead, status.behind) +print(status.file_status) + +branches = sandbox.git.branches('/workspace/repo') +print(branches.current_branch) +print(branches.branches) +``` + + +## Create and manage branches + + +```js JavaScript & TypeScript +await sandbox.git.createBranch('/workspace/repo', 'feature/new-docs') +await sandbox.git.checkoutBranch('/workspace/repo', 'main') +await sandbox.git.deleteBranch('/workspace/repo', 'feature/old-docs', { force: true }) +``` +```python Python +sandbox.git.create_branch('/workspace/repo', 'feature/new-docs') +sandbox.git.checkout_branch('/workspace/repo', 'main') +sandbox.git.delete_branch('/workspace/repo', 'feature/old-docs', force=True) +``` + + +## Stage and commit + + +```js JavaScript & TypeScript +await sandbox.git.add('/workspace/repo', { all: true }) +await sandbox.git.commit('/workspace/repo', 'Initial commit', { + authorName: 'E2B Bot', + authorEmail: 'bot@example.com', +}) +``` +```python Python +sandbox.git.add('/workspace/repo', all=True) +sandbox.git.commit( + '/workspace/repo', + 'Initial commit', + author_name='E2B Bot', + author_email='bot@example.com', +) +``` + + +## Pull and push (with credentials) + +For private repos over HTTP(S), pass `username` and `password` (token) to the command that needs it. A username is required whenever you pass a password/token. + + +```js JavaScript & TypeScript +await sandbox.git.push('/workspace/repo', { + remote: 'origin', + branch: 'main', + setUpstream: true, + username: process.env.GIT_USERNAME, + password: process.env.GIT_TOKEN, +}) + +await sandbox.git.pull('/workspace/repo', { + remote: 'origin', + branch: 'main', + username: process.env.GIT_USERNAME, + password: process.env.GIT_TOKEN, +}) +``` +```python Python +import os + +sandbox.git.push( + '/workspace/repo', + remote='origin', + branch='main', + set_upstream=True, + username=os.environ.get('GIT_USERNAME'), + password=os.environ.get('GIT_TOKEN'), +) + +sandbox.git.pull( + '/workspace/repo', + remote='origin', + branch='main', + username=os.environ.get('GIT_USERNAME'), + password=os.environ.get('GIT_TOKEN'), +) +``` + + +## Manage remotes + + +```js JavaScript & TypeScript +await sandbox.git.remoteAdd('/workspace/repo', 'origin', 'https://git.example.com/org/repo.git', { + fetch: true, + overwrite: true, +}) +``` +```python Python +sandbox.git.remote_add( + '/workspace/repo', + 'origin', + 'https://git.example.com/org/repo.git', + fetch=True, + overwrite=True, +) +``` + + +## Authenticate once (credential helper) + +If you want to avoid passing credentials on each command, you can store them in the git credential helper inside the sandbox. + + +`dangerouslyAuthenticate()` / `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. + + + +```js JavaScript & TypeScript +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 can use the stored credentials. +await sandbox.git.clone('https://git.example.com/org/private-repo.git', { + path: '/workspace/repo', +}) +await sandbox.git.push('/workspace/repo', { remote: 'origin', branch: 'main' }) +``` +```python Python +import os + +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 can use the stored credentials. +sandbox.git.clone('https://git.example.com/org/private-repo.git', path='/workspace/repo') +sandbox.git.push('/workspace/repo', remote='origin', branch='main') +``` + + +## Keep credentials in the remote URL + +If you intentionally want to keep credentials in the cloned repository, set the `dangerouslyStoreCredentials` / `dangerously_store_credentials` flag. + + +Storing credentials in the repository remote persists them in the repo config. Any process or agent with access to the sandbox can read them. Only use this when required. + + + +```js JavaScript & TypeScript +await sandbox.git.clone('https://git.example.com/org/private-repo.git', { + username: process.env.GIT_USERNAME, + password: process.env.GIT_TOKEN, + dangerouslyStoreCredentials: true, +}) +``` +```python Python +import os + +sandbox.git.clone( + 'https://git.example.com/org/private-repo.git', + username=os.environ.get('GIT_USERNAME'), + password=os.environ.get('GIT_TOKEN'), + dangerously_store_credentials=True, +) +``` + + +## Configure identity and config + +Set the global git author and other config values as needed. + + +```js JavaScript & TypeScript +await sandbox.git.configureUser('E2B Bot', 'bot@example.com') +await sandbox.git.configSet('pull.rebase', 'false') +const rebase = await sandbox.git.configGet('pull.rebase') +``` +```python Python +sandbox.git.configure_user('E2B Bot', 'bot@example.com') +sandbox.git.config_set('pull.rebase', 'false') +rebase = sandbox.git.config_get('pull.rebase') +``` + diff --git a/docs/git/authentication.mdx b/docs/git/authentication.mdx deleted file mode 100644 index d06a144..0000000 --- a/docs/git/authentication.mdx +++ /dev/null @@ -1,123 +0,0 @@ ---- -title: "Git authentication" -sidebarTitle: Authentication ---- - -Use the `sandbox.git` helper to authenticate for private repositories. The helper does not perform interactive prompts, so pass credentials explicitly or store them. - - -Git is available in the default sandbox template. If you’re using a custom or minimal template without git, install it first. See the [install custom packages](/docs/quickstart/install-custom-packages) guide or add git in your [template definition](/docs/template/defining-template). - - -## Authenticate per command - -For HTTP(S) repositories, pass `username` and `password` (token) to the command that needs it. A username is required whenever you pass a password/token. - - -```js JavaScript & TypeScript -import { Sandbox } from '@e2b/code-interpreter' - -const sandbox = await Sandbox.create() - -await sandbox.git.push('/workspace/repo', { - remote: 'origin', - branch: 'main', - setUpstream: true, - username: process.env.GIT_USERNAME, - password: process.env.GIT_TOKEN, -}) - -await sandbox.git.pull('/workspace/repo', { - remote: 'origin', - branch: 'main', - username: process.env.GIT_USERNAME, - password: process.env.GIT_TOKEN, -}) -``` -```python Python -import os -from e2b_code_interpreter import Sandbox - -sandbox = Sandbox.create() - -sandbox.git.push( - '/workspace/repo', - remote='origin', - branch='main', - set_upstream=True, - username=os.environ.get('GIT_USERNAME'), - password=os.environ.get('GIT_TOKEN'), -) - -sandbox.git.pull( - '/workspace/repo', - remote='origin', - branch='main', - username=os.environ.get('GIT_USERNAME'), - password=os.environ.get('GIT_TOKEN'), -) -``` - - -## Authenticate once (credential helper) - -If you want to avoid passing credentials on each command, you can store them in the git credential helper inside the sandbox. - - -`dangerouslyAuthenticate()` / `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. - - - -```js JavaScript & TypeScript -import { Sandbox } from '@e2b/code-interpreter' - -const sandbox = await Sandbox.create() - -await sandbox.git.dangerouslyAuthenticate({ - username: process.env.GIT_USERNAME, - password: process.env.GIT_TOKEN, - host: 'github.com', - protocol: 'https', -}) - -// After this, HTTPS git operations can use the stored credentials. -await sandbox.git.clone('https://github.com/org/private-repo.git', { - path: '/workspace/repo', -}) -await sandbox.git.push('/workspace/repo', { remote: 'origin', branch: 'main' }) -``` -```python Python -import os -from e2b_code_interpreter import Sandbox - -sandbox = Sandbox.create() - -sandbox.git.dangerously_authenticate( - username=os.environ.get('GIT_USERNAME'), - password=os.environ.get('GIT_TOKEN'), - host='github.com', - protocol='https', -) - -# After this, HTTPS git operations can use the stored credentials. -sandbox.git.clone('https://github.com/org/private-repo.git', path='/workspace/repo') -sandbox.git.push('/workspace/repo', remote='origin', branch='main') -``` - - -## Configure identity and config - -Set the global git author and other config values as needed. - - -```js JavaScript & TypeScript -await sandbox.git.configureUser('E2B Bot', 'bot@example.com') -await sandbox.git.configSet('pull.rebase', 'false') -const rebase = await sandbox.git.configGet('pull.rebase') -``` -```python Python -sandbox.git.configure_user('E2B Bot', 'bot@example.com') -sandbox.git.config_set('pull.rebase', 'false') -rebase = sandbox.git.config_get('pull.rebase') -``` - diff --git a/docs/git/clone.mdx b/docs/git/clone.mdx deleted file mode 100644 index 779c504..0000000 --- a/docs/git/clone.mdx +++ /dev/null @@ -1,151 +0,0 @@ ---- -title: "Clone a repository" -sidebarTitle: Clone ---- - -Use the `sandbox.git` helper to clone repositories into the sandbox. - - -Git is available in the default sandbox template. If you’re using a custom or minimal template without git, install it first. See the [install custom packages](/docs/quickstart/install-custom-packages) guide or add git in your [template definition](/docs/template/defining-template). - - -## Basic clone - - -```js JavaScript & TypeScript -import { Sandbox } from '@e2b/code-interpreter' - -const sandbox = await Sandbox.create() - -await sandbox.git.clone('https://github.com/org/repo.git', { - path: '/workspace/repo', - branch: 'main', - depth: 1, -}) -``` -```python Python -from e2b_code_interpreter import Sandbox - -sandbox = Sandbox.create() - -sandbox.git.clone( - 'https://github.com/org/repo.git', - path='/workspace/repo', - branch='main', - depth=1, -) -``` - - -## Clone with credentials - -For private repos over HTTP(S), pass `username` and `password` (token). By default, credentials are stripped from the remote URL after cloning. - - -```js JavaScript & TypeScript -await sandbox.git.clone('https://github.com/org/private-repo.git', { - path: '/workspace/private-repo', - username: process.env.GIT_USERNAME, - password: process.env.GIT_TOKEN, -}) -``` -```python Python -import os - -sandbox.git.clone( - 'https://github.com/org/private-repo.git', - path='/workspace/private-repo', - username=os.environ.get('GIT_USERNAME'), - password=os.environ.get('GIT_TOKEN'), -) -``` - - -## Keep credentials in the remote URL - -If you intentionally want to keep credentials in the cloned repository, set the `dangerouslyStoreCredentials` / `dangerously_store_credentials` flag. - - -Storing credentials in the repository remote persists them in the repo config. Any process or agent with access to the sandbox can read them. Only use this when required. - - - -```js JavaScript & TypeScript -await sandbox.git.clone('https://github.com/org/private-repo.git', { - username: process.env.GIT_USERNAME, - password: process.env.GIT_TOKEN, - dangerouslyStoreCredentials: true, -}) -``` -```python Python -import os - -sandbox.git.clone( - 'https://github.com/org/private-repo.git', - username=os.environ.get('GIT_USERNAME'), - password=os.environ.get('GIT_TOKEN'), - dangerously_store_credentials=True, -) -``` - - -## 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. - - -```js JavaScript & TypeScript -const status = await sandbox.git.status('/workspace/repo') -console.log(status.currentBranch, status.ahead, status.behind) -console.log(status.fileStatus) - -const branches = await sandbox.git.branches('/workspace/repo') -console.log(branches.currentBranch) -console.log(branches.branches) -``` -```python Python -status = sandbox.git.status('/workspace/repo') -print(status.current_branch, status.ahead, status.behind) -print(status.file_status) - -branches = sandbox.git.branches('/workspace/repo') -print(branches.current_branch) -print(branches.branches) -``` - - -## Manage branches - - -```js JavaScript & TypeScript -await sandbox.git.createBranch('/workspace/repo', 'feature/new-docs') -await sandbox.git.checkoutBranch('/workspace/repo', 'main') -await sandbox.git.deleteBranch('/workspace/repo', 'feature/old-docs', { force: true }) -``` -```python Python -sandbox.git.create_branch('/workspace/repo', 'feature/new-docs') -sandbox.git.checkout_branch('/workspace/repo', 'main') -sandbox.git.delete_branch('/workspace/repo', 'feature/old-docs', force=True) -``` - - -## Stage and commit - - -```js JavaScript & TypeScript -await sandbox.git.add('/workspace/repo', { all: true }) -await sandbox.git.commit('/workspace/repo', 'Initial commit', { - authorName: 'E2B Bot', - authorEmail: 'bot@example.com', -}) -``` -```python Python -sandbox.git.add('/workspace/repo', all=True) -sandbox.git.commit( - '/workspace/repo', - 'Initial commit', - author_name='E2B Bot', - author_email='bot@example.com', -) -``` - diff --git a/docs/git/create-repo.mdx b/docs/git/create-repo.mdx deleted file mode 100644 index c3dad85..0000000 --- a/docs/git/create-repo.mdx +++ /dev/null @@ -1,126 +0,0 @@ ---- -title: "Create a GitHub repository" -sidebarTitle: Create repo ---- - -Use the `sandbox.git` helper to create GitHub repositories via the GitHub API and wire them up as remotes. - - -Git is available in the default sandbox template. If you’re using a custom or minimal template without git, install it first. See the [install custom packages](/docs/quickstart/install-custom-packages) guide or add git in your [template definition](/docs/template/defining-template). - - -## Create a repository (remote only) - -You can pass a token explicitly or set `GITHUB_PAT`, `GITHUB_TOKEN`, or `GH_TOKEN` in the environment. - - -```js JavaScript & TypeScript -import { Sandbox } from '@e2b/code-interpreter' - -const sandbox = await Sandbox.create() - -const repo = await sandbox.git.createGitHubRepo({ - name: 'demo-repo', - private: true, - token: process.env.GITHUB_TOKEN, - description: 'Docs example', -}) - -console.log(repo.cloneUrl) -``` -```python Python -import os -from e2b_code_interpreter import Sandbox - -sandbox = Sandbox.create() - -repo = sandbox.git.create_github_repo( - name='demo-repo', - private=True, - token=os.environ.get('GITHUB_TOKEN'), - description='Docs example', -) - -print(repo['clone_url']) -``` - - -## Create and add as a remote - -When you already have a local repository in the sandbox, you can add the created GitHub repo as a remote in one step. - - -```js JavaScript & TypeScript -const repo = await sandbox.git.createGitHubRepo({ - name: 'demo-repo', - private: true, - token: process.env.GITHUB_TOKEN, - addRemote: { - path: '/workspace/repo', - remoteName: 'origin', - fetch: true, - overwrite: true, - }, -}) - -console.log(repo.cloneUrl) -``` -```python Python -import os - -repo = sandbox.git.create_github_repo( - name='demo-repo', - private=True, - token=os.environ.get('GITHUB_TOKEN'), - add_remote_path='/workspace/repo', - add_remote_name='origin', - add_remote_fetch=True, - add_remote_overwrite=True, -) - -print(repo['clone_url']) -``` - - -## Add or update a remote manually - - -```js JavaScript & TypeScript -await sandbox.git.remoteAdd('/workspace/repo', 'origin', 'https://github.com/org/repo.git', { - fetch: true, - overwrite: true, -}) -``` -```python Python -sandbox.git.remote_add( - '/workspace/repo', - 'origin', - 'https://github.com/org/repo.git', - fetch=True, - overwrite=True, -) -``` - - -## GitHub Enterprise - -Use `apiBaseUrl` / `api_base_url` to target GitHub Enterprise. - - -```js JavaScript & TypeScript -await sandbox.git.createGitHubRepo({ - name: 'demo-repo', - token: process.env.GITHUB_TOKEN, - apiBaseUrl: 'https://github.example.com/api/v3', -}) -``` -```python Python -import os - -sandbox.git.create_github_repo( - name='demo-repo', - token=os.environ.get('GITHUB_TOKEN'), - api_base_url='https://github.example.com/api/v3', -) -``` - From f6994d2d306958c0c4a92e9e755f4097c6943616 Mon Sep 17 00:00:00 2001 From: Matt Brockman Date: Wed, 28 Jan 2026 15:30:13 -0800 Subject: [PATCH 03/15] config set/get changed --- docs/git.mdx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/git.mdx b/docs/git.mdx index b514a48..49d189d 100644 --- a/docs/git.mdx +++ b/docs/git.mdx @@ -237,12 +237,12 @@ Set the global git author and other config values as needed. ```js JavaScript & TypeScript await sandbox.git.configureUser('E2B Bot', 'bot@example.com') -await sandbox.git.configSet('pull.rebase', 'false') -const rebase = await sandbox.git.configGet('pull.rebase') +await sandbox.git.setConfig('pull.rebase', 'false') +const rebase = await sandbox.git.getConfig('pull.rebase') ``` ```python Python sandbox.git.configure_user('E2B Bot', 'bot@example.com') -sandbox.git.config_set('pull.rebase', 'false') -rebase = sandbox.git.config_get('pull.rebase') +sandbox.git.set_config('pull.rebase', 'false') +rebase = sandbox.git.get_config('pull.rebase') ``` From f209caf19c4e19071953fa73b91b25c57eca59e6 Mon Sep 17 00:00:00 2001 From: Matt Brockman Date: Thu, 29 Jan 2026 11:44:08 -0800 Subject: [PATCH 04/15] fully spell out repositories --- docs/git.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/git.mdx b/docs/git.mdx index 49d189d..2e2f767 100644 --- a/docs/git.mdx +++ b/docs/git.mdx @@ -102,7 +102,7 @@ sandbox.git.commit( ## Pull and push (with credentials) -For private repos over HTTP(S), pass `username` and `password` (token) to the command that needs it. A username is required whenever you pass a password/token. +For private repositories over HTTP(S), pass `username` and `password` (token) to the command that needs it. A username is required whenever you pass a password/token. ```js JavaScript & TypeScript From 495750a0a50b8308a9ea9a9242dd2de1ed2c8ad4 Mon Sep 17 00:00:00 2001 From: Matt Brockman Date: Thu, 29 Jan 2026 12:04:14 -0800 Subject: [PATCH 05/15] change wording to method --- docs/git.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/git.mdx b/docs/git.mdx index 2e2f767..50e2c95 100644 --- a/docs/git.mdx +++ b/docs/git.mdx @@ -3,7 +3,7 @@ title: "Git" sidebarTitle: Overview --- -Use the `sandbox.git` helper to run common git operations inside a sandbox. The helper is non-interactive, so pass credentials explicitly or store them. +Use the `sandbox.git` methods to run common git operations inside a sandbox. Git is available in the default sandbox template. If you're using a custom or minimal template without git, install it first. See the [install custom packages](/docs/quickstart/install-custom-packages) guide or add git in your [template definition](/docs/template/defining-template). From 7cc025f609982c765a8381e40b0794878c2e6879 Mon Sep 17 00:00:00 2001 From: Matt Brockman Date: Thu, 29 Jan 2026 12:04:28 -0800 Subject: [PATCH 06/15] git now will be on box by default --- docs/git.mdx | 6 ------ 1 file changed, 6 deletions(-) diff --git a/docs/git.mdx b/docs/git.mdx index 50e2c95..1a84adc 100644 --- a/docs/git.mdx +++ b/docs/git.mdx @@ -5,12 +5,6 @@ sidebarTitle: Overview Use the `sandbox.git` methods to run common git operations inside a sandbox. - -Git is available in the default sandbox template. If you're using a custom or minimal template without git, install it first. See the [install custom packages](/docs/quickstart/install-custom-packages) guide or add git in your [template definition](/docs/template/defining-template). - - -All examples below assume you already created a `sandbox` instance. - ## Clone a repository From f8345bb9deb2db11f436b8f59ed99dcb425fdacd Mon Sep 17 00:00:00 2001 From: Matt Brockman Date: Thu, 29 Jan 2026 12:05:15 -0800 Subject: [PATCH 07/15] don't need to pass default values --- docs/git.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/git.mdx b/docs/git.mdx index 1a84adc..0b69358 100644 --- a/docs/git.mdx +++ b/docs/git.mdx @@ -64,12 +64,12 @@ print(branches.branches) ```js JavaScript & TypeScript await sandbox.git.createBranch('/workspace/repo', 'feature/new-docs') await sandbox.git.checkoutBranch('/workspace/repo', 'main') -await sandbox.git.deleteBranch('/workspace/repo', 'feature/old-docs', { force: true }) +await sandbox.git.deleteBranch('/workspace/repo', 'feature/old-docs') ``` ```python Python sandbox.git.create_branch('/workspace/repo', 'feature/new-docs') sandbox.git.checkout_branch('/workspace/repo', 'main') -sandbox.git.delete_branch('/workspace/repo', 'feature/old-docs', force=True) +sandbox.git.delete_branch('/workspace/repo', 'feature/old-docs') ``` @@ -77,7 +77,7 @@ sandbox.git.delete_branch('/workspace/repo', 'feature/old-docs', force=True) ```js JavaScript & TypeScript -await sandbox.git.add('/workspace/repo', { all: true }) +await sandbox.git.add('/workspace/repo') await sandbox.git.commit('/workspace/repo', 'Initial commit', { authorName: 'E2B Bot', authorEmail: 'bot@example.com', From b4ab292d47bec4c3f2abf13890d355ca6ce158a7 Mon Sep 17 00:00:00 2001 From: Matt Brockman Date: Thu, 29 Jan 2026 12:05:45 -0800 Subject: [PATCH 08/15] rm the protocal stuff, only support https now --- docs/git.mdx | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/git.mdx b/docs/git.mdx index 0b69358..274ed9e 100644 --- a/docs/git.mdx +++ b/docs/git.mdx @@ -171,7 +171,6 @@ 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 can use the stored credentials. @@ -187,7 +186,6 @@ 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 can use the stored credentials. From 80717331edca38ebffec631945dac4e0647cbb7e Mon Sep 17 00:00:00 2001 From: Matt Brockman Date: Thu, 29 Jan 2026 12:20:13 -0800 Subject: [PATCH 09/15] rm the sandbox imports, can import any sandbox type --- docs/git.mdx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/docs/git.mdx b/docs/git.mdx index 274ed9e..0cc7fb9 100644 --- a/docs/git.mdx +++ b/docs/git.mdx @@ -9,8 +9,6 @@ Use the `sandbox.git` methods to run common git operations inside a sandbox. ```js JavaScript & TypeScript -import { Sandbox } from '@e2b/code-interpreter' - const sandbox = await Sandbox.create() await sandbox.git.clone('https://git.example.com/org/repo.git', { @@ -20,8 +18,6 @@ await sandbox.git.clone('https://git.example.com/org/repo.git', { }) ``` ```python Python -from e2b_code_interpreter import Sandbox - sandbox = Sandbox.create() sandbox.git.clone( From 6650624d8a260eecfa0d14d81f8af831c2f761df Mon Sep 17 00:00:00 2001 From: Matt Brockman Date: Thu, 29 Jan 2026 12:26:55 -0800 Subject: [PATCH 10/15] rm optional params --- docs/git.mdx | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/docs/git.mdx b/docs/git.mdx index 0cc7fb9..63f981b 100644 --- a/docs/git.mdx +++ b/docs/git.mdx @@ -80,7 +80,7 @@ await sandbox.git.commit('/workspace/repo', 'Initial commit', { }) ``` ```python Python -sandbox.git.add('/workspace/repo', all=True) +sandbox.git.add('/workspace/repo') sandbox.git.commit( '/workspace/repo', 'Initial commit', @@ -97,16 +97,11 @@ For private repositories over HTTP(S), pass `username` and `password` (token) to ```js JavaScript & TypeScript await sandbox.git.push('/workspace/repo', { - remote: 'origin', - branch: 'main', - setUpstream: true, username: process.env.GIT_USERNAME, password: process.env.GIT_TOKEN, }) await sandbox.git.pull('/workspace/repo', { - remote: 'origin', - branch: 'main', username: process.env.GIT_USERNAME, password: process.env.GIT_TOKEN, }) @@ -116,17 +111,12 @@ import os sandbox.git.push( '/workspace/repo', - remote='origin', - branch='main', - set_upstream=True, username=os.environ.get('GIT_USERNAME'), password=os.environ.get('GIT_TOKEN'), ) sandbox.git.pull( '/workspace/repo', - remote='origin', - branch='main', username=os.environ.get('GIT_USERNAME'), password=os.environ.get('GIT_TOKEN'), ) @@ -173,7 +163,7 @@ await sandbox.git.dangerouslyAuthenticate({ await sandbox.git.clone('https://git.example.com/org/private-repo.git', { path: '/workspace/repo', }) -await sandbox.git.push('/workspace/repo', { remote: 'origin', branch: 'main' }) +await sandbox.git.push('/workspace/repo') ``` ```python Python import os @@ -186,7 +176,7 @@ sandbox.git.dangerously_authenticate( # After this, HTTPS git operations can use the stored credentials. sandbox.git.clone('https://git.example.com/org/private-repo.git', path='/workspace/repo') -sandbox.git.push('/workspace/repo', remote='origin', branch='main') +sandbox.git.push('/workspace/repo') ``` From d577e886a3feed8abceec3c58b6453e79bd7bcdb Mon Sep 17 00:00:00 2001 From: Matt Brockman Date: Thu, 29 Jan 2026 12:35:38 -0800 Subject: [PATCH 11/15] rm branch/depth on clone --- docs/git.mdx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/docs/git.mdx b/docs/git.mdx index 63f981b..42ca296 100644 --- a/docs/git.mdx +++ b/docs/git.mdx @@ -13,8 +13,6 @@ const sandbox = await Sandbox.create() await sandbox.git.clone('https://git.example.com/org/repo.git', { path: '/workspace/repo', - branch: 'main', - depth: 1, }) ``` ```python Python @@ -23,8 +21,6 @@ sandbox = Sandbox.create() sandbox.git.clone( 'https://git.example.com/org/repo.git', path='/workspace/repo', - branch='main', - depth=1, ) ``` From d23a98425161f49f0df2742cc7d5749b2805c6bc Mon Sep 17 00:00:00 2001 From: Matt Brockman Date: Thu, 29 Jan 2026 13:06:00 -0800 Subject: [PATCH 12/15] levels of extra options in the examples --- docs/git.mdx | 295 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 232 insertions(+), 63 deletions(-) diff --git a/docs/git.mdx b/docs/git.mdx index 42ca296..26b997c 100644 --- a/docs/git.mdx +++ b/docs/git.mdx @@ -3,25 +3,38 @@ title: "Git" sidebarTitle: Overview --- -Use the `sandbox.git` methods to run common git operations inside a sandbox. +Use the `sandbox.git` methods to run common git operations inside a sandbox. Examples show a default call first, then common options. + +All examples below assume you already created a `sandbox` instance. ## Clone a repository ```js JavaScript & TypeScript -const sandbox = await Sandbox.create() +const repoUrl = 'https://git.example.com/org/repo.git' +const repoPath = '/home/user/repo' -await sandbox.git.clone('https://git.example.com/org/repo.git', { - path: '/workspace/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 }) ``` ```python Python -sandbox = Sandbox.create() +repo_url = "https://git.example.com/org/repo.git" +repo_path = "/home/user/repo" -sandbox.git.clone( - 'https://git.example.com/org/repo.git', - path='/workspace/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) ``` @@ -31,20 +44,24 @@ sandbox.git.clone( ```js JavaScript & TypeScript -const status = await sandbox.git.status('/workspace/repo') +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('/workspace/repo') +const branches = await sandbox.git.branches(repoPath) console.log(branches.currentBranch) console.log(branches.branches) ``` ```python Python -status = sandbox.git.status('/workspace/repo') +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('/workspace/repo') +branches = sandbox.git.branches(repo_path) print(branches.current_branch) print(branches.branches) ``` @@ -54,14 +71,34 @@ print(branches.branches) ```js JavaScript & TypeScript -await sandbox.git.createBranch('/workspace/repo', 'feature/new-docs') -await sandbox.git.checkoutBranch('/workspace/repo', 'main') -await sandbox.git.deleteBranch('/workspace/repo', 'feature/old-docs') +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 }) ``` ```python Python -sandbox.git.create_branch('/workspace/repo', 'feature/new-docs') -sandbox.git.checkout_branch('/workspace/repo', 'main') -sandbox.git.delete_branch('/workspace/repo', 'feature/old-docs') +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) ``` @@ -69,19 +106,39 @@ sandbox.git.delete_branch('/workspace/repo', 'feature/old-docs') ```js JavaScript & TypeScript -await sandbox.git.add('/workspace/repo') -await sandbox.git.commit('/workspace/repo', 'Initial 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, }) ``` ```python Python -sandbox.git.add('/workspace/repo') +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( - '/workspace/repo', - 'Initial commit', - author_name='E2B Bot', - author_email='bot@example.com', + repo_path, + "Docs sync", + author_name="E2B Bot", + author_email="bot@example.com", + allow_empty=True, ) ``` @@ -90,14 +147,35 @@ sandbox.git.commit( For private repositories over HTTP(S), pass `username` and `password` (token) to the command that needs it. A username is required whenever you pass a password/token. +If the repository has multiple remotes, pass `remote` when using credentials. + ```js JavaScript & TypeScript -await sandbox.git.push('/workspace/repo', { +const repoPath = '/home/user/repo' + +// Default (uses upstream when set) +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, }) -await sandbox.git.pull('/workspace/repo', { +// Target a specific remote/branch and set upstream +await sandbox.git.push(repoPath, { + remote: 'origin', + branch: 'main', + setUpstream: true, + username: process.env.GIT_USERNAME, + password: process.env.GIT_TOKEN, +}) + +await sandbox.git.pull(repoPath, { + remote: 'origin', + branch: 'main', username: process.env.GIT_USERNAME, password: process.env.GIT_TOKEN, }) @@ -105,16 +183,37 @@ await sandbox.git.pull('/workspace/repo', { ```python Python import os +repo_path = "/home/user/repo" + +# Default (uses upstream when set) sandbox.git.push( - '/workspace/repo', - username=os.environ.get('GIT_USERNAME'), - password=os.environ.get('GIT_TOKEN'), + repo_path, + username=os.environ.get("GIT_USERNAME"), + password=os.environ.get("GIT_TOKEN"), ) sandbox.git.pull( - '/workspace/repo', - username=os.environ.get('GIT_USERNAME'), - password=os.environ.get('GIT_TOKEN'), + repo_path, + username=os.environ.get("GIT_USERNAME"), + password=os.environ.get("GIT_TOKEN"), +) + +# Target a specific remote/branch and set upstream +sandbox.git.push( + repo_path, + remote="origin", + branch="main", + set_upstream=True, + username=os.environ.get("GIT_USERNAME"), + password=os.environ.get("GIT_TOKEN"), +) + +sandbox.git.pull( + repo_path, + remote="origin", + branch="main", + username=os.environ.get("GIT_USERNAME"), + password=os.environ.get("GIT_TOKEN"), ) ``` @@ -123,19 +222,30 @@ sandbox.git.pull( ```js JavaScript & TypeScript -await sandbox.git.remoteAdd('/workspace/repo', 'origin', 'https://git.example.com/org/repo.git', { - fetch: true, - overwrite: true, -}) +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 }) ``` ```python Python -sandbox.git.remote_add( - '/workspace/repo', - 'origin', - 'https://git.example.com/org/repo.git', - fetch=True, - 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) ``` @@ -149,30 +259,50 @@ If you want to avoid passing credentials on each command, you can store them in ```js JavaScript & TypeScript +const repoUrl = 'https://git.example.com/org/private-repo.git' +const repoPath = '/home/user/repo' + +// Default (GitHub) +await sandbox.git.dangerouslyAuthenticate({ + username: process.env.GIT_USERNAME, + password: process.env.GIT_TOKEN, +}) + +// Custom host/protocol (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 can use the stored credentials. -await sandbox.git.clone('https://git.example.com/org/private-repo.git', { - path: '/workspace/repo', -}) -await sandbox.git.push('/workspace/repo') +await sandbox.git.clone(repoUrl, { path: repoPath }) +await sandbox.git.push(repoPath) ``` ```python Python import os +repo_url = "https://git.example.com/org/private-repo.git" +repo_path = "/home/user/repo" + +# Default (GitHub) +sandbox.git.dangerously_authenticate( + username=os.environ.get("GIT_USERNAME"), + password=os.environ.get("GIT_TOKEN"), +) + +# Custom host/protocol (self-hosted) sandbox.git.dangerously_authenticate( - username=os.environ.get('GIT_USERNAME'), - password=os.environ.get('GIT_TOKEN'), - host='git.example.com', + username=os.environ.get("GIT_USERNAME"), + password=os.environ.get("GIT_TOKEN"), + host="git.example.com", + protocol="https", ) # After this, HTTPS git operations can use the stored credentials. -sandbox.git.clone('https://git.example.com/org/private-repo.git', path='/workspace/repo') -sandbox.git.push('/workspace/repo') +sandbox.git.clone(repo_url, path=repo_path) +sandbox.git.push(repo_path) ``` @@ -186,7 +316,18 @@ Storing credentials in the repository remote persists them in the repo config. A ```js JavaScript & TypeScript -await sandbox.git.clone('https://git.example.com/org/private-repo.git', { +const repoUrl = 'https://git.example.com/org/private-repo.git' +const repoPath = '/home/user/repo' + +// Default: credentials are stripped from the remote URL +await sandbox.git.clone(repoUrl, { + path: repoPath, + username: process.env.GIT_USERNAME, + password: process.env.GIT_TOKEN, +}) + +// Keep credentials in the remote URL +await sandbox.git.clone(repoUrl, { username: process.env.GIT_USERNAME, password: process.env.GIT_TOKEN, dangerouslyStoreCredentials: true, @@ -195,10 +336,22 @@ await sandbox.git.clone('https://git.example.com/org/private-repo.git', { ```python Python import os +repo_url = "https://git.example.com/org/private-repo.git" +repo_path = "/home/user/repo" + +# Default: credentials are stripped from the remote URL +sandbox.git.clone( + repo_url, + path=repo_path, + 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/private-repo.git', - username=os.environ.get('GIT_USERNAME'), - password=os.environ.get('GIT_TOKEN'), + repo_url, + username=os.environ.get("GIT_USERNAME"), + password=os.environ.get("GIT_TOKEN"), dangerously_store_credentials=True, ) ``` @@ -206,17 +359,33 @@ sandbox.git.clone( ## Configure identity and config -Set the global git author and other config values as needed. +Set the git author and other config values as needed. ```js JavaScript & TypeScript +const repoPath = '/home/user/repo' + +// Default (global config) await sandbox.git.configureUser('E2B Bot', 'bot@example.com') await sandbox.git.setConfig('pull.rebase', 'false') const rebase = await sandbox.git.getConfig('pull.rebase') + +// Repo-local config +await sandbox.git.configureUser('E2B Bot', 'bot@example.com', { scope: 'local', path: repoPath }) +await sandbox.git.setConfig('pull.rebase', 'false', { scope: 'local', path: repoPath }) +const localRebase = await sandbox.git.getConfig('pull.rebase', { scope: 'local', path: repoPath }) ``` ```python Python -sandbox.git.configure_user('E2B Bot', 'bot@example.com') -sandbox.git.set_config('pull.rebase', 'false') -rebase = sandbox.git.get_config('pull.rebase') +repo_path = "/home/user/repo" + +# Default (global config) +sandbox.git.configure_user("E2B Bot", "bot@example.com") +sandbox.git.set_config("pull.rebase", "false") +rebase = sandbox.git.get_config("pull.rebase") + +# Repo-local config +sandbox.git.configure_user("E2B Bot", "bot@example.com", scope="local", path=repo_path) +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) ``` From 1eabc3ab23938b6711aa1e4f5a05a3cea427acad Mon Sep 17 00:00:00 2001 From: Matt Brockman Date: Thu, 29 Jan 2026 13:36:15 -0800 Subject: [PATCH 13/15] move auth to top --- docs/git.mdx | 332 ++++++++++++++++++++++++++++----------------------- 1 file changed, 182 insertions(+), 150 deletions(-) diff --git a/docs/git.mdx b/docs/git.mdx index 26b997c..82ed1a9 100644 --- a/docs/git.mdx +++ b/docs/git.mdx @@ -7,8 +7,180 @@ Use the `sandbox.git` methods to run common git operations inside a sandbox. Exa All examples below assume you already created a `sandbox` instance. +## Authentication & Identity + +### Passing credentials inline + +For private repositories over HTTP(S), pass `username` and `password` (token) directly to commands that need authentication. A username is required whenever you pass a password/token. + + +```js JavaScript & TypeScript +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, +}) +``` +```python Python +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 using `dangerouslyAuthenticate()` / `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. + + + +```js JavaScript & TypeScript +// 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') +``` +```python Python +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. + + + +```js JavaScript & TypeScript +// 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, +}) +``` +```python Python +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. + + +```js JavaScript & TypeScript +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 +}) +``` +```python Python +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 & Identity](#authentication--identity) for how to authenticate with private repositories. + ```js JavaScript & TypeScript const repoUrl = 'https://git.example.com/org/repo.git' @@ -143,60 +315,36 @@ sandbox.git.commit( ``` -## Pull and push (with credentials) - -For private repositories over HTTP(S), pass `username` and `password` (token) to the command that needs it. A username is required whenever you pass a password/token. +## Pull and push -If the repository has multiple remotes, pass `remote` when using credentials. +See [Authentication & Identity](#authentication--identity) for how to authenticate with private repositories. ```js JavaScript & TypeScript const repoPath = '/home/user/repo' // Default (uses upstream when set) -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, -}) +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, - username: process.env.GIT_USERNAME, - password: process.env.GIT_TOKEN, }) await sandbox.git.pull(repoPath, { remote: 'origin', branch: 'main', - username: process.env.GIT_USERNAME, - password: process.env.GIT_TOKEN, }) ``` ```python Python -import os - repo_path = "/home/user/repo" # Default (uses upstream when set) -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"), -) +sandbox.git.push(repo_path) +sandbox.git.pull(repo_path) # Target a specific remote/branch and set upstream sandbox.git.push( @@ -204,16 +352,12 @@ sandbox.git.push( remote="origin", branch="main", set_upstream=True, - username=os.environ.get("GIT_USERNAME"), - password=os.environ.get("GIT_TOKEN"), ) sandbox.git.pull( repo_path, remote="origin", branch="main", - username=os.environ.get("GIT_USERNAME"), - password=os.environ.get("GIT_TOKEN"), ) ``` @@ -249,142 +393,30 @@ sandbox.git.remote_add(repo_path, "origin", repo_url, overwrite=True) ``` -## Authenticate once (credential helper) - -If you want to avoid passing credentials on each command, you can store them in the git credential helper inside the sandbox. - - -`dangerouslyAuthenticate()` / `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. - - - -```js JavaScript & TypeScript -const repoUrl = 'https://git.example.com/org/private-repo.git' -const repoPath = '/home/user/repo' - -// Default (GitHub) -await sandbox.git.dangerouslyAuthenticate({ - username: process.env.GIT_USERNAME, - password: process.env.GIT_TOKEN, -}) - -// Custom host/protocol (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 can use the stored credentials. -await sandbox.git.clone(repoUrl, { path: repoPath }) -await sandbox.git.push(repoPath) -``` -```python Python -import os - -repo_url = "https://git.example.com/org/private-repo.git" -repo_path = "/home/user/repo" - -# Default (GitHub) -sandbox.git.dangerously_authenticate( - username=os.environ.get("GIT_USERNAME"), - password=os.environ.get("GIT_TOKEN"), -) - -# Custom host/protocol (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 can use the stored credentials. -sandbox.git.clone(repo_url, path=repo_path) -sandbox.git.push(repo_path) -``` - - -## Keep credentials in the remote URL - -If you intentionally want to keep credentials in the cloned repository, set the `dangerouslyStoreCredentials` / `dangerously_store_credentials` flag. - - -Storing credentials in the repository remote persists them in the repo config. Any process or agent with access to the sandbox can read them. Only use this when required. - - - -```js JavaScript & TypeScript -const repoUrl = 'https://git.example.com/org/private-repo.git' -const repoPath = '/home/user/repo' - -// Default: credentials are stripped from the remote URL -await sandbox.git.clone(repoUrl, { - path: repoPath, - username: process.env.GIT_USERNAME, - password: process.env.GIT_TOKEN, -}) - -// Keep credentials in the remote URL -await sandbox.git.clone(repoUrl, { - username: process.env.GIT_USERNAME, - password: process.env.GIT_TOKEN, - dangerouslyStoreCredentials: true, -}) -``` -```python Python -import os - -repo_url = "https://git.example.com/org/private-repo.git" -repo_path = "/home/user/repo" - -# Default: credentials are stripped from the remote URL -sandbox.git.clone( - repo_url, - path=repo_path, - username=os.environ.get("GIT_USERNAME"), - password=os.environ.get("GIT_TOKEN"), -) - -# Keep credentials in the remote URL -sandbox.git.clone( - repo_url, - username=os.environ.get("GIT_USERNAME"), - password=os.environ.get("GIT_TOKEN"), - dangerously_store_credentials=True, -) -``` - - -## Configure identity and config +## Git config -Set the git author and other config values as needed. +Set and get git configuration values. See [Configure git identity](#configure-git-identity) for configuring the commit author. ```js JavaScript & TypeScript const repoPath = '/home/user/repo' -// Default (global config) -await sandbox.git.configureUser('E2B Bot', 'bot@example.com') +// Global config await sandbox.git.setConfig('pull.rebase', 'false') const rebase = await sandbox.git.getConfig('pull.rebase') // Repo-local config -await sandbox.git.configureUser('E2B Bot', 'bot@example.com', { scope: 'local', path: repoPath }) await sandbox.git.setConfig('pull.rebase', 'false', { scope: 'local', path: repoPath }) const localRebase = await sandbox.git.getConfig('pull.rebase', { scope: 'local', path: repoPath }) ``` ```python Python repo_path = "/home/user/repo" -# Default (global config) -sandbox.git.configure_user("E2B Bot", "bot@example.com") +# Global config sandbox.git.set_config("pull.rebase", "false") rebase = sandbox.git.get_config("pull.rebase") # Repo-local config -sandbox.git.configure_user("E2B Bot", "bot@example.com", scope="local", path=repo_path) 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) ``` From bb060533ec3c893d84b86e960594fac2595a1369 Mon Sep 17 00:00:00 2001 From: Matt Brockman Date: Thu, 29 Jan 2026 15:19:47 -0800 Subject: [PATCH 14/15] use ### instead of ## --- docs/git.mdx | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/git.mdx b/docs/git.mdx index 82ed1a9..0a7a16e 100644 --- a/docs/git.mdx +++ b/docs/git.mdx @@ -7,9 +7,9 @@ Use the `sandbox.git` methods to run common git operations inside a sandbox. Exa All examples below assume you already created a `sandbox` instance. -## Authentication & Identity +### Authentication & Identity -### Passing credentials inline +#### Passing credentials inline For private repositories over HTTP(S), pass `username` and `password` (token) directly to commands that need authentication. A username is required whenever you pass a password/token. @@ -46,7 +46,7 @@ sandbox.git.pull( ``` -### Credential helper (authenticate once) +#### Credential helper (authenticate once) To avoid passing credentials on each command, store them in the git credential helper inside the sandbox using `dangerouslyAuthenticate()` / `dangerously_authenticate()`. @@ -97,7 +97,7 @@ sandbox.git.push("/home/user/repo") ``` -### Keep credentials in the remote URL +#### 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`. @@ -144,7 +144,7 @@ sandbox.git.clone( ``` -### Configure git identity +#### Configure git identity Set the git author name and email for commits. Configure globally or per-repository. @@ -177,7 +177,7 @@ sandbox.git.configure_user( ``` -## Clone a repository +### Clone a repository See [Authentication & Identity](#authentication--identity) for how to authenticate with private repositories. @@ -210,7 +210,7 @@ sandbox.git.clone(repo_url, path=repo_path, depth=1) ``` -## Check status and branches +### 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. @@ -239,7 +239,7 @@ print(branches.branches) ``` -## Create and manage branches +### Create and manage branches ```js JavaScript & TypeScript @@ -274,7 +274,7 @@ sandbox.git.delete_branch(repo_path, "feature/stale-docs", force=True) ``` -## Stage and commit +### Stage and commit ```js JavaScript & TypeScript @@ -315,7 +315,7 @@ sandbox.git.commit( ``` -## Pull and push +### Pull and push See [Authentication & Identity](#authentication--identity) for how to authenticate with private repositories. @@ -362,7 +362,7 @@ sandbox.git.pull( ``` -## Manage remotes +### Manage remotes ```js JavaScript & TypeScript @@ -393,7 +393,7 @@ sandbox.git.remote_add(repo_path, "origin", repo_url, overwrite=True) ``` -## Git config +### Git config Set and get git configuration values. See [Configure git identity](#configure-git-identity) for configuring the commit author. From 0baca9cf176b4ce584f636108ce8ecc27e460a86 Mon Sep 17 00:00:00 2001 From: Matt Brockman Date: Thu, 29 Jan 2026 16:56:19 -0800 Subject: [PATCH 15/15] rm extra description --- docs/git.mdx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/git.mdx b/docs/git.mdx index 0a7a16e..a0355a0 100644 --- a/docs/git.mdx +++ b/docs/git.mdx @@ -3,9 +3,7 @@ title: "Git" sidebarTitle: Overview --- -Use the `sandbox.git` methods to run common git operations inside a sandbox. Examples show a default call first, then common options. - -All examples below assume you already created a `sandbox` instance. +Use the `sandbox.git` methods to run common git operations inside a sandbox. ### Authentication & Identity