Skip to main content
jj-git

Revsets: Powerful Commit Queries

Step 7 of 12

Revsets: Powerful Commit Queries

Revsets (revision sets) are jj's query language for selecting commits—much more powerful than git's commit limiting.

Basic Revset Syntax

jj
jj log -l 10
jj log -r @-
jj log -r @
Command comparison: git commands on the left, jj commands on the right
gitjj
git log -n 10jj log -l 10
git log HEAD~1jj log -r @-

Common Revsets

Working copy and parents:

jj log -r @           # Current working copy
jj log -r @-          # Parent of @
jj log -r @-          # Grandparent (keeps adding -)
jj log -r @+          # Child of @

Branches:

jj log -r main                # Commits in main
jj log -r main@origin         # Remote-tracking main
jj log -r main..              # main and descendants

Ancestry:

jj log -r ::@           # Ancestors of @ (including @)
jj log -r @::           # Descendants of @ (including @)
jj log -r abc..def      # abc to def (ancestors of def, not abc)
jj log -r abc:def       # Range abc to def (inclusive)

Filtering by Description

jj
jj log -r 'description("fix")'
Command comparison: git commands on the left, jj commands on the right
gitjj
git log --grep="fix"jj log -r 'description("fix")'

Filtering by Author

jj
jj log -r 'author("alice")'
Command comparison: git commands on the left, jj commands on the right
gitjj
git log --author="alice"jj log -r 'author("alice")'

Filtering by Time

jj
jj log -r 'recent()'
Command comparison: git commands on the left, jj commands on the right
gitjj
git log --since="2024-01-01"jj log -r 'recent()'
git log --until="2024-02-01"

Combining Filters

Revsets support boolean logic:

# Commits by Alice OR Bob
jj log -r 'author("alice") | author("bob")'

# Commits by Alice AND contain "fix"
jj log -r 'author("alice") & description("fix")'

# Commits by Alice but NOT "wip"
jj log -r 'author("alice") ~ description("wip")'

# All commits except those by Bob
jj log -r '~author("bob")'

Practical Examples

Show my recent work:

jj log -r 'author("me") & ::@'

Show what I'll push:

jj log -r 'main@origin..@'

Show commits since last release:

jj log -r 'tags("v1.0")..@'

Show merge commits:

jj log -r 'description("Merge")'

Empty Revsets

When a revset matches nothing:

$ jj log -r 'description("nonexistent")'
"..." (no matches)

This is useful for scripts—if a revset is empty, nothing happens.

Using Revsets with Commands

Revsets work with many jj commands:

# Show specific commits
jj show 'description("fix")'

# Diff between revsets
jj diff --from 'main@origin' --to @

# Rebase based on revset
jj rebase -d 'description("baseline")'

# Abandon multiple commits
jj abandon 'description("wip")'

Change IDs vs Commit IDs

Revsets can query by change ID (stable across rebases) or commit ID (specific instance):

# By change ID (survives rebases)
jj log -r 'change(abc)'

# By commit ID (specific)
jj log -r 'commit(xyz)'

All Commits

To see all commits including abandoned:

jj log --all
# or
jj log -r 'all()'

DAG Operations

Revsets understand the commit DAG:

# Heads of repository (branches without children)
jj log -r 'heads()'

# Roots (commits without parents)
jj log -r 'roots()'

# Visible commits (not hidden)
jj log -r 'visible_heads()'

Try It Yourself

$
$
$

Key Takeaways

  • Revsets are a powerful query language
  • -r flag accepts revset expressions
  • :: for ancestry, .. for ranges
  • Boolean operators: &, |, ~
  • Filter by author, description, time
  • Use change IDs for stable references

Next Steps

Now let's explore jj's approach to rebasing and editing history.

Practice Exercises

0/5 completed

  1. 1Create a new bookmark
  2. 2Set bookmark to a specific commit
  3. 3Rename a bookmark
  4. 4Delete a bookmark
  5. 5List all bookmarks