···1313 };
14141515 aliases = {
1616- record = ["commit"];
1717- ci = ["commit"];
1818- rci = ["squash"];
1919- lg = ["log"];
2016 tug = ["bookmark" "move" "--from" "closest_bookmark(@-)" "--to" "@-"];
2117 pull = ["git" "fetch"];
2218 push = ["git" "push"];
···2521 "--source" "roots(trunk()..mutable())"
2622 "--destination" "trunk()"
2723 ];
2424+2525+ # Put changes from `@` into another change
2626+ # Inverse of `extract`
2727+ inject = ["squash" "--from" "@" "--into"];
2828+2929+ # Fetch changes from change into `@`
3030+ # Inverse of `inject`
3131+ extract = ["squash" "--into" "@" "--form"];
3232+3333+ # 'jj sandwich xyz' to move xyz into the megamerge in parallel to everything
3434+ # else. See notes on 'megamerge()' above for how it's resolved.
3535+ sandwich = [ "rebase" "-B" "megamerge()" "-A" "trunk()" "-r"];
2836 };
29373038 revset-aliases = {
3139 "closest_bookmark(to)" = "heads(::to & bookmarks())";
4040+4141+ # stack(x, n) is the set of mutable commits reachable from 'x', with 'n'
4242+ # parents. 'n' is often useful to customize the display and return set for
4343+ # certain operations. 'x' can be used to target the set of 'roots' to traverse,
4444+ # e.g. @ is the current stack.
4545+ "stack()" = "stack(@)";
4646+ "stack(x)" = "stack(x, 2)";
4747+ "stack(x, n)" = "ancestors(reachable(x, mutable()), n)";
4848+4949+ # Find the megamerge. Mostly useful in combination with other aliases, primarily
5050+ # 'sandwich'. Normally when there's only one megamerge, sandwich works perfectly
5151+ # fine and is basically "magic". However, there are more complex cases; consider
5252+ # something like this which represents a forked repository of an upstream:
5353+ #
5454+ #
5555+ # ----> P1 ... Pn -----------\
5656+ # / \
5757+ # /---> X --\ (main) \
5858+ # B M1 --> T1 ... Tn --> M2 --> @
5959+ # \---> Y --/
6060+ #
6161+ # X and Y are typical features on top of base B, combined inside megamerge M1.
6262+ # However, we may want changes T1...Tn to go on top of M1, because (in my case)
6363+ # they're custom and will never go upstream, but are correctly published as part
6464+ # of the fork; Tn is where the main bookmark points. Finally, we have changes P1
6565+ # ... Pn which are private and should never be pushed upstream at all.
6666+ #
6767+ # In this case, sandwich will fail because 'reachable(stack(), merges())' will
6868+ # resolve to {M1, M2}, which is an invalid argument for 'rebase -B' due to not
6969+ # having an all: prefix modifier. So to handle that case, we allow the user
7070+ # to either specify the merge via literal tag "megamerge". In this case if we
7171+ # 'bookmark set megamerge -r M1' then sandwich will always work correctly.
7272+ "megamerge()" = "coalesce(present(megamerge), reachable(stack(), merges()))";
3273 };
33743475 git = {
7676+ colocate = true;
3577 write-change-id-header = true;
3678 push-new-bookmarks = true;
3779 };