]> Git — Sourcephile - julm/julm-nix.git/blob - home-manager/profiles/jujutsu/jj/config.toml
use/op(jjui): fix keys.squash.interactive
[julm/julm-nix.git] / home-manager / profiles / jujutsu / jj / config.toml
1 [signing]
2 behavior = "own"
3 backend = "gpg"
4 key = "A58CD81C3863926F"
5
6 [fsmonitor]
7 backend = "watchman"
8 fsmonitor.watchman.register-snapshot-trigger = true
9
10 [snapshot]
11 max-new-file-size = "2MiB"
12 auto-update-stale = true
13
14 [aliases]
15 a = ["absorb"]
16 dlog = ["log", "-r"]
17 l = ["log", "-r", "(trunk()..@):: | (trunk()..@)-"]
18 #l = ["log", "-r", "more()"]
19 fresh = ["new", "trunk()"]
20 # Figures out the closest bookmark
21 # and pulls it up to the latest change that can be pushed.
22 tug = [
23 "bookmark",
24 "move",
25 "--from",
26 "closest_bookmark(@)",
27 "--to",
28 "closest_pushable(@)",
29 ]
30 bl = ["bookmark", "list"]
31 blr = ["bookmark", "list", "--revisions", "recent()"]
32 c = ["commit"]
33 ci = ["commit", "--interactive"] # commit interactive
34 m = ["describe"]
35 mm = ["describe", "--message"]
36 d = ["diff", "--stat", "--revisions"]
37 dd = ["diff", "--revisions"]
38 files = ["diff", "--name-only", "--revisions"]
39 review-files = ["diff", "--name-only", "--revisions", "review()"]
40 dp = ["describe", "@-"] # describe previous
41 e = ["edit"]
42 para = [ "parallelize", "closest_tip()..@-" ]
43 patch = ["show", "--git", "--template", "git_format_patch_email_headers"]
44 pull = ["git", "fetch"]
45 push = ["git", "push"]
46 gf = ["git", "fetch"] # git fetchq
47 gi = ["git", "init", "--colocate"]
48 gp = ["git", "push"] # git push
49 i = ["git", "init", "--colocate"]
50 nb = ["bookmark", "create", "-r @-"] # new bookmark (for creating bookmark to push)
51 nc = ["new", "-B", "@", "--no-edit"] # new change before
52 r = ["rebase"]
53 rm = ["rebase", "-d", "main"] # "re-main"
54 s = ["show", "--stat"]
55 ss = ["show"]
56 sq = ["squash"]
57 sqi = ["squash", "--interactive"]
58 si = ["squash", "--interactive"]
59 sp = ["show", "@-"]
60 up = ["util", "exec", "--", "sh", "-c", """
61 if [ $# == 0 ]; then
62 jj bookmark move --from "closest_bookmark(@)" --to "closest_pushable(@)"
63 else
64 jj bookmark move --to "closest_pushable(@)" "$@"
65 fi
66 """, ""]
67 upp = ["util", "exec", "--", "sh", "-c", "jj up && jj git push", ""]
68
69 track-github-PR = ["util", "exec", "--", 'sh', '-euxc', '''
70 PR=$1
71 gh pr view --json headRepository,headRefName,headRepositoryOwner $PR --jq '"
72 set_remote() {
73 jj 2>/dev/null git remote add \"$1\" \"$2\" ||
74 jj git remote set-url \"$1\" \"$2\"
75 }
76 set_remote \(.headRepositoryOwner.login) git@github.com:\(.headRepositoryOwner.login)/\(.headRepository.name)
77 jj git fetch --remote \(.headRepositoryOwner.login) --branch \(.headRefName)
78 jj bookmark track --remote=\(.headRepositoryOwner.login) \(.headRefName)
79 origin=$(gh repo view --json owner,name --jq .owner.login)
80 set_remote \"$origin\" \"$(gh repo view --json sshUrl --jq .sshUrl)\"
81 git fetch --force --update-head-ok \"$origin\" \"refs/pull/'"$PR"'/head:refs/remotes/$origin/pull/'"$PR"'\"
82 "' |
83 sh -euxs
84 ''', "jj-track-github-PR"]
85
86 untrack-github-PR = ["util", "exec", "--", 'sh', '-euxc', '''
87 PR=$1
88 gh pr view --json headRepository,headRefName,headRepositoryOwner $PR --jq '"
89 jj bookmark forget \(.headRefName) || true
90 origin=$(gh repo view --json owner,name --jq .owner.login)
91 git for-each-ref --format \"delete %(refname)\" \\
92 \"refs/remotes/\(.headRepositoryOwner.login)/\(.headRefName)\" \\
93 \"refs/remotes/$origin/pull/'"$PR"'\" |
94 tee /dev/stderr |
95 git update-ref --stdin
96 "' |
97 sh -euxs
98 ''', "jj-untrack-github-PR"]
99
100 # Get all open stacks of work.
101 open = ["log", "-r", "open()"]
102
103 # Better name, IMO.
104 credit = ["file", "annotate"]
105
106 # Retrunk a series. Typically used as `jj retrunk -s ...`, and notably can be
107 # used with open:
108 # - jj retrunk -s 'all:roots(open())'
109 retrunk = ["rebase", "-d", "trunk()"]
110
111 # Retrunk the current stack of work.
112 reheat = ["rebase", "-d", "trunk()", "-s", "all:roots(trunk()..stack(@))"]
113
114 # Take content from any change, and move it into @.
115 # - jj consume xyz path/to/file`
116 consume = ["squash", "--into", "@", "--from"]
117
118 # Eject content from @ into any other change.
119 # - jj eject xyz --interactive
120 eject = ["squash", "--from", "@", "--into"]
121
122
123 # All operations
124 o = ["op", "log"]
125 # All operations, with more whitespace
126 oo = ["op", "log", "-T", "builtin_op_log_comfortable"]
127
128 abandon-empties = ["abandon", "-r", "description(exact:'') ~ root()"]
129
130 # Move $commit just after the bookmark, and then move $bookmark on top of it.
131 #
132 # "$bookmark+" works, because after rebase -A, the only child of $bookmark is $commit.
133 # I do not use $commit itself because it might point to a
134 # different commit after the rebase (e.g. @-).
135 #
136 # My workflow uses mega-merge: I write a commit or two,
137 # and then move them to relevant branches with jj to.
138 # As a bonus, bookmarks are kept up-to-date for easy pushing.
139 # https://github.com/jj-vcs/jj/discussions/5568#discussioncomment-14289564
140 to = ['util', 'exec', '--', 'sh', '-c', '''
141 set -eux
142
143 bookmark=$1
144 commit=${2-}
145
146 # default to latest non-ephemeral commit
147 if [ -z "$commit" ]; then
148 commit=$(jj log --no-graph -T change_id -r '@ ~ ephemeral')
149 if [ -n "$commit" ]; then
150 # Moving current commit, create a new one to preserve
151 # current position in the commit DAG
152 jj new
153 else
154 commit=@-
155 fi
156 fi
157
158 jj rebase -r "$commit" -A "$bookmark"
159 jj bookmark move -f "$bookmark" -t "$bookmark+"
160 ''', 'jj-to']
161
162 [revsets]
163 log = "default()"
164
165 [revset-aliases]
166 # Focus current commit, trunk(), on local work and remote work by removing ancestors of trunk()
167 "default()" = "@ | trunk() | ancestors_and_children(bookmarks() | tracked_remote_bookmarks()) ~ ..trunk()"
168
169 "active(rev)" = "(ancestors(rev) | descendants(rev)) ~ immutable()"
170 "ancestors_and_children(x)" = "..x | x::"
171
172 # Remote commits not merged in trunk()
173 "review()" = "ancestors_and_children(@) ~ ..trunk()"
174 "review(x)" = "ancestors_and_children(remote_bookmarks(x)) ~ ..trunk()"
175 "reviews()" = "ancestors_and_children(remote_bookmarks()) ~ ..trunk()"
176
177 #
178 "wip()" = "ancestors_and_children(bookmarks()) ~ ..(remote_bookmarks() | trunk())"
179 "wip(x)" = "trunk() | ..bookmarks(x) ~ ..(remote_bookmarks() | trunk())"
180
181
182 # Authored or committed by specified user
183 'user(x)' = 'author(x) | committer(x)'
184
185 'closest_tip()' = 'heads(::@ & remote_bookmarks())'
186
187 # Those who would be abandoned if you check out something else
188 ephemeral = '(empty() ~ merges() ~ root()) & description(exact:"")'
189
190 # show everything in the current set of branches off of trunk():
191 branch = '(coalesce(trunk(),root())..@)- | (coalesce(trunk(),root())..@)::'
192
193 # radicle
194 'closest_bookmark(to)' = 'heads(::to & bookmarks())'
195 'closest_pushable(to)' = 'heads(::to & mutable() & ~description(exact:"") & (~empty() | merges()))'
196
197 "desc(x)" = "description(x)"
198 "pending()" = ".. ~ ::tags() ~ ::remote_bookmarks() ~ @ ~ private()"
199 "private()" = "description(glob:'wip:*') | description(glob:'private:*') | description(glob:'WIP:*') | description(glob:'PRIVATE:*') | conflicts() | (empty() ~ merges()) | description('substring-i:\"DO NOT MAIL\"')"
200 #"trunk()" = "main@rad"
201 #"immutable_heads()" = "tags()"
202 "immutable_heads()" = "present(trunk()) | tags() | ( untracked_remote_bookmarks() ~ untracked_remote_bookmarks(remote=glob:'rad') ~ untracked_remote_bookmarks(regex:'^patch(es)/',remote=glob:'rad'))"
203 #'default()' = 'coalesce(trunk(), root())::present(@) | ancestors(visible_heads(), 2)'
204
205 # dev
206 'bases' = 'present(main@rad) | present(master@origin) | present(main@origin)'
207 'downstream(x,y)' = '(x::y) & y'
208 'branches' = 'downstream(trunk(), bookmarks()) & mine()'
209 'branchesandheads' = 'branches | (heads(trunk()::) & mine())'
210 'curbranch' = 'latest(branches::@- & branches)'
211 'nextbranch' = 'roots(@:: & branchesandheads)'
212
213 'more' = 'log | ancestors(visible_heads(), 2)'
214 'unmerged()' = 'bookmarks() & ~(trunk():: | trunk())'
215 'recent()' = 'committer_date(after:"1 months ago")'
216 'recent(revset)' = 'revset & recent()'
217
218
219 # stack(x, n) is the set of mutable commits reachable from 'x', with 'n'
220 # parents. 'n' is often useful to customize the display and return set for
221 # certain operations. 'x' can be used to target the set of 'roots' to traverse,
222 # e.g. @ is the current stack.
223 'stack()' = 'ancestors(reachable(@, mutable()), 2)'
224 'stack(x)' = 'ancestors(reachable(x, mutable()), 2)'
225 'stack(x, n)' = 'ancestors(reachable(x, mutable()), n)'
226
227 # The current set of "open" works. It is defined as:
228 #
229 # - given the set of commits not in trunk, that are written by me,
230 # - calculate the given stack() for each of those commits
231 #
232 # n = 1, meaning that nothing from `trunk()` is included, so all resulting
233 # commits are mutable by definition.
234 'open()' = 'stack(trunk().. & mine(), 1)'
235
236 # the set of 'ready()' commits. defined as the set of open commits, but nothing
237 # that is blacklisted or any of their children.
238 #
239 # often used with gerrit, which you can use to submit whole stacks at once:
240 #
241 # - jj gerrit send -r 'ready()' --dry-run
242 'ready()' = 'open() ~ blacklist()::'
243
244 [template-aliases]
245 # Hide unnecessary bits to make the jj log more concise
246 #'format_short_change_id(id)' = 'id.shortest(4)'
247 #'format_short_commit_id(id)' = 'id.shortest(4)'
248 'format_timestamp(timestamp)' = 'timestamp.ago()'
249
250 #'format_short_signature(signature)' = 'signature.email()'
251 # Both name and email address
252 #'format_short_signature(signature)' = 'signature'
253 # Username part of the email address
254 #'format_short_signature(signature)' = 'signature.email().local()'
255 'format_short_signature(signature)' = 'signature.name()'
256
257 [git]
258 write-change-id-header = true
259 # Prevent pushing work in progress or anything explicitly labeled "private"
260 private-commits = "description(glob:'wip:*') | description(glob:'private:*')"
261 # Don't require --allow-new when pushing a new bookmark
262 fetch = ["origin", "rad"]
263 push = "origin"
264
265 [remotes]
266 origin.auto-track-bookmarks = 'glob:*'
267 ju1m.auto-track-bookmarks = 'glob:*'
268
269 [user]
270 name = "Julien Moutinho"
271 email = "julm@sourcephile.fr"
272
273 [ui]
274 paginate = "auto"
275 default-command = "log"
276 diff-editor = ":builtin"
277 # From https://github.com/julienvincent/hunk.nvim
278 #diff-editor = ["nvim", "-c", "DiffEditor $left $right $output"]
279 show-cryptographic-signatures = true
280
281 [merge-tools.diffconflicts]
282 program = "nvim"
283 merge-args = [
284 "-c", "let g:jj_diffconflicts_marker_length=$marker_length",
285 "-c", "JJDiffConflicts!", "$output", "$base", "$left", "$right",
286 ]
287 merge-tool-edits-conflict-markers = true
288
289 # # via @dubi steinkek in the jj discord
290 # [merge-tools.gitpatch]
291 # program = "sh"
292 # edit-args = ["-c", '''
293 # set -eu
294 # rm -f "$right/JJ-INSTRUCTIONS"
295 # git -C "$left" init -q
296 # git -C "$left" add -A
297 # git -C "$left" commit -q -m baseline --allow-empty
298 # mv "$left/.git" "$right"
299 # git -C "$right" add --intent-to-add --ignore-removal . # tell git to include new files in interactive patch mode
300 # git -C "$right" add -p
301 # git -C "$right" diff-index --quiet --cached HEAD && { echo "No changes done, aborting split."; exit 1; }
302 # git -C "$right" commit -q -m split
303 # git -C "$right" reset -q --hard # undo changes in modified files, remove added files
304 # ''',
305 # ]
306 # merge-args = ["-c", "echo gitpatch cannot be used as a diff tool"]
307 # diff-args = ["-c", "echo gitpatch cannot be used as a diff tool"]