Initial commit
This commit is contained in:
82
commands/cleanup.md
Normal file
82
commands/cleanup.md
Normal file
@@ -0,0 +1,82 @@
|
||||
---
|
||||
allowed-tools: Bash(jj workspace:*), Bash(jj log:*)
|
||||
description: Remove empty or stale jj workspaces
|
||||
model: claude-haiku-4-5
|
||||
---
|
||||
|
||||
## Context
|
||||
|
||||
- Available workspaces: !`jj workspace list`
|
||||
- Current workspace: !`jj workspace list | grep '*'`
|
||||
|
||||
## Your Task
|
||||
|
||||
Clean up empty or stale jj workspaces.
|
||||
|
||||
**What are jj workspaces?**
|
||||
|
||||
Jujutsu workspaces allow you to have multiple working copies of your repository simultaneously. Each workspace can work on different revisions independently.
|
||||
|
||||
**When to use cleanup:**
|
||||
|
||||
- After finishing work in a temporary workspace
|
||||
- When you have orphaned workspaces from interrupted work
|
||||
- To reclaim disk space from unused workspaces
|
||||
- Regular maintenance to keep workspace list clean
|
||||
|
||||
**Steps:**
|
||||
|
||||
1. **List all workspaces:**
|
||||
|
||||
```bash
|
||||
jj workspace list
|
||||
```
|
||||
|
||||
2. **Check each workspace status:**
|
||||
For each workspace (except the current one), check if it's empty or stale:
|
||||
|
||||
```bash
|
||||
jj log -r <workspace-name>@ --no-graph -T 'if(empty, "empty", "has_changes")'
|
||||
```
|
||||
|
||||
3. **Remove empty/stale workspaces:**
|
||||
```bash
|
||||
jj workspace forget <workspace-name>
|
||||
```
|
||||
|
||||
**Safety notes:**
|
||||
|
||||
- Never remove the current workspace (marked with `*`)
|
||||
- `jj workspace forget` doesn't delete files, it just removes the workspace tracking
|
||||
- You can always recreate a workspace if needed
|
||||
- This is a maintenance operation, not a destructive one
|
||||
|
||||
**Example workflow:**
|
||||
|
||||
```bash
|
||||
# List workspaces
|
||||
jj workspace list
|
||||
# Output:
|
||||
# default: sqxoqmn 7a9a3c5 (empty) (no description set)
|
||||
# * feature-work: rlzxqmpv 0c4a1b2 Add login feature
|
||||
# old-bugfix: xyz123ab (empty) (no description set)
|
||||
|
||||
# Remove empty workspaces
|
||||
jj workspace forget default
|
||||
jj workspace forget old-bugfix
|
||||
|
||||
# Verify
|
||||
jj workspace list
|
||||
# Output:
|
||||
# * feature-work: rlzxqmpv 0c4a1b2 Add login feature
|
||||
```
|
||||
|
||||
**What if I don't have multiple workspaces?**
|
||||
|
||||
If you only have one workspace (the default), this command won't do anything. Workspaces are optional - they're useful for:
|
||||
|
||||
- Working on multiple features simultaneously
|
||||
- Code review without switching commits
|
||||
- Parallel development on different branches
|
||||
|
||||
Show final state: !`jj workspace list`
|
||||
77
commands/commit.md
Normal file
77
commands/commit.md
Normal file
@@ -0,0 +1,77 @@
|
||||
---
|
||||
allowed-tools: Bash(jj log:*), Bash(jj diff:*), Bash(jj commit:*), Bash(jj describe:*), Bash(jj new:*), Bash(jj status:*), Bash(jj file track:*)
|
||||
argument-hint: [message]
|
||||
description: Stack a commit with intelligent message generation
|
||||
model: claude-haiku-4-5
|
||||
---
|
||||
|
||||
!# Determine workflow state
|
||||
|
||||
# Check if current commit has a description
|
||||
|
||||
has_description=$(jj log -r @ --no-graph -T 'if(description, "has", "none")')
|
||||
|
||||
# Check if current commit is empty
|
||||
|
||||
is_empty=$(jj log -r @ --no-graph -T 'if(empty, "empty", "has_changes")')
|
||||
|
||||
!# Handle workflow logic
|
||||
|
||||
if [ "$is_empty" = "empty" ] && [ "$has_description" = "none" ]; then
|
||||
|
||||
# Empty commit with no description - need changes first
|
||||
|
||||
echo "ℹ️ **Current commit is empty with no description**"
|
||||
echo ""
|
||||
jj log -r @ -T 'concat("Current: ", change_id.short(), " (empty)")' --no-graph
|
||||
echo ""
|
||||
echo "💡 **Tip:** Make some changes first, then use \`/jj:commit\` to describe and stack"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
!# Track any untracked files before committing
|
||||
|
||||
jj file track . 2>/dev/null || true
|
||||
|
||||
!# Determine action based on user argument
|
||||
|
||||
if [ -n "$ARGUMENTS" ]; then
|
||||
|
||||
# User provided explicit message - use it directly
|
||||
|
||||
if [ "$has_description" = "has" ]; then # Current commit already described, create new on top
|
||||
echo "📦 **Creating new commit:** $ARGUMENTS"
|
||||
echo ""
|
||||
jj new -m "$ARGUMENTS" 2>/dev/null || true
|
||||
echo "✅ **New commit created, ready for changes**"
|
||||
else # Describe current commit using jj commit (describes @ and creates new working copy)
|
||||
echo "📝 **Committing changes:** $ARGUMENTS"
|
||||
echo ""
|
||||
jj commit -m "$ARGUMENTS" 2>/dev/null || { # Fallback to describe if no changes
|
||||
jj describe -m "$ARGUMENTS"
|
||||
echo "💡 **Tip:** No changes to commit, description updated"
|
||||
}
|
||||
echo "✅ **Committed and created new working copy**"
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
## Context
|
||||
|
||||
- Status: !`jj status`
|
||||
- Changes: !`jj diff -r @`
|
||||
|
||||
## Task
|
||||
|
||||
Create commit for changes above. New files already tracked.
|
||||
|
||||
**Workflow:**
|
||||
|
||||
- Has "plan:" description → Update with actual work: `jj commit -m "message"`
|
||||
- Has other description → Stack new commit: `jj new -m "message"`
|
||||
- Needs description → Commit changes: `jj commit -m "message"`
|
||||
|
||||
Use conventional commit (feat/fix/refactor/docs/test/chore), under 72 chars, `-m` flag.
|
||||
Note: `jj commit` describes @ and creates new working copy in one command.
|
||||
|
||||
Result: !`jj log -r @ -T 'concat(change_id.short(), ": ", description)' --no-graph`
|
||||
90
commands/split.md
Normal file
90
commands/split.md
Normal file
@@ -0,0 +1,90 @@
|
||||
---
|
||||
allowed-tools: Bash(jj log:*), Bash(jj diff:*), Bash(jj status:*), Bash(jj new:*), Bash(jj move:*), Bash(jj describe:*), Bash(~/bin/jj-ai-desc.py:*)
|
||||
argument-hint: <pattern>
|
||||
description: Split unwanted changes into new child commit with AI description
|
||||
model: claude-haiku-4-5
|
||||
---
|
||||
|
||||
!# Validate pattern argument
|
||||
|
||||
if [ -z "$ARGUMENTS" ]; then
|
||||
echo "❌ **Error: Pattern required**"
|
||||
echo ""
|
||||
echo "**Usage:** \`/jj:split <pattern>\`"
|
||||
echo ""
|
||||
echo "**Common patterns:**"
|
||||
echo "- \`test\` - Test and spec files"
|
||||
echo "- \`docs\` - Documentation (*.md, README, CHANGELOG)"
|
||||
echo "- \`config\` - Config files (*.json, *.yaml, *.toml)"
|
||||
echo "- Custom glob patterns (e.g., \`*.md\`, \`src/**/*.test.ts\`)"
|
||||
echo ""
|
||||
echo "**What it does:**"
|
||||
echo "1. Keeps wanted changes in current commit (@)"
|
||||
echo "2. Moves unwanted (matching pattern) changes to new child commit"
|
||||
echo "3. Auto-generates description for child commit"
|
||||
echo ""
|
||||
echo "**Example:** \`/jj:split test\` - splits test files into new child commit"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
## Context
|
||||
|
||||
- Current status: !`jj status`
|
||||
- Current commit: !`jj log -r @ --no-graph -T 'concat(change_id.short(), ": ", description)'`
|
||||
- Changed files: !`jj diff -r @ --summary`
|
||||
|
||||
## Your Task
|
||||
|
||||
Split unwanted changes matching pattern "$ARGUMENTS" from current commit (@) into a new child commit with an AI-generated description.
|
||||
|
||||
**Pattern Expansion:**
|
||||
|
||||
- `test` → Match test files: `*test*.{py,js,ts,jsx,tsx,java,go,rs,cpp,c,h}`, `*spec*.{py,js,ts,jsx,tsx}`, `test_*.py`, `*_test.go`, `*Test.java`
|
||||
- `docs` → Match documentation: `*.md`, `README*`, `CHANGELOG*`, `LICENSE*`, `docs/**/*`
|
||||
- `config` → Match config files: `*.json`, `*.yaml`, `*.yml`, `*.toml`, `*.ini`, `*.conf`, `.*.rc`, `.*ignore`
|
||||
- Custom patterns → Use as-is (glob syntax)
|
||||
|
||||
**Workflow:**
|
||||
|
||||
1. **Identify matching files** - Show which files in current commit match the pattern
|
||||
2. **Create child commit** - `jj new @` to create empty child where split changes will go
|
||||
3. **Move matching changes** - `jj move --from @- -p 'glob:pattern'` to move unwanted files from parent to child
|
||||
4. **Generate description** - Use `~/bin/jj-ai-desc.py @` to analyze split changes and generate commit message
|
||||
5. **Show result** - Display final commit structure
|
||||
|
||||
**Result structure:**
|
||||
```
|
||||
@ (new child): unwanted changes with AI description
|
||||
@- (original): wanted changes, original description preserved
|
||||
```
|
||||
|
||||
**Important notes:**
|
||||
|
||||
- Use multiple `-p` flags for multiple patterns: `jj move --from @- -p 'glob:*.md' -p 'glob:README*'`
|
||||
- Always quote glob patterns: `'glob:pattern'`
|
||||
- The original commit description stays intact, only the unwanted changes move
|
||||
- If no files match, inform user and suggest alternatives
|
||||
- After moving, the AI will analyze what was split and generate an appropriate description
|
||||
|
||||
**Example execution:**
|
||||
|
||||
```bash
|
||||
# Split test files
|
||||
jj new @
|
||||
jj move --from @- -p 'glob:**/*test*.py' -p 'glob:**/*_test.py'
|
||||
~/bin/jj-ai-desc.py @
|
||||
|
||||
# Split documentation
|
||||
jj new @
|
||||
jj move --from @- -p 'glob:*.md' -p 'glob:README*' -p 'glob:docs/**'
|
||||
~/bin/jj-ai-desc.py @
|
||||
|
||||
# Split config files
|
||||
jj new @
|
||||
jj move --from @- -p 'glob:*.json' -p 'glob:*.yaml' -p 'glob:*.toml'
|
||||
~/bin/jj-ai-desc.py @
|
||||
```
|
||||
|
||||
**Final verification:**
|
||||
|
||||
Show the result: !`jj log -r '@|@-' -T 'concat(change_id.short(), ": ", description)'`
|
||||
78
commands/squash.md
Normal file
78
commands/squash.md
Normal file
@@ -0,0 +1,78 @@
|
||||
---
|
||||
allowed-tools: Bash(jj log:*), Bash(jj diff:*), Bash(jj status:*), Bash(jj squash:*)
|
||||
argument-hint: [revision]
|
||||
description: Merge commits in the stack
|
||||
model: claude-haiku-4-5
|
||||
---
|
||||
|
||||
## Context
|
||||
|
||||
- Current status: !`jj status`
|
||||
- Current commit: !`jj log -r @ --no-graph -T 'concat(change_id.short(), ": ", description)'`
|
||||
- Parent commit: !`jj log -r @- --no-graph -T 'concat(change_id.short(), ": ", description)'`
|
||||
- Recent stack: !`jj log -r 'ancestors(@, 5)' -T 'concat(change_id.short(), ": ", description)' --no-graph`
|
||||
|
||||
## Your Task
|
||||
|
||||
Merge commits in the jujutsu stack.
|
||||
|
||||
**Usage Modes:**
|
||||
|
||||
1. **Default (no argument):** Merge current commit (@) into its parent (@-)
|
||||
|
||||
```bash
|
||||
jj squash
|
||||
```
|
||||
|
||||
This moves all changes from @ into @-, then abandons @.
|
||||
|
||||
2. **With revision:** Merge a specific revision into its parent
|
||||
```bash
|
||||
jj squash -r <revision>
|
||||
```
|
||||
Useful for cleaning up a specific commit in the stack.
|
||||
|
||||
**When to use:**
|
||||
|
||||
- Multiple WIP commits for the same feature
|
||||
- Cleaning up incremental work before sharing
|
||||
- Combining related changes into a single commit
|
||||
- Fixing typos or small changes that belong in the parent
|
||||
|
||||
**Workflow:**
|
||||
|
||||
1. Explain what will be merged (which commits, what changes)
|
||||
2. Execute the squash operation
|
||||
3. Show the result with `jj log` and confirm the changes
|
||||
|
||||
**Important:**
|
||||
|
||||
- Squashing is safe - you can undo with `jj undo`
|
||||
- Use `jj squash -i` for interactive mode to select specific changes
|
||||
- Consider if you should update the description after squashing
|
||||
|
||||
**Example scenarios:**
|
||||
|
||||
**Scenario 1: Merge current WIP into parent**
|
||||
|
||||
```bash
|
||||
# Before: @ = "WIP: fix tests", @- = "Add login feature"
|
||||
jj squash
|
||||
# After: @ = "Add login feature" (now includes test fixes)
|
||||
```
|
||||
|
||||
**Scenario 2: Merge specific revision**
|
||||
|
||||
```bash
|
||||
# Merge revision abc123 into its parent
|
||||
jj squash -r abc123
|
||||
```
|
||||
|
||||
**Scenario 3: Interactive squash**
|
||||
|
||||
```bash
|
||||
# Choose which changes to move
|
||||
jj squash -i
|
||||
```
|
||||
|
||||
Show result: !`jj log -r 'ancestors(@, 3)' -T 'concat(change_id.short(), ": ", description)' --no-graph`
|
||||
Reference in New Issue
Block a user