mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-01-30 14:22:02 +00:00
Resolves merge conflicts: - apps/server/src/routes/terminal/common.ts: Keep randomBytes import, use @automaker/utils for createLogger - apps/ui/eslint.config.mjs: Use main's explicit globals list with XMLHttpRequest and MediaQueryListEvent additions - apps/ui/src/components/views/terminal-view.tsx: Keep our terminal improvements (killAllSessions, beforeunload, better error handling) - apps/ui/src/config/terminal-themes.ts: Keep our search highlight colors for all themes - apps/ui/src/store/app-store.ts: Keep our terminal settings persistence improvements (merge function) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
277 lines
6.7 KiB
Markdown
277 lines
6.7 KiB
Markdown
# @automaker/git-utils
|
|
|
|
Git operations and utilities for AutoMaker.
|
|
|
|
## Overview
|
|
|
|
This package provides git-related utilities including repository detection, status parsing, and diff generation for both tracked and untracked files.
|
|
|
|
## Installation
|
|
|
|
```bash
|
|
npm install @automaker/git-utils
|
|
```
|
|
|
|
## Exports
|
|
|
|
### Repository Detection
|
|
|
|
Check if a path is a git repository.
|
|
|
|
```typescript
|
|
import { isGitRepo } from '@automaker/git-utils';
|
|
|
|
const isRepo = await isGitRepo('/project/path');
|
|
if (isRepo) {
|
|
console.log('This is a git repository');
|
|
}
|
|
```
|
|
|
|
### Status Parsing
|
|
|
|
Parse git status output into structured data.
|
|
|
|
```typescript
|
|
import { parseGitStatus } from '@automaker/git-utils';
|
|
import type { FileStatus } from '@automaker/git-utils';
|
|
|
|
const statusOutput = await execAsync('git status --porcelain');
|
|
const files: FileStatus[] = parseGitStatus(statusOutput.stdout);
|
|
|
|
files.forEach((file) => {
|
|
console.log(`${file.statusText}: ${file.path}`);
|
|
// Example: "Modified: src/index.ts"
|
|
// Example: "Untracked: new-file.ts"
|
|
});
|
|
```
|
|
|
|
### Diff Generation
|
|
|
|
Generate diffs including untracked files.
|
|
|
|
```typescript
|
|
import {
|
|
generateSyntheticDiffForNewFile,
|
|
appendUntrackedFileDiffs,
|
|
getGitRepositoryDiffs,
|
|
} from '@automaker/git-utils';
|
|
|
|
// Generate diff for single untracked file
|
|
const diff = await generateSyntheticDiffForNewFile('/project/path', 'src/new-file.ts');
|
|
|
|
// Get complete repository diffs (tracked + untracked)
|
|
const result = await getGitRepositoryDiffs('/project/path');
|
|
console.log(result.diff); // Combined diff string
|
|
console.log(result.files); // Array of FileStatus
|
|
console.log(result.hasChanges); // Boolean
|
|
```
|
|
|
|
### Non-Git Directory Support
|
|
|
|
Handle non-git directories by treating all files as new.
|
|
|
|
```typescript
|
|
import { listAllFilesInDirectory, generateDiffsForNonGitDirectory } from '@automaker/git-utils';
|
|
|
|
// List all files (excluding build artifacts)
|
|
const files = await listAllFilesInDirectory('/project/path');
|
|
|
|
// Generate diffs for non-git directory
|
|
const result = await generateDiffsForNonGitDirectory('/project/path');
|
|
console.log(result.diff); // Synthetic diffs for all files
|
|
console.log(result.files); // All files as "New" status
|
|
```
|
|
|
|
## Types
|
|
|
|
### FileStatus
|
|
|
|
```typescript
|
|
interface FileStatus {
|
|
status: string; // Git status code (M/A/D/R/C/U/?/!)
|
|
path: string; // File path relative to repo root
|
|
statusText: string; // Human-readable status
|
|
}
|
|
```
|
|
|
|
### Status Codes
|
|
|
|
- `M` - Modified
|
|
- `A` - Added
|
|
- `D` - Deleted
|
|
- `R` - Renamed
|
|
- `C` - Copied
|
|
- `U` - Updated
|
|
- `?` - Untracked
|
|
- `!` - Ignored
|
|
- ` ` - Unmodified
|
|
|
|
### Status Text Examples
|
|
|
|
- `"Modified"` - File has changes
|
|
- `"Added"` - New file in staging
|
|
- `"Deleted"` - File removed
|
|
- `"Renamed"` - File renamed
|
|
- `"Untracked"` - New file not in git
|
|
- `"Modified (staged), Modified (unstaged)"` - Changes in both areas
|
|
|
|
## Usage Example
|
|
|
|
```typescript
|
|
import { isGitRepo, getGitRepositoryDiffs, parseGitStatus } from '@automaker/git-utils';
|
|
|
|
async function getProjectChanges(projectPath: string) {
|
|
const isRepo = await isGitRepo(projectPath);
|
|
|
|
if (!isRepo) {
|
|
console.log('Not a git repository, analyzing all files...');
|
|
}
|
|
|
|
const result = await getGitRepositoryDiffs(projectPath);
|
|
|
|
if (!result.hasChanges) {
|
|
console.log('No changes detected');
|
|
return;
|
|
}
|
|
|
|
console.log(`Found ${result.files.length} changed files:\n`);
|
|
|
|
// Group by status
|
|
const byStatus = result.files.reduce(
|
|
(acc, file) => {
|
|
acc[file.statusText] = acc[file.statusText] || [];
|
|
acc[file.statusText].push(file.path);
|
|
return acc;
|
|
},
|
|
{} as Record<string, string[]>
|
|
);
|
|
|
|
Object.entries(byStatus).forEach(([status, paths]) => {
|
|
console.log(`${status}:`);
|
|
paths.forEach((path) => console.log(` - ${path}`));
|
|
});
|
|
|
|
return result.diff;
|
|
}
|
|
```
|
|
|
|
## Features
|
|
|
|
### Binary File Detection
|
|
|
|
Automatically detects binary files by extension and generates appropriate diff markers.
|
|
|
|
**Supported binary extensions:**
|
|
|
|
- Images: `.png`, `.jpg`, `.jpeg`, `.gif`, `.svg`, etc.
|
|
- Documents: `.pdf`, `.doc`, `.docx`, etc.
|
|
- Archives: `.zip`, `.tar`, `.gz`, etc.
|
|
- Media: `.mp3`, `.mp4`, `.wav`, etc.
|
|
- Fonts: `.ttf`, `.otf`, `.woff`, etc.
|
|
|
|
### Large File Handling
|
|
|
|
Files larger than 1MB show size information instead of full content.
|
|
|
|
### Synthetic Diff Format
|
|
|
|
Generates unified diff format for untracked files:
|
|
|
|
```diff
|
|
diff --git a/new-file.ts b/new-file.ts
|
|
new file mode 100644
|
|
index 0000000..0000000
|
|
--- /dev/null
|
|
+++ b/new-file.ts
|
|
@@ -0,0 +1,10 @@
|
|
+export function hello() {
|
|
+ console.log('Hello');
|
|
+}
|
|
```
|
|
|
|
### Directory Filtering
|
|
|
|
When scanning non-git directories, automatically excludes:
|
|
|
|
- `node_modules`, `.git`, `.automaker`
|
|
- Build outputs: `dist`, `build`, `out`, `tmp`, `.tmp`
|
|
- Framework caches: `.next`, `.nuxt`, `.cache`, `coverage`
|
|
- Language-specific: `__pycache__` (Python), `target` (Rust), `vendor` (Go/PHP), `.gradle` (Gradle), `.venv`/`venv` (Python)
|
|
|
|
## Error Handling
|
|
|
|
Git operations can fail for various reasons. This package provides graceful error handling patterns:
|
|
|
|
### Common Error Scenarios
|
|
|
|
**1. Repository Not Found**
|
|
|
|
```typescript
|
|
const isRepo = await isGitRepo('/path/does/not/exist');
|
|
// Returns: false (no exception thrown)
|
|
```
|
|
|
|
**2. Not a Git Repository**
|
|
|
|
```typescript
|
|
const result = await getGitRepositoryDiffs('/not/a/git/repo');
|
|
// Fallback behavior: treats all files as "new"
|
|
// Returns synthetic diffs for all files in directory
|
|
```
|
|
|
|
**3. Git Command Failures**
|
|
|
|
```typescript
|
|
// Permission errors, corrupted repos, or git not installed
|
|
try {
|
|
const result = await getGitRepositoryDiffs('/project');
|
|
} catch (error) {
|
|
// Handle errors from git commands
|
|
// Errors are logged via @automaker/utils logger
|
|
console.error('Git operation failed:', error);
|
|
}
|
|
```
|
|
|
|
**4. File Read Errors**
|
|
|
|
```typescript
|
|
// When generating synthetic diffs for inaccessible files
|
|
const diff = await generateSyntheticDiffForNewFile('/path', 'locked-file.txt');
|
|
// Returns placeholder: "[Unable to read file content]"
|
|
// Error is logged but doesn't throw
|
|
```
|
|
|
|
### Best Practices
|
|
|
|
1. **Check repository status first**:
|
|
|
|
```typescript
|
|
const isRepo = await isGitRepo(path);
|
|
if (!isRepo) {
|
|
// Handle non-git case appropriately
|
|
}
|
|
```
|
|
|
|
2. **Expect non-git directories**:
|
|
- `getGitRepositoryDiffs()` automatically handles both cases
|
|
- Always returns a valid result structure
|
|
|
|
3. **Monitor logs**:
|
|
- Errors are logged with the `[GitUtils]` prefix
|
|
- Check logs for permission issues or git configuration problems
|
|
|
|
4. **Handle edge cases**:
|
|
- Empty repositories (no commits yet)
|
|
- Detached HEAD states
|
|
- Corrupted git repositories
|
|
- Missing git binary
|
|
|
|
## Dependencies
|
|
|
|
- `@automaker/types` - FileStatus type definition
|
|
- `@automaker/utils` - Logger utilities
|
|
|
|
## Used By
|
|
|
|
- `@automaker/server` - Git routes, worktree operations, feature context
|