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_reposfor optimal performance
Security Notes¶
- Never commit
.envfile - it contains credentials (already in .gitignore) - Use
.env.exampleas 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)