Skip to content

Git Environment

A Git server environment using Gitea that provides isolated Git repository management optimized for task-based RL training. Perfect for training agents on Git operations with fast reset capabilities.

Overview

The Git Environment connects to a shared external Gitea service for optimal task-based isolation. Perfect for: RL training, task-based workflows, parallel execution

Architecture

┌────────────────────────────────────┐
│ Shared Gitea (start once)          │
│ Port 3000                          │
│ - Pre-migrated repositories        │
└──────────────┬─────────────────────┘
               │ HTTP API
      ┾────────┼────────┾
      │        │        │
  ┌───▼──┐ ┌──▼───┐ ┌──▼───┐
  │Env 1 │ │Env 2 │ │Env 3 │
  │Task A│ │Task B│ │Task A│
  │@abc  │ │@def  │ │@abc  │
  └──────┘ └──────┘ └──────┘
  Isolated workspaces

Quick Start

from envs.git_env import GitAction, GitEnv

# Create environment from Docker image
git_env = GitEnv.from_docker_image("git-env:latest")

# Reset environment
result = git_env.reset()
print(result.observation.message)

# List available repositories (pre-migrated to shared Gitea)
result = git_env.step(GitAction(action_type="list_repos"))
for repo in result.observation.repos:
    print(f"{repo['name']}: {repo['clone_url']}")

# Clone to workspace
result = git_env.step(GitAction(action_type="clone_repo", repo_name="OpenEnv"))
print(result.observation.output)  # Cloned to: /workspace/OpenEnv

# Execute git commands
result = git_env.step(GitAction(
    action_type="execute_git_command",
    command="status",
    working_dir="OpenEnv"
))
print(result.observation.output)

# Cleanup
git_env.close()

Setup and Running the Example

Complete setup (run these steps in order):

# 0. Configure environment variables
cp .env.example .env
# Edit .env and set your Gitea credentials if needed

# 1. Start shared Gitea service (one-time)
./scripts/setup_shared_gitea.sh

# 2. Migrate a test repository to Gitea (one-time)
docker exec openenv-gitea curl -X POST \
  http://localhost:3000/api/v1/repos/migrate \
  -u gitea:gitea123 \
  -H 'Content-Type: application/json' \
  -d '{
    "clone_addr": "https://github.com/meta-pytorch/OpenEnv",
    "repo_name": "OpenEnv",
    "repo_owner": "gitea",
    "service": "github"
  }'

# 3. Build Docker images
docker build -t openenv-base:latest -f src/core/containers/images/Dockerfile .
docker build -t git-env:latest -f src/envs/git_env/server/Dockerfile .

# 4. Install Python dependencies
uv pip install -e .

# 5. Run the example (loads credentials from .env)
python3 examples/local_git_env.py

Note: - Steps 1-3 are one-time setup - Make sure .env file exists with your Gitea credentials - After initial setup, you only need step 5 to run the example

Environment Details

Actions

GitAction: Unified action class for all Git operations

@dataclass
class GitAction(Action):
    action_type: str           # Operation type
    repo_name: str            # Repository name (for clone/execute)
    target_dir: Optional[str] # Target directory (for clone)
    command: str              # Git command (for execute)
    working_dir: str          # Working directory (for execute)

Supported action_type values:

"clone_repo" - Clone repository to workspace

GitAction(action_type="clone_repo", repo_name="OpenEnv")
GitAction(action_type="clone_repo", repo_name="OpenEnv", target_dir="custom-dir")

"list_repos" - List available repositories

GitAction(action_type="list_repos")

"execute_git_command" - Execute git command

GitAction(
    action_type="execute_git_command",
    command="status",
    working_dir="OpenEnv"
)

Observation

GitObservation: Contains results of Git operations

@dataclass
class GitObservation(Observation):
    success: bool          # Whether operation succeeded
    message: str           # Human-readable message
    output: str            # Command output or detailed result
    error: str             # Error message if failed
    repos: list[dict]      # List of repositories (for list_repos)

State

GitState: Tracks environment state

@dataclass
class GitState(State):
    episode_id: str           # Unique episode identifier
    step_count: int           # Number of steps taken
    gitea_ready: bool         # Whether Gitea is accessible
    workspace_path: str       # Path to workspace directory

Advanced: Task-Based Training

For RL training scenarios where you need fast resets to specific repository states, you can configure task-specific base states in the environment. This is done by setting environment variables before starting containers:

# Example: Configure tasks for your training setup
docker run \
  -e GITEA_URL=http://host.docker.internal:3000 \
  -e TASK_REPOS='{"bug_fix": ["my-repo", "abc123"], "feature": ["my-repo", "def456"]}' \
  git-env:latest

Then in your training code, environments automatically reset to the configured state.

See examples/local_git_env.py for complete working example.

Project Structure

git_env/
├── README.md                      # This file
├── __init__.py                    # Exports
├── models.py                      # Action, Observation, State definitions
├── client.py                      # GitEnv HTTP client
├── docker-compose.gitea.yml       # Shared Gitea service
└── server/
    ├── __init__.py
    ├── git_task_environment.py    # Task-optimized environment
    ├── app.py                     # FastAPI application
    └── Dockerfile                 # Lightweight container image

Troubleshooting

Gitea Not Ready

If environment can't connect to Gitea: 1. Ensure Gitea is running: docker ps | grep gitea 2. Check Gitea URL in environment: GITEA_URL=http://gitea:3000 3. Verify network connectivity: docker network ls | grep openenv

Repository Not Found

Ensure repository is migrated to Gitea:

# List repos
curl -u gitea:gitea123 http://localhost:3000/api/v1/user/repos

Slow Clone/Reset

  • First clone is slower (~5-10s) - downloads from Gitea
  • Subsequent resets are fast (<1s) - just git operations
  • Use task-based mode with task_repos for optimal performance

Security Notes

  • Never commit .env file - it contains credentials (already in .gitignore)
  • Use .env.example as a template and create your own .env
  • Gitea credentials are for local development only
  • For production, use proper secret management (Docker secrets, k8s secrets, etc.)
  • All workspaces are isolated per container
  • Only public repositories supported (no private repo auth)