Skip to content

Instantly share code, notes, and snippets.

@thoughtpolice
Last active February 13, 2025 08:07
Show Gist options
  • Save thoughtpolice/8f2fd36ae17cd11b8e7bd93a70e31ad6 to your computer and use it in GitHub Desktop.
Save thoughtpolice/8f2fd36ae17cd11b8e7bd93a70e31ad6 to your computer and use it in GitHub Desktop.
my jujutsu config
## ------------------------------------------------------------------------------------------------
# Schema published automatically on the website. This allows TOML language
# servers to autocomplete and show documentation for the entries below.
#
# I use the prerelease version as my builds on my machines are often from trunk.
"$schema" = "https://jj-vcs.github.io/jj/prerelease/config-schema.json"
## ------------------------------------------------------------------------------------------------
## ---- Basic settings
[user]
name = "Austin Seipp"
# email has to be configured per-repository
[ui]
default-command = "log"
diff.tool = "difft"
merge-editor = "vscode"
log-synthetic-elided-nodes = true
graph.style = "square"
pager = { command = ["less", "-FRX"], env = { LESSCHARSET = "utf-8" } }
should-sign-off = true
[merge-tools.difft]
program = "difft"
diff-args = ["--color=always", "$left", "$right"]
[merge-tools.mergiraf]
program = "mergiraf"
merge-args = ["merge", "$base", "$left", "$right", "-o", "$output", "--fast"]
merge-conflict-exit-codes = [1]
conflict-marker-style = "git"
[git]
auto-local-bookmark = false
push-bookmark-prefix = "aseipp/push-"
private-commits = 'blacklist()'
colocate = true
subprocess = true
[snapshot]
# FIXME (upstream): why isn't this on by default?
auto-update-stale = true
[gerrit]
enabled = false
url = 'http://example.com'
## ------------------------------------------------------------------------------------------------
## ---- Revsets & filesets
[revsets]
# By default, show the current stack of work.
log = 'stack(@)'
[revset-aliases]
# Useful on Windows. Technically conflicts with any bookmark/tag named 'at', but
# seems OK...
'at' = '@'
# FIXME (upstream): should this be upstream?
'user(x)' = 'author(x) | committer(x)'
# By default, show the repo trunk, the remote bookmarks, and all remote tags. We
# don't want to change these in most cases, but in some repos it's useful.
'immutable_heads()' = 'present(trunk()) | remote_bookmarks() | tags()'
# Useful to ignore this, in many repos. For repos like `jj` these are
# consistently populated with a bunch of auto-generated commits, so ignoring it
# is often nice.
'gh_pages()' = 'ancestors(remote_bookmarks(exact:"gh-pages"))'
# trunk() by default resolves to the latest 'main'/'master' remote bookmark. May
# require customization for repos like nixpkgs.
'trunk()' = 'latest((present(main) | present(master)) & remote_bookmarks())'
# Private and WIP commits that should never be pushed anywhere. Often part of
# work-in-progress merge stacks.
'wip()' = 'description(glob:"wip:*")'
'private()' = 'description(glob:"private:*")'
'blacklist()' = 'wip() | private()'
# stack(x, n) is the set of mutable commits reachable from 'x', with 'n'
# parents. 'n' is often useful to customize the display and return set for
# certain operations. 'x' can be used to target the set of 'roots' to traverse,
# e.g. @ is the current stack.
'stack()' = 'ancestors(reachable(@, mutable()), 2)'
'stack(x)' = 'ancestors(reachable(x, mutable()), 2)'
'stack(x, n)' = 'ancestors(reachable(x, mutable()), n)'
# The current set of "open" works. It is defined as:
#
# - given the set of commits not in trunk, that are written by me,
# - calculate the given stack() for each of those commits
#
# n = 1, meaning that nothing from `trunk()` is included, so all resulting
# commits are mutable by definition.
'open()' = 'stack(trunk().. & mine(), 1)'
# the set of 'ready()' commits. defined as the set of open commits, but nothing
# that is blacklisted or any of their children.
#
# often used with gerrit, which you can use to submit whole stacks at once:
#
# - jj gerrit send -r 'ready()' --dry-run
'ready()' = 'open() ~ blacklist()::'
## ------------------------------------------------------------------------------------------------
## ---- UX/UI Configuration
[aliases]
# Convenient shorthands.
d = ["diff"]
s = ["show"]
ll = ["log", "-T", "builtin_log_detailed"]
nt = ["new", "trunk()"]
# Get all open stacks of work.
open = ["log", "-r", "open()"]
# Better name, IMO.
credit = ["file", "annotate"]
# Retrunk a series. Typically used as `jj retrunk -s ...`, and notably can be
# used with open:
# - jj retrunk -s 'all:roots(open())'
retrunk = ["rebase", "-d", "trunk()"]
# Retrunk the current stack of work.
reheat = ["rebase", "-d", "trunk()", "-s", "all:roots(trunk()..stack(@))"]
# Take content from any change, and move it into @.
# - jj consume xyz path/to/file`
consume = ["squash", "--into", "@", "--from"]
# Eject content from @ into any other change.
# - jj eject xyz --interactive
eject = ["squash", "--from", "@", "--into"]
[colors]
# Base customizations
"normal change_id" = { bold = true, fg = "magenta" }
"immutable change_id" = { bold = false, fg = "bright cyan" }
# Used by log node template
"node" = { bold = true }
"node elided" = { fg = "bright black" }
"node working_copy" = { fg = "green" }
"node conflict" = { fg = "red" }
"node immutable" = { fg = "bright cyan" }
"node wip" = { fg = "yellow" }
"node normal" = { bold = false }
# Used in other various templates
"text link" = { bold = true, fg = "magenta" }
"text warning" = { bold = true, fg = "red" }
[template-aliases]
# Code to hyperlink something for the terminal.
# FIXME (upstream): should this go upstream?
'hyperlink(url, text)' = '''
concat(
raw_escape_sequence("\e]8;;" ++ url ++ "\e\\"),
label("text link", text),
raw_escape_sequence("\e]8;;\e\\"),
)
'''
# Basic customizations.
'format_short_signature(signature)' = '"<" ++ if(signature.email(), signature.email(), label("text warning", "NO EMAIL")) ++ ">"'
'format_timestamp(ts)' = '"[" ++ ts.ago() ++ "]"'
'render_bookmarks(commit)' = '''
commit.bookmarks().map(|b|
if(b.remote(),
b,
hyperlink(gh_pr_base() ++ "/tree/" ++ b.name(), b),
)
)
'''
# Commit header. This includes code to automatically link to Gerrit code reviews
# for matching commits in a very basic way.
'format_short_commit_header(commit)' = '''separate(" ",
format_short_change_id_with_hidden_and_divergent_info(commit),
format_short_signature(commit.author()),
format_timestamp(commit_timestamp(commit)),
render_bookmarks(commit),
commit.tags(),
commit.working_copies(),
format_short_commit_id(commit.commit_id()),
if(has_ghpr_url(commit.description()),
"[" ++
hyperlink(
get_ghpr_url(commit.description()),
"GH: #1234"
) ++ "]"
),
if(has_change_id(commit.description()),
"[" ++
hyperlink(
config("gerrit.url").as_string() ++ "/q/" ++ gerrit_id(change_id),
"CR: " ++ gerrit_id(change_id, 10)
) ++ "]"
),
if(commit.git_head(), label("git_head", "git_head()")),
if(commit.conflict(), label("conflict", "conflict")),
)'''
'has_ghpr_url(s)' = 's.contains("GH-PR: ")'
'get_ghpr_url(s)' = '''
s.lines().filter(|l| l.starts_with("GH-PR: ")).map(|l| l.remove_prefix("GH-PR: ")).join("")
'''
# 6a6a636c is hex("jjcl").
'has_change_id(s)' = 's.contains("Change-Id: I")'
'gerrit_id(c, n)' = '"I" ++ raw_escape_sequence(c.normal_hex().substr(0, n)) ++ if(n > 31, "6a6a636c")'
'gerrit_id(c)' = 'gerrit_id(c, 31)'
'gh_pr_base()' = '"undefined"'
[templates]
# Improve the default representation in the log. This colors
# and changes the node icon for each.
op_log_node = 'if(current_operation, "@", "◉")'
log_node = '''
label("node",
coalesce(
if(!self, label("elided", "⇋")),
if(current_working_copy, label("working_copy", "◉")),
if(conflict, label("conflict", "x")),
if(immutable, label("immutable", "◆")),
if(description.starts_with("wip: "), label("wip", "!")),
label("normal", "○")
)
)
'''
# Draft commit description. Includes:
# - Change-Id fields for Gerrit, and
# - Signed-off-by lines
draft_commit_description = '''
concat(
description,
"\n",
if(
config("gerrit.enabled").as_boolean() && !has_change_id(description),
"\nChange-Id: I" ++ gerrit_id(change_id),
),
if(
config("ui.should-sign-off").as_boolean() && !description.contains("Signed-off-by: " ++ author.name()),
"\nSigned-off-by: " ++ author.name() ++ " <" ++ author.email() ++ ">",
),
"\n",
surround(
"\nJJ: This commit contains the following changes:\n", "",
indent("JJ: ", diff.summary()),
),
)
'''
@valodzka
Copy link

valodzka commented Feb 6, 2025

for gerrit change-id generation: this example isn't working for me as of revision 19, see alternative solution
https://github.com/avamsi/dotfiles/blob/28a0e40439de56fe179a1b0e705727c85e075464/.jjconfig.toml#L146-L156

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment