Skip to content

Attachments

📎 Section 6: Managing Attachments

Have you ever needed to include screenshots, design mockups, or documentation with your tickets? Gira's attachment system makes it easy to keep all related files organized while using cloud storage to keep your repository lightweight.

In this guide, you'll learn how to: - Configure cloud storage for attachments - Attach single or multiple files to tickets and epics - Download attachments for processing - Use wildcards and patterns to manage files efficiently - Keep your repository clean with external storage

Understanding Attachments in Gira

Gira supports two approaches for file attachments:

Cloud Storage (Default)

  • Small YAML pointer files are stored in Git (under .gira/attachments/)
  • Actual file content is stored in cloud storage (S3, GCS, Azure, R2, B2)
  • This keeps your repository fast while maintaining full version control

Git LFS (Git-Native Option)

  • Files are stored directly in the repository using Git Large File Storage
  • No external dependencies or cloud accounts required
  • Files are automatically tracked by Git LFS based on extension
  • Ideal for teams already using Git LFS or wanting a simpler setup

Supported Storage Providers

  • Git LFS - Git Large File Storage (no external dependencies)
  • Amazon S3 - AWS Simple Storage Service
  • Google Cloud Storage - GCS buckets
  • Azure Blob Storage - Microsoft Azure
  • Cloudflare R2 - S3-compatible object storage
  • Backblaze B2 - Cost-effective cloud storage

Setting Up Storage

Before using attachments, configure your storage provider:

Git LFS Setup (Simplest)

For Git LFS, ensure it's installed and initialized:

# Install Git LFS (if not already installed)
# macOS: brew install git-lfs
# Ubuntu: sudo apt-get install git-lfs
# Windows: choco install git-lfs

# Initialize Git LFS in your repository
git lfs install

# Configure Gira to use Git LFS
gira storage configure --provider git-lfs

Cloud Storage Setup

For cloud storage providers:

# Interactive setup
gira storage configure

# Or specify provider directly
gira storage configure --provider s3 --bucket my-gira-attachments

Test your configuration:

gira storage status

Adding Attachments

Single File Attachment

The simplest case - attaching one file:

# Attach a screenshot to a ticket
gira attachment add GCM-123 screenshot.png --note "UI bug on mobile"

# Attach to an epic
gira attachment add EPIC-001 roadmap.pdf --note "Q1 planning document"

Multiple Files at Once

Need to attach several files? Just list them:

# Attach multiple files
gira attachment add GCM-123 error.log stacktrace.txt screenshot.png

# With a note for all files
gira attachment add GCM-123 *.log --note "Debug logs from production"

Directory Upload

Upload all files from a directory:

# Upload entire directory
gira attachment add GCM-123 ./debug-output/

# Only specific file types
gira attachment add GCM-123 ./screenshots/ --include "*.png"

# Exclude certain files
gira attachment add GCM-123 ./logs/ --exclude "*.tmp"

Advanced Patterns

Combine includes and excludes for precise control:

# Upload test results but skip temporary files
gira attachment add GCM-123 ./test-results/ --include "*.xml" --exclude "*-temp.xml"

Listing Attachments

View all attachments for an entity:

# List ticket attachments
gira attachment list GCM-123

# List epic attachments
gira attachment list EPIC-001

Output shows:

📎 Attachments for GCM-123 (3 files, 15.2 MB)

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 Filename              Size     Type         Uploaded
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 screenshot.png        2.1 MB   image/png    2024-03-15 14:32:10
 error.log            512 KB   text/plain   2024-03-15 14:33:45
 stacktrace.txt       8 KB     text/plain   2024-03-15 14:33:45
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Downloading Attachments

Single File Download

Download a specific file:

# Download by exact name
gira attachment download GCM-123 error.log

# Download with partial name (if unique)
gira attachment download GCM-123 error

# Download to specific location
gira attachment download GCM-123 screenshot.png --output ~/Downloads/

Multiple File Download

Download multiple files at once:

# Download specific files
gira attachment download GCM-123 error.log stacktrace.txt screenshot.png

# Use wildcards
gira attachment download GCM-123 "*.log"

# Download all logs and images
gira attachment download GCM-123 "*.log" "*.png" "*.jpg"

Download All Attachments

Get everything at once:

# Download all attachments for a ticket
gira attachment download GCM-123 --all

# Download to specific directory
gira attachment download GCM-123 --all --output ./ticket-files/

Viewing File Content

For text files, you can view content directly without downloading:

# Stream text file to terminal
gira attachment cat GCM-123 error.log

# View configuration file
gira attachment cat GCM-123 config.yaml

# Pipe to other commands
gira attachment cat GCM-123 data.csv | grep ERROR

Opening Attachments

Open files with system default applications:

# Open PDF in default viewer (use attachment ID/filename)
gira attachment open GCM-123 design.pdf

# Open image in default image viewer  
gira attachment open GCM-123 screenshot.png

# Note: Use the exact filename or attachment ID as shown in 'gira attachment list'

Removing Attachments

Remove Pointer Only

Remove attachment reference but keep file in storage:

# Single file
gira attachment remove GCM-123 old-screenshot.png

# Multiple files
gira attachment remove GCM-123 temp1.log temp2.log temp3.log

# With confirmation
gira attachment remove GCM-123 "*.tmp" --force

Complete Deletion

Remove both pointer and storage file:

# Delete from storage too (destructive!)
gira attachment remove GCM-123 large-video.mp4 --delete-remote

# Dry run first
gira attachment remove GCM-123 "*.bak" --delete-remote --dry-run

AI Agent Integration

Gira's attachment commands are designed to work seamlessly with AI agents:

Download for Processing

# AI agents can download files quietly
gira attachment download GCM-123 data.csv --quiet

# Output only the downloaded path
$ /path/to/data.csv

Stream for Analysis

# Stream content directly for processing
gira attachment cat GCM-123 log.txt | analyze-log-tool

# Get specific file content
content=$(gira attachment cat GCM-123 config.json)

Batch Operations

# Download all CSVs for analysis
gira attachment download GCM-123 "*.csv" --output /tmp/analysis/

# Process each file
for file in /tmp/analysis/*.csv; do
    process-csv "$file"
done

Best Practices

1. Use Descriptive Filenames

Choose clear, descriptive names:

# Good - descriptive
gira attachment add GCM-123 2024-03-15-mobile-login-error.png

# Avoid - vague
gira attachment add GCM-123 screenshot1.png

2. Add Context with Notes

Always include notes for context:

# Helpful note
gira attachment add GCM-123 performance.log \
    --note "CPU spike during checkout process, prod server"

# Even better with details
gira attachment add GCM-123 heap-dump.hprof \
    --note "OOM error at 14:32 UTC, 8GB heap, 2000 concurrent users"

3. Organize with Directories

For multiple related files:

# Organize files first
mkdir bug-123-evidence
mv *.log *.png bug-123-evidence/

# Upload organized directory
gira attachment add GCM-123 bug-123-evidence/

4. Use Patterns Effectively

Leverage wildcards and filters:

# Upload only relevant logs
gira attachment add GCM-123 ./logs/ \
    --include "app-*.log" \
    --exclude "*-debug.log"

5. Regular Cleanup

Keep attachments relevant:

# Review what's attached
gira attachment list GCM-123

# Remove outdated files
gira attachment remove GCM-123 "old-*.png" --force

Common Scenarios

Bug Reports

Comprehensive bug documentation:

# Screenshot of the issue
gira attachment add BUG-101 login-error.png \
    --note "Error message appears after entering password"

# Browser console logs
gira attachment add BUG-101 console-export.json \
    --note "Browser console output showing JavaScript errors"

# Related server logs
gira attachment add BUG-101 server-logs/ \
    --include "*.log" \
    --note "Server logs from the time of error"

Feature Development

Keep design assets accessible:

# Mockups and designs
gira attachment add FEAT-200 ui-mockups/ \
    --include "*.fig" "*.sketch" "*.png"

# Technical specifications
gira attachment add FEAT-200 api-spec.yaml tech-design.md

# Test data
gira attachment add FEAT-200 test-data/ \
    --include "*.json" \
    --exclude "*-temp.json"

Code Reviews

Support code reviews with evidence:

# Performance benchmarks
gira attachment add REVIEW-50 benchmarks/ \
    --include "*.txt" "*.csv" \
    --note "Before/after optimization results"

# Coverage reports
gira attachment add REVIEW-50 coverage-report.html \
    --note "Test coverage increased from 72% to 89%"

Automation Examples

Git Hook Integration

Automatically attach build artifacts:

#!/bin/bash
# .git/hooks/post-commit

TICKET_ID=$(git log -1 --pretty=%B | grep -oE '[A-Z]+-[0-9]+' | head -1)

if [[ $TICKET_ID ]]; then
    # Attach test results
    if [[ -f "test-results.xml" ]]; then
        gira attachment add "$TICKET_ID" test-results.xml \
            --note "Test results from commit $(git rev-parse --short HEAD)"
    fi
fi

CI/CD Pipeline

Add artifacts from CI builds:

# .github/workflows/build.yml
- name: Upload build artifacts to Gira
  run: |
    TICKET_ID="${{ github.event.pull_request.title }}"
    gira attachment add "$TICKET_ID" dist/ \
      --include "*.tar.gz" \
      --note "Build artifacts from PR #${{ github.event.pull_request.number }}"

Troubleshooting

Storage Connection Issues

# Check storage status and configuration
gira storage status

# Validate credentials
gira storage validate

# Re-configure if needed
gira storage configure

File Not Found

When downloads fail: 1. Check exact filename: gira attachment list GCM-123 2. Try partial matching: gira attachment download GCM-123 "partial" 3. Ensure correct ticket ID

Large File Handling

For files over 100MB: 1. Consider uploading to external service and linking 2. Ensure sufficient storage quota 3. Use compression when possible

Permission Errors

If operations fail: 1. Verify storage bucket permissions 2. Check local directory write access 3. Ensure valid credentials

Git LFS Specifics

When using Git LFS as your storage provider, there are some important differences:

How It Works

  1. Files are stored directly in .gira/attachments/{entity-id}/
  2. Git LFS automatically converts large files to pointer files
  3. No YAML metadata files are created (Git tracks everything)
  4. File extensions are automatically tracked (pdf, png, jpg, zip, etc.)

Advantages

  • No external dependencies - Just Git and Git LFS
  • Simpler setup - No cloud credentials needed
  • Unified storage - Everything in one place
  • Works offline - No internet required for local operations

Considerations

  • Repository size grows with attachments
  • Git hosting provider must support LFS (GitHub, GitLab, Bitbucket all do)
  • May incur LFS bandwidth costs on some platforms
  • Best for smaller attachments (< 100MB recommended)

Migration from Cloud to Git LFS

If you're currently using cloud storage and want to switch to Git LFS:

# 1. Configure Git LFS
gira storage configure --provider git-lfs

# 2. Existing attachments remain accessible via their pointers
# 3. New attachments will use Git LFS

Git LFS Commands

Common Git LFS operations:

# View LFS tracking patterns
git lfs track

# See LFS files in repository
git lfs ls-files

# Pull LFS content
git lfs pull

# Prune old LFS files
git lfs prune

Summary

Gira's attachment system provides powerful file management while keeping your repository clean:

  • Flexible Storage - Choose between Git LFS or cloud storage
  • Cloud Storage - Files stored externally, pointers in Git
  • Git LFS - Files stored in repository with automatic large file handling
  • Bulk Operations - Handle multiple files efficiently
  • Pattern Matching - Use wildcards and filters
  • AI-Friendly - Commands designed for automation
  • Version Controlled - Full history of attachment changes

By following these practices, your team will have all necessary files at their fingertips, whether using cloud storage for scalability or Git LFS for simplicity.