Sign Up

Git

class Git()

Provides Git operations within a Sandbox.

Example:

# Clone a repository
sandbox.git.clone(
    url="https://github.com/user/repo.git",
    path="workspace/repo"
)

# Check repository status
status = sandbox.git.status("workspace/repo")
print(f"Modified files: {status.modified}")

# Stage and commit changes
sandbox.git.add("workspace/repo", ["file.txt"])
sandbox.git.commit(
    path="workspace/repo",
    message="Update file",
    author="John Doe",
    email="john@example.com"
)

Git.__init__

def __init__(api_client: GitApi)

Initializes a new Git handler instance.

Arguments:

  • api_client GitApi - API client for Sandbox Git operations.

Git.add

@intercept_errors(message_prefix="Failed to add files: ")
@with_instrumentation()
def add(path: str,
        files: list[str],
        request_timeout: float | None = None) -> None

Stages the specified files for the next commit, similar to running 'git add' on the command line.

Arguments:

  • path str - Path to the Git repository root. Relative paths are resolved based on the sandbox working directory.
  • files list[str] - List of file paths or directories to stage, relative to the repository root.
  • request_timeout float | None - Optional client-side request timeout in seconds. Client-side only. It bounds how long the SDK waits for the HTTP response and does not cancel the operation on the server. Positive values under 1 second are rounded up to 1 second; 0 disables the client-side timeout and negative values are rejected.

Example:

# Stage a single file
sandbox.git.add("workspace/repo", ["file.txt"])

# Stage multiple files
sandbox.git.add("workspace/repo", [
    "src/main.py",
    "tests/test_main.py",
    "README.md"
])

Git.branches

@intercept_errors(message_prefix="Failed to list branches: ")
@with_instrumentation()
def branches(path: str,
             request_timeout: float | None = None) -> ListBranchResponse

Lists branches in the repository.

Arguments:

  • path str - Path to the Git repository root. Relative paths are resolved based on the sandbox working directory.
  • request_timeout float | None - Optional client-side request timeout in seconds. Client-side only. It bounds how long the SDK waits for the HTTP response and does not cancel the operation on the server. Positive values under 1 second are rounded up to 1 second; 0 disables the client-side timeout and negative values are rejected.

Returns:

  • ListBranchResponse - List of branches in the repository.

Example:

response = sandbox.git.branches("workspace/repo")
print(f"Branches: {response.branches}")

Git.clone

@intercept_errors(message_prefix="Failed to clone repository: ")
@with_instrumentation()
def clone(url: str,
          path: str,
          branch: str | None = None,
          commit_id: str | None = None,
          username: str | None = None,
          password: str | None = None,
          insecure_skip_tls: bool | None = None,
          depth: int | None = None,
          request_timeout: float | None = None) -> None

Clones a Git repository into the specified path. It supports cloning specific branches or commits, and can authenticate with the remote repository if credentials are provided.

Arguments:

  • url str - Repository URL to clone from.
  • path str - Path where the repository should be cloned. Relative paths are resolved based on the sandbox working directory.
  • branch str | None - Specific branch to clone. If not specified, clones the default branch.
  • commit_id str | None - Specific commit to clone. If specified, the repository will be left in a detached HEAD state at this commit.
  • username str | None - Git username for authentication.
  • password str | None - Git password or token for authentication.
  • insecure_skip_tls bool | None - Skip TLS certificate verification (insecure). Use only for trusted internal Git servers with self-signed or private-CA certs; credentials, if supplied, are transmitted over an unverified TLS connection.
  • depth int | None - Create a shallow clone truncated to the given number of commits.
  • request_timeout float | None - Optional client-side request timeout in seconds. Client-side only. It bounds how long the SDK waits for the HTTP response and does not cancel the operation on the server. Positive values under 1 second are rounded up to 1 second; 0 disables the client-side timeout and negative values are rejected.

Example:

# Clone the default branch
sandbox.git.clone(
    url="https://github.com/user/repo.git",
    path="workspace/repo"
)

# Clone a specific branch with authentication
sandbox.git.clone(
    url="https://github.com/user/private-repo.git",
    path="workspace/private",
    branch="develop",
    username="user",
    password="token"
)

# Clone a specific commit
sandbox.git.clone(
    url="https://github.com/user/repo.git",
    path="workspace/repo-old",
    commit_id="abc123"
)

Git.commit

@intercept_errors(message_prefix="Failed to commit changes: ")
@with_instrumentation()
def commit(path: str,
           message: str,
           author: str,
           email: str,
           allow_empty: bool = False,
           request_timeout: float | None = None) -> GitCommitResponse

Creates a new commit with the staged changes. Make sure to stage changes using the add() method before committing.

Arguments:

  • path str - Path to the Git repository root. Relative paths are resolved based on the sandbox working directory.
  • message str - Commit message describing the changes.
  • author str - Name of the commit author.
  • email str - Email address of the commit author.
  • allow_empty bool, optional - Allow creating an empty commit when no changes are staged. Defaults to False.
  • request_timeout float | None - Optional client-side request timeout in seconds. Client-side only. It bounds how long the SDK waits for the HTTP response and does not cancel the operation on the server. Positive values under 1 second are rounded up to 1 second; 0 disables the client-side timeout and negative values are rejected.

Example:

# Stage and commit changes
sandbox.git.add("workspace/repo", ["README.md"])
sandbox.git.commit(
    path="workspace/repo",
    message="Update documentation",
    author="John Doe",
    email="john@example.com",
    allow_empty=True
)

Git.push

@intercept_errors(message_prefix="Failed to push changes: ")
@with_instrumentation()
def push(path: str,
         username: str | None = None,
         password: str | None = None,
         branch: str | None = None,
         remote: str | None = None,
         set_upstream: bool = False,
         request_timeout: float | None = None) -> None

Pushes all local commits on the current branch to the remote repository. If the remote repository requires authentication, provide username and password/token.

Arguments:

  • path str - Path to the Git repository root. Relative paths are resolved based on the sandbox working directory.
  • username str | None - Git username for authentication.
  • password str | None - Git password or token for authentication.
  • branch str | None - Branch to push. Defaults to the current branch.
  • remote str | None - Remote to push to. Defaults to "origin".
  • set_upstream bool, optional - Record the pushed branch as the upstream tracking branch. Defaults to False.
  • request_timeout float | None - Optional client-side request timeout in seconds. Client-side only. It bounds how long the SDK waits for the HTTP response and does not cancel the operation on the server. Positive values under 1 second are rounded up to 1 second; 0 disables the client-side timeout and negative values are rejected.

Example:

# Push without authentication (for public repos or SSH)
sandbox.git.push("workspace/repo")

# Push with authentication
sandbox.git.push(
    path="workspace/repo",
    username="user",
    password="github_token"
)

# Push a new branch and set its upstream
sandbox.git.push("workspace/repo", branch="feature", set_upstream=True)

Git.pull

@intercept_errors(message_prefix="Failed to pull changes: ")
@with_instrumentation()
def pull(path: str,
         username: str | None = None,
         password: str | None = None,
         branch: str | None = None,
         remote: str | None = None,
         request_timeout: float | None = None) -> None

Pulls changes from the remote repository. If the remote repository requires authentication, provide username and password/token.

Arguments:

  • path str - Path to the Git repository root. Relative paths are resolved based on the sandbox working directory.
  • username str | None - Git username for authentication.
  • password str | None - Git password or token for authentication.
  • branch str | None - Branch to pull. Defaults to the current branch's upstream.
  • remote str | None - Remote to pull from. Defaults to "origin".
  • request_timeout float | None - Optional client-side request timeout in seconds. Client-side only. It bounds how long the SDK waits for the HTTP response and does not cancel the operation on the server. Positive values under 1 second are rounded up to 1 second; 0 disables the client-side timeout and negative values are rejected.

Example:

# Pull without authentication
sandbox.git.pull("workspace/repo")

# Pull with authentication
sandbox.git.pull(
    path="workspace/repo",
    username="user",
    password="github_token"
)

# Pull a specific branch from a specific remote
sandbox.git.pull("workspace/repo", remote="upstream", branch="main")

Git.status

@intercept_errors(message_prefix="Failed to get status: ")
@with_instrumentation()
def status(path: str, request_timeout: float | None = None) -> GitStatus

Gets the current Git repository status.

Arguments:

  • path str - Path to the Git repository root. Relative paths are resolved based on the sandbox working directory.
  • request_timeout float | None - Optional client-side request timeout in seconds. Client-side only. It bounds how long the SDK waits for the HTTP response and does not cancel the operation on the server. Positive values under 1 second are rounded up to 1 second; 0 disables the client-side timeout and negative values are rejected.

Returns:

  • GitStatus - Repository status information including:
    • current_branch: Current branch name
    • file_status: List of file statuses
    • ahead: Number of local commits not pushed to remote
    • behind: Number of remote commits not pulled locally
    • branch_published: Whether the branch has been published to the remote repository

Example:

status = sandbox.git.status("workspace/repo")
print(f"On branch: {status.current_branch}")
print(f"Commits ahead: {status.ahead}")
print(f"Commits behind: {status.behind}")

Git.checkout_branch

@intercept_errors(message_prefix="Failed to checkout branch: ")
@with_instrumentation()
def checkout_branch(path: str,
                    branch: str,
                    request_timeout: float | None = None) -> None

Checkout branch in the repository.

Arguments:

  • path str - Path to the Git repository root. Relative paths are resolved based on the sandbox working directory.
  • branch str - Name of the branch to checkout
  • request_timeout float | None - Optional client-side request timeout in seconds. Client-side only. It bounds how long the SDK waits for the HTTP response and does not cancel the operation on the server. Positive values under 1 second are rounded up to 1 second; 0 disables the client-side timeout and negative values are rejected.

Example:

# Checkout a branch
sandbox.git.checkout_branch("workspace/repo", "feature-branch")

Git.create_branch

@intercept_errors(message_prefix="Failed to create branch: ")
@with_instrumentation()
def create_branch(path: str,
                  name: str,
                  request_timeout: float | None = None) -> None

Create branch in the repository.

Arguments:

  • path str - Path to the Git repository root. Relative paths are resolved based on the sandbox working directory.
  • name str - Name of the new branch to create
  • request_timeout float | None - Optional client-side request timeout in seconds. Client-side only. It bounds how long the SDK waits for the HTTP response and does not cancel the operation on the server. Positive values under 1 second are rounded up to 1 second; 0 disables the client-side timeout and negative values are rejected.

Example:

# Create a new branch
sandbox.git.create_branch("workspace/repo", "new-feature")

Git.delete_branch

@intercept_errors(message_prefix="Failed to delete branch: ")
@with_instrumentation()
def delete_branch(path: str,
                  name: str,
                  request_timeout: float | None = None) -> None

Delete branch in the repository.

Arguments:

  • path str - Path to the Git repository root. Relative paths are resolved based on the sandbox working directory.
  • name str - Name of the branch to delete
  • request_timeout float | None - Optional client-side request timeout in seconds. Client-side only. It bounds how long the SDK waits for the HTTP response and does not cancel the operation on the server. Positive values under 1 second are rounded up to 1 second; 0 disables the client-side timeout and negative values are rejected.

Example:

# Delete a branch
sandbox.git.delete_branch("workspace/repo", "old-feature")

Git.init

@intercept_errors(message_prefix="Failed to initialize repository: ")
@with_instrumentation()
def init(path: str,
         bare: bool = False,
         initial_branch: str | None = None,
         request_timeout: float | None = None) -> None

Initializes a new Git repository at the specified path.

Arguments:

  • path str - Path where the repository should be initialized. Relative paths are resolved based on the sandbox working directory.
  • bare bool, optional - Create a bare repository without a working tree. Defaults to False.
  • initial_branch str | None - Name of the initial branch. If not specified, uses the Git default.
  • request_timeout float | None - Optional client-side request timeout in seconds. Client-side only. It bounds how long the SDK waits for the HTTP response and does not cancel the operation on the server. Positive values under 1 second are rounded up to 1 second; 0 disables the client-side timeout and negative values are rejected.

Example:

sandbox.git.init("workspace/repo", initial_branch="main")

Git.reset

@intercept_errors(message_prefix="Failed to reset: ")
@with_instrumentation()
def reset(path: str,
          mode: str | None = None,
          target: str | None = None,
          files: list[str] | None = None,
          request_timeout: float | None = None) -> None

Resets the current HEAD to the specified state.

Arguments:

  • path str - Path to the Git repository root. Relative paths are resolved based on the sandbox working directory.
  • mode str | None - Reset mode, one of "soft", "mixed" (default), "hard", "merge" or "keep".
  • target str | None - Revision to reset to. Defaults to HEAD.
  • files list[str] | None - Constrain the reset to the given paths.
  • request_timeout float | None - Optional client-side request timeout in seconds. Client-side only. It bounds how long the SDK waits for the HTTP response and does not cancel the operation on the server. Positive values under 1 second are rounded up to 1 second; 0 disables the client-side timeout and negative values are rejected.

Example:

# Unstage all changes (mixed reset to HEAD)
sandbox.git.reset("workspace/repo")

# Hard reset to a previous commit
sandbox.git.reset("workspace/repo", mode="hard", target="HEAD~1")

Git.restore

@intercept_errors(message_prefix="Failed to restore files: ")
@with_instrumentation()
def restore(path: str,
            files: list[str],
            staged: bool | None = None,
            worktree: bool | None = None,
            source: str | None = None,
            request_timeout: float | None = None) -> None

Restores working tree files or unstages changes.

Arguments:

  • path str - Path to the Git repository root. Relative paths are resolved based on the sandbox working directory.
  • files list[str] - File paths to restore.
  • staged bool | None - Restore the staging index for the given files.
  • worktree bool | None - Restore the working tree for the given files. Defaults to True when neither staged nor worktree is provided.
  • source str | None - Restore file contents from the given revision instead of the index.
  • request_timeout float | None - Optional client-side request timeout in seconds. Client-side only. It bounds how long the SDK waits for the HTTP response and does not cancel the operation on the server. Positive values under 1 second are rounded up to 1 second; 0 disables the client-side timeout and negative values are rejected.

Example:

# Discard working tree changes
sandbox.git.restore("workspace/repo", ["file.txt"])

# Unstage changes
sandbox.git.restore("workspace/repo", ["file.txt"], staged=True)

Git.remote_add

@intercept_errors(message_prefix="Failed to add remote: ")
@with_instrumentation()
def remote_add(path: str,
               name: str,
               url: str,
               fetch: bool = False,
               overwrite: bool = False,
               request_timeout: float | None = None) -> None

Adds (or overwrites) a remote in the repository.

Arguments:

  • path str - Path to the Git repository root. Relative paths are resolved based on the sandbox working directory.
  • name str - Name of the remote.
  • url str - URL of the remote.
  • fetch bool, optional - Fetch from the remote immediately after adding it. Defaults to False.
  • overwrite bool, optional - Replace an existing remote with the same name. Defaults to False.
  • request_timeout float | None - Optional client-side request timeout in seconds. Client-side only. It bounds how long the SDK waits for the HTTP response and does not cancel the operation on the server. Positive values under 1 second are rounded up to 1 second; 0 disables the client-side timeout and negative values are rejected.

Example:

sandbox.git.remote_add("workspace/repo", "origin", "https://github.com/user/repo.git")

Git.remotes

@intercept_errors(message_prefix="Failed to list remotes: ")
@with_instrumentation()
def remotes(path: str,
            request_timeout: float | None = None) -> ListRemotesResponse

Lists the remotes configured in the repository.

Arguments:

  • path str - Path to the Git repository root. Relative paths are resolved based on the sandbox working directory.
  • request_timeout float | None - Optional client-side request timeout in seconds. Client-side only. It bounds how long the SDK waits for the HTTP response and does not cancel the operation on the server. Positive values under 1 second are rounded up to 1 second; 0 disables the client-side timeout and negative values are rejected.

Returns:

  • ListRemotesResponse - The configured remotes (name + URL).

Example:

response = sandbox.git.remotes("workspace/repo")
for remote in response.remotes:
    print(f"{remote.name}: {remote.url}")

Git.remote_get

@intercept_errors(message_prefix="Failed to get remote: ")
@with_instrumentation()
def remote_get(path: str,
               name: str,
               request_timeout: float | None = None) -> str | None

Gets the URL of a remote, or None when it does not exist.

Arguments:

  • path str - Path to the Git repository root. Relative paths are resolved based on the sandbox working directory.
  • name str - Name of the remote.
  • request_timeout float | None - Optional client-side request timeout in seconds. Client-side only. It bounds how long the SDK waits for the HTTP response and does not cancel the operation on the server. Positive values under 1 second are rounded up to 1 second; 0 disables the client-side timeout and negative values are rejected.

Returns:

str | None: The remote URL, or None when the remote does not exist.

Example:

url = sandbox.git.remote_get("workspace/repo", "origin")

Git.set_config

@intercept_errors(message_prefix="Failed to set config: ")
@with_instrumentation()
def set_config(key: str,
               value: str,
               scope: str = "global",
               path: str | None = None,
               request_timeout: float | None = None) -> None

Sets a Git config value at the given scope.

Arguments:

  • key str - Config key in dotted form (e.g. "user.name").
  • value str - Config value.
  • scope str, optional - Config scope, one of "global" (default), "local" or "system".
  • path str | None - Repository path, required when scope is "local".
  • request_timeout float | None - Optional client-side request timeout in seconds. Client-side only. It bounds how long the SDK waits for the HTTP response and does not cancel the operation on the server. Positive values under 1 second are rounded up to 1 second; 0 disables the client-side timeout and negative values are rejected.

Example:

sandbox.git.set_config("user.name", "John Doe")

Git.get_config

@intercept_errors(message_prefix="Failed to get config: ")
@with_instrumentation()
def get_config(key: str,
               scope: str = "global",
               path: str | None = None,
               request_timeout: float | None = None) -> str | None

Gets a Git config value at the given scope, or None when unset.

Arguments:

  • key str - Config key in dotted form (e.g. "user.name").
  • scope str, optional - Config scope, one of "global" (default), "local" or "system".
  • path str | None - Repository path, required when scope is "local".
  • request_timeout float | None - Optional client-side request timeout in seconds. Client-side only. It bounds how long the SDK waits for the HTTP response and does not cancel the operation on the server. Positive values under 1 second are rounded up to 1 second; 0 disables the client-side timeout and negative values are rejected.

Returns:

str | None: The config value, or None when the key is not set.

Example:

name = sandbox.git.get_config("user.name")

Git.configure_user

@intercept_errors(message_prefix="Failed to configure user: ")
@with_instrumentation()
def configure_user(name: str,
                   email: str,
                   scope: str = "global",
                   path: str | None = None,
                   request_timeout: float | None = None) -> None

Configures the Git user name and email at the given scope.

Arguments:

  • name str - User name (user.name).
  • email str - User email (user.email).
  • scope str, optional - Config scope, one of "global" (default), "local" or "system".
  • path str | None - Repository path, required when scope is "local".
  • request_timeout float | None - Optional client-side request timeout in seconds. Client-side only. It bounds how long the SDK waits for the HTTP response and does not cancel the operation on the server. Positive values under 1 second are rounded up to 1 second; 0 disables the client-side timeout and negative values are rejected.

Example:

sandbox.git.configure_user("John Doe", "john@example.com")

Git.dangerously_authenticate

@intercept_errors(message_prefix="Failed to authenticate: ")
@with_instrumentation()
def dangerously_authenticate(username: str,
                             password: str,
                             host: str | None = None,
                             protocol: str | None = None,
                             request_timeout: float | None = None) -> None

Persists Git credentials globally so that subsequent operations against the given host authenticate automatically.

Warnings:

This stores the password in plaintext on disk via the Git credential store.

Arguments:

  • username str - Git username.
  • password str - Git password or token.
  • host str | None - Host to authenticate against. Defaults to "github.com".
  • protocol str | None - Protocol to authenticate against. Defaults to "https".
  • request_timeout float | None - Optional client-side request timeout in seconds. Client-side only. It bounds how long the SDK waits for the HTTP response and does not cancel the operation on the server. Positive values under 1 second are rounded up to 1 second; 0 disables the client-side timeout and negative values are rejected.

Example:

sandbox.git.dangerously_authenticate("user", "github_token")

GitCommitResponse

class GitCommitResponse()

Response from the git commit.

Attributes:

  • sha str - The SHA of the commit