Files
CodePilot/src/hooks/useGitLog.ts
T
7418andClaude Opus 4.6 0eabed8c27 feat: Git integration, terminal, unified layout — full Phase 1-5 implementation
**Layout refactor (Phase 1):**
- UnifiedTopBar replacing Header.tsx — chat title editing, project folder,
  commit/push split button, Git branch+dirty badge, terminal/file-tree toggles
- PanelZone renders FileTree, GitPanel, PreviewPanel side-by-side on the right
- Independent panel toggle states in PanelContext
- ResizeHandle unified across all panels
- Removed old RightPanel, Header, DocPreview components

**Git backend (Phase 2):**
- src/lib/git/service.ts — execFile-based Git operations with timeout + injection safety
- API routes: status, branches, checkout, log, commit, push, commit-detail, worktrees, derive
- Worktree derive creates DB session inheriting source session settings

**Git frontend (Phase 3):**
- GitPanel with 4 collapsible sections: Status, Branches, History, Worktrees
- CommitDialog with commit vs commit-and-push modes
- GitBranchSelector with inline error, worktree-occupied branches disabled
- GitWorktreeSection with switch-to/derive actions, current/dirty indicators
- useGitStatus polled in AppShell, derived into context (no redundant setState)

**Terminal (Phase 4):**
- electron/terminal-manager.ts — child_process.spawn fallback (PTY upgrade documented)
- IPC handlers + TerminalDrawer/TerminalInstance components

**Polish (Phase 5):**
- Push inline feedback with 4s auto-dismiss
- Branch detection fix, commit diff exit-code handling
- Removed redundant git state: currentBranch/gitDirtyCount now derived, not setState
- useTerminal isElectron uses lazy initializer instead of effect
- i18n keys (en + zh), user tutorial docs, handover document

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 00:38:00 +08:00

32 lines
949 B
TypeScript

"use client";
import { useState, useCallback } from "react";
import type { GitLogEntry } from "@/types";
export function useGitLog(cwd: string) {
const [entries, setEntries] = useState<GitLogEntry[]>([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const fetch_ = useCallback(async (limit = 50) => {
if (!cwd) return;
setLoading(true);
setError(null);
try {
const res = await fetch(`/api/git/log?cwd=${encodeURIComponent(cwd)}&limit=${limit}`);
if (!res.ok) {
const data = await res.json();
throw new Error(data.error || 'Failed to fetch log');
}
const data = await res.json();
setEntries(data.entries);
} catch (err) {
setError(err instanceof Error ? err.message : 'Failed to fetch log');
} finally {
setLoading(false);
}
}, [cwd]);
return { entries, loading, error, fetch: fetch_ };
}