[aliases] a = ["absorb"] dlog = ["log", "-r"] l = ["log", "-r", "(trunk()..@):: | (trunk()..@)-"] #l = ["log", "-r", "more()"] fresh = ["new", "trunk()"] # Figures out the closest bookmark # and pulls it up to the latest change that can be pushed. tug = [ "bookmark", "move", "--from", "closest_bookmark(@)", "--to", "closest_pushable(@)", ] bl = ["bookmark", "list"] blr = ["bookmark", "list", "--revisions", "recent()"] c = ["commit"] ci = ["commit", "--interactive"] # commit interactive m = ["describe"] mm = ["describe", "--message"] d = ["diff", "--stat", "--revisions"] dd = ["diff", "--revisions"] dp = ["describe", "@-"] # describe previous e = ["edit"] para = [ "parallelize", "closest_tip()..@-" ] pull = ["git", "fetch"] push = ["git", "push"] gf = ["git", "fetch"] # git fetchq gi = ["git", "init", "--colocate"] gp = ["git", "push"] # git push i = ["git", "init", "--colocate"] nb = ["bookmark", "create", "-r @-"] # new bookmark (for creating bookmark to push) nc = ["new", "-B", "@", "--no-edit"] # new change before r = ["rebase"] rm = ["rebase", "-d", "main"] # "re-main" s = ["show", "--stat"] ss = ["show"] sq = ["squash"] sqi = ["squash", "--interactive"] si = ["squash", "--interactive"] sp = ["show", "@-"] up = ["util", "exec", "--", "sh", "-c", """ if [ $# == 0 ]; then jj bookmark move --from "closest_bookmark(@)" --to "closest_pushable(@)" else jj bookmark move --to "closest_pushable(@)" "$@" fi """, ""] upp = ["util", "exec", "--", "sh", "-c", "jj up && jj git push", ""] # 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"] # All operations o = ["op", "log"] # All operations, with more whitespace oo = ["op", "log", "-T", "builtin_op_log_comfortable"] abandon-empties = ["abandon", "-r", "description(exact:'') ~ root()"] # Move $commit just after the bookmark, and then move $bookmark on top of it. # # "$bookmark+" works, because after rebase -A, the only child of $bookmark is $commit. # I do not use $commit itself because it might point to a # different commit after the rebase (e.g. @-). # # My workflow uses mega-merge: I write a commit or two, # and then move them to relevant branches with jj to. # As a bonus, bookmarks are kept up-to-date for easy pushing. # https://github.com/jj-vcs/jj/discussions/5568#discussioncomment-14289564 to = ['util', 'exec', '--', 'sh', '-c', ''' set -eux bookmark=$1 commit=${2-} # default to latest non-ephemeral commit if [ -z "$commit" ]; then commit=$(jj log --no-graph -T change_id -r '@ ~ ephemeral') if [ -n "$commit" ]; then # Moving current commit, create a new one to preserve # current position in the commit DAG jj new else commit=@- fi fi jj rebase -r "$commit" -A "$bookmark" jj bookmark move -f "$bookmark" -t "$bookmark+" ''', 'jj-to'] [revsets] log = "@ | bases | branches | curbranch::@ | @::nextbranch | downstream(@, branchesandheads)" [revset-aliases] # Authored or committed by specified user 'user(x)' = 'author(x) | committer(x)' 'closest_tip()' = 'heads(::@ & remote_bookmarks())' # Those who would be abandoned if you check out something else ephemeral = 'description(exact:"") & empty()' # show everything in the current set of branches off of trunk(): branch = '(coalesce(trunk(),root())..@)- | (coalesce(trunk(),root())..@)::' # radicle 'closest_bookmark(to)' = 'heads(::to & bookmarks())' 'closest_pushable(to)' = 'heads(::to & mutable() & ~description(exact:"") & (~empty() | merges()))' "desc(x)" = "description(x)" "pending()" = ".. ~ ::tags() ~ ::remote_bookmarks() ~ @ ~ private()" "private()" = "description(glob:'wip:*') | description(glob:'private:*') | description(glob:'WIP:*') | description(glob:'PRIVATE:*') | conflicts() | (empty() ~ merges()) | description('substring-i:\"DO NOT MAIL\"')" #"trunk()" = "main@rad" #"immutable_heads()" = "tags()" "immutable_heads()" = "present(trunk()) | tags() | ( untracked_remote_bookmarks() ~ untracked_remote_bookmarks(remote='rad') ~ untracked_remote_bookmarks(regex:'^patch(es)/',remote='rad'))" #'default()' = 'coalesce(trunk(), root())::present(@) | ancestors(visible_heads(), 2)' # dev 'bases' = 'present(main@rad) | present(master@origin) | present(main@origin)' 'downstream(x,y)' = '(x::y) & y' 'branches' = 'downstream(trunk(), bookmarks()) & mine()' 'branchesandheads' = 'branches | (heads(trunk()::) & mine())' 'curbranch' = 'latest(branches::@- & branches)' 'nextbranch' = 'roots(@:: & branchesandheads)' 'more' = 'log | ancestors(visible_heads(), 2)' 'unmerged()' = 'bookmarks() & ~(trunk():: | trunk())' 'recent()' = 'committer_date(after:"1 months ago")' 'recent(revset)' = 'revset & recent()' # 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()::' [template-aliases] # Hide unnecessary bits to make the jj log more concise #'format_short_change_id(id)' = 'id.shortest(4)' #'format_short_commit_id(id)' = 'id.shortest(4)' 'format_timestamp(timestamp)' = 'timestamp.ago()' #'format_short_signature(signature)' = 'signature.email()' # Both name and email address #'format_short_signature(signature)' = 'signature' # Username part of the email address #'format_short_signature(signature)' = 'signature.email().local()' 'format_short_signature(signature)' = 'signature.name()' [git] write-change-id-header = true # Prevent pushing work in progress or anything explicitly labeled "private" private-commits = "description(glob:'wip:*') | description(glob:'private:*')" # Don't require --allow-new when pushing a new bookmark push-new-bookmarks = true fetch = ["origin", "rad"] push = "origin" [user] name = "Julien Moutinho" email = "julm@sourcephile.fr" [ui] paginate = "auto" default-command = "log" diff-editor = ":builtin" # From https://github.com/julienvincent/hunk.nvim #diff-editor = ["nvim", "-c", "DiffEditor $left $right $output"] [merge-tools.diffconflicts] program = "nvim" merge-args = [ "-c", "let g:jj_diffconflicts_marker_length=$marker_length", "-c", "JJDiffConflicts!", "$output", "$base", "$left", "$right", ] merge-tool-edits-conflict-markers = true # # via @dubi steinkek in the jj discord # [merge-tools.gitpatch] # program = "sh" # edit-args = ["-c", ''' # set -eu # rm -f "$right/JJ-INSTRUCTIONS" # git -C "$left" init -q # git -C "$left" add -A # git -C "$left" commit -q -m baseline --allow-empty # mv "$left/.git" "$right" # git -C "$right" add --intent-to-add --ignore-removal . # tell git to include new files in interactive patch mode # git -C "$right" add -p # git -C "$right" diff-index --quiet --cached HEAD && { echo "No changes done, aborting split."; exit 1; } # git -C "$right" commit -q -m split # git -C "$right" reset -q --hard # undo changes in modified files, remove added files # ''', # ] # merge-args = ["-c", "echo gitpatch cannot be used as a diff tool"] # diff-args = ["-c", "echo gitpatch cannot be used as a diff tool"]