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:
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¶
- Files are stored directly in
.gira/attachments/{entity-id}/
- Git LFS automatically converts large files to pointer files
- No YAML metadata files are created (Git tracks everything)
- 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.