Skip to main content
This example demonstrates how to work with Git repositories in Daytona sandboxes, including cloning, status checking, and using the Language Server Protocol (LSP).

What You’ll Learn

  • Cloning Git repositories
  • Pulling latest changes
  • Checking repository status
  • Listing branches
  • Integrating with LSP for code intelligence
  • Finding and modifying code

Complete Example

from daytona import CreateSandboxFromImageParams, Daytona, Image, LspCompletionPosition


def main():
    daytona = Daytona()

    sandbox = daytona.create(
        CreateSandboxFromImageParams(
            image=(
                Image.base("ubuntu:25.10").run_commands(
                    "apt-get update && apt-get install -y --no-install-recommends nodejs npm coreutils",
                    "curl -fsSL https://deb.nodesource.com/setup_20.x | bash -",
                    "apt-get install -y nodejs",
                    "npm install -g ts-node typescript typescript-language-server",
                )
            ),
        ),
        timeout=200,
        on_snapshot_create_logs=print,
    )

    try:
        project_dir = "learn-typescript"

        # Clone the repository
        sandbox.git.clone(
            "https://github.com/panaverse/learn-typescript",
            project_dir,
            "master",
        )

        sandbox.git.pull(project_dir)

        # Search for the file we want to work on
        matches = sandbox.fs.find_files(project_dir, "var obj1 = new Base();")
        print("Matches:", matches)

        # Start the language server
        lsp = sandbox.create_lsp_server("typescript", project_dir)
        lsp.start()

        # Notify the language server of the document we want to work on
        lsp.did_open(matches[0].file)

        # Get symbols in the document
        symbols = lsp.document_symbols(matches[0].file)
        print("Symbols:", symbols)

        # Fix the error in the document
        _ = sandbox.fs.replace_in_files([matches[0].file], "var obj1 = new Base();", "var obj1 = new E();")

        # Notify the language server of the document change
        lsp.did_close(matches[0].file)
        lsp.did_open(matches[0].file)

        # Get completions at a specific position
        completions = lsp.completions(matches[0].file, LspCompletionPosition(line=12, character=18))
        print("Completions:", completions)

    except Exception as error:
        print("Error executing example:", error)
    finally:
        # Cleanup
        daytona.delete(sandbox)


if __name__ == "__main__":
    main()

Expected Output

Creating sandbox...
[Build logs...]
Cloning repository...
Matches: {"files": [{"file": "learn-typescript/step08_classes/class.ts", "line": 15}]}
Starting LSP server...
Symbols: [{"name": "Base", "kind": "class", ...}]
Replacing content...
Completions: [{"label": "E", "kind": "class", ...}]

Key Concepts

Cloning Repositories

Clone any public or private Git repository:
# Public repository
sandbox.git.clone(
    "https://github.com/user/repo.git",
    "local-dir",
    "main"  # branch name
)

# Private repository with auth
sandbox.git.clone(
    "https://github.com/user/private-repo.git",
    "local-dir",
    "main",
    username="your-username",
    password="ghp_your_token"
)

Git Status and Branches

Check repository status and available branches:
# Get status
status = sandbox.git.status("repo-dir")
print(f"Branch: {status.current_branch}")
print(f"Modified files: {status.modified}")

# List branches
branches = sandbox.git.branches("repo-dir")
for branch in branches:
    print(f"  - {branch}")

Language Server Protocol (LSP)

Use LSP for code intelligence:
# Create LSP server for TypeScript
lsp = sandbox.create_lsp_server("typescript", "project-dir")
lsp.start()

# Open a file
lsp.did_open("src/index.ts")

# Get completions
completions = lsp.completions(
    "src/index.ts",
    LspCompletionPosition(line=10, character=5)
)

# Get symbols
symbols = lsp.document_symbols("src/index.ts")

# Close when done
lsp.did_close("src/index.ts")
Supported LSP languages:
  • typescript / javascript
  • python
  • go
  • rust
  • java
  • And more…

Finding Code

Search for code patterns across files:
# Find specific text
matches = sandbox.fs.find_files("project-dir", "function handleClick")

for match in matches:
    print(f"Found in {match.file} at line {match.line}")
    print(f"Content: {match.content}")

Common Workflows

Clone, Modify, and Analyze

# 1. Clone repository
sandbox.git.clone("https://github.com/user/project", "project")

# 2. Find files to modify
matches = sandbox.fs.find_files("project", "TODO:")

# 3. Replace content
for match in matches:
    sandbox.fs.replace_in_files(
        [match.file],
        "TODO: implement this",
        "# Implementation complete"
    )

# 4. Check status
status = sandbox.git.status("project")
print(f"Modified: {status.modified}")

Code Intelligence Workflow

# 1. Clone and setup LSP
sandbox.git.clone(repo_url, "project")
lsp = sandbox.create_lsp_server("python", "project")
lsp.start()

# 2. Analyze code
lsp.did_open("project/main.py")
symbols = lsp.document_symbols("project/main.py")

# 3. Get completions for refactoring
completions = lsp.completions(
    "project/main.py",
    LspCompletionPosition(line=20, character=10)
)

# 4. Make changes and re-analyze
sandbox.fs.replace_in_files(["project/main.py"], old, new)
lsp.did_close("project/main.py")
lsp.did_open("project/main.py")

Best Practices

Use shallow clones: For large repositories, consider cloning only recent history to save time and space.
Authentication: For private repositories, use personal access tokens instead of passwords. Store tokens securely.
LSP Performance: LSP servers may take a moment to initialize. Wait for initialization before requesting completions or symbols.

Next Steps

Code Execution

Execute code in sandboxes

File Operations

Advanced file manipulation

Build docs developers (and LLMs) love