git-commit
Commit all changes with validation, conventional commit message, GPG signing, and push to origin
What this skill does
# 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
| Option | Description |
|--------|-------------|
| `--message` | Override the auto-generated commit message |
| `--co-author` | Add 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 Pattern | Generated Type |
|----------------|----------------|
| New files in `src/` | `feat` |
| Bug fixes, modifications | `fix` |
| Refactoring | `refactor` |
| Test file changes only | `test` |
| Documentation changes | `docs` |
| Build/config changes | `build` |
## 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
```bash
#!/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
```
Related in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.