Releases: sven42xyz/gitools
Release list
v0.5.1 — Homebrew packaging fix
Packaging-only release — no changes to gitls itself.
Fixed
- Homebrew: the formula no longer inherits Homebrew's injected
-march=<cpu>
optimisation flag (HOMEBREW_OPTFLAGS). The compiler shim appends it to every
invocation, so on installations where the detected CPU and the active
toolchain disagree, clang rejects the architecture name and the build fails
before it starts (unsupported argument '<cpu>' to option '-march='). gitls
is I/O-bound and already compiles with-O2, so the CPU tuning bought
nothing.
v0.5.0 — Watch-mode categories & robustness hardening
Added
- Watch mode (
-w) groups repositories into collapsible category folders.
Repos are bucketed by their path breadcrumb relative to the scan root, joined
with a chevron (core › packages); repos directly under the root stay flat,
and single-repo folders fold back to just the repo name. Category headers
carry an aggregated status (✓/↑ ↓ ●) in the STATUS column and are shown
in cyan + bold.↑/↓move a cursor,Enterexpands/collapses, and the
expand state survives refreshes. Nav hints appear only when categories exist. ~/.gitlsrckeycategories(defaulttrue) — set it tofalsefor one
flat, alphabetically sorted list in watch mode.docs/ROADMAP.md— the plan through 1.0.0.
Changed
- The one-shot status table is now sorted alphabetically by repo name
(case-insensitive) instead of directory-traversal order, matching watch mode.
Sorting is display-only — summary counts and column widths are unaffected. - The watch-mode table is sized to its content instead of being stretched to the
terminal width; long breadcrumbs overflow the row rather than widening the
NAME column. - The watch footer drops the redundant scan path and shows a "dirty only" hint
while--dirtyis active.
Fixed
run_git_capture()no longer hangs when a child process fills the pipe —
read()is retried onEINTR. The same applies towaitpid(), which could
report a spurious clean exit and leave a zombie behind.- Watch mode handles
SIGWINCH: column widths are recomputed and the table is
redrawn when the terminal is resized. SIGINT/SIGTERM/SIGWINCHare blocked in worker threads, so only the
main thread handles them.- The watch cursor stays anchored to the selected repo / category across
rescans. - Table alignment with wide and zero-width characters: display width is now
measured with wcwidth-style tables (combining marks = 0, CJK / emoji = 2). max_depthfrom~/.gitlsrcis validated (errno /INT_MAX), and a bare~
asdefault_diris expanded.- The watch footer no longer offers fetch / pull when git is unavailable.
- The footer note is derived from the actual result, so a failed action reads
"… failed" instead of reporting success. usage()prints to stdout for an explicit-h, not to stderr.
v0.4.0 — Watch mode, dirty filter & man page
Added
gitls -w/--watch— watch mode: refreshes the status table in place at a
configurable interval (default 3 s, e.g.-w 10). Uses the alternate screen
buffer so scrollback is left untouched, hides the cursor, and quits onqor
Ctrl-C. The terminal is always restored on exit, including onSIGINT/
SIGTERM. Noncursesdependency — raw ANSI escapes andtermiosonly.
Interactive keys act on the whole tree without leaving the view:ffetch,
ppull,sswitch,rrefresh now. Theskey opens a branch picker that
lists recently active branches (most recent first) with type-to-filter, ↑/↓
navigation and Tab/Enter selection.gitls --dirty— list only repos that are not clean and in sync (staged /
modified / untracked files, ahead/behind, diverged or detachedHEAD). The
summary line still counts all scanned repos and appends(N hidden). Works in
one-shot mode and under-w.~/.gitlsrckeyswatch_intervalanddirty_only; CLI flags override them
(--no-dirtyopts out ofdirty_onlyfor a single run).gitls(1)man page, installed bymake installand packaged in the RPM. The
install/uninstall targets now honourDESTDIRfor packaging.
Fixed
-
Long branch names (or any over-wide row) no longer wrap and corrupt the table:
the NAME / BRANCH columns are now capped to the terminal width (content is
truncated with~). Affects both the one-shot table and watch mode. Piped
output is still emitted at full width. Over-longScanned:/ footer paths are
shortened with a leading…. -
Watch mode no longer corrupted the table when a refresh produced a narrower
frame (e.g. switching to a shorter branch name) — each rewritten line is now
cleared to its end, so no stale columns (a duplicate WHEN/STATUS) are left
behind. The table also stays on screen while an action runs.
Changed
- Watch mode now animates a spinner with the action verb (Fetching / Pulling /
Switching) while a fetch / pull / switch runs, instead of a static line.
v0.3.1
Highlights
- Parallel Phase 2: fetch/pull now runs concurrently via a thread pool (previously sequential)
- Fork safety: child process uses
execvewith pre-resolvedg_git_path; unsafeexecvpfallback removed - Spinner: async-signal-safe
write(2)output, explicit Phase 1 → Phase 2 transition with separate spinner labels - Bounded write length on
snprintftruncation (long paths)
Fixes
- Spinner no longer hangs after Phase 1
- Fetch correctly reports "up to date"
- Branch-name parsing fix
- Last-commit time refreshes after branch switch
- Locale handling consistent across child processes
[0.3.0] – 2026-02-28
Added
gitls fetch— fetch all repos from theiroriginremote; shows per-repo result (fetched / up to date / no remote / error)gitls pull— fast-forward pull all clean repos; dirty repos are skipped, diverged repos are reportedgitls fetch -s <branch>— fetch first, then switch; creates a local tracking branch automatically if the branch only exists on the remote~/.gitlsrcconfig file — persistent defaults fordefault_dir,max_depth,skip_dirs(glob patterns via fnmatch),no_colorGITLS_CONFIGenvironment variable to override the config file pathgitlsrc.exampleinstalled to$(PREFIX)/share/doc/gitls/as a referencemake uninstalltargetmake helptarget- Compiler-generated header dependencies (
-MMD -MP) - Version derived from git tags via
git describe— no manual version bumps needed
Fixed
gitls .now correctly scans the current directory even whendefault_diris set in the config
Changed
- Parallel repo processing uses a two-phase design: local libgit2 queries run in a thread pool (Phase 1), subprocess fetch/pull runs sequentially on the main thread (Phase 2) — eliminates fork-in-multithreaded-process issues
make cleanremoves all*.ddependency files including those in subdirectories
gitls v0.2.0
gitls v0.1.0 - hello world
A fast, minimal CLI to inspect and act on multiple git repositories.
Features
- Recursively scans a directory for git repositories
- Displays branch, staged/modified/untracked file counts, ahead/behind remote, and relative last-commit time in a compact table
- Bulk branch switching across all clean repos with
-s <branch> - Color output, configurable scan depth, hidden directory support
- Skips
vendor/andnode_modules/automatically - Built on libgit2 — no shell spawning
Installation
Build from source
# macOS
brew install libgit2
# Debian / Ubuntu
sudo apt install libgit2-dev
# Fedora / RHEL
sudo dnf install libgit2-devel
git clone https://github.com/sven42xyz/gitools.git
cd gitools && make && sudo make install
Usage
gitls [OPTIONS] [DIRECTORY]
-s <branch> Switch all clean repos to <branch>
-d <n> Max search depth (default: 5)
-a Include hidden directories
--no-color Disable ANSI colours