Advanced

Git Hooks Setup

Set up Git hooks for automatic m1f bundle generation

This guide explains how to set up Git hooks for automatic m1f bundle generation in your projects.

Overview

The m1f Git pre-commit hook automatically runs m1f-update before each commit, ensuring that your bundled files are always up-to-date with your source code.

Features

  • Automatic bundle generation - Bundles are regenerated on every commit
  • Fail-safe commits - Commits are blocked if bundle generation fails
  • Auto-staging - Generated bundles in the m1f/ directory are automatically added to commits
  • Conditional execution - Only runs if .m1f.config.yml exists in your project

Installation

  1. Navigate to your project root (where .m1f.config.yml is located)
  2. Run the installation script:
# Download and run the installation script
curl -sSL https://raw.githubusercontent.com/franzundfranz/m1f/main/scripts/install-git-hooks.sh | bash

# Or if you have the m1f repository cloned
bash /path/to/m1f/scripts/install-git-hooks.sh

The script will:

  • Check if you’re in a Git repository
  • Install the pre-commit hook
  • Backup any existing pre-commit hook
  • Make the hook executable

Method 2: Manual Installation

  1. Create the pre-commit hook file:
cat > .git/hooks/pre-commit << 'EOF'
#!/bin/bash
# m1f Auto-Bundle Git Pre-Commit Hook

if [ -f ".m1f.config.yml" ]; then
    if ! command -v m1f &> /dev/null; then
        echo "Error: m1f command not found!"
        echo "Please install m1f: pip install m1f"
        exit 1
    fi

    echo "Running m1f-update..."
    if m1f-update; then
        echo "Auto-bundle completed successfully."
        [ -d "m1f" ] && git add m1f/*
    else
        echo "Auto-bundle failed. Please fix the issues before committing."
        exit 1
    fi
fi
exit 0
EOF
  1. Make it executable:
chmod +x .git/hooks/pre-commit

How It Works

When you run git commit, the pre-commit hook:

  1. Checks if .m1f.config.yml exists in your repository
  2. Verifies that the m1f command is available
  3. If both conditions are met, runs m1f-update
  4. If bundle generation succeeds:
    • Adds all files in the m1f/ directory to the commit
    • Allows the commit to proceed
  5. If bundle generation fails:
    • Displays the error message
    • Blocks the commit
    • You must fix the issues before committing

Usage

Once installed, the hook works automatically:

# Normal commit - bundles are generated automatically
git add your-files.py
git commit -m "feat: add new feature"

# Skip the hook if needed
git commit --no-verify -m "wip: quick save"

Troubleshooting

Hook Not Running

  1. Check if the hook is executable:

    ls -la .git/hooks/pre-commit
    
  2. Make it executable if needed:

    chmod +x .git/hooks/pre-commit
    

Bundle Generation Fails

  1. Run auto-bundle manually to see the error:

    m1f-update
    
  2. Fix any issues in your .m1f.config.yml

  3. Try committing again

m1f Command Not Found

If you get “m1f command not found”, ensure m1f is installed:

pip install m1f
# or for development
pip install -e /path/to/m1f

Disable the Hook Temporarily

Use the --no-verify flag:

git commit --no-verify -m "your message"

Remove the Hook

To uninstall the pre-commit hook:

rm .git/hooks/pre-commit

Best Practices

  1. Include m1f/ in version control - This ensures bundled files are available to all team members and AI tools

  2. Review bundle changes - Check the generated bundles in your diffs before committing

  3. Keep bundles focused - Configure smaller, specific bundles rather than one large bundle

  4. Use bundle groups - Organize related bundles into groups for better management

  5. Test hook behavior - Verify the hook works correctly before relying on it

Example Workflow

1. Set up your project with m1f:

m1f-init  # Initialize m1f in your project

2. Create .m1f.config.yml:

bundles:
  project-docs:
    description: "Project documentation"
    output: "m1f/docs.txt"
    sources:
      - path: "docs"
        include_extensions: [".md"]

  source-code:
    description: "Source code bundle"
    output: "m1f/code.txt"
    sources:
      - path: "src"
        include_extensions: [".py", ".js", ".ts"]
        excludes: ["**/*.test.*"]

3. Install the Git hook:

bash /path/to/m1f/scripts/install-git-hooks.sh

4. Work normally - bundles update automatically:

echo "# New Feature" > docs/feature.md
git add docs/feature.md
git commit -m "docs: add feature documentation"
# Bundle is regenerated and included in the commit

Integration with CI/CD

The pre-commit hook ensures local development stays in sync. For CI/CD pipelines, you can also run auto-bundle as a build step:

GitHub Actions

name: Build and Test

on: [push, pull_request]

jobs:
  build:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v2
    
    - name: Set up Python
      uses: actions/setup-python@v2
      with:
        python-version: '3.10'
    
    - name: Install dependencies
      run: |
        pip install -r requirements.txt
    
    - name: Generate m1f bundles
      run: m1f-update
    
    - name: Check for bundle changes
      run: |
        if [ -n "$(git status --porcelain m1f/)" ]; then
          echo "Bundle files are out of date. Please run 'm1f-update' and commit the changes."
          exit 1
        fi

GitLab CI

stages:
  - build
  - test

variables:
  PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"

before_script:
  - pip install -r requirements.txt

bundle:
  stage: build
  script:
    - m1f-update
    - |
      if [ -n "$(git status --porcelain m1f/)" ]; then
        echo "Bundle files are out of date"
        exit 1
      fi
  cache:
    paths:
      - .cache/pip

Advanced Configuration

Custom Hook Behavior

You can customize the hook by modifying the script:

#!/bin/bash
# Enhanced m1f Auto-Bundle Git Pre-Commit Hook

# Configuration
BUNDLE_DIR="m1f"
CONFIG_FILE=".m1f.config.yml"
VERBOSE=false

# Check if we should run
if [ ! -f "$CONFIG_FILE" ]; then
    exit 0
fi

# Check if m1f is available
if ! command -v m1f &> /dev/null; then
    echo "Error: m1f command not found!"
    echo "Please install m1f or add it to your PATH"
    exit 1
fi

# Run bundle generation
echo "Generating m1f bundles..."
if [ "$VERBOSE" = true ]; then
    m1f-update --verbose
else
    m1f-update --quiet
fi

# Check if command succeeded
if [ $? -ne 0 ]; then
    echo "Bundle generation failed. Please fix the issues before committing."
    exit 1
fi

# Add generated bundles to commit
if [ -d "$BUNDLE_DIR" ]; then
    git add "$BUNDLE_DIR"/*
    echo "Bundle files added to commit"
fi

echo "Auto-bundle completed successfully."
exit 0

Conditional Bundle Generation

Only generate bundles when specific files change:

#!/bin/bash
# Conditional m1f Auto-Bundle Hook

# Check if relevant files have changed
if git diff --cached --name-only | grep -E '\.(py|js|ts|md)$' > /dev/null; then
    echo "Source files changed, regenerating bundles..."
    m1f-update
    [ -d "m1f" ] && git add m1f/*
else
    echo "No relevant changes detected, skipping bundle generation"
fi

Team Setup

For teams using m1f with Git hooks:

1. Include Hook in Repository

Add the hook to your repository for easy team setup:

# Create hooks directory
mkdir -p .githooks

# Copy the hook
cp .git/hooks/pre-commit .githooks/

# Configure git to use the hooks directory
git config core.hooksPath .githooks

2. Setup Script

Create a setup script for new team members:

#!/bin/bash
# setup-m1f.sh

echo "Setting up m1f for this project..."

# Install m1f if not available
if ! command -v m1f &> /dev/null; then
    echo "Installing m1f..."
    pip install m1f
fi

# Set up git hooks
git config core.hooksPath .githooks
chmod +x .githooks/pre-commit

# Initial bundle generation
m1f-update

echo "m1f setup complete!"

3. Documentation

Add to your project’s README:

## Development Setup

This project uses m1f for automated bundling. After cloning:

1. Install dependencies: `pip install -r requirements.txt`
2. Set up m1f: `./setup-m1f.sh`
3. Start developing - bundles update automatically on commit

Next Steps

  1. Set up the hook in your current project
  2. Configure bundles that make sense for your workflow
  3. Test the integration with a few commits
  4. Share with your team using the team setup approach
  5. Monitor bundle quality and adjust configuration as needed