スキル一覧に戻る
kbrockhoff

git-commit

by kbrockhoff

Brockhoff Cloud Claude Plugins

0🍴 0📅 2026年1月24日
GitHubで見るManusで実行

SKILL.md


name: git-commit description: Commit all changes with validation, conventional commit message, GPG signing, and push to origin invocation: /bkff:git-commit arguments:

  • name: --message type: string required: false description: Override auto-generated commit message
  • name: --co-author type: string required: false description: Add co-author attribution (format "Name ")

Commit Changes

Validates changes, stages all new and modified files, generates a conventional commit message, creates a GPG-signed commit, and pushes to origin.

Usage

/bkff:git-commit [--message "custom message"] [--co-author "Name <email>"]

Options

OptionDescription
--messageOverride the auto-generated commit message
--co-authorAdd a co-author to the commit

What It Does

  1. Validates changes using build tool (make lint, npm run lint, etc.)
  2. Halts if validation fails with error details
  3. Stages all changes (git add -A)
  4. Analyzes changes to generate conventional commit type and scope
  5. Creates a GPG-signed commit
  6. Pushes to origin

Conventional Commit Types

Change PatternGenerated Type
New files in src/feat
Bug fixes, modificationsfix
Refactoringrefactor
Test file changes onlytest
Documentation changesdocs
Build/config changesbuild

Example Output

## Commit Created

### Validation
- ✓ Build tool validation passed

### Changes Committed
- **Files**: 3 files changed
  - M src/auth.ts
  - A src/utils.ts
  - M README.md

### Commit
- **Hash**: abc1234
- **Message**: feat(auth): implement login functionality
- **Signed**: Yes

### Push
- **Status**: Success

Requirements

  • Must be run inside a git worktree
  • git CLI for commit and push
  • GPG configured for commit signing
  • Build tool with validate/lint target (optional)

Error Cases

  • No changes: "Nothing to commit"
  • Validation failed: Shows lint/test errors
  • GPG unavailable: Error with configuration instructions
  • Push failed: Commit preserved locally, retry instructions

Implementation

#!/usr/bin/env bash
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PLUGIN_DIR="$(dirname "$(dirname "$SCRIPT_DIR")")"
source "$PLUGIN_DIR/lib/common.sh"
source "$PLUGIN_DIR/lib/git-helpers.sh"
source "$PLUGIN_DIR/lib/validation.sh"

# Parse arguments
CUSTOM_MESSAGE=""
CO_AUTHOR=""
while [[ $# -gt 0 ]]; do
    case "$1" in
        --message|-m)
            CUSTOM_MESSAGE="$2"
            shift 2
            ;;
        --co-author)
            CO_AUTHOR="$2"
            shift 2
            ;;
        *)
            shift
            ;;
    esac
done

require_worktree

# Check for changes
if ! has_changes; then
    info "Nothing to commit. Working directory is clean."
    exit 0
fi

echo "## Commit Process"
echo ""

# FR-012, FR-013: Run validation
echo "### Validation"
if has_validate_target; then
    if run_validation; then
        echo "- ✓ Build tool validation passed"
    else
        echo "- ✗ Build tool validation failed"
        echo ""
        error_exit "Fix validation errors before committing."
    fi
else
    echo "- ⊘ No validation target found (skipped)"
fi
echo ""

# FR-016: Check GPG signing availability
if ! has_signing_available; then
    error_exit "GPG signing required but unavailable. Configure GPG key first:\n  git config --global user.signingkey <KEY_ID>\n  git config --global commit.gpgsign true"
fi

# FR-014: Stage all changes
info "Staging all changes..."
git add -A

# Get list of staged files for display and analysis
STAGED_FILES=$(git diff --cached --name-status)
STAGED_COUNT=$(echo "$STAGED_FILES" | grep -c '^' || echo "0")

echo "### Changes to Commit"
echo "- **Files**: $STAGED_COUNT files"
echo "$STAGED_FILES" | while IFS=$'\t' read -r status file; do
    printf "  - %s %s\n" "$status" "$file"
done
echo ""

# FR-015: Generate conventional commit message
generate_commit_type() {
    local files="$1"

    # Check for new files (feat)
    if echo "$files" | grep -q '^A'; then
        # New source files = feat
        if echo "$files" | grep -qE '^A.*\.(ts|js|py|go|rs|java|sh)$'; then
            echo "feat"
            return
        fi
    fi

    # Check for test files only
    if echo "$files" | grep -qE 'test|spec' && ! echo "$files" | grep -vqE 'test|spec'; then
        echo "test"
        return
    fi

    # Check for docs only
    if echo "$files" | grep -qE '\.(md|txt|rst)$' && ! echo "$files" | grep -vqE '\.(md|txt|rst)$'; then
        echo "docs"
        return
    fi

    # Check for build/config files
    if echo "$files" | grep -qE '(Makefile|package\.json|Cargo\.toml|\.yml|\.yaml)'; then
        echo "build"
        return
    fi

    # Default to fix for modifications
    echo "fix"
}

generate_scope() {
    local files="$1"

    # Extract common directory from changed files
    local first_dir
    first_dir=$(echo "$files" | head -1 | awk -F'\t' '{print $2}' | cut -d'/' -f1)

    # If it's a known directory, use it as scope
    case "$first_dir" in
        src|lib|pkg|cmd|internal)
            # Get the next level directory as scope
            local scope
            scope=$(echo "$files" | head -1 | awk -F'\t' '{print $2}' | cut -d'/' -f2)
            if [[ -n "$scope" && "$scope" != *.* ]]; then
                echo "$scope"
                return
            fi
            ;;
        skills|plugins|commands)
            echo "$first_dir"
            return
            ;;
    esac

    echo ""
}

generate_description() {
    local commit_type="$1"
    local files="$2"

    # Get the first changed file for context
    local first_file
    first_file=$(echo "$files" | head -1 | awk -F'\t' '{print $2}' | xargs basename 2>/dev/null || echo "files")
    first_file="${first_file%.*}"  # Remove extension

    case "$commit_type" in
        feat) echo "add ${first_file} functionality" ;;
        fix) echo "update ${first_file}" ;;
        docs) echo "update documentation" ;;
        test) echo "update tests" ;;
        build) echo "update build configuration" ;;
        *) echo "update ${first_file}" ;;
    esac
}

if [[ -n "$CUSTOM_MESSAGE" ]]; then
    COMMIT_MSG="$CUSTOM_MESSAGE"
else
    COMMIT_TYPE=$(generate_commit_type "$STAGED_FILES")
    COMMIT_SCOPE=$(generate_scope "$STAGED_FILES")
    COMMIT_DESC=$(generate_description "$COMMIT_TYPE" "$STAGED_FILES")

    if [[ -n "$COMMIT_SCOPE" ]]; then
        COMMIT_MSG="${COMMIT_TYPE}(${COMMIT_SCOPE}): ${COMMIT_DESC}"
    else
        COMMIT_MSG="${COMMIT_TYPE}: ${COMMIT_DESC}"
    fi
fi

# Add co-author if specified
if [[ -n "$CO_AUTHOR" ]]; then
    COMMIT_MSG="${COMMIT_MSG}

Co-authored-by: ${CO_AUTHOR}"
fi

# FR-016: Create signed commit
info "Creating signed commit..."
if git commit -S -m "$COMMIT_MSG"; then
    COMMIT_HASH=$(git rev-parse --short HEAD)
    success "Commit created: $COMMIT_HASH"
else
    error_exit "Failed to create commit"
fi

echo ""
echo "### Commit"
echo "- **Hash**: $COMMIT_HASH"
echo "- **Message**: $(echo "$COMMIT_MSG" | head -1)"
echo "- **Signed**: Yes"
[[ -n "$CO_AUTHOR" ]] && echo "- **Co-Author**: $CO_AUTHOR"
echo ""

# FR-017: Push to origin
echo "### Push"
info "Pushing to origin..."
if git push; then
    echo "- **Status**: Success"
    echo ""
    success "Commit pushed to origin."
else
    warn "Push failed (commit preserved locally)"
    echo "- **Status**: Failed"
    echo ""
    echo "Run 'git push' to retry."
fi

スコア

総合スコア

60/100

リポジトリの品質指標に基づく評価

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

+10
説明文

100文字以上の説明がある

0/10
人気

GitHub Stars 100以上

0/15
最近の活動

3ヶ月以内に更新がある

0/10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

0/5

レビュー

💬

レビュー機能は近日公開予定です