Skip to content

Releases: Driste/gitty

Release list

0.2.0

Choose a tag to compare

@Driste Driste released this 25 Aug 20:14

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 pullgit 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.01.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-broken
  • init: --force
  • status: --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 --http sync 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 as oauth2, CI_JOB_TOKEN as
    gitlab-ci-token. gitty init also defaults to CI_SERVER_URL inside 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 actual origin first.
  • 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-broken renames it aside (never deletes) and re-clones.
  • Concurrent syncing via --jobs — roughly 5× faster on large groups.
    --jobs=1 restores serial behavior.
  • Path-boundary bug: a workspace root of acme/team mangled unrelated
    paths under acme/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.
  • --verbose prints 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 version

Full changelog: 0.1.0...v0.2.0

0.1.0

Choose a tag to compare

@Driste Driste released this 30 Jul 13:01
ac7db2c

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 and git pull those that do, mirroring the GitLab namespace as
    local directories:
    • Granular selection with --groups and --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-run to preview every directory and git action without touching disk.
    • CI-friendly token resolution: --token flag → GITLAB_TOKEN
      CI_JOB_TOKEN.
  • 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),
    generates SHA256SUMS, 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

Full Changelog: https://github.com/Driste/gitty/commits/0.1.0