Skip to main content
The Git API provides comprehensive Git repository management capabilities within sandbox environments, supporting authentication, branching, and all standard Git operations.

Overview

Daytona’s Git integration enables:
  • Repository cloning - Clone public and private repositories
  • Branch management - Create, checkout, and delete branches
  • Commit operations - Stage, commit, push, and pull changes
  • Status tracking - Monitor repository state and changes

Repository Cloning

Clone Public Repository

Clone a public repository with default branch:
await sandbox.git.clone(
  'https://github.com/user/repo.git',
  'workspace/repo'
);

Clone Specific Branch

Clone a specific branch:
await sandbox.git.clone(
  'https://github.com/user/repo.git',
  'workspace/repo',
  'develop' // branch name
);

Clone Private Repository

Clone with authentication credentials:
await sandbox.git.clone(
  'https://github.com/user/private-repo.git',
  'workspace/private',
  'main',          // branch
  undefined,       // commitId
  'username',      // GitHub username
  'ghp_token123'   // Personal access token
);

Clone Specific Commit

Clone and checkout a specific commit (detached HEAD):
await sandbox.git.clone(
  'https://github.com/user/repo.git',
  'workspace/repo',
  undefined,                    // branch
  'abc123def456'                // commit ID
);
url
string
required
Repository URL to clone from
path
string
required
Destination path in sandbox. Relative paths resolved from sandbox working directory.
branch
string
Specific branch to clone. If not specified, clones the default branch.
commitId
string
Specific commit to checkout. Repository will be in detached HEAD state.
username
string
Git username for authentication
password
string
Git password or personal access token for authentication

Branch Management

List Branches

Get all branches in the repository:
const response = await sandbox.git.branches('workspace/repo');

console.log('Branches:', response.branches);
console.log('Current branch:', response.current);

Create Branch

Create a new branch:
await sandbox.git.createBranch(
  'workspace/repo',
  'feature/new-feature'
);

Checkout Branch

Switch to an existing branch:
await sandbox.git.checkoutBranch(
  'workspace/repo',
  'develop'
);

Delete Branch

Delete a branch:
await sandbox.git.deleteBranch(
  'workspace/repo',
  'feature/old-feature'
);
path
string
required
Path to Git repository root. Relative paths resolved from sandbox working directory.
name
string
required
Branch name

Staging and Committing

Stage Files

Add files to the staging area:
// Stage specific files
await sandbox.git.add(
  'workspace/repo',
  ['file1.txt', 'file2.js']
);

// Stage all changes
await sandbox.git.add(
  'workspace/repo',
  ['.']
);

Commit Changes

Commit staged changes:
const response = await sandbox.git.commit(
  'workspace/repo',
  'Add new feature',           // commit message
  'John Doe',                  // author name
  '[email protected]',          // author email
  false                        // allowEmpty
);

console.log('Commit SHA:', response.sha);

Create Empty Commit

Create a commit without changes:
const response = await sandbox.git.commit(
  'workspace/repo',
  'Trigger CI',
  'John Doe',
  '[email protected]',
  true  // allowEmpty
);
files
string[]
required
List of file paths or directories to stage, relative to repository root
message
string
required
Commit message describing the changes
author
string
required
Name of the commit author
email
string
required
Email address of the commit author
allowEmpty
boolean
Allow creating an empty commit when no changes are staged

Push and Pull

Push to Remote

Push local commits to remote repository:
// Push to public repository
await sandbox.git.push('workspace/repo');

// Push to private repository with authentication
await sandbox.git.push(
  'workspace/repo',
  'username',
  'token'
);

Pull from Remote

Pull changes from remote repository:
// Pull from public repository
await sandbox.git.pull('workspace/repo');

// Pull from private repository with authentication
await sandbox.git.pull(
  'workspace/repo',
  'username',
  'token'
);
username
string
Git username for authentication
password
string
Git password or token for authentication

Repository Status

Get Status

Check repository status:
const status = await sandbox.git.status('workspace/repo');

console.log('Current branch:', status.currentBranch);
console.log('Commits ahead:', status.ahead);
console.log('Commits behind:', status.behind);
console.log('Branch published:', status.branchPublished);

// Check file status
status.fileStatus.forEach(file => {
  console.log(`${file.status}: ${file.path}`);
});
Status Response:
interface GitStatus {
  currentBranch: string;      // Name of current branch
  ahead: number;              // Commits ahead of remote
  behind: number;             // Commits behind remote
  branchPublished: boolean;   // Whether branch exists on remote
  fileStatus: FileStatus[];   // List of file changes
}

Complete Workflow Example

import { Daytona } from '@daytonaio/sdk';

const daytona = new Daytona();
const sandbox = await daytona.create();

try {
  const repoPath = 'workspace/myproject';
  
  // Clone repository
  await sandbox.git.clone(
    'https://github.com/user/project.git',
    repoPath,
    'main'
  );
  
  // Create and checkout new branch
  await sandbox.git.createBranch(repoPath, 'feature/update-readme');
  await sandbox.git.checkoutBranch(repoPath, 'feature/update-readme');
  
  // Make changes to files
  await sandbox.fs.uploadFile(
    Buffer.from('# Updated README'),
    `${repoPath}/README.md`
  );
  
  // Check status
  const status = await sandbox.git.status(repoPath);
  console.log('Modified files:', status.fileStatus.length);
  
  // Stage and commit
  await sandbox.git.add(repoPath, ['README.md']);
  const commit = await sandbox.git.commit(
    repoPath,
    'Update README with new information',
    'Developer',
    '[email protected]'
  );
  
  console.log('Created commit:', commit.sha);
  
  // Push changes (with authentication)
  await sandbox.git.push(
    repoPath,
    'username',
    'personal_access_token'
  );
  
  console.log('Changes pushed successfully!');
  
} finally {
  await daytona.delete(sandbox);
}

Authentication Best Practices

For GitHub and GitLab, use personal access tokens instead of passwords:
  • GitHub: Generate at Settings → Developer settings → Personal access tokens
  • GitLab: Generate at User Settings → Access Tokens
Tokens should have appropriate scopes (repo read/write).
Never hardcode credentials. Use environment variables or secret management:
const token = process.env.GITHUB_TOKEN;
await sandbox.git.clone(url, path, branch, undefined, username, token);
For automated workflows, consider using SSH keys instead of HTTPS with tokens.

Error Handling

try {
  await sandbox.git.clone(
    'https://github.com/user/repo.git',
    'workspace/repo'
  );
} catch (error) {
  if (error.message.includes('authentication failed')) {
    console.error('Invalid credentials');
  } else if (error.message.includes('not found')) {
    console.error('Repository does not exist');
  } else {
    console.error('Clone failed:', error.message);
  }
}

File System

Manage files and directories in sandboxes

Language Server Protocol

Code intelligence for repository analysis

Build docs developers (and LLMs) love