Initial commit

This commit is contained in:
Zhongwei Li
2025-11-30 09:02:31 +08:00
commit 866f3dbf18
34 changed files with 8341 additions and 0 deletions

View 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>` |

View 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 |

View 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 |

View 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()` |

View 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