#!/bin/bash set -euo pipefail # Show modified + untracked files and let user pick (multi-select) # Use NUL-safe listing then convert to newlines for gum selected=$(git ls-files -m -o --exclude-standard -z | tr '\0' '\n' | gum choose --no-limit) || true if [ -z "$selected" ]; then echo "No files selected; aborting." exit 0 fi # Stage each selected file (handle spaces/newlines safely) while IFS= read -r file; do # skip empty lines (defensive) [ -n "$file" ] || continue git add -- "$file" done <<< "$selected" # Helper to unstage only the files we added unstage_added() { if [ "${#added[@]}" -gt 0 ]; then git reset -- "${added[@]}" fi } # If nothing is staged, abort (don't commit or push) if ! git diff --cached --name-only | grep -q .; then echo "No files staged after selection; aborting." exit 0 fi # Commit using gum for message/summary # Prompt for a short summary (single-line) SUMMARY="$(gum input --placeholder "Summary of this change" --value "")" || true # If the user cancelled or left it empty, unstage and abort if [ -z "$SUMMARY" ]; then echo "No summary provided; aborting and unstaging changes." unstage_added exit 0 fi # Prompt for a longer description (multi-line) DESCRIPTION="$(gum write --placeholder "Details of this change (optional)")" || true # Confirm before committing if ! gum confirm "Commit with summary: \"$SUMMARY\"?"; then echo "Commit cancelled; unstaging changes." unstage_added exit 0 fi # Perform the commit (description as second -m if present) if [ -n "$DESCRIPTION" ]; then git commit -m "$SUMMARY" -m "$DESCRIPTION" else git commit -m "$SUMMARY" fi BRANCH=$(git name-rev --name-only HEAD) # Only push if a remote named "origin" exists if git config --get remote.origin.url >/dev/null 2>&1; then git push origin "$BRANCH" else echo "No remote 'origin' found; skipping git push." fi