818 lines
19 KiB
Markdown
818 lines
19 KiB
Markdown
# Jujutsu Revsets - Complete Reference
|
|
|
|
Revsets are a functional language in jujutsu for selecting and querying commits. This document provides comprehensive coverage of revset syntax, symbols, operators, functions, and practical usage patterns.
|
|
|
|
## Overview
|
|
|
|
The revset language (inspired by Mercurial) enables powerful commit selection across jujutsu commands. Expressions in this language are called "revsets" and are fundamental to working effectively with jujutsu.
|
|
|
|
The language consists of:
|
|
- **Symbols** - References to specific commits or sets of commits
|
|
- **Operators** - Ways to traverse and combine commit sets
|
|
- **Functions** - Queries and filters for finding commits
|
|
|
|
## Core Symbols
|
|
|
|
### Working Copy References
|
|
|
|
#### `@`
|
|
The current working copy commit.
|
|
|
|
```bash
|
|
jj log -r @ # Show working copy commit
|
|
jj diff -r @ # Diff of working copy
|
|
jj new @- # Create new commit on parent of @
|
|
```
|
|
|
|
#### `<workspace>@`
|
|
Working copy in a named workspace.
|
|
|
|
```bash
|
|
jj log -r main@ # Working copy in "main" workspace
|
|
jj diff -r feature@ # Working copy in "feature" workspace
|
|
```
|
|
|
|
### Remote References
|
|
|
|
#### `<name>@<remote>`
|
|
Remote-tracking bookmark.
|
|
|
|
```bash
|
|
jj log -r main@origin # Remote tracking branch
|
|
jj rebase -d main@origin # Rebase onto remote main
|
|
jj diff --from main@origin --to @ # Compare to remote
|
|
```
|
|
|
|
### Commit Identifiers
|
|
|
|
#### Change IDs and Commit IDs
|
|
Full hexadecimal IDs or unique prefixes.
|
|
|
|
```bash
|
|
jj log -r k # Unique prefix
|
|
jj log -r kmkuslsw # Longer prefix
|
|
jj log -r kmkuslswpqwq # Full change ID
|
|
jj show a1b2c3d # Commit ID prefix
|
|
```
|
|
|
|
**Resolution order:** Tags → Bookmarks → Git refs → Commit IDs
|
|
|
|
### Special Symbols
|
|
|
|
#### `root()`
|
|
The root commit (virtual commit at base of history).
|
|
|
|
```bash
|
|
jj log -r root() # Show root commit
|
|
jj log -r ::@ # All ancestors including root
|
|
```
|
|
|
|
## Operators
|
|
|
|
Operators traverse commit history and combine commit sets.
|
|
|
|
### Ancestry Operators
|
|
|
|
#### `x-` (Parents)
|
|
Immediate parent(s) of x.
|
|
|
|
```bash
|
|
jj log -r @- # Parent of working copy
|
|
jj log -r @-- # Grandparent
|
|
jj show @- # Show parent commit
|
|
jj edit @- # Edit parent commit
|
|
```
|
|
|
|
Multiple parents (merge commits):
|
|
```bash
|
|
jj log -r @-+ # Children of all parents (siblings)
|
|
```
|
|
|
|
#### `x+` (Children)
|
|
Immediate children of x.
|
|
|
|
```bash
|
|
jj log -r @+ # Children of working copy
|
|
jj log -r main@origin+ # Children of remote main
|
|
```
|
|
|
|
#### `::x` (Ancestors)
|
|
All ancestors of x, including x itself.
|
|
|
|
```bash
|
|
jj log -r ::@ # All ancestors of working copy
|
|
jj log -r ::main # All ancestors of main
|
|
jj log -r ::@- # Ancestors up to parent
|
|
```
|
|
|
|
#### `x::` (Descendants)
|
|
All descendants of x, including x itself.
|
|
|
|
```bash
|
|
jj log -r @:: # Working copy and all descendants
|
|
jj log -r main:: # main and its descendants
|
|
```
|
|
|
|
#### `x::y` (DAG Range)
|
|
Commits reachable from y through ancestor relationships with x.
|
|
|
|
```bash
|
|
jj log -r main::@ # Commits from main to @
|
|
jj log -r @-::@ # Just @ (parent to working copy)
|
|
```
|
|
|
|
#### `::x` with depth
|
|
Ancestors with limited depth.
|
|
|
|
```bash
|
|
jj log -r ancestors(@, 5) # Last 5 ancestors
|
|
jj log -r ancestors(@, 1) # Just parent (same as @-)
|
|
```
|
|
|
|
### Range Operators
|
|
|
|
#### `..x` (Ancestors excluding root)
|
|
Ancestors of x, excluding the root commit.
|
|
|
|
```bash
|
|
jj log -r ..@ # Ancestors of @ without root
|
|
jj log -r ..main # History up to main
|
|
```
|
|
|
|
#### `x..` (Non-ancestors)
|
|
x and its descendants, excluding ancestors.
|
|
|
|
```bash
|
|
jj log -r @.. # Working copy and descendants
|
|
jj log -r main.. # Everything not ancestral to main
|
|
```
|
|
|
|
#### `x..y` (Range)
|
|
Commits in y but not in x (y's descendants minus x's ancestors).
|
|
|
|
```bash
|
|
jj log -r main..@ # Commits added since main
|
|
jj log -r @-..@ # Just @ (changes since parent)
|
|
jj log -r @..main # Commits in main not in @
|
|
```
|
|
|
|
### Set Operators
|
|
|
|
#### `x | y` (Union)
|
|
Commits in either x or y (or both).
|
|
|
|
```bash
|
|
jj log -r '@- | @' # Parent and working copy
|
|
jj log -r 'main | feature' # Both branches
|
|
jj log -r 'bookmarks() | tags()' # All bookmarks and tags
|
|
```
|
|
|
|
#### `x & y` (Intersection)
|
|
Commits in both x and y.
|
|
|
|
```bash
|
|
jj log -r 'author(alice) & description(bug)' # Alice's bug fixes
|
|
jj log -r 'mine() & ::main' # My commits in main's history
|
|
```
|
|
|
|
#### `x ~ y` (Difference)
|
|
Commits in x but not in y.
|
|
|
|
```bash
|
|
jj log -r 'all() ~ main' # All commits except main
|
|
jj log -r '@:: ~ @' # Descendants excluding working copy
|
|
jj log -r 'mine() ~ ::main' # My commits not yet in main
|
|
```
|
|
|
|
#### `~x` (Complement)
|
|
All commits except those in x.
|
|
|
|
```bash
|
|
jj log -r '~@' # Everything except working copy
|
|
jj log -r '~main::' # Everything not descended from main
|
|
```
|
|
|
|
### Operator Precedence
|
|
|
|
From highest to lowest:
|
|
1. `-` (parents), `+` (children)
|
|
2. `::`, `..` (DAG ranges)
|
|
3. `~` (negation/complement)
|
|
4. `&` (intersection)
|
|
5. `~` (set difference)
|
|
6. `|` (union)
|
|
|
|
Use parentheses to override:
|
|
```bash
|
|
jj log -r '(main | feature) & author(alice)'
|
|
jj log -r 'main::(@ | feature)'
|
|
```
|
|
|
|
## Functions
|
|
|
|
Functions query and filter commits based on various criteria.
|
|
|
|
### Traversal Functions
|
|
|
|
#### `ancestors(x[, depth])`
|
|
All ancestors of x, optionally limited by depth.
|
|
|
|
```bash
|
|
jj log -r 'ancestors(@)' # All ancestors
|
|
jj log -r 'ancestors(@, 5)' # 5 generations back
|
|
jj log -r 'ancestors(main, 10)' # 10 commits before main
|
|
```
|
|
|
|
#### `descendants(x)`
|
|
All descendants of x, including x.
|
|
|
|
```bash
|
|
jj log -r 'descendants(main)' # main and everything after
|
|
jj log -r 'descendants(@-)' # Parent and its descendants
|
|
```
|
|
|
|
#### `connected(x)`
|
|
Commits connected to x through parents and children.
|
|
|
|
```bash
|
|
jj log -r 'connected(@)' # Connected component containing @
|
|
```
|
|
|
|
#### `reachable(x, domain)`
|
|
Commits in domain that are reachable from x.
|
|
|
|
```bash
|
|
jj log -r 'reachable(@, all())' # All reachable from @
|
|
```
|
|
|
|
### Set Functions
|
|
|
|
#### `all()`
|
|
All commits in the repository.
|
|
|
|
```bash
|
|
jj log -r 'all()' # Entire history
|
|
jj log -r 'all() ~ ::main' # Everything not in main's history
|
|
```
|
|
|
|
#### `none()`
|
|
Empty set (no commits).
|
|
|
|
```bash
|
|
jj log -r 'none()' # No output
|
|
jj log -r 'none() | @' # Just @ (contrived example)
|
|
```
|
|
|
|
#### `heads(x)`
|
|
Commits in x that have no children in x.
|
|
|
|
```bash
|
|
jj log -r 'heads(all())' # All branch tips
|
|
jj log -r 'heads(main::)' # Tips descended from main
|
|
```
|
|
|
|
#### `roots(x)`
|
|
Commits in x that have no parents in x.
|
|
|
|
```bash
|
|
jj log -r 'roots(main..@)' # First commits after branching from main
|
|
jj log -r 'roots(bookmarks())' # Root commits of bookmarked branches
|
|
```
|
|
|
|
#### `latest(x[, count])`
|
|
Latest (newest) commits from x, optionally limited.
|
|
|
|
```bash
|
|
jj log -r 'latest(all())' # Most recent commit
|
|
jj log -r 'latest(all(), 10)' # 10 most recent commits
|
|
jj log -r 'latest(author(alice), 5)' # Alice's 5 latest commits
|
|
```
|
|
|
|
### Bookmark and Tag Functions
|
|
|
|
#### `bookmarks([pattern])`
|
|
Commits pointed to by bookmarks, optionally filtered by pattern.
|
|
|
|
```bash
|
|
jj log -r 'bookmarks()' # All bookmarked commits
|
|
jj log -r 'bookmarks(main)' # Main bookmark
|
|
jj log -r 'bookmarks(glob:feature-*)' # Feature branches
|
|
```
|
|
|
|
Pattern types: `substring:`, `exact:`, `glob:`, `regex:` (append `-i` for case-insensitive)
|
|
|
|
#### `remote_bookmarks([pattern[, [remote=]pattern]])`
|
|
Remote-tracking bookmarks, optionally filtered.
|
|
|
|
```bash
|
|
jj log -r 'remote_bookmarks()' # All remote bookmarks
|
|
jj log -r 'remote_bookmarks(main)' # main on all remotes
|
|
jj log -r 'remote_bookmarks(main, origin)' # main@origin
|
|
jj log -r 'remote_bookmarks(glob:feature-*, origin)' # Feature branches on origin
|
|
```
|
|
|
|
#### `tags([pattern])`
|
|
Commits with tags, optionally filtered.
|
|
|
|
```bash
|
|
jj log -r 'tags()' # All tagged commits
|
|
jj log -r 'tags(v1.0.0)' # Specific tag
|
|
jj log -r 'tags(glob:v1.*)' # All v1.x tags
|
|
```
|
|
|
|
#### `git_refs()`
|
|
All Git references.
|
|
|
|
```bash
|
|
jj log -r 'git_refs()' # All Git refs
|
|
```
|
|
|
|
#### `git_head()`
|
|
Git's HEAD reference.
|
|
|
|
```bash
|
|
jj log -r 'git_head()' # Show Git HEAD
|
|
```
|
|
|
|
#### `tracked_remote_bookmarks([bookmark_pattern[, [remote=]remote_pattern]])`
|
|
Bookmarks with remote tracking configured.
|
|
|
|
```bash
|
|
jj log -r 'tracked_remote_bookmarks()' # All tracked bookmarks
|
|
jj log -r 'tracked_remote_bookmarks(main)' # Tracked main branches
|
|
```
|
|
|
|
#### `untracked_remote_bookmarks([bookmark_pattern[, [remote=]remote_pattern]])`
|
|
Remote bookmarks without local tracking.
|
|
|
|
```bash
|
|
jj log -r 'untracked_remote_bookmarks()' # Untracked remotes
|
|
```
|
|
|
|
### Author and Committer Functions
|
|
|
|
#### `author(pattern)`
|
|
Commits where author matches pattern.
|
|
|
|
```bash
|
|
jj log -r 'author(alice)' # Alice's commits
|
|
jj log -r 'author("Alice Smith")' # Exact name
|
|
jj log -r 'author(glob:*@example.com)' # By email domain
|
|
jj log -r 'author(regex:^A)' # Names starting with A
|
|
```
|
|
|
|
Pattern matching supports: `substring:`, `exact:`, `glob:`, `regex:` (with `-i` suffix for case-insensitive)
|
|
|
|
#### `committer(pattern)`
|
|
Commits where committer matches pattern.
|
|
|
|
```bash
|
|
jj log -r 'committer(bot)' # Commits by bot
|
|
jj log -r 'committer(glob:*@github.com)' # GitHub committers
|
|
```
|
|
|
|
#### `mine()`
|
|
Commits authored or committed by the current user.
|
|
|
|
```bash
|
|
jj log -r 'mine()' # All my commits
|
|
jj log -r 'mine() & ::main' # My commits in main
|
|
jj log -r 'mine() ~ ::main' # My commits not in main
|
|
```
|
|
|
|
### Description Functions
|
|
|
|
#### `description(pattern)`
|
|
Commits with description matching pattern.
|
|
|
|
```bash
|
|
jj log -r 'description(bug)' # Commits mentioning "bug"
|
|
jj log -r 'description(exact:Fix bug #123)' # Exact match
|
|
jj log -r 'description(glob:*BREAKING*)' # Contains "BREAKING"
|
|
jj log -r 'description(regex:^fix:)' # Conventional commit fixes
|
|
```
|
|
|
|
#### `subject(pattern)`
|
|
Commits with first line of description matching pattern.
|
|
|
|
```bash
|
|
jj log -r 'subject(feat:)' # Feature commits
|
|
jj log -r 'subject(glob:*WIP*)' # WIP commits
|
|
```
|
|
|
|
### File Functions
|
|
|
|
#### `files(pattern)`
|
|
Commits modifying files matching pattern.
|
|
|
|
```bash
|
|
jj log -r 'files(glob:*.rs)' # Commits changing Rust files
|
|
jj log -r 'files(src/main.rs)' # Commits changing specific file
|
|
jj log -r 'files(glob:**/test_*)' # Commits changing test files
|
|
```
|
|
|
|
Uses fileset syntax (see filesets.md).
|
|
|
|
#### `diff_contains(pattern[, [files=]fileset])`
|
|
Commits with diff containing pattern, optionally in specific files.
|
|
|
|
```bash
|
|
jj log -r 'diff_contains(TODO)' # Commits adding/removing TODO
|
|
jj log -r 'diff_contains(bug, files=glob:*.rs)' # "bug" in Rust files
|
|
jj log -r 'diff_contains(regex:\bfix\b)' # Word "fix" in diff
|
|
```
|
|
|
|
### State Functions
|
|
|
|
#### `empty()`
|
|
Commits with no changes (empty diffs).
|
|
|
|
```bash
|
|
jj log -r 'empty()' # All empty commits
|
|
jj log -r 'mine() & empty()' # My empty commits
|
|
jj abandon $(jj log -r 'empty()' -T commit_id --no-graph) # Remove empty commits
|
|
```
|
|
|
|
#### `conflict()`
|
|
Commits with unresolved conflicts.
|
|
|
|
```bash
|
|
jj log -r 'conflict()' # Find conflicted commits
|
|
jj resolve $(jj log -r 'conflict()' -T commit_id --no-graph | head -1) # Resolve first
|
|
```
|
|
|
|
#### `immutable()`
|
|
Commits considered immutable (configured in settings).
|
|
|
|
```bash
|
|
jj log -r 'immutable()' # Show immutable commits
|
|
jj log -r 'all() ~ immutable()' # Only mutable commits
|
|
```
|
|
|
|
#### `present(x)`
|
|
Returns x if it exists, otherwise empty set.
|
|
|
|
```bash
|
|
jj log -r 'present(some-branch)' # Branch if it exists
|
|
jj rebase -d 'present(main) | @-' # Use main if exists, else parent
|
|
```
|
|
|
|
Useful for scripting to avoid errors when references don't exist.
|
|
|
|
### Visibility Functions
|
|
|
|
#### `visible_heads()`
|
|
Commits that are visible heads.
|
|
|
|
```bash
|
|
jj log -r 'visible_heads()' # All visible heads
|
|
```
|
|
|
|
#### `immutable_heads()`
|
|
Heads of immutable commits.
|
|
|
|
```bash
|
|
jj log -r 'immutable_heads()' # Immutable heads
|
|
```
|
|
|
|
## Pattern Matching
|
|
|
|
String patterns in functions support multiple matching modes.
|
|
|
|
### Pattern Prefixes
|
|
|
|
- `substring:` - Default, matches if pattern appears anywhere
|
|
- `exact:` - Exact match only
|
|
- `glob:` - Unix-style glob patterns
|
|
- `regex:` - Regular expression matching
|
|
|
|
Add `-i` suffix for case-insensitive matching:
|
|
- `substring-i:`, `exact-i:`, `glob-i:`, `regex-i:`
|
|
|
|
### Examples
|
|
|
|
```bash
|
|
# Substring (default)
|
|
jj log -r 'author(alice)'
|
|
jj log -r 'author(substring:alice)' # Equivalent
|
|
|
|
# Exact match
|
|
jj log -r 'author(exact:Alice Smith)'
|
|
jj log -r 'description(exact:Fix bug #123)'
|
|
|
|
# Glob patterns
|
|
jj log -r 'author(glob:*@example.com)'
|
|
jj log -r 'bookmarks(glob:feature-*)'
|
|
jj log -r 'files(glob:**/*.rs)'
|
|
|
|
# Regular expressions
|
|
jj log -r 'description(regex:^feat:)'
|
|
jj log -r 'author(regex:\d+\+.*@users.noreply.github.com)'
|
|
|
|
# Case-insensitive
|
|
jj log -r 'author(substring-i:ALICE)'
|
|
jj log -r 'description(glob-i:*breaking*)'
|
|
```
|
|
|
|
## Practical Examples
|
|
|
|
### Finding Commits
|
|
|
|
```bash
|
|
# Recent work
|
|
jj log -r 'latest(mine(), 10)' # My 10 most recent commits
|
|
|
|
# Commits by criteria
|
|
jj log -r 'author(alice) & description(bug)' # Alice's bug fixes
|
|
jj log -r 'mine() & conflict()' # My conflicted commits
|
|
jj log -r 'files(glob:*.rs) & description(perf)' # Rust performance commits
|
|
|
|
# Branch comparisons
|
|
jj log -r 'main..@' # My commits not in main
|
|
jj log -r 'main..feature' # Commits in feature not in main
|
|
jj log -r 'main@origin..' # All commits not pushed
|
|
```
|
|
|
|
### Working with Branches
|
|
|
|
```bash
|
|
# View all branches
|
|
jj log -r 'bookmarks()'
|
|
|
|
# Active development branches
|
|
jj log -r 'heads(all()) ~ remote_bookmarks()'
|
|
|
|
# Branches needing updates
|
|
jj log -r 'bookmarks() ~ ::remote_bookmarks(main, origin)'
|
|
|
|
# Merged branches
|
|
jj log -r 'bookmarks() & ::main'
|
|
```
|
|
|
|
### History Analysis
|
|
|
|
```bash
|
|
# Commits touching specific files
|
|
jj log -r 'files(src/auth.rs)'
|
|
|
|
# Recent changes to tests
|
|
jj log -r 'latest(files(glob:**/*_test.rs), 20)'
|
|
|
|
# Commits between tags
|
|
jj log -r 'tags(v1.0.0)..tags(v2.0.0)'
|
|
|
|
# Commits not yet tagged
|
|
jj log -r 'heads(all()) ~ ::tags()'
|
|
```
|
|
|
|
### Commit Cleanup
|
|
|
|
```bash
|
|
# Find empty commits
|
|
jj log -r 'empty()'
|
|
|
|
# Find WIP commits
|
|
jj log -r 'description(glob:*WIP*)'
|
|
|
|
# Commits needing attention
|
|
jj log -r 'conflict() | empty() | description(glob:*TODO*)'
|
|
```
|
|
|
|
### Working with Remotes
|
|
|
|
```bash
|
|
# Commits not pushed
|
|
jj log -r 'mine() ~ ::remote_bookmarks()'
|
|
|
|
# Remote updates
|
|
jj log -r 'remote_bookmarks() ~ ::bookmarks()'
|
|
|
|
# Diverged branches
|
|
jj log -r '(main ~ ::main@origin) | (main@origin ~ ::main)'
|
|
```
|
|
|
|
## Complex Queries
|
|
|
|
### Multi-Criteria Searches
|
|
|
|
```bash
|
|
# My recent bug fixes in Rust code
|
|
jj log -r '
|
|
latest(
|
|
mine()
|
|
& description(glob:*fix*|*bug*)
|
|
& files(glob:**/*.rs),
|
|
20
|
|
)
|
|
'
|
|
|
|
# Commits by team members on feature branches
|
|
jj log -r '
|
|
(author(alice) | author(bob) | author(carol))
|
|
& bookmarks(glob:feature-*)::
|
|
~ ::main
|
|
'
|
|
|
|
# Risky commits (large changes, no tests)
|
|
jj log -r '
|
|
files(glob:src/**/*.rs)
|
|
~ files(glob:**/*_test.rs)
|
|
& description(regex:(?i)\b(refactor|rewrite)\b)
|
|
'
|
|
```
|
|
|
|
### Conditional Selection
|
|
|
|
```bash
|
|
# Use main@origin if it exists, otherwise main
|
|
jj rebase -d 'present(main@origin) | main'
|
|
|
|
# Latest stable release or head
|
|
jj log -r 'present(tags(glob:v*.*.0)) | heads(all())'
|
|
```
|
|
|
|
### Graph Queries
|
|
|
|
```bash
|
|
# All commits between branches
|
|
jj log -r 'main::feature ~ (::main | feature::)'
|
|
|
|
# Divergent changes
|
|
jj log -r '(main ~ ::feature) | (feature ~ ::main)'
|
|
|
|
# Common ancestors
|
|
jj log -r '::main & ::feature'
|
|
```
|
|
|
|
## Best Practices
|
|
|
|
### 1. Start Simple, Then Refine
|
|
|
|
```bash
|
|
# Start broad
|
|
jj log -r 'mine()'
|
|
|
|
# Add date constraints
|
|
jj log -r 'latest(mine(), 20)'
|
|
|
|
# Add content filter
|
|
jj log -r 'latest(mine() & description(feature), 20)'
|
|
```
|
|
|
|
### 2. Use Readable Multi-Line Queries
|
|
|
|
```bash
|
|
# Hard to read
|
|
jj log -r 'latest(mine() & (description(bug) | description(fix)) & files(glob:src/**/*.rs) ~ ::main, 10)'
|
|
|
|
# Readable
|
|
jj log -r '
|
|
latest(
|
|
mine()
|
|
& (description(bug) | description(fix))
|
|
& files(glob:src/**/*.rs)
|
|
~ ::main,
|
|
10
|
|
)
|
|
'
|
|
```
|
|
|
|
### 3. Create Aliases for Common Queries
|
|
|
|
Edit config with `jj config edit --user`:
|
|
|
|
```toml
|
|
[revset-aliases]
|
|
# My commits not in main
|
|
work = "mine() ~ ::main"
|
|
|
|
# Commits needing attention
|
|
attention = "conflict() | empty() | description(glob:*WIP*) | description(glob:*TODO*)"
|
|
|
|
# Recent changes
|
|
recent = "latest(all(), 20)"
|
|
|
|
# Unpushed work
|
|
unpushed = "mine() ~ ::remote_bookmarks()"
|
|
```
|
|
|
|
Use in commands:
|
|
```bash
|
|
jj log -r work
|
|
jj log -r attention
|
|
jj log -r recent
|
|
```
|
|
|
|
### 4. Use `present()` for Robustness
|
|
|
|
```bash
|
|
# Fails if branch doesn't exist
|
|
jj rebase -d some-branch
|
|
|
|
# Safe version
|
|
jj rebase -d 'present(some-branch) | @-'
|
|
```
|
|
|
|
### 5. Combine with Templates for Insight
|
|
|
|
```bash
|
|
# Show commit IDs of specific commits
|
|
jj log -r 'conflict()' -T commit_id --no-graph
|
|
|
|
# Count commits
|
|
jj log -r 'mine() ~ ::main' --no-graph | wc -l
|
|
|
|
# Custom format for scripting
|
|
jj log -r 'latest(mine(), 5)' -T 'commit_id ++ " " ++ description.first_line() ++ "\n"'
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### No Commits Matched
|
|
|
|
```bash
|
|
# Check individual parts
|
|
jj log -r 'author(alice)' # Does author filter work?
|
|
jj log -r 'description(bug)' # Does description filter work?
|
|
jj log -r 'author(alice) & description(bug)' # Combine
|
|
|
|
# Verify symbols exist
|
|
jj bookmark list # Check bookmark names
|
|
jj log -r 'bookmarks()' # See all bookmarks
|
|
```
|
|
|
|
### Unexpected Results
|
|
|
|
```bash
|
|
# Use `all()` to understand set size
|
|
jj log -r 'all() ~ ::main' # Everything not in main
|
|
|
|
# Break down complex queries
|
|
jj log -r 'mine()' # Step 1
|
|
jj log -r 'mine() ~ ::main' # Step 2
|
|
jj log -r 'latest(mine() ~ ::main, 10)' # Step 3
|
|
```
|
|
|
|
### Performance Issues
|
|
|
|
```bash
|
|
# Large repositories may be slow with broad queries
|
|
jj log -r 'all()' # Can be slow
|
|
|
|
# Optimize by limiting scope
|
|
jj log -r 'latest(all(), 100)' # Faster
|
|
jj log -r '::@' # Just ancestors
|
|
jj log -r 'ancestors(@, 50)' # Limited depth
|
|
```
|
|
|
|
## Integration with Commands
|
|
|
|
Revsets work with most jujutsu commands:
|
|
|
|
### Viewing History
|
|
|
|
```bash
|
|
jj log -r '<revset>' # Show log
|
|
jj show -r '<revset>' # Show details
|
|
jj diff -r '<revset>' # Show changes
|
|
jj evolog -r '<revset>' # Show evolution log
|
|
```
|
|
|
|
### Modifying Commits
|
|
|
|
```bash
|
|
jj edit <revset> # Edit commit
|
|
jj squash -r <revset> # Squash commit
|
|
jj abandon <revset> # Abandon commits
|
|
jj describe -r <revset> # Set description
|
|
```
|
|
|
|
### Rebasing
|
|
|
|
```bash
|
|
jj rebase -d <revset> # Rebase destination
|
|
jj rebase -r <revset> -d <dest> # Rebase specific commit
|
|
jj rebase -s <revset> -d <dest> # Rebase source and descendants
|
|
```
|
|
|
|
### Branching
|
|
|
|
```bash
|
|
jj bookmark set <name> -r <revset> # Set bookmark
|
|
jj new <revset> # New commit on base
|
|
```
|
|
|
|
## Summary
|
|
|
|
Revsets are the foundation of powerful commit selection in jujutsu:
|
|
|
|
- **Symbols**: `@`, `root()`, commit IDs, bookmarks, tags
|
|
- **Operators**: `-/+` (parents/children), `::` (ancestors/descendants), `|/&/~` (set operations)
|
|
- **Functions**: `mine()`, `author()`, `description()`, `files()`, `conflict()`, `empty()`, etc.
|
|
- **Patterns**: `substring:`, `exact:`, `glob:`, `regex:` (with `-i` for case-insensitive)
|
|
- **Best practices**: Start simple, use aliases, combine with templates
|
|
- **Integration**: Works across all jujutsu commands
|
|
|
|
For file-based filtering, see filesets.md. For output customization, see templating.md.
|
|
|
|
Master revsets to unlock jujutsu's full potential for commit management and history navigation.
|