Skip to content

Commit a6d12fc

Browse files
feat(cli): default mainline fetch, --rain TUI, --sync hydrate
Replace the interactive --select flow with --rain (git-fire parity). Default invocation scans repos then runs targeted mainline git fetch per remote; add --sync for full RainRepository hydration. Remove --select entirely. Made-with: Cursor
1 parent 7ce021f commit a6d12fc

7 files changed

Lines changed: 456 additions & 58 deletions

File tree

CLAUDE.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## Project Overview
44

5-
`git-rain` is a standalone Go CLI that syncs local git repositories _from_ their remotes — the reverse of `git-fire`. It is extracted from the `git-fire` codebase and promoted to a first-class tool.
5+
`git-rain` is a standalone Go CLI for pulling remote state back down — the reverse of `git-fire`. By default it **fetches mainline remote-tracking refs** after scanning; **`--sync`** runs full local branch hydration (fast-forward / safe skip / risky reset). It is extracted from the `git-fire` codebase and promoted to a first-class tool.
66

77
Module: `github.com/git-rain/git-rain`
88
Go version: 1.24.2
@@ -48,10 +48,12 @@ main.go
4848

4949
**Key design decisions:**
5050
- Uses native `git` binary via `exec.Command` — not go-git.
51+
- Default run: `internal/git.MainlineFetchRemotes` (targeted `git fetch` per remote for mainline branches). Full hydrate: `RainRepository` when `--sync`, non-mainline `branch_mode`, or risky mode is active.
52+
- Interactive picker: `--rain` (mirrors `git-fire --fire`).
5153
- Backup branch prefix: `git-rain-backup-` (was `git-fire-rain-backup-` in git-fire).
5254
- Config env prefix: `GIT_RAIN_`.
53-
- Safe mode (default): never rewrites local-only commits.
54-
- Risky mode (`--risky` / `config: global.risky_mode`): allows hard reset to upstream after creating a `git-rain-backup-*` ref.
55+
- Safe mode (default): never rewrites local-only commits (applies to `--sync` path).
56+
- Risky mode (`--risky` / `config: global.risky_mode`): allows hard reset to upstream after creating a `git-rain-backup-*` ref (implies full sync).
5557

5658
---
5759

README.md

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@
1515
1616
```
1717
git-fire → commit + push everything out
18-
git-rain → pull everything back down
18+
git-rain → fetch (default) or full reverse sync with --sync
1919
```
2020

21-
`git-rain` discovers all your local git repositories and syncs them from their remotes in one command — fast-forwarding branches, updating non-checked-out refs, and skipping anything that would rewrite local-only commits (unless you ask it to).
21+
`git-rain` discovers git repositories under your scan path (and known registry entries), then by default **fetches mainline remote-tracking refs** only (`main`, `master`, `trunk`, `develop`, `dev`, gitflow prefixes, plus your configured patterns). Use **`--sync`** for full hydration: fast-forwarding branches, updating non-checked-out refs, and skipping anything that would rewrite local-only commits unless you enable risky mode.
2222

2323
Invocation note: `git-rain` and `git rain` are equivalent when `git-rain` is on your PATH.
2424

@@ -39,7 +39,7 @@ Invocation note: `git-rain` and `git rain` are equivalent when `git-rain` is on
3939
- [Core Commands](#core-commands)
4040
- [Flags](#flags)
4141
- [Configuration](#configuration)
42-
- [TUI Selector](#tui-selector)
42+
- [Interactive TUI](#interactive-tui)
4343
- [Safe Mode vs Risky Mode](#safe-mode-vs-risky-mode)
4444
- [Registry](#registry)
4545
- [Security Notes](#security-notes)
@@ -52,11 +52,14 @@ Invocation note: `git-rain` and `git rain` are equivalent when `git-rain` is on
5252
# preview first — shows what would be synced without touching anything
5353
git-rain --dry-run
5454

55-
# sync all repos under the configured scan path
55+
# default: scan repos, then fetch mainline remote-tracking refs from remotes
5656
git-rain
5757

58-
# interactive TUI: pick exactly which repos to sync
59-
git-rain --select
58+
# full local branch sync (same safety/risky rules as before)
59+
git-rain --sync
60+
61+
# interactive TUI: pick repos, then default fetch or --sync behavior
62+
git-rain --rain
6063
```
6164

6265
## Install
@@ -151,38 +154,41 @@ Requires Go 1.24.2+.
151154

152155
## How It Works
153156

154-
1. **Scan** — walks your configured scan path discovering git repositories
155-
2. **Fetch** — runs `git fetch --all --prune` for each repo
156-
3. **Sync** — for each local branch with a tracked upstream:
157+
1. **Scan** — walks your configured scan path and includes known registry repos (`--no-scan` limits to registry only)
158+
2. **Default: mainline fetch**for each repo, runs targeted `git fetch <remote> --prune` for mainline branches so `origin/main` (etc.) advance; **local branch refs are not moved**
159+
3. **With `--sync` (or non-mainline `branch_mode` in config, or `--risky`)**full hydrate: runs `git fetch --all --prune` (optional `--tags`), then for each eligible local branch with a tracked upstream:
157160
- If the branch can be fast-forwarded: updates it
158161
- If the branch has local-only commits: skips (safe mode) or backs up and resets (risky mode)
159162
- If the working tree is dirty on the checked-out branch: skips
160-
4. **Report** — per-branch outcomes: updated, up-to-date, skipped (with reason), failed
163+
4. **Report** — per-branch outcomes: fetched, synced, up-to-date, skipped (with reason), failed
161164

162165
## Key Features
163166

164-
- **One-command sync** — discover and update all repos from a single invocation
167+
- **One-command workflow** — discover repos, then default mainline fetch or full `--sync` hydrate
165168
- **Safety-first defaults** — never rewrites local-only commits; dirty worktrees are skipped, not clobbered
166169
- **Risky mode** — opt-in destructive realignment: creates a `git-rain-backup-*` ref, then hard-resets to upstream
167170
- **Non-checked-out branches** — updated directly without touching the worktree
168-
- **Interactive TUI** — streaming repo selector lets you pick exactly which repos to sync
171+
- **Interactive TUI (`--rain`)** — streaming repo picker (mirrors `git-fire --fire`), then the same default fetch or `--sync` behavior
169172
- **Registry** — discovered repos persist across runs; mark repos ignored to skip them permanently
170173
- **Dry run** — preview all repos that would be synced without making any changes
171-
- **Fetch-only mode** — run `git fetch --all --prune` everywhere without touching local refs
174+
- **Fetch-only mode (`--fetch-only`)** — run `git fetch --all --prune` per repo (all refs), without the mainline-only default
172175

173176
## Core Commands
174177

175178
```bash
176179
# dry run — preview repos, no changes
177180
git-rain --dry-run
178181

179-
# default run — scan and sync all repos
182+
# default run — scan repos, fetch mainline remote-tracking refs
180183
git-rain
181184

182-
# interactive repo selection before syncing
183-
git-rain --select
185+
# full local branch sync after scan
186+
git-rain --sync
187+
188+
# interactive TUI before default fetch or sync
189+
git-rain --rain
184190

185-
# fetch only (no local ref updates)
191+
# fetch everything from all remotes (broader than default mainline fetch)
186192
git-rain --fetch-only
187193

188194
# sync only known registry repos, skip filesystem scan
@@ -191,8 +197,8 @@ git-rain --no-scan
191197
# scan a specific path
192198
git-rain --path ~/projects
193199

194-
# risky mode — realign local-only commits after creating backup branches
195-
git-rain --risky
200+
# risky full sync — realign local-only commits after creating backup branches
201+
git-rain --sync --risky
196202

197203
# generate example config file
198204
git-rain --init
@@ -202,9 +208,10 @@ git-rain --init
202208

203209
| Flag | Description |
204210
|---|---|
205-
| `--dry-run` | Show what would be synced without making changes |
206-
| `--select` | Interactive TUI repo selector before syncing |
207-
| `--fetch-only` | Fetch from all remotes but skip local ref updates |
211+
| `--dry-run` | Show what would run without making changes |
212+
| `--rain` | Interactive TUI repo picker before running (like `git-fire --fire`) |
213+
| `--sync` | Update local branches from remotes (default is mainline fetch only) |
214+
| `--fetch-only` | `git fetch --all --prune` per repo (all refs); skips local branch updates |
208215
| `--path <dir>` | Scan path override (default: config `global.scan_path`) |
209216
| `--no-scan` | Skip filesystem scan; hydrate only known registry repos |
210217
| `--risky` | Allow destructive local branch realignment after creating backup refs |
@@ -248,17 +255,17 @@ GIT_RAIN_GLOBAL_RISKY_MODE=true git-rain
248255
GIT_RAIN_GLOBAL_SCAN_PATH=/tmp/repos git-rain
249256
```
250257

251-
## TUI Selector
258+
## Interactive TUI
252259

253-
`git-rain --select` opens an interactive selector. Repositories stream in as the filesystem scan finds them — no waiting for the full scan to complete before you can start picking.
260+
`git-rain --rain` opens an interactive picker. Repositories stream in as the filesystem scan finds them — no waiting for the full scan to complete before you can start picking. After you confirm, the tool runs the **default mainline fetch** unless you also passed **`--sync`** (or config implies full sync).
254261

255262
**Key bindings:**
256263

257264
| Key | Action |
258265
|---|---|
259266
| `space` | Toggle repo selection |
260267
| `a` | Select all / deselect all |
261-
| `enter` | Confirm selection and begin sync |
268+
| `enter` | Confirm selection and begin fetch or sync |
262269
| `q` / `esc` | Abort |
263270
| `` / `` | Navigate |
264271

0 commit comments

Comments
 (0)