Gitea Commands
Overview
The netapi gitea commands provide CLI access to Gitea’s REST API. All commands support -f json for jq piping.
Gitea is a self-hosted Git service, ideal for private infrastructure.
Prerequisites
# Set Gitea URL and token
export GITEA_URL="https://gitea-01.inside.domusdigitalis.dev"
export GITEA_TOKEN="..."
# Or load from dsec
dsource d000 dev/gitea
Create token at: <GITEA_URL>/user/settings/applications
Commands (16 total)
| Command | Description |
|---|---|
|
Get authenticated user |
|
Get Gitea version |
|
List user repositories |
|
Get repository details |
|
Search repositories |
|
List branches |
|
List commits |
|
List releases |
|
List issues |
|
List pull requests |
|
List organizations |
|
List org repositories |
|
Create new repository |
|
Delete repository |
|
Mirror external repository |
|
Raw API request |
JSON Output
All commands support -f json:
netapi gitea repos -f json
netapi gitea repo owner/repo -f json
netapi gitea prs owner/repo -f json
jq Patterns
Exploring Structure
# See all keys in first object
netapi gitea repos -f json | jq '.[0] | keys'
# Keys with types
netapi gitea repos -f json | jq '.[0] | to_entries | .[] | "\(.key): \(.value | type)"'
# Full first object
netapi gitea repos -f json | jq '.[0]'
Repository Operations
# List all repo names
netapi gitea repos -f json | jq -r '.[].full_name'
# Filter private repos
netapi gitea repos -f json | jq -r '.[] | select(.private) | .full_name'
# Get specific fields
netapi gitea repos -f json | jq '.[] | {name: .full_name, private, default_branch}'
# Sort by updated
netapi gitea repos -f json | jq 'sort_by(.updated_at) | reverse | .[] | "\(.full_name): \(.updated_at[0:10])"'
# Repos with stars
netapi gitea repos -f json | jq '.[] | select(.stars_count > 0) | "\(.full_name): \(.stars_count) stars"'
Single Repository
# Full repo details
netapi gitea repo evanusmodestus/netapi -f json | jq '.'
# Summary object
netapi gitea repo evanusmodestus/netapi -f json | jq '{
name: .full_name,
private,
default_branch,
stars: .stars_count,
forks: .forks_count,
created: .created_at[0:10],
updated: .updated_at[0:10]
}'
# Clone URLs
netapi gitea repo evanusmodestus/netapi -f json | jq '{clone: .clone_url, ssh: .ssh_url}'
Commits
# Recent commits - short format
netapi gitea commits evanusmodestus/netapi -l 10 -f json | jq -r '.[] | "\(.sha[0:8]) \(.commit.author.name): \(.commit.message | split("\n")[0])"'
# Commits by author
netapi gitea commits evanusmodestus/netapi -f json | jq -r '.[].commit.author.name' | sort | uniq -c | sort -rn
# Commits with date
netapi gitea commits evanusmodestus/netapi -f json | jq '.[] | {
sha: .sha[0:8],
author: .commit.author.name,
date: .commit.author.date[0:10],
message: (.commit.message | split("\n")[0])
}'
Pull Requests
# Open PRs - titles only
netapi gitea prs evanusmodestus/netapi -f json | jq -r '.[] | "#\(.number): \(.title)"'
# PRs with stats
netapi gitea prs evanusmodestus/netapi -f json | jq '.[] | {
number,
title,
author: .user.login,
base: .base.ref,
head: .head.ref
}'
# Closed PRs
netapi gitea prs evanusmodestus/netapi -s closed -f json | jq '.[] | {number, title}'
Issues
# Open issues - titles
netapi gitea issues evanusmodestus/netapi -f json | jq -r '.[] | "#\(.number): \(.title)"'
# Issues with labels
netapi gitea issues evanusmodestus/netapi -f json | jq '.[] | {
number,
title,
author: .user.login,
labels: [.labels[].name]
}'
# Filter by label
netapi gitea issues evanusmodestus/netapi -f json | jq '.[] | select(.labels | map(.name) | index("bug"))'
Branches
# List branches
netapi gitea branches evanusmodestus/netapi -f json | jq -r '.[].name'
# Protected branches
netapi gitea branches evanusmodestus/netapi -f json | jq '.[] | select(.protected) | .name'
Releases
# List releases
netapi gitea releases evanusmodestus/netapi -f json | jq '.[] | {tag: .tag_name, name, published: .published_at[0:10]}'
# Latest release
netapi gitea releases evanusmodestus/netapi -f json | jq '.[0] | {tag: .tag_name, name}'
Organizations
# List orgs
netapi gitea orgs -f json | jq -r '.[].name'
# Org details
netapi gitea orgs -f json | jq '.[] | {name, full_name, description}'
# Org repos
netapi gitea org-repos myorg -f json | jq '.[] | {name, private, default_branch}'
Repository Management
# Create new repo
netapi gitea create my-new-repo --private
# Create public repo with description
netapi gitea create my-public-repo --public -d "My public project"
# Mirror external repo
netapi gitea mirror https://github.com/user/repo.git mirrored-repo --private
# Delete repo (requires confirmation)
netapi gitea delete evanusmodestus/old-repo --yes
Raw API Access
# Any GET endpoint
netapi gitea api /user | jq '.'
# Repo topics
netapi gitea api /repos/evanusmodestus/netapi/topics | jq '.topics'
# User's starred repos
netapi gitea api /user/starred | jq '.[].full_name'
Environment Variables
| Variable | Description |
|---|---|
|
Gitea instance URL (required) |
|
Personal access token (required) |
Mirror Workflow
Mirror GitHub repos to private Gitea for backup:
# Mirror a GitHub repo
netapi gitea mirror https://github.com/ansible/ansible.git ansible-mirror --private
# Verify
netapi gitea repo evanusmodestus/ansible-mirror -f json | jq '{name, mirror, clone_url}'
Useful jq Recipes
Export to CSV
netapi gitea repos -f json | jq -r '.[] | [.full_name, .private, .stars_count] | @csv'
Backup All Repos List
# Get all clone URLs for backup script
netapi gitea repos -f json | jq -r '.[].ssh_url' > repos-to-backup.txt
Count by Field
# Repos by privacy
netapi gitea repos -f json | jq 'group_by(.private) | map({private: .[0].private, count: length})'
Recent Activity
# Repos updated today
netapi gitea repos -f json | jq --arg d "$(date -I)" '.[] | select(.updated_at | startswith($d)) | .full_name'
# Repos updated in last 7 days
netapi gitea repos -f json | jq --arg d "$(date -d '7 days ago' -I)" '.[] | select(.updated_at > $d) | "\(.full_name): \(.updated_at[0:10])"'
Self-Hosted Tips
Bulk Operations
# Create repos from list
cat repos.txt | while read name; do
netapi gitea create "$name" --private
done
# Mirror all starred GitHub repos
gh api /user/starred --paginate | jq -r '.[].clone_url' | while read url; do
name=$(basename "$url" .git)
netapi gitea mirror "$url" "$name-mirror" --private
done