A pin on a pushed feature branch showed as diverged from origin/main
because the .gitmodules branch won before any distance was compared.
Now the branch containing the pin with the fewest commits after it wins;
the .gitmodules branch, the upstream and the remote default branch only
break ties and are always compared. An unpushed pin compares just those
preferred refs by commits on either side.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
For a dirty submodule, list the changed files so the user can remember
what they were doing there:
Changes 5 files · 2M 1A 1D 1R · +37 −12
──────────────────────────────────
M render.go src/render/ +20 −4 3d ago
? scratch.txt 5m ago
- Status.Changes: files changed against HEAD (staged and unstaged
combined) with kind, line counts and modification time; sorted by kind,
then by size; capped at 200 with totals over all files.
- Git provider: parse `status --porcelain=v2 -z` and one
`diff HEAD --numstat -z -M`, only for dirty submodules.
- Detail pane: flat list with a colored status letter per file, like IDE
source-control views; counts and age in compact columns; up to 10 files,
every kind keeps a line, the rest is summarized as "n more".
- Fixture gains libs/work with every kind of change; mock data extended.
- Docs: F24, change preview in the UX guide, D17.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Implement submodule.Provider with the git CLI so submarine reads real
repositories: `submarine [dir]`, with `--mock` for the built-in data.
- Tree reads .gitmodules recursively; Status derives presence, checkout,
worktree, staged pin, pushed state and pin -> ref resolution from local
git commands only (no network).
- Concurrent Status calls are bounded by runtime.NumCPU().
- scripts/make-fixture.sh builds a superproject covering every state; the
integration tests run against it.
- theme.Ago shows "never" for a zero time.
- Docs updated; decisions D14-D16 added.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>