Git Integration & Panel
Relevant source files
The following files were used as context for generating this wiki page:
Termul provides a comprehensive Git integration module that enables version control operations directly within the workspace. The system facilitates staging, committing, stashing, and branch management through a dedicated UI panel and a platform-agnostic API layer. Sources: README.md:95-98, src/renderer/components/git/GitPanel.tsx
Architecture Overview
The Git integration follows a layered architecture to ensure parity between desktop and web environments. The React-based GitPanel serves as the primary user interface, which interacts with the gitApi facade. This facade routes requests to either Tauri IPC commands in the desktop app or HTTP endpoints in the web client. Sources: src/renderer/lib/tests/git-api.web.test.ts:7-13
Data Flow Diagram
The following diagram illustrates how a Git action (e.g., staging a file) travels from the UI to the underlying Git implementation.
Git Panel Components
The GitPanel organizes information into several logical sections to manage the repository state. Sources: src/renderer/components/git/GitPanel.tsx:128-155
Interface Sections
- Branch Section: Displays the current branch and provides controls to switch or create branches.
- Changes List: Categorizes files into "Staged Changes" and "Changes" (working tree).
- Stash Section: Manages stashed changes, allowing for applying, popping, or dropping stashes.
- Commit Composer: Contains fields for commit summary and description, including AI-powered message generation.
- Diff View: Shows the specific changes in a selected file with support for inline or side-by-side modes.
Sources: src/renderer/components/git/GitPanel.tsx:280-450
Mobile vs. Desktop Layouts
Termul adapts the Git UI based on the viewport. On mobile devices, the panel uses a stacked single-panel layout where the file list and diff view are toggled. Desktop view uses a two-column split layout with a persistent sidebar. Sources: src/renderer/components/git/GitPanel.tsx:210-216
| Feature | Desktop Layout | Mobile Layout |
|---|---|---|
| View Type | Two-column (Sidebar + Diff) | Stacked (Single view) |
| File Navigation | Persistent sidebar | Back button navigation |
| Row Sizing | Dense (24px actions) | Touch-sized (44px floor) |
Sources: src/renderer/components/git/GitPanel.mobile.test.tsx:102-140, src/renderer/components/git/GitPanel.tsx:218-450
Git API and Data Models
The system uses standardized TypeScript interfaces to represent Git states across all platforms. Sources: src/shared/types/ipc.types.ts:160-240
Key Data Structures
GitStatusDetail
Represents the state of a single file in the repository.
export interface GitStatusDetail {
path: string;
status: 'added' | 'modified' | 'deleted' | 'renamed' | 'untracked' | 'staged';
staged: boolean;
}
Sources: src/shared/types/ipc.types.ts:172-176
GitCommitContext
Provides metadata for the current commit environment.
export interface GitCommitContext {
branch: string | null;
hasUpstream: boolean;
ahead: number;
behind: number;
stagedCount: number;
hasHead: boolean;
lastSubject: string;
lastBody: string;
}
Sources: src/shared/types/ipc.types.ts:208-217
API Interface
The GitApi interface defines the core operations supported by the integration:
getStatus(cwd: string): Retrieves the status of all files in the repository.getDiff(cwd: string, path: string, staged?: boolean): Fetches a unified diff for a file.stage(cwd: string, path: string): Adds a file to the Git index.commit(cwd: string, summary: string, description?: string, amend?: boolean): Creates a new commit.stashSave(cwd: string, message?: string, includeUntracked?: boolean): Stashes current changes.
Sources: src/shared/types/ipc.types.ts:223-245
AI Commit Message Generation
Termul integrates with the ACP (Agent Control Plane) to generate commit messages based on staged diffs. Sources: src/renderer/components/git/GitPanel.test.tsx:85-110
Generation Logic Sequence
Constraints and Safety
- Staged Only: Generation only uses staged changes to ensure accuracy. Sources: src/renderer/components/git/use-git-actions.ts:178-185
- Size Limit: Aggregate diffs exceeding 120,000 characters are rejected to prevent agent overload. Sources: src/renderer/components/git/use-git-actions.ts:227-230
- Staleness Guard: The system rejects generation if staged files change during the process. Sources: src/renderer/components/git/use-git-actions.ts:213-220
Git Operations Logic
Staging and Multi-selection
The GitPanel supports VSCode-style selection modifiers:
- Plain Click: Selects a single row.
- Ctrl/Cmd + Click: Toggles individual rows in the selection.
- Shift + Click: Selects a contiguous range of files.
Sources: src/renderer/components/git/GitPanel.tsx:112-126
Hunk-Level Operations
Users can stage or unstage specific hunks (parts of a file) rather than the entire file. This is performed by building a patch from the GitDiffView and applying it to the index. Sources: src/renderer/components/git/use-git-actions.ts:108-150
Stash Management
The stash implementation allows users to temporarily shelve changes.
- Stash Save: Includes an option to include untracked files. Sources: src/renderer/components/git/use-git-actions.ts:335-348
- Stash Pop: Applies the most recent (or selected) stash and removes it from the stash list. Sources: src/renderer/components/git/use-git-actions.ts:375-388
Branch Management
Termul handles branch creation and switching. If a user attempts to switch branches with uncommitted changes, the system prompts them to either "bring" the changes to the new branch or "stash" them automatically before switching. Sources: src/renderer/components/git/use-git-actions.ts:286-310