Gitea CLI
Gitea CLI patterns for self-hosted Git workflows.
tea CLI — Authentication
Login to your Gitea instance
tea login add --name domus --url https://git.domusdigitalis.dev --token <your-token>
List configured logins
tea login list
Set default login
tea login default domus
tea CLI — Repositories
Create a repo
tea repo create --name domus-api --private
List your repos
tea repo list
Clone a repo
git clone git@git.domusdigitalis.dev:evan/domus-api.git
tea CLI — Issues & PRs
Create an issue
tea issue create --title "Add Ollama RAG endpoint" --body "Phase 3 of domus-api roadmap"
List issues
tea issue list
Create a pull request
tea pr create --title "feat: multi-spoke support" --base main --head feature-branch
List PRs
tea pr list
Gitea REST API — Direct Access with curl
Gitea has a Swagger-documented REST API. No special CLI needed — just curl + jq.
Set your token as a variable
export GITEA_TOKEN="your-api-token"
export GITEA_URL="https://git.domusdigitalis.dev/api/v1"
List your repos
curl -s -H "Authorization: token $GITEA_TOKEN" "$GITEA_URL/user/repos" | jq -r '.[] | "\(.name)\t\(.size) KB"' | sort
Create a repo
curl -s -X POST -H "Authorization: token $GITEA_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"association-engine","private":true}' \
"$GITEA_URL/user/repos" | jq '{name, clone_url: .ssh_url}'
Get repo details
curl -s -H "Authorization: token $GITEA_TOKEN" \
"$GITEA_URL/repos/evan/domus-api" | jq '{name, size, created_at, updated_at}'
List repo contents (directory listing)
curl -s -H "Authorization: token $GITEA_TOKEN" \
"$GITEA_URL/repos/evan/domus-api/contents/src/domus_api" | jq -r '.[] | "\(.type)\t\(.size)\t\(.name)"'
Read a file (base64 decode)
curl -s -H "Authorization: token $GITEA_TOKEN" \
"$GITEA_URL/repos/evan/domus-api/contents/pyproject.toml" | jq -r '.content' | base64 -d
List commits
curl -s -H "Authorization: token $GITEA_TOKEN" \
"$GITEA_URL/repos/evan/domus-api/commits?limit=10" | jq -r '.[] | "\(.commit.author.date[:10])\t\(.commit.message | split("\n")[0])"'
Create an issue via API
curl -s -X POST -H "Authorization: token $GITEA_TOKEN" \
-H "Content-Type: application/json" \
-d '{"title":"Phase 3: Ollama RAG","body":"Architecture documented in roadmap partial"}' \
"$GITEA_URL/repos/evan/domus-api/issues" | jq '{number, title, state}'
List issues
curl -s -H "Authorization: token $GITEA_TOKEN" \
"$GITEA_URL/repos/evan/domus-api/issues" | jq '[.[] | {number, title, state}]'
Gitea + jq Patterns
All repos sorted by last update
curl -s -H "Authorization: token $GITEA_TOKEN" \
"$GITEA_URL/user/repos?limit=50" | jq -r '.[] | "\(.updated_at[:10])\t\(.name)"' | sort -r
Find repos by language
curl -s -H "Authorization: token $GITEA_TOKEN" \
"$GITEA_URL/user/repos?limit=50" | jq -r '.[] | "\(.language // "none")\t\(.name)"' | sort
Repo sizes ranked
curl -s -H "Authorization: token $GITEA_TOKEN" \
"$GITEA_URL/user/repos?limit=50" | jq -r '.[] | "\(.size)\t\(.name)"' | sort -rn
Why Three Forges?
| Forge | Purpose | When It Matters |
|---|---|---|
GitHub |
Primary — PRs, community, CI, portfolio visibility |
Always. This is where people see your work. |
GitLab |
Work backup — CHLA CI/CD, enterprise features |
When work requires GitLab. Backup for everything. |
Gitea |
Sovereignty — self-hosted at git.domusdigitalis.dev |
When GitHub/GitLab go down. When you want full control. When privacy matters. |
The data is the same. The remotes are different interfaces to the same truth. See Multi-Remote Workflow for configuring all three.