Releases: Driste/gitty
Release list
0.2.0
v0.2.0
The first substantial release since 0.1.0: gitty goes from a working
prototype to a tool that's safe to run unattended in CI. Two new read-only
commands, HTTP clone authentication that actually works on a runner,
concurrent syncing, a machine-readable output contract, real exit codes, and
the project's first test suite (0 → 90 tests).
9 commits · 25 files · +5,324 / −227
⚠️ Breaking changes
Read this section before upgrading — the output and exit-code contracts both
changed.
1. Output format. gitty sync now writes one machine-readable event per
line to stdout, and moves every human diagnostic (banners, progress, git's
own chatter) to stderr:
clone tenant/images/app
pull tenant/images/app
group tenant/images
error tenant/images/lib git pull failed
summary cloned=3 pulled=12 skipped=0 errors=1
Anything parsing gitty's stdout must be updated. Under --dry-run the action
lines are prefixed with plan , so a dry run diffs cleanly against a real one.
2. Exit codes. Usage and configuration errors now exit 2 (previously
1). Per-item sync failures still exit 1. New: 130 on Ctrl-C.
| Code | Meaning |
|---|---|
| 0 | success |
| 1 | completed, but one or more repos failed (retryable) |
| 2 | usage or configuration error (don't retry unchanged) |
| 130 | interrupted; re-run resumes cleanly |
3. git pull → git pull --ff-only. A diverged or dirty checkout now
fails loudly and is reported as an error instead of silently creating a merge
commit. Your local commits are left untouched.
4. gitty init refuses to overwrite an existing .gitty/config without
--force. Re-running init used to silently reset root_path, which made the
next sync re-clone an entire namespace nested inside a subgroup.
5. Agent schema 1.0.0 → 1.3.0 — new tools, new flags, and an
exitCodes section.
New commands
gitty status — branch and freshness for every checkout in the workspace,
one greppable line each. Read-only, needs no token or network:
status tenant/images/app branch=main ahead=0 behind=3 dirty=false
status tenant/images/spike branch=exp ahead=0 behind=0 dirty=false upstream=none
summary repos=2 dirty=0 ahead=0 behind=1 errors=0
--fetch refreshes remote refs first for accurate behind counts.
upstream=none marks a branch with no tracking ref, so 0/0 is never
mistaken for "in sync".
gitty ls — remote inventory with per-group project counts, marking each
project new (a sync would clone it) or present. Never runs git, never
writes to disk. --format=text|tree|json.
gitty version — prints the release tag for published binaries, or
dev+<commit> for source builds.
New flags
sync:--anon,--jobs N(default 4),--verbose,--reclone-brokeninit:--forcestatus:--fetch,--jobs,--verbose,--token,--anon
Fixes and hardening
- HTTP clones now authenticate. Previously the API call authenticated but
git clone https://…fell back to ambient credential helpers — absent on CI
runners, so--httpsync failed exactly where it was most needed. gitty now
re-execs as git's askpass helper, passing the token via the child process
environment: never in argv, never written to any git config or credential
store. Personal tokens authenticate asoauth2,CI_JOB_TOKENas
gitlab-ci-token.gitty initalso defaults toCI_SERVER_URLinside a
GitLab CI job. - Credentials never leave your instance. Clone URLs are host-checked before
use, and an authenticated pull re-checks the checkout's actualoriginfirst. - Ctrl-C is safe. In-flight git processes are signalled so they clean up
partial clones; the run exits 130 and a re-run resumes. A destination that
exists but isn't a usable repo (a wedged half-clone) used to make every
future sync fail with an opaque git error — it's now detected and reported,
and--reclone-brokenrenames it aside (never deletes) and re-clones. - Concurrent syncing via
--jobs— roughly 5× faster on large groups.
--jobs=1restores serial behavior. - Path-boundary bug: a workspace root of
acme/teammangled unrelated
paths underacme/team-x. - Workspace escape guard: namespace paths containing
..or absolute
paths are refused rather than written outside the tree. - Public groups without a token via
--anon. --verboseprints every git invocation to stderr with URL credentials
redacted.
Releases and CI
Tagged versions now publish prebuilt binaries for Linux, macOS (Intel and
Apple Silicon), and Windows, plus a SHA256SUMS file. The release workflow
runs gofmt, go vet, go test and -race before publishing anything —
tags don't otherwise run CI — stamps the tag into each binary, and smoke-tests
the result so a release can't ship reporting the wrong version.
Under the hood
First test suite: 90 tests, 58.6% statement coverage, race-clean. The
end-to-end tests build the real binary and drive it against an in-process fake
GitLab that serves both the REST API and real git repositories over HTTP, so
clones and pulls exercise a genuine git transport with no network access.
Install
Download the binary for your platform from the assets below, verify it, and
put it on your PATH:
sha256sum -c SHA256SUMS --ignore-missing
chmod +x gitty_v0.2.0_linux_amd64
sudo mv gitty_v0.2.0_linux_amd64 /usr/local/bin/gitty
gitty versionFull changelog: 0.1.0...v0.2.0
0.1.0
0.1.0 - 2026-07-30
First public release of gitty — a minimal, configurable Go CLI that
synchronizes (clones/pulls) GitLab groups, subgroups, and repositories to your
local machine while preserving the GitLab namespace directory structure.
Added
- Workspace configuration (
gitty init) — anchor a workspace by writing a
.gitty/config(TOML) file so the GitLab URL and SSH/HTTP preference don't
have to be repeated on every command. Flags:--url(default
https://gitlab.com),--http. - Group & repository sync (
gitty sync) — clone repositories that don't
exist locally andgit pullthose that do, mirroring the GitLab namespace as
local directories:- Granular selection with
--groupsand--repos(defaults to--repos
when neither is passed) — sync only repos, only the group/subgroup
directory scaffolding, or both. - Recursive (
--nested) or flat traversal of subgroups/projects. --dry-runto preview every directory and git action without touching disk.- CI-friendly token resolution:
--tokenflag →GITLAB_TOKEN→
CI_JOB_TOKEN.
- Granular selection with
- Agent schema (
gitty agent schema) — emit an MCP-style JSON description
of every command (purpose, arguments, defaults, and argv mapping) so an
LLM/agent can drive gitty as a tool. - Continuous integration — GitHub Actions workflow (
go.yml) building and
testing on Go 1.24.4. - Release automation — GitHub Actions workflow (
release.yml) that, on any
v*tag, cross-compiles binaries for linux/darwin/windows (amd64/arm64),
generatesSHA256SUMS, and publishes a GitHub Release. - Dependency automation — Dependabot for Go modules and GitHub Actions.
What's Changed
- Add 'gitty agent schema' command for LLM tool integration by @Driste in #3
- Add dependabot, release workflow, and AI context doc by @Driste in #4
- gomod: bump github.com/pelletier/go-toml/v2 from 2.3.0 to 2.4.3 in the go-dependencies group by @dependabot[bot] in #6
- ci: bump the github-actions group with 2 updates by @dependabot[bot] in #5
New Contributors
- @dependabot[bot] made their first contribution in #6
Full Changelog: https://github.com/Driste/gitty/commits/0.1.0