Skip to content

Directory Structure

Detailed reference of the .gira/ directory layout and file organization.

Overview

Gira stores all project data in a .gira/ directory at the root of your Git repository. This directory contains configuration files, tickets organized by status, and metadata for tracking project state.

Complete Structure

Small Projects (Legacy/Flat Structure)

.gira/
├── config.json          # Main project configuration
├── board.json           # Board swimlanes and transitions
├── .state.json         # Internal state (next ticket ID)
├── backlog/            # Tickets not yet scheduled (flat structure)
│   ├── PROJ-1.json
│   └── PROJ-2.json
├── board/              # Active tickets by status
│   ├── todo/          
│   │   ├── PROJ-3.json
│   │   └── PROJ-4.json
│   ├── in_progress/
│   │   └── PROJ-5.json
│   ├── review/
│   │   └── PROJ-6.json
│   └── done/
│       └── PROJ-7.json
├── epics/              # Epic tracking (future)
├── sprints/            # Sprint management (future)
│   ├── active/
│   └── completed/
└── archive/            # Archived tickets organized by month
    ├── 2025-06/       # June 2025 archived tickets
    │   ├── PROJ-1.json
    │   └── PROJ-2.json
    └── 2025-07/       # July 2025 archived tickets
        └── PROJ-3.json

Large Projects (Hybrid Structure)

.gira/
├── config.json          # Main project configuration
├── board.json           # Board swimlanes and transitions
├── .state.json         # Internal state (next ticket ID)
├── backlog/            # Tickets organized by hash (hybrid structure)
│   ├── GC/             # First hash level (GCM prefix)
│   │   └── M-/         # Second hash level
│   │       ├── GCM-100.json
│   │       ├── GCM-101.json
│   │       └── GCM-102.json
│   ├── EP/             # First hash level (EPIC prefix)
│   │   └── IC/         # Second hash level
│   │       ├── EPIC-001.json
│   │       └── EPIC-002.json
│   └── PR/             # First hash level (PROJ prefix)
│       └── OJ/         # Second hash level
│           ├── PROJ-200.json
│           └── PROJ-201.json
├── board/              # Active tickets by status (always flat)
│   ├── todo/          
│   │   ├── GCM-103.json
│   │   └── PROJ-204.json
│   ├── in_progress/
│   │   └── EPIC-003.json
│   ├── review/
│   │   └── GCM-104.json
│   └── done/
│       └── PROJ-205.json
├── epics/              # Epic tracking (future)
├── sprints/            # Sprint management (future)
│   ├── active/
│   └── completed/
└── archive/            # Archived tickets organized by month
    ├── 2025-06/       # June 2025 archived tickets
    │   ├── GCM-090.json
    │   └── PROJ-180.json
    └── 2025-07/       # July 2025 archived tickets
        └── EPIC-001.json

File Descriptions

Configuration Files

config.json

Main project configuration containing project metadata and settings.

{
  "project": {
    "name": "My Project",
    "prefix": "PROJ",
    "created_at": "2024-01-15T10:30:00Z",
    "default_assignee": null
  }
}

board.json

Defines the kanban board structure, swimlanes, and workflow transitions.

{
  "swimlanes": [
    {"id": "todo", "name": "To Do", "limit": 10},
    {"id": "in_progress", "name": "In Progress", "limit": 3},
    {"id": "review", "name": "Review", "limit": 2},
    {"id": "done", "name": "Done"}
  ],
  "transitions": {
    "todo": ["in_progress"],
    "in_progress": ["review", "todo"],
    "review": ["done", "in_progress"],
    "done": ["todo"]
  }
}

.state.json

Internal state tracking, primarily for the next ticket ID.

{
  "next_id": 8
}

Ticket Storage

Tickets are JSON files stored in directories based on their current status:

backlog/

Contains tickets that haven't been scheduled for work yet.

board/

Active tickets organized by swimlane: - todo/ - Ready to start - in_progress/ - Currently being worked on - review/ - In review/QA - done/ - Completed

Ticket File Format

Each ticket is stored as {PREFIX}-{ID}.json:

{
  "id": "PROJ-1",
  "title": "Implement user authentication",
  "description": "Add login and registration functionality",
  "type": "feature",
  "priority": "high",
  "status": "todo",
  "reporter": "alice@example.com",
  "assignee": "bob@example.com",
  "created_at": "2024-01-15T10:30:00Z",
  "updated_at": "2024-01-16T14:20:00Z",
  "labels": ["backend", "security"],
  "epic_id": null,
  "parent_id": null,
  "blocked_by": [],
  "blocks": []
}

Future Directories

These directories are created but not yet implemented:

epics/

Will contain epic definitions for grouping related tickets.

sprints/

Will manage sprint cycles: - active/ - Current sprint data - completed/ - Historical sprints

archive/

Stores completed tickets organized by month (YYYY-MM format). Archived tickets retain all their original data plus archive metadata:

{
  "id": "PROJ-1",
  "title": "Original ticket title",
  "status": "done",
  // ... all original ticket fields ...
  "_archive_metadata": {
    "archived_at": "2025-07-13T10:30:00Z",
    "archived_from_status": "done",
    "archived_by": "gira-cli"
  }
}

Archive features: - Tickets are organized in YYYY-MM subdirectories - Archive metadata tracks when and from where tickets were archived - Empty archive directories are automatically cleaned up - Archived tickets can be restored to any status

File Movement

Tickets move between directories as their status changes:

  1. New tickets start in board/todo/ (or backlog/ if status is backlog)
  2. gira ticket move relocates the file to match the new status
  3. Done tickets can be archived to archive/YYYY-MM/ using gira archive commands
  4. Archived tickets can be restored to any status using gira archive restore

Git Integration

By default, all .gira/ contents are tracked in Git, enabling: - Team collaboration - Change history - Branch-based workflows - Merge conflict resolution

To exclude from Git:

echo ".gira/" >> .gitignore

Best Practices

  1. Atomic Commits: Commit ticket changes with related code
  2. Branch Workflows: Create feature branches with ticket updates
  3. Regular Cleanup: Archive old done tickets periodically
  4. Backup Strategy: Use Git's history as your backup

Hybrid Directory Structure

For projects with large backlogs (1000+ tickets), Gira supports a hybrid directory structure that optimizes performance while maintaining usability:

Structure Overview

  • Active Board Tickets: Remain in flat, human-readable structure

    .gira/board/todo/PROJ-123.json
    .gira/board/in_progress/PROJ-124.json
    

  • Backlog Tickets: Use 2-level hashed directory structure

    .gira/backlog/GC/M-/GCM-456.json
    .gira/backlog/EP/IC/EPIC-001.json
    

Hash Path Generation

The hashing algorithm creates balanced, readable directory structures:

  • Standard IDs (PREFIX-NUMBER): Uses prefix characters
  • GCM-123GC/M-/
  • EPIC-001EP/IC/
  • AB-1AB/-1/

  • Non-standard IDs: Uses MD5 hash

  • unusual-id5a/b2/

Benefits

  • Git Performance: Faster operations with large backlogs
  • Human Usability: Active tickets remain easily browsable
  • Automatic Routing: Tickets move between structures based on status
  • Backward Compatibility: Existing projects work unchanged

Migration

Projects can be migrated to hybrid structure using:

# Preview migration
gira migrate hybrid --dry-run

# Perform migration
gira migrate hybrid

# Verify completion
gira migrate hybrid --verify

The hybrid backlog structure is automatically enabled for new projects when needed.

Storage Limits

  • No hard limits on number of tickets
  • Performance considerations:
  • 1-1000 tickets: Flat structure performs excellently
  • 1000-10,000 tickets: Consider hybrid structure for optimal Git performance
  • 10,000+ tickets: Hybrid structure recommended, consider archiving old tickets
  • 50,000+ tickets: Archive management becomes important for maintenance

File Permissions

Standard file permissions apply: - Directories: 755 (rwxr-xr-x) - JSON files: 644 (rw-r--r--)

Customization

You can extend the structure by: 1. Adding custom directories 2. Modifying swimlane directories (update board.json) 3. Adding metadata files

See Also