Initial commit
This commit is contained in:
205
skills/git-jj/SKILL.md
Normal file
205
skills/git-jj/SKILL.md
Normal file
@@ -0,0 +1,205 @@
|
||||
---
|
||||
name: git-jj
|
||||
description: "Used when working with vcs/git/jj/commit task, triggered by phrase like [git], [git commit], [diff], [push], [check git status], [create git branch], [git worktree], [git sqaush], [review with changes], [review with lifeguard], [jj], [jj commit], [jj changes], [commit changes]"
|
||||
---
|
||||
|
||||
# Git/JJ VCS Skill
|
||||
|
||||
**Note**: `<skill-base-dir>` refers to the git skill directory (~/.claude/skills/git-jj/) containing this SKILL.md file.
|
||||
|
||||
## Purpose
|
||||
Provide specialized workflows for Git and Jujutsu (jj) version control systems with automatic repository detection, command reference lookup, and safe operation practices.
|
||||
|
||||
## Trigger Conditions
|
||||
Activate this skill for VCS tasks involving Git or Jujutsu (jj), such as:
|
||||
- Checking status, diffs, logs
|
||||
- Staging, committing, branching/bookmarks
|
||||
- Pushing, pulling, fetching
|
||||
- Managing worktrees/workspaces
|
||||
- Integrating with lifeguard subagent for code reviews
|
||||
- Repository initialization and configuration
|
||||
|
||||
## Repository Detection & Branching Workflow
|
||||
|
||||
### Step 1: Detect Repository Type
|
||||
Run the repository detection script using the Bash tool:
|
||||
|
||||
```bash
|
||||
bash ~/.claude/skills/git-jj/scripts/repo_check.sh
|
||||
```
|
||||
|
||||
**Important**: Execute this command from the repository root (user's current working directory). The script checks for `.jj` or `.git` folders in the current directory.
|
||||
|
||||
The script outputs one of three values to stdout:
|
||||
- `jj` - Jujutsu repository detected (.jj folder exists)
|
||||
- `git` - Git repository detected
|
||||
- `no-repo` - No repository found
|
||||
|
||||
**Priority**: If both `.jj` folder and `.git` exist (common when jj operates atop git), the script returns `jj` to respect jj-first preference.
|
||||
|
||||
### Step 2: Branch to Appropriate Workflow
|
||||
|
||||
| Output | Action |
|
||||
|--------|--------|
|
||||
| `jj` | Follow **JJ Branch** workflow. Read `~/.claude/skills/git-jj/references/jj_workflows.md` for core commands and working copy model. |
|
||||
| `git` | Follow **Git Branch** workflow. Read `~/.claude/skills/git-jj/references/git_workflows.md` for command syntax. |
|
||||
| `no-repo` | Proceed to **Repository Initialization** workflow below. |
|
||||
|
||||
#### JJ Branch: Conditional Reference read
|
||||
|
||||
When following the JJ branch, load additional references based on task complexity:
|
||||
|
||||
**Always read first:**
|
||||
|
||||
- `~/.claude/skills/git-jj/references/jj_workflows.md` - Core commands, working copy model, WIP pattern, filesets
|
||||
|
||||
**Read conditionally when needed:**
|
||||
- **Bookmark operations** (create, track, push, conflicts): Read `~/.claude/skills/git-jj/references/jj_bookmarks.md`
|
||||
- **Complex history queries** (ranges, filtering, ancestry): Read `~/.claude/skills/git-jj/references/jj_revset.md`
|
||||
- **Automation/structured output** (CI scripts, release notes): Read `~/.claude/skills/git-jj/references/jj_template.md`
|
||||
|
||||
**Reference selection rules:**
|
||||
- User mentions "bookmark", "track remote", "push bookmark" → Load `jj_bookmarks.md`
|
||||
- User asks "show commits where...", "filter by author", "range between..." → Load `jj_revset.md`
|
||||
- User requests "JSON output", "custom format", "parse for script" → Load `jj_template.md`
|
||||
- Multiple file path filtering (globs, exclude patterns) → Already covered in `jj_workflows.md` (Fileset section)
|
||||
|
||||
#### Git Branch: Reference Loading
|
||||
- Read `<skill-base-dir>/references/git_workflows.md` for all Git operations (covers branches, worktrees, stashing, troubleshooting)
|
||||
|
||||
### Step 3: Repository Initialization (if no-repo)
|
||||
1. Use `AskUserQuestion` tool to ask: "No repository found. Initialize jj or git?"
|
||||
- Options: "jj (recommended)", "git"
|
||||
- header: "VCS choice"
|
||||
2. Based on user selection:
|
||||
- **jj**: Run `jj init` or `jj git init` (if git backend desired), then load `references/jj_workflows.md`
|
||||
- **git**: Run `git init`, then load `references/git_workflows.md`
|
||||
3. After initialization, proceed with original user intent
|
||||
|
||||
## Common Workflows
|
||||
|
||||
For command syntax, see reference files. This section covers workflow orchestration.
|
||||
|
||||
### 1. Show Status/Diff
|
||||
- Always gather diff output via `Bash` tool BEFORE invoking other tools
|
||||
- See `jj_workflows.md` or `git_workflows.md` for commands
|
||||
|
||||
### 2. Review Changes with Lifeguard
|
||||
- Run `scripts/repo_check.sh` first to confirm VCS type.
|
||||
- Git workflow (small diff <500 lines): you MAY embed the git diff directly. For larger diffs, prefer letting lifeguard fetch them itself.
|
||||
- JJ workflow (preferred): DO NOT paste full `jj diff` output unless very small (<200 lines). Instead launch the lifeguard subagent with an execution plan listing jj commands it should run to gather its own context.
|
||||
- Rationale: JJ diffs can be large and lifeguard has Bash(jj:*) capability; letting it execute jj commands avoids prompt bloat and enables multi‑commit exploration.
|
||||
- Skill loading directive: In every lifeguard prompt include either (a) explicit phrase: `please load git claude skill` (this triggers skill reference loading), OR (b) inline list of reference file paths you want it to consult. Prefer phrase for brevity; attach paths when focusing on specialized areas (revsets, bookmarks, templates).
|
||||
|
||||
Reference file path list
|
||||
|
||||
- ~/.claude/skills/git-jj/references/git_workflows.md
|
||||
- Read ~/.claude/skills/git-jj/references/jj_workflows.md (when commit changes, logs, review with jj etc)
|
||||
- ~/.claude/skills/git-jj/references/jj_bookmarks.md
|
||||
- ~/.claude/skills/git-jj/references/jj_revset.md
|
||||
- ~/.claude/skills/git-jj/references/jj_template.md
|
||||
|
||||
Use this canonical jj command set in the lifeguard prompt (adjust as needed):
|
||||
|
||||
```
|
||||
# Core context collection
|
||||
jj --no-pager status
|
||||
jj --no-pager log -n 20 --no-graph
|
||||
jj --no-pager diff # working copy changes
|
||||
|
||||
# Targeted commit review (replace <rev>)
|
||||
jj --no-pager show <rev>
|
||||
|
||||
# Compare parent vs current working copy commit
|
||||
jj --no-pager diff -r @-..@
|
||||
|
||||
# Multi-commit / ancestry exploration examples
|
||||
jj --no-pager log -r "ancestors(@, 10)"
|
||||
jj --no-pager log -r "descendants(@, 5)"
|
||||
```
|
||||
Optional revset queries when user asks for filtering:
|
||||
```
|
||||
# Author filter
|
||||
jj --no-pager log -r "author('name@example.com') & ancestors(@, 20)"
|
||||
# Files touched
|
||||
jj --no-pager log -r "file('src/**') & ancestors(@, 30)"
|
||||
```
|
||||
Bookmark/WIP context to include in the lifeguard prompt (if applicable):
|
||||
- Current bookmark name
|
||||
- Whether parent description starts with "WIP:" and intended final message
|
||||
|
||||
Prompt template example (JJ):
|
||||
```
|
||||
Please load git claude skill.
|
||||
Review JJ working copy and recent commits. Run the listed jj commands (modify as needed) to inspect changes; focus on correctness, style, and potential refactors. Repository uses JJ atop git.
|
||||
Commands to run:
|
||||
1. jj --no-pager status
|
||||
2. jj --no-pager diff
|
||||
3. jj --no-pager log -n 20 --no-graph
|
||||
4. jj --no-pager diff -r @-..@
|
||||
If needed: jj --no-pager show <rev>, jj --no-pager log -r "ancestors(@, 10)".
|
||||
Bookmark: <bookmark-name>
|
||||
Parent commit description: <parent-desc>
|
||||
Relevant references (if needed): ~/.claude/skills/git-jj/references/jj_revset.md
|
||||
```
|
||||
Git prompt template (large diff scenario):
|
||||
```
|
||||
Please load git claude skill.
|
||||
Review pending changes. Fetch diffs yourself; do NOT rely on inline diff copy. Focus on correctness, style, and commit structuring.
|
||||
Commands to run:
|
||||
1. git status
|
||||
2. git diff
|
||||
3. git log --oneline -n 20
|
||||
```
|
||||
When focusing on a subset of files, pass a short list of paths (not full diff). Lifeguard will retrieve their diffs directly.
|
||||
|
||||
Summary:
|
||||
- Git: small diff inline OK; large diff let lifeguard fetch; always include skill loading phrase.
|
||||
- JJ: pass command plan + context, not full diff; include skill loading phrase or attach needed reference paths.
|
||||
|
||||
### 3. Stage Changes
|
||||
- **JJ**: Auto-tracks all changes (no staging needed)
|
||||
- **Git**: Standard `git add` workflow
|
||||
|
||||
### 4. Commit Changes
|
||||
- **CRITICAL**: NEVER commit without explicit user confirmation
|
||||
- Before committing: Show summary and ask user to confirm
|
||||
- **JJ**: Always use `-m` flag (bare `jj commit` opens editor, blocks agent). See `~/.claude/skills/git-jj/references/jj_workflows.md` for WIP pattern.
|
||||
- After JJ commit: verify with `jj --no-pager log -n 4 --no-graph`
|
||||
|
||||
### 5. Push to Remote
|
||||
- **CRITICAL**: NEVER push without explicit user confirmation
|
||||
- NEVER use `--force` unless explicitly requested
|
||||
|
||||
### 6. Other Operations
|
||||
- History, branches/bookmarks, worktrees: See reference files
|
||||
|
||||
## Key JJ vs Git Differences
|
||||
|
||||
- **JJ colocated**: When `.jj` + `.git` coexist, prefer jj commands
|
||||
- **No staging in JJ**: All changes auto-tracked
|
||||
- **JJ conflicts**: First-class objects (can commit conflicts)
|
||||
- See `git_workflows.md` for full mapping table
|
||||
|
||||
## Example: Commit Workflow
|
||||
|
||||
1. Run `scripts/repo_check.sh` → Determine VCS type
|
||||
2. Show current status/diff
|
||||
3. **JJ**: Check for WIP commits (see `jj_workflows.md` WIP pattern)
|
||||
4. **ASK USER** to confirm commit message
|
||||
5. Execute commit only after confirmation
|
||||
6. Verify with log output
|
||||
|
||||
## Safety Guidelines
|
||||
|
||||
1. **NEVER commit or push without explicit user confirmation**
|
||||
2. **NEVER use force push** unless user explicitly requests it
|
||||
3. **Verify branch/bookmark** before pushing (avoid main/master/staging)
|
||||
4. **Pre-commit**: Show summary, suggest message, wait for approval
|
||||
5. **Pre-push**: Show commits ahead of remote, verify target
|
||||
|
||||
## Integration Notes
|
||||
|
||||
- Favor `jj` when `.jj` folder exists
|
||||
- Use `TodoWrite` for multi-step VCS workflows
|
||||
- Read reference files only when command syntax is uncertain
|
||||
32
skills/git-jj/references/git_workflows.md
Normal file
32
skills/git-jj/references/git_workflows.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# Git Quick Reference
|
||||
|
||||
Standard git commands assumed known. This covers less common operations and JJ mapping.
|
||||
|
||||
## Less Common Commands
|
||||
|
||||
```bash
|
||||
git add -p <file> # Interactive hunk staging
|
||||
git restore --staged <file> # Unstage (preferred over reset)
|
||||
git switch -c <name> # Create+switch (preferred over checkout -b)
|
||||
git reflog # Local HEAD history (recovery)
|
||||
git worktree add ../<dir> <branch> # Parallel working directory
|
||||
git stash show -p stash@{0} # Show stash diff
|
||||
```
|
||||
|
||||
## Safety Reminders
|
||||
|
||||
- Confirm before: `reset --hard`, `branch -D`, `push --force`, `clean -fd`
|
||||
- Recovery: `git reflog` + `git branch <name> <hash>`
|
||||
|
||||
## Git to JJ Mapping
|
||||
|
||||
| Git | JJ |
|
||||
|-----|-----|
|
||||
| branch | bookmark |
|
||||
| stash | `jj new` (checkpoint) |
|
||||
| worktree | workspace |
|
||||
| checkout/switch | `jj edit` |
|
||||
| commit --amend | `jj describe` or `jj squash` |
|
||||
| rebase | `jj rebase` (non-destructive) |
|
||||
| cherry-pick | `jj duplicate` |
|
||||
| merge | `jj new <rev1> <rev2>` |
|
||||
81
skills/git-jj/references/jj_bookmarks.md
Normal file
81
skills/git-jj/references/jj_bookmarks.md
Normal file
@@ -0,0 +1,81 @@
|
||||
# JJ Bookmarks Reference
|
||||
|
||||
Source: https://docs.jj-vcs.dev/latest/bookmarks/
|
||||
|
||||
## Core Concepts
|
||||
|
||||
- **Named pointer** to a revision - similar to Git branch but NO "current branch" concept
|
||||
- **Auto-moves** when target is rewritten (`jj rebase`, `jj squash`, `jj describe`)
|
||||
- **Auto-deletes** when commit is abandoned
|
||||
- Usable anywhere a revision is expected: `jj new main`, `jj rebase -r feature -d main`
|
||||
- In colocated repos, bookmarks map directly to Git branches
|
||||
|
||||
## Commands
|
||||
|
||||
| Action | Command |
|
||||
|--------|---------|
|
||||
| List local | `jj bookmark list` |
|
||||
| List all (local + remote) | `jj bookmark list --all` |
|
||||
| Create at @ | `jj bookmark create <name>` |
|
||||
| Point to revision | `jj bookmark set <name> -r <rev>` |
|
||||
| Delete | `jj bookmark delete <name>` |
|
||||
| Rename | `jj bookmark rename <old> <new>` |
|
||||
| Track remote | `jj bookmark track <name>@<remote>` |
|
||||
| Untrack remote | `jj bookmark untrack <name>@<remote>` |
|
||||
| Push single | `jj git push -b <name>` |
|
||||
| Push all | `jj git push --all` |
|
||||
|
||||
Alias: `jj b` for `jj bookmark` (e.g., `jj b c` for create, `jj b d` for delete)
|
||||
|
||||
## Remote & Tracking
|
||||
|
||||
- Address remote: `<bookmark>@<remote>` (e.g., `main@origin`)
|
||||
- Can track same-name bookmarks on multiple remotes
|
||||
- Auto-tracked on: clone (default remote), first push of local bookmark
|
||||
- Enable auto-track fetched: `git.auto-local-bookmark = true`
|
||||
|
||||
## Status Indicators
|
||||
|
||||
| Suffix | Meaning |
|
||||
|--------|---------|
|
||||
| `*` | Local differs from remote (needs push) |
|
||||
| `??` | Conflicted (multiple targets) |
|
||||
| `@<remote>` | Remote snapshot reference |
|
||||
|
||||
## Conflict Resolution
|
||||
|
||||
When bookmark becomes conflicted (divergent updates):
|
||||
```bash
|
||||
jj log -r 'all:<bookmark>' # Inspect divergent commits
|
||||
jj new 'all:<bookmark>' # Merge path: create merge commit
|
||||
jj rebase -r <sideA> -d <sideB> # Rebase path
|
||||
jj bookmark set <name> -r <resolved> # Finalize
|
||||
```
|
||||
|
||||
## Safe Push Pattern
|
||||
|
||||
1. `jj git fetch` - sync remote state
|
||||
2. `jj status` - check for conflicts (look for `??` markers)
|
||||
3. `jj git push -b <name>` - push single bookmark
|
||||
|
||||
Push safety checks (force-with-lease equivalent):
|
||||
- Remote position matches last known
|
||||
- Local bookmark not conflicted
|
||||
- Remote bookmark tracked (or use `--allow-new`)
|
||||
|
||||
## Revset with Bookmarks
|
||||
|
||||
```bash
|
||||
jj new <bookmark> # New commit on top
|
||||
<bookmark>:: # Ancestors
|
||||
::<bookmark> # Descendants
|
||||
heads(all:<bookmark>) # All heads involving bookmark
|
||||
```
|
||||
|
||||
## Git Comparison
|
||||
|
||||
| Git | JJ |
|
||||
|-----|-----|
|
||||
| Branch HEAD moves on commit | Bookmark only moves on rewrite |
|
||||
| Single upstream per branch | Can track multiple remotes |
|
||||
| Force push risk | Built-in force-with-lease protection |
|
||||
87
skills/git-jj/references/jj_revset.md
Normal file
87
skills/git-jj/references/jj_revset.md
Normal file
@@ -0,0 +1,87 @@
|
||||
# JJ Revset Language Reference
|
||||
|
||||
Source: https://docs.jj-vcs.dev/latest/revsets/
|
||||
|
||||
Revsets select sets of revisions for inspection, history manipulation, and automation.
|
||||
|
||||
## Atoms
|
||||
|
||||
| Atom | Meaning |
|
||||
|------|---------|
|
||||
| `@` | Working-copy commit |
|
||||
| `<commit-id>` | Specific commit (short/full hex) |
|
||||
| `<change-id>` | Latest visible commit for change |
|
||||
| `<bookmark>` | Bookmark target |
|
||||
| `<bookmark>@<remote>` | Remote bookmark snapshot |
|
||||
| `root()` | Virtual root |
|
||||
| `trunk()` | Main branch |
|
||||
|
||||
## Operators
|
||||
|
||||
| Syntax | Meaning |
|
||||
|--------|---------|
|
||||
| `X::` | Ancestors of X (inclusive) |
|
||||
| `::X` | Descendants of X (inclusive) |
|
||||
| `A..B` | Reachable from B but not A |
|
||||
| `A \| B` | Union |
|
||||
| `A & B` | Intersection |
|
||||
| `A - B` | Difference |
|
||||
|
||||
## Functions
|
||||
|
||||
| Function | Purpose |
|
||||
|----------|---------|
|
||||
| `all()` | All commits (visible + hidden) |
|
||||
| `visible()` | Non-abandoned commits |
|
||||
| `ancestors(X)` / `descendants(X)` | Ancestry traversal |
|
||||
| `parents(X)` / `children(X)` | Direct relatives |
|
||||
| `heads(X)` | Commits with no descendants in X |
|
||||
| `author("name")` | By author substring |
|
||||
| `description("regex")` | By description regex |
|
||||
| `file("path")` | Commits affecting path |
|
||||
| `present(X)` | Filter to visible form |
|
||||
|
||||
## Common Patterns
|
||||
|
||||
```bash
|
||||
# Work since branching from main
|
||||
main..@
|
||||
|
||||
# Commits affecting file
|
||||
descendants(main) & file("src/lib.rs")
|
||||
|
||||
# Ahead of remote (push candidates)
|
||||
feature - feature@origin
|
||||
|
||||
# Behind remote (need to pull)
|
||||
feature@origin - feature
|
||||
|
||||
# Find WIP commits
|
||||
description("WIP") & ::@
|
||||
|
||||
# Filter by author
|
||||
author("alice") & main..@
|
||||
|
||||
# Divergent heads (conflicts)
|
||||
heads(<change-id>)
|
||||
|
||||
# Hidden/abandoned commits
|
||||
all() - visible()
|
||||
```
|
||||
|
||||
## File Filtering
|
||||
|
||||
```bash
|
||||
file("src/") # Commits under src/
|
||||
file("src/") - file("src/test/") # Exclude test dir
|
||||
descendants(main) & file("*.rs") # Rust files since main
|
||||
```
|
||||
|
||||
## Pitfalls
|
||||
|
||||
| Issue | Fix |
|
||||
|-------|-----|
|
||||
| `A..B` direction confusion | B's ancestors minus A's ancestors |
|
||||
| Using `all()` unnecessarily | Use `visible()` for normal queries |
|
||||
| Hidden commits not showing | Use `all()` or `present()` |
|
||||
| Shell expansion | Quote paths and regex |
|
||||
86
skills/git-jj/references/jj_template.md
Normal file
86
skills/git-jj/references/jj_template.md
Normal file
@@ -0,0 +1,86 @@
|
||||
# JJ Templating Language
|
||||
|
||||
Source: https://docs.jj-vcs.dev/latest/templates/
|
||||
|
||||
**Use templates only when** plain `jj log` output is insufficient: machine-readable output, conditional formatting, scripting pipelines.
|
||||
|
||||
## Invocation
|
||||
|
||||
```bash
|
||||
jj log -r @ --template '...' # Single commit
|
||||
jj log -r 'trunk()..@' --template '...' # Range
|
||||
jj log --no-pager --template '...' | jq ... # Pipe to tools
|
||||
```
|
||||
|
||||
## Commit Fields
|
||||
|
||||
| Field | Description |
|
||||
|-------|-------------|
|
||||
| `commit_id` / `.short()` | Full/short commit id |
|
||||
| `change_id` / `.short()` | Change identity |
|
||||
| `description` / `subject` | Full message / first line |
|
||||
| `author.email` / `author.name` | Author metadata |
|
||||
| `timestamp` | Commit timestamp |
|
||||
| `bookmarks` / `tags` | Lists |
|
||||
| `conflict` | Boolean |
|
||||
| `is_empty` | Boolean |
|
||||
| `divergent` | Boolean |
|
||||
| `parents` | List of parent commits |
|
||||
|
||||
## Functions
|
||||
|
||||
| Function | Example |
|
||||
|----------|---------|
|
||||
| `format()` | `format("[", change_id.short(), "] ", subject)` |
|
||||
| `if(cond, a, b)` | `if(conflict, "⚠", "")` |
|
||||
| `short()` | `commit_id.short()` |
|
||||
| `json()` | `author.email.json()` |
|
||||
| `contains()` | `subject.contains("WIP")` |
|
||||
| `truncate(n)` | `description.truncate(80)` |
|
||||
| `indent(n)` | `description.indent(4)` |
|
||||
| `join()` | `bookmarks.join(", ")` |
|
||||
| `map()` / `filter()` | `bookmarks.map(lower())` |
|
||||
| `len()` | `parents.len()` |
|
||||
|
||||
Chaining: `bookmarks.filter(!contains("WIP")).map(lower()).join(" ")`
|
||||
|
||||
## Examples
|
||||
|
||||
```bash
|
||||
# Minimal
|
||||
change_id.short() " " subject
|
||||
|
||||
# WIP emphasis
|
||||
format(if(subject.contains("WIP"),"[WIP] ",""), change_id.short(), " ", subject)
|
||||
|
||||
# Conflicts
|
||||
format(if(conflict,"⚠ ",""), change_id.short(), " ", subject)
|
||||
|
||||
# Bookmarks
|
||||
format(change_id.short()," ",bookmarks.join(",")," ",subject)
|
||||
|
||||
# JSON output
|
||||
format(
|
||||
'{"change":"', change_id.short().json(), '",',
|
||||
'"author":"', author.email.json(), '",',
|
||||
'"conflict":', if(conflict, 'true','false'), '}'
|
||||
)
|
||||
```
|
||||
|
||||
## Revset + Template
|
||||
|
||||
```bash
|
||||
# Divergent heads with conflicts
|
||||
jj log -r 'heads(all()) & conflicts()' --template 'format(change_id.short()," ",subject)'
|
||||
|
||||
# Commits ahead of remote
|
||||
jj log -r 'myfeature - myfeature@origin' --template 'format("AHEAD ", change_id.short())'
|
||||
```
|
||||
|
||||
## Pitfalls
|
||||
|
||||
| Issue | Fix |
|
||||
|-------|-----|
|
||||
| Unescaped quotes in JSON | Use `.json()` on dynamic fields |
|
||||
| Slow on huge histories | Narrow revset first |
|
||||
| Complex templates | Build incrementally with `format()` |
|
||||
177
skills/git-jj/references/jj_workflows.md
Normal file
177
skills/git-jj/references/jj_workflows.md
Normal file
@@ -0,0 +1,177 @@
|
||||
# Jujutsu (jj) Workflows Guide
|
||||
|
||||
**Version**: jj 0.9+
|
||||
|
||||
## Core Concepts
|
||||
|
||||
**Key differences from Git:**
|
||||
- **Auto-snapshotting**: Most commands automatically commit working-copy changes
|
||||
- **No staging area**: All tracked files are automatically included
|
||||
- **`@` symbol**: Always represents current working-copy commit
|
||||
- **Immutable history**: Operations create new commits; old commits remain accessible
|
||||
|
||||
## Quick Reference
|
||||
|
||||
### Status & Inspection
|
||||
```bash
|
||||
jj status # Snapshot and show status
|
||||
jj diff --git # Working copy changes
|
||||
jj diff --git -r <rev> # Changes in specific revision
|
||||
jj log -n 10 # History (graph by default)
|
||||
jj show <rev> # Commit details
|
||||
```
|
||||
|
||||
### Creating & Modifying Commits
|
||||
```bash
|
||||
jj describe -m "message" # Update current commit description
|
||||
jj describe -r <rev> -m "msg" # Update specific revision
|
||||
jj commit -m "message" # Create new commit, move @ forward
|
||||
jj new -m "message" # Create empty checkpoint commit
|
||||
jj squash # Fold @ into parent (amend-like)
|
||||
jj squash -f <src> -t <dest> # Move changes between commits
|
||||
jj abandon <rev> # Remove commit from history
|
||||
jj duplicate <rev> # Cherry-pick equivalent
|
||||
jj rebase -r <rev> -d <dest> # Rebase revision
|
||||
jj edit <rev> # Edit specific revision directly
|
||||
```
|
||||
|
||||
### File Operations
|
||||
```bash
|
||||
jj restore <file> # Restore from parent
|
||||
jj restore --from <rev> <file> # Restore from specific revision
|
||||
jj file track <path> # Start tracking
|
||||
jj file untrack <path> # Stop tracking
|
||||
```
|
||||
|
||||
### Bookmarks (Branches)
|
||||
```bash
|
||||
jj bookmark list # List all
|
||||
jj bookmark create <name> # Create at @
|
||||
jj bookmark set <name> -r <rev> # Point to revision
|
||||
jj bookmark delete <name> # Delete
|
||||
jj bookmark track <name>@<remote> # Set up tracking
|
||||
```
|
||||
|
||||
### Remotes
|
||||
```bash
|
||||
jj git fetch # Fetch all
|
||||
jj git fetch --remote <name> # Fetch specific
|
||||
jj git push -b <bookmark> # Push bookmark
|
||||
jj git push --all # Push all bookmarks
|
||||
```
|
||||
|
||||
### Workspaces
|
||||
```bash
|
||||
jj workspace add <path> # Create (like git worktree)
|
||||
jj workspace list # List all
|
||||
jj workspace forget <name> # Remove
|
||||
```
|
||||
|
||||
## WIP Commit Pattern
|
||||
|
||||
```bash
|
||||
# Start work
|
||||
jj describe -m "WIP: feature"
|
||||
|
||||
# Continue working (auto-snapshots on jj commands)
|
||||
|
||||
# Finalize (if @ is the WIP commit)
|
||||
jj commit -m "feat: completed"
|
||||
# use describe with `-r` if wip commits is in parents.
|
||||
|
||||
# Or squash into parent
|
||||
jj squash
|
||||
```
|
||||
|
||||
**Before committing**, check state:
|
||||
```bash
|
||||
jj --no-pager status
|
||||
jj --no-pager log -r '@-' # Check parent
|
||||
```
|
||||
|
||||
## Conflict Resolution
|
||||
|
||||
JJ allows committing conflicts and resolving them later.
|
||||
|
||||
### Recommended: Resolve in New Commit
|
||||
```bash
|
||||
jj new <conflicted-commit> # Create child
|
||||
# ... edit files to resolve ...
|
||||
jj diff # Review resolutions
|
||||
jj squash # Merge back into parent
|
||||
```
|
||||
|
||||
### Alternative: Direct Edit
|
||||
```bash
|
||||
jj edit <conflicted-commit>
|
||||
# ... resolve conflicts ...
|
||||
jj describe -m "resolved conflicts"
|
||||
```
|
||||
|
||||
### External Tool
|
||||
```bash
|
||||
jj resolve # Opens merge tool (2-sided conflicts only)
|
||||
```
|
||||
|
||||
## Git Command Mappings
|
||||
|
||||
| Git | jj |
|
||||
|-----|-----|
|
||||
| `git status` | `jj status` |
|
||||
| `git diff` | `jj diff --git` |
|
||||
| `git add .` | (automatic) |
|
||||
| `git commit -m` | `jj commit -m` |
|
||||
| `git commit --amend` | `jj squash` or `jj describe` |
|
||||
| `git log` | `jj log` |
|
||||
| `git branch` | `jj bookmark list` |
|
||||
| `git checkout <branch>` | `jj edit <bookmark>` |
|
||||
| `git merge <branch>` | `jj new <rev1> <rev2>` |
|
||||
| `git rebase` | `jj rebase -r <rev> -d <dest>` |
|
||||
| `git cherry-pick` | `jj duplicate <rev>` |
|
||||
| `git stash` | `jj new` (checkpoint) |
|
||||
| `git worktree add` | `jj workspace add` |
|
||||
|
||||
## Revision Syntax
|
||||
|
||||
- `@` - Working copy
|
||||
- `@-` - Parent of working copy
|
||||
- `<bookmark>` - Bookmark target
|
||||
- `<rev>::` - Ancestors
|
||||
- `::<rev>` - Descendants
|
||||
- `<rev1>..<rev2>` - Range
|
||||
- `trunk()` - Main branch
|
||||
- `file('<path>')` - Revisions modifying file
|
||||
|
||||
## Fileset Language
|
||||
|
||||
### Patterns
|
||||
| Pattern | Description |
|
||||
|---------|-------------|
|
||||
| `"path"` | CWD-relative prefix (recursive) |
|
||||
| `file:"path"` | Exact file match |
|
||||
| `glob:"*.rs"` | CWD-relative glob |
|
||||
| `root:"path"` | Workspace-relative prefix |
|
||||
| `root-glob:"**/*.rs"` | Workspace-relative glob |
|
||||
|
||||
### Operators
|
||||
| Op | Meaning | Example |
|
||||
|----|---------|---------|
|
||||
| `~x` | NOT | `~Cargo.lock` |
|
||||
| `x & y` | AND | `src & glob:"*.rs"` |
|
||||
| `x ~ y` | MINUS | `src ~ glob:"*test*"` |
|
||||
| `x \| y` | OR | `src \| tests` |
|
||||
|
||||
### Examples
|
||||
```bash
|
||||
jj diff '~Cargo.lock' # Exclude file
|
||||
jj diff 'glob:"**/*.md"' # Only markdown
|
||||
jj log -r 'trunk()..@ & file("src/core")' # Commits touching path
|
||||
jj diff --git -f "trunk()" -t "@" # Diff vs trunk
|
||||
```
|
||||
|
||||
## Important Notes
|
||||
|
||||
1. **Always use `-m` flag** in non-interactive contexts (scripts, LLM agents)
|
||||
2. **Check status before critical ops**: `jj --no-pager status`
|
||||
3. **Conflicts are first-class**: Can be committed, shared, resolved incrementally
|
||||
4. **Operations are recoverable**: `jj op log` shows history
|
||||
30
skills/git-jj/scripts/repo_check.sh
Executable file
30
skills/git-jj/scripts/repo_check.sh
Executable file
@@ -0,0 +1,30 @@
|
||||
#!/bin/bash
|
||||
|
||||
# repo_check.sh - Determine whether to use jj or git for this repository
|
||||
# Outputs to stdout: "jj", "git", or "no-repo"
|
||||
# Always exits with 0 on success
|
||||
#
|
||||
# Detection priority:
|
||||
# 1. .jj folder exists → "jj" (even if git repo also present)
|
||||
# 2. Git repository detected → "git"
|
||||
# 3. Neither found → "no-repo"
|
||||
|
||||
set -e
|
||||
|
||||
# Check for jj repository - priority 1
|
||||
# Note: jj often operates atop git, so check .jj first
|
||||
# Use `jj root` to detect jj workspace from any subdirectory
|
||||
if jj root > /dev/null 2>&1; then
|
||||
echo "jj"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Check for git repository - priority 2
|
||||
if git rev-parse --git-dir > /dev/null 2>&1; then
|
||||
echo "git"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Neither found - user needs to initialize
|
||||
echo "no-repo"
|
||||
exit 0
|
||||
Reference in New Issue
Block a user