mirror of
https://github.com/prdlk/gh-commit.git
synced 2026-09-16 23:16:25 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2ab62dd347 | ||
|
|
d81fc02693 | ||
|
|
0acee0a694 | ||
|
|
3086dac5d6 | ||
|
|
f1302fd1ec | ||
|
|
ae36a7052d | ||
|
|
9647c854c9 |
@@ -1,2 +1 @@
|
||||
/.omc
|
||||
/__pycache__
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025 Prad
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -1,6 +1,11 @@
|
||||
# gh-commit
|
||||
|
||||
AI-powered scoped git commits. Groups changes by project area, generates commit messages with `crush run`, and pushes — all in one command.
|
||||
AI-powered scoped git commits as a GitHub CLI extension, driven by the
|
||||
[Crush](https://github.com/charmbracelet/crush) CLI. Scopes map Conventional
|
||||
Commit scope names to path prefixes. They are generated from the repository
|
||||
file tree, stored in a local DuckDB database, and auto-regenerate whenever
|
||||
`.gitignore` changes. Changed files are grouped by scope and committed one
|
||||
scope at a time with generated `type(scope): message` subjects.
|
||||
|
||||
## Install
|
||||
|
||||
@@ -14,61 +19,31 @@ gh extension install prdlk/gh-commit
|
||||
- [Crush](https://github.com/charmbracelet/crush) — non-interactive AI runner
|
||||
- `GROQ_API_KEY` — authenticates the default Groq model
|
||||
|
||||
By default, gh-commit uses Groq's `openai/gpt-oss-120b`. Override the model with `GH_COMMIT_CRUSH_MODEL`.
|
||||
By default, gh-commit uses Groq's `openai/gpt-oss-120b` via the bundled `crush-provider` config. Override the model with `GH_COMMIT_CRUSH_MODEL`.
|
||||
|
||||
## Usage
|
||||
|
||||
```sh
|
||||
# Initialize scopes for your repo (uses Crush to analyze structure)
|
||||
gh commit init
|
||||
|
||||
# Commit changes grouped by scope
|
||||
gh commit
|
||||
|
||||
# Auto-confirm + auto-push
|
||||
gh commit --auto --push
|
||||
|
||||
# Manually refresh scopes after structural changes
|
||||
gh commit refresh
|
||||
|
||||
# Sync scopes as GitHub labels
|
||||
gh commit sync
|
||||
cd your-repo
|
||||
gh commit init # generate scopes for this repo
|
||||
gh commit # commit changes grouped by scope
|
||||
```
|
||||
|
||||
## How it works
|
||||
|
||||
1. **`gh commit init`** — `crush run` analyzes your repo structure and generates scope definitions (e.g., `core → src/`, `docs → docs/, README.md`, `ci → .github/workflows/`)
|
||||
2. **`gh commit`** — Groups dirty files by scope, sends each staged diff to `crush run`, and commits each group separately
|
||||
3. **Auto-refresh** — Whenever your `.gitignore` changes, scopes are automatically regenerated before committing (a content hash of `.gitignore` is tracked per repo)
|
||||
4. Remaining unscoped files are handled in a final pass
|
||||
5. Unpushed commits are offered for push
|
||||
|
||||
Scopes are stored in a local DuckDB database (`~/.local/share/gh-commit/gh-commit.db`) — no config files in your repo.
|
||||
|
||||
### Why Crush?
|
||||
|
||||
The former Mods roles now live directly in `smartcommit.py`, so gh-commit no longer depends on Mods configuration. Each generation invokes Crush's supported non-interactive mode with a self-contained prompt.
|
||||
|
||||
## Commands
|
||||
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `gh commit` | Commit changes grouped by scope |
|
||||
| `gh commit init` | Generate scopes for current repo |
|
||||
| `gh commit refresh` | Update scopes from current structure |
|
||||
| `gh commit sync` | Sync scopes → GitHub labels |
|
||||
| `gh commit list` | List all configured repositories |
|
||||
| `gh commit remove` | Remove current repo from database |
|
||||
| `gh commit db-path` | Print database file path |
|
||||
| `gh commit version` | Print version |
|
||||
| `gh commit help` | Show help |
|
||||
| Command | Behavior |
|
||||
|---|---|
|
||||
| `gh commit` | Full scoped-commit flow: group changed files by scope, generate a message per group, confirm, commit, offer to push |
|
||||
| `gh commit init` | Generate scopes from the file tree via Crush; migrates legacy configs; confirms overwrite |
|
||||
| `gh commit refresh` | Show current scopes, regenerate with existing scopes as context, confirm apply |
|
||||
| `gh commit sync` | Create/update GitHub labels from scopes (color = first 6 hex chars of MD5 of the scope name) |
|
||||
| `gh commit list` | Table of configured repositories: name, path, scope count |
|
||||
| `gh commit remove` | Delete the current repo from the database after confirmation |
|
||||
| `gh commit db-path` | Print the database file path |
|
||||
| `gh commit version` | Print `gh-commit <version>` |
|
||||
| `gh commit help` | Help, including the DB path and environment variable docs |
|
||||
|
||||
## Flags
|
||||
|
||||
| Flag | Description |
|
||||
|------|-------------|
|
||||
| `--auto` | Skip all confirmation prompts |
|
||||
| `--push` | Auto-push after committing |
|
||||
Flags: `--auto` (skip confirmations), `--push` (auto-push).
|
||||
|
||||
## Environment
|
||||
|
||||
@@ -82,10 +57,35 @@ The former Mods roles now live directly in `smartcommit.py`, so gh-commit no lon
|
||||
| `GH_COMMIT_CRUSH_TIMEOUT` | Per-prompt timeout in seconds (default `120`) |
|
||||
| `GH_COMMIT_DEBUG=1` | Show scope-response parse diagnostics |
|
||||
|
||||
## Migration
|
||||
## Storage
|
||||
|
||||
Existing `.github/Repo.toml` or `.github/scopes.json` files are automatically detected and migrated to DuckDB on first run.
|
||||
Scopes live in `${XDG_DATA_HOME:-~/.local/share}/gh-commit/gh-commit.db`
|
||||
(DuckDB). Legacy `.github/Repo.toml` and `.github/scopes.json` files are
|
||||
migrated automatically on first run (the source file is archived as
|
||||
`*.migrated.<timestamp>`).
|
||||
|
||||
## License
|
||||
## Manual acceptance
|
||||
|
||||
MIT
|
||||
```sh
|
||||
mkdir /tmp/accept && cd /tmp/accept && git init
|
||||
mkdir -p src docs
|
||||
echo 'package app' > src/app.go
|
||||
echo '# Docs' > docs/README.md
|
||||
gh commit init # scopes generated and saved
|
||||
echo '// change' >> src/app.go
|
||||
echo 'More docs' >> docs/README.md
|
||||
gh commit # one commit per scope
|
||||
git log --format='%s' # verify type(scope): message subjects
|
||||
```
|
||||
|
||||
## Development
|
||||
|
||||
The extension is a bash launcher (`gh-commit`) that runs `smartcommit.py`
|
||||
with `uv run --script`; uv resolves the inline dependencies (duckdb, rich,
|
||||
questionary) automatically.
|
||||
|
||||
```sh
|
||||
python -m py_compile smartcommit.py # syntax check
|
||||
bash -n gh-commit # launcher check
|
||||
./gh-commit version # smoke test
|
||||
```
|
||||
|
||||
Binary file not shown.
@@ -1,23 +1,12 @@
|
||||
#!/usr/bin/env bash
|
||||
# gh-commit launcher — runs the bundled Python implementation via uv.
|
||||
set -euo pipefail
|
||||
|
||||
# gh-commit: AI-powered scoped git commits (Crush for scopes and messages)
|
||||
# Install: gh extension install prdlk/gh-commit
|
||||
# Requires: uv (https://docs.astral.sh/uv) and the Crush CLI
|
||||
# (https://github.com/charmbracelet/crush)
|
||||
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
EXTENSION_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
SCRIPT="${EXTENSION_DIR}/smartcommit.py"
|
||||
|
||||
if ! command -v uv &>/dev/null; then
|
||||
echo "error: 'uv' is required but not installed"
|
||||
echo "install: curl -LsSf https://astral.sh/uv/install.sh | sh"
|
||||
if ! command -v uv >/dev/null 2>&1; then
|
||||
echo "gh-commit: 'uv' is required (https://docs.astral.sh/uv)" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -z "${GH_COMMIT_CRUSH_CMD:-}" ]] && ! command -v crush &>/dev/null; then
|
||||
echo "warning: 'crush' not found — gh-commit uses 'crush run' for scopes and commit messages."
|
||||
echo "install Crush (https://github.com/charmbracelet/crush), or set GH_COMMIT_CRUSH_CMD."
|
||||
fi
|
||||
|
||||
exec uv run --script "${SCRIPT}" "$@"
|
||||
exec uv run --script "$DIR/smartcommit.py" "$@"
|
||||
|
||||
Binary file not shown.
+1
-1
@@ -54,7 +54,7 @@ AUTO_PUSH = os.environ.get("GH_COMMIT_PUSH", "0") == "1"
|
||||
NO_AUTO_REFRESH = os.environ.get("GH_COMMIT_NO_AUTO_REFRESH", "0") == "1"
|
||||
DEBUG = os.environ.get("GH_COMMIT_DEBUG", "0") == "1"
|
||||
|
||||
VERSION = "2.0.0"
|
||||
VERSION = "5.0.1"
|
||||
|
||||
|
||||
# ── Helpers ───────────────────────────────────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user