external/ag-shared/prompts/skills/git-split/SKILL.md
You are an expert in Git history management and code refactoring. Your goal is to split large files into smaller, focused modules while preserving the complete git history (blame, log) for the extracted code.
If the user provides a command option of help:
# Verify clean working tree
git status --porcelain
# Verify we're not on main branch
current_branch=$(git rev-parse --abbrev-ref HEAD)
if [ "$current_branch" = "latest" ] || [ "$current_branch" = "main" ] || [ "$current_branch" = "master" ]; then
echo "ERROR: Cannot split on main branch. Create a feature branch first."
exit 1
fi
This technique preserves git history by:
# Get file history
git log --oneline --follow -- "path/to/large-file.ts"
# Find first commit that introduced the file
git log --diff-filter=A --follow --format="%H" -- "path/to/large-file.ts" | tail -1
# Count lines and identify logical sections
wc -l "path/to/large-file.ts"
Before splitting, identify:
# Find the commit that introduced the file
first_commit=$(git log --diff-filter=A --follow --format="%H" -- "path/to/large-file.ts" | tail -1)
# Create branch from parent of first commit
git checkout -b split-history "${first_commit}^"
# Copy the original file to new locations (as copies, not moves)
cp "path/to/large-file.ts" "path/to/new-file-1.ts"
cp "path/to/large-file.ts" "path/to/new-file-2.ts"
# Commit the copies
git add .
git commit -m "chore: prepare split of large-file.ts (history preservation)"
# Return to feature branch
git checkout -
# Merge the history branch with ours strategy
git merge split-history --no-commit -X ours
# Now make the actual content changes
# - Trim new-file-1.ts to only contain its portion
# - Trim new-file-2.ts to only contain its portion
# - Update large-file.ts to re-export from new files (or remove)
# - Update imports throughout codebase
# Stage and commit
git add -A
git commit -m "refactor: split large-file.ts into focused modules
- Extract [description] to new-file-1.ts
- Extract [description] to new-file-2.ts
- Update imports throughout codebase
- Preserve git history with branch-merge technique"
# Delete the history branch
git branch -d split-history
# Verify history is preserved
git log --follow -- "path/to/new-file-1.ts"
git blame "path/to/new-file-1.ts"
For simpler cases where exact history preservation isn't critical:
# Git will detect renames if files are similar enough
git mv "path/to/large-file.ts" "path/to/new-location.ts"
# Make content changes
# ... edit files ...
# Commit with -C to help rename detection
git commit -C HEAD --amend
git log --follow and git blame after splitting