Skip to content

feat: add git file status and enhanced git widgets#208

Open
tejasdc wants to merge 1 commit intosirmalloc:mainfrom
tejasdc:feat/git-status-widgets
Open

feat: add git file status and enhanced git widgets#208
tejasdc wants to merge 1 commit intosirmalloc:mainfrom
tejasdc:feat/git-status-widgets

Conversation

@tejasdc
Copy link

@tejasdc tejasdc commented Mar 8, 2026

Summary

Adds 7 new git widgets addressing issue #20 ("Add enhanced git status options to git widgets"). These provide granular git repository status information that the current widget set lacks — file-level counts, upstream tracking, conflict detection, clean/dirty status, and commit SHA.

All widgets follow existing patterns exactly: Widget interface, git-no-git shared helpers, hideNoGit metadata support, rawValue mode, and cross-platform git commands via runGit().

Comparable in scope to PR #201 (Skills widget) — 19 files changed, 1,378 lines added.

New Widgets

Widget Type String Default Output rawValue Color Git Command
Git Staged Files git-staged-files S:3 3 green git diff --cached --name-only
Git Unstaged Files git-unstaged-files M:2 2 yellow git diff --name-only
Git Untracked Files git-untracked-files A:1 1 red git ls-files --others --exclude-standard
Git Ahead/Behind git-ahead-behind ↑2 ↓1 2 1 cyan git rev-list --left-right --count HEAD...@{upstream}
Git Merge Conflicts git-merge-conflicts ⚠1 1 red git diff --name-only --diff-filter=U
Git Clean Status git-clean-status / clean / dirty green git status --porcelain
Git SHA git-sha a3f2c1d N/A brightBlack git rev-parse --short HEAD

Edge Cases

  • No upstream branch: git-ahead-behind shows (no upstream) or hides via hideNoGit
  • No merge conflicts: git-merge-conflicts returns null (hidden) — only visible when conflicts exist
  • Clean working tree: File count widgets show S:0, M:0, A:0 — counts are always meaningful
  • Detached HEAD: git-sha works normally; git-ahead-behind falls back to no-upstream behavior

Complementary to PR #153

PR #153 (git-indicators) adds binary yes/no indicators for staged/unstaged. These widgets provide actual counts and cover additional features (untracked files, ahead/behind, conflicts, clean status, SHA). The two are complementary, not overlapping.

Changes

File Change
src/widgets/GitStagedFiles.ts New widget: staged file count
src/widgets/GitUnstagedFiles.ts New widget: unstaged file count
src/widgets/GitUntrackedFiles.ts New widget: untracked file count
src/widgets/GitAheadBehind.ts New widget: ahead/behind upstream
src/widgets/GitMergeConflicts.ts New widget: merge conflict count
src/widgets/GitCleanStatus.ts New widget: clean/dirty indicator
src/widgets/GitSha.ts New widget: short commit SHA
src/widgets/__tests__/GitStagedFiles.test.ts Tests for staged files widget
src/widgets/__tests__/GitUnstagedFiles.test.ts Tests for unstaged files widget
src/widgets/__tests__/GitUntrackedFiles.test.ts Tests for untracked files widget
src/widgets/__tests__/GitAheadBehind.test.ts Tests for ahead/behind widget
src/widgets/__tests__/GitMergeConflicts.test.ts Tests for merge conflicts widget
src/widgets/__tests__/GitCleanStatus.test.ts Tests for clean status widget
src/widgets/__tests__/GitSha.test.ts Tests for SHA widget
src/utils/git.ts Add getGitFileStatusCounts() utility + GitFileStatusCounts interface
src/utils/__tests__/git.test.ts Tests for new git utility
src/widgets/index.ts Add 7 new widget exports
src/utils/widget-manifest.ts Add 7 new manifest entries
src/widgets/__tests__/GitWidgetSharedBehavior.test.ts Add 7 entries to shared behavior tests

14 new files + 5 modified files = 19 files total

Implementation Details

Shared Utility: getGitFileStatusCounts()

Added to src/utils/git.ts — returns { staged, unstaged, untracked } counts. Used by the three file count widgets to avoid redundant git command logic.

export interface GitFileStatusCounts {
    staged: number;
    unstaged: number;
    untracked: number;
}

Pattern Compliance

Every widget follows the exact patterns established by existing git widgets:

  • Implements Widget interface from src/types/Widget.ts
  • Uses git-no-git shared helpers for hideNoGit toggle and keybinds
  • Uses isInsideGitWorkTree() to gate git operations
  • Uses runGit() for all git commands (cross-platform via child_process.execSync)
  • Supports rawValue mode where applicable
  • Returns null to hide when appropriate (no git, no upstream, no conflicts)
  • Includes preview values for the TUI editor

Test Plan

  • 21 new tests across 7 test files — all passing
  • Each widget tested for: preview mode, normal rendering, rawValue mode, no-git fallback, hideNoGit behavior, error handling
  • GitAheadBehind additionally tested for: no-upstream (empty output), no-upstream (throw), invalid output parsing
  • GitMergeConflicts tested for: zero conflicts returning null (hidden)
  • Shared behavior tests updated with 7 new entries
  • getGitFileStatusCounts() utility tested
  • bun run lint passes (TypeScript type checking + ESLint)
  • Tested locally with live Claude Code status line

Closes #20

…hind, conflicts, clean status, SHA)

Add granular git repository status widgets addressing issue sirmalloc#20:
- GitStagedFiles: staged file count (S:N format)
- GitUnstagedFiles: unstaged file count (M:N format)
- GitUntrackedFiles: untracked file count (A:N format)
- GitAheadBehind: upstream ahead/behind tracking (↑N ↓M format)
- GitMergeConflicts: merge conflict count (⚠N, hidden when 0)
- GitCleanStatus: clean/dirty indicator (✓/✗)
- GitSha: short commit SHA

All widgets follow existing patterns: Widget interface, git-no-git shared
helpers, hideNoGit support, rawValue support, and cross-platform git
commands via runGit(). Includes shared getGitFileStatusCounts() utility
for the file count widgets.

21 new tests across 7 test files + shared behavior test entries.

Closes sirmalloc#20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add enhanced git status options to git widgets

1 participant