This guide explains how to set up and use Git safety hooks to prevent accidental commits with local file dependencies when using PackDev.
The Git safety hook prevents you from accidentally committing local file dependencies (like "file:../my-package") to your repository. This is crucial for maintaining clean, production-ready code.
The hook scans your package.json for:
file:protocol dependencies- Relative path dependencies (starting with
./or../) - Dependencies in all sections:
dependencies,devDependencies,peerDependencies,optionalDependencies
# Create the safety hooks
packdev setup-hooks
# Hooks are automatically installed in .git/hooks/ and active immediately# Switch to local development
packdev init
# Try to commit (should be blocked)
git add .
git commit -m "test commit"
# Commit with WIP (should be allowed)
git commit -m "WIP: testing local changes"# Create new hooks
packdev setup-hooks
# Create hooks with auto-commit flow
packdev setup-hooks --auto-commit
# Overwrite existing hooks
packdev setup-hooks --force
# Enable auto-commit flow on existing hooks
packdev setup-hooks --auto-commit --force
# Remove/disable hooks
packdev setup-hooks --disablegraph TD
A[Git Commit] --> B[Pre-commit Hook]
B --> C[Check package.json]
C --> D{Local deps found?}
D -->|No| E[✅ Allow Commit]
D -->|Yes| F{WIP in message?}
F -->|Yes| G[⚠️ Allow with Warning]
F -->|No| H{Auto-commit flow enabled?}
H -->|No| I[❌ Block Commit]
H -->|Yes| J[❓ Ask: Finish and commit?]
J -->|No| I
J -->|Yes| K[🔄 packdev finish]
K --> L[📦 git add package.*]
L --> M[💾 git commit]
M --> N[🔄 packdev init]
N --> O[✅ Complete]
.git/hooks/pre-commit- Shell script that triggers the check.git/hooks/check-local-deps.js- Node.js script that performs the validation
There are several ways to proceed when the hook blocks your commit:
# Restore original dependencies
packdev finish
# Now commit normally
git add .
git commit -m "implement feature X"# Add WIP to commit message
git commit -m "WIP: testing local package changes"
git commit -m "work in progress: debugging issue"
git commit -m "wip - incomplete feature"# Disable hooks temporarily
packdev setup-hooks --disable
# Make your commits
git commit -m "commit with local deps"
# Re-enable hooks
packdev setup-hooks# Enable auto-commit flow when setting up hooks
packdev setup-hooks --auto-commit
# Or enable on existing hooks
packdev setup-hooks --auto-commit --forceWhen auto-commit flow is enabled, the pre-commit hook will:
- Detect local dependencies in your commit
- Ask interactively: "Do you want to finish development and commit the changes? (y/n)"
- If you answer 'yes':
- Run
packdev finishto restore original dependencies - Run
git add package.*to stage package files - Commit with your original commit message
- Run
packdev initto restore development environment
- Run
- If you answer 'no': Block the commit (traditional behavior)
Benefits:
- 🚀 Streamlined workflow - No need to manually run finish/init cycle
- 🔒 Safe by default - Always asks before proceeding
- 💾 Preserves your commit message - Uses exactly what you typed
- 🔄 Automatic re-initialization - Ready for continued development
- 💡 Configurable - Saved in
.packdev.jsonfor team consistency
Example interaction:
$ git commit -m "feat: add new user authentication"
⚠️ Local file dependencies detected!
📦 my-shared-lib: file:../shared-lib (dependencies)
🤖 Do you want to finish development and commit the changes? (y/n): y
🔄 Running packdev finish...
✅ Dependencies restored
📦 Adding package files...
✅ Package files staged
💾 Committing with message: "feat: add new user authentication"
✅ Changes committed
🔄 Running packdev init...
✅ Development environment restored
🎉 Auto-commit flow completed successfully!# 1. Start local development
packdev add my-utils ../shared/utils
packdev init
# 2. Make changes and test
# ... development work ...
# 3. Commit work-in-progress
git add .
git commit -m "WIP: implementing new feature with local utils"
# 4. Continue development
# ... more work ...
# 5. Finish and commit properly
packdev finish
git add .
git commit -m "implement new feature using shared utils"# Share WIP branch with team
git checkout -b feature/new-ui
packdev init
git commit -m "WIP: initial UI components with local deps"
git push origin feature/new-ui
# Later, clean up before merge
packdev finish
git add .
git commit -m "finalize UI components"
git push origin feature/new-ui# No local dependencies
git commit -m "fix bug in authentication"
# WIP commits with local deps
git commit -m "WIP: testing new features"
# After restoring dependencies
packdev finish
git commit -m "add new utility functions"# Local deps without WIP
git commit -m "add new features" # BLOCKED
# Case-sensitive WIP check passes
git commit -m "Work In Progress: testing" # ALLOWED
git commit -m "wip testing" # ALLOWED# Check if hooks are installed
ls -la .git/hooks/pre-commit
# Should show the packdev hook file# Make hook executable
chmod +x .git/hooks/pre-commit
# Or recreate with proper permissions
packdev setup-hooks --force# Test the check script directly
node .git/hooks/check-local-deps.js
# Check if package.json has local deps
grep -E "(file:|\.\.\/|\.\/)" package.json# On Windows, ensure Node.js is in PATH
where node
# The hook should work with Git Bash, PowerShell, or CMD# Hooks are installed in standard .git/hooks/ directory
# No additional configuration needed
# Check if hooks are installed
ls -la .git/hooks/pre-commitThe generated hook script can be modified if needed:
// In .git/hooks/check-local-deps.js
// Modify the WIP pattern
const wipPattern = /\b(wip|draft|temp)\b/i;
// Add exclusions
const excludePackages = ['@my-org/dev-tools'];# 1. One team member sets up hooks
packdev setup-hooks
# Note: .git/hooks/ is not committed to git
# 2. Other team members just run:
packdev setup-hooks
# Each developer installs hooks locally# .github/workflows/safety-check.yml
name: Safety Check
on: [push, pull_request]
jobs:
check-deps:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
- name: Check for local dependencies
run: |
# Create a temporary check script for CI
cat > check-deps.js << 'EOF'
const fs = require('fs');
const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'));
const deps = {...(packageJson.dependencies || {}), ...(packageJson.devDependencies || {})};
const localDeps = Object.entries(deps).filter(([_, version]) =>
typeof version === 'string' && (version.startsWith('file:') || version.includes('../'))
);
if (localDeps.length > 0) {
console.log('❌ Local dependencies found:', localDeps.map(([name]) => name));
process.exit(1);
}
console.log('✅ No local dependencies found');
EOF
node check-deps.js# ❌ Not descriptive
git commit -m "WIP"
# ✅ Descriptive
git commit -m "WIP: implementing user authentication with local auth-lib"# Before merging or releasing
packdev finish
npm install # Ensure all deps are properly installed
npm test # Verify everything works
git commit -m "finalize feature implementation"# In commit messages
git commit -m "WIP: testing with local @myorg/utils v2.1.0-beta"
# In pull request descriptions
echo "Note: This PR uses local dependencies for testing purposes"# Create feature branch
git checkout -b feature/local-testing
# Work with local deps
packdev init
git commit -m "WIP: initial implementation"
# Clean up in separate commit
packdev finish
git commit -m "clean up dependencies"# Remove husky
npm uninstall husky
# Remove .husky directory
rm -rf .husky
# Setup packdev hooks
packdev setup-hooks# Remove .pre-commit-config.yaml
rm .pre-commit-config.yaml
# Setup packdev hooks
packdev setup-hooks- Never deploy code with
file:dependencies to production - Always run
packdev finishbefore creating release builds - Use CI/CD checks to catch any missed local dependencies
- Don't commit hook files (
.git/hooks/is local to each developer) - Do commit
.packdev.jsonto share configuration with your team - Each team member should run
packdev setup-hooksto install hooks locally - Include hook setup in your project's README
- Communicate when using local dependencies in shared branches
- Document which packages have local overrides
- Coordinate local dependency versions across team members
The GitHub safety hooks provide an essential safety net for teams using packdev. They prevent accidental commits of local dependencies while allowing flexibility for development workflows through WIP commits and easy bypass mechanisms.
For more information, see:
- PACKAGING.md - Complete packaging guide
- YARN-SUPPORT.md - Yarn-specific instructions
- README.md - Main project documentation