WIP and private commits
Sometimes I do not know what I am building yet.
I still commit.
Not because the work is done, but because I want to make the idea durable. Once it is a commit, I can move it, compare it, abandon it, rebase it, or come back to it later.
jj diff
jj commit -m "wip: try stacked push flow"
If the work is not meant for review, I mark it more clearly:
jj commit -m "private: notes from debugging auth callback"
Private does not mean secret
private: is just a label in my commit message. It helps me search and remember intent. It is not access control, and I do not put secrets there.
Keep private commits off the remote
Once I started using private: as a real parking lot, I wanted one extra guardrail: if I ever try to push those commits, jj should refuse.
This config does that:
[git]
private-commits = "subject('private:*')"
With that set, jj git push refuses to push commits whose subject matches private:*. It also refuses to push descendants that would require pushing the private commit.
The command-line form is:
jj config set --user git.private-commits "'''subject('private:*')'''"
The nested quotes are only there so the revset quotes survive the shell.
I leave wip: pushable because sometimes the whole point of a WIP commit is to get CI or a teammate’s eyes on it. private: is the stronger word in my vocabulary.
Find the messy stuff later
Because I use a prefix, I can search for these commits later:
jj log -r 'subject("wip:*")'
jj log -r 'subject("private:*")'
That searches all visible history, so it can return old commits from other people too.
Most of the time I only want WIP commits in my current stack. For that, I intersect the subject search with trunk()..@:
jj log -r 'subject("wip:*") & trunk()..@'
jj log -r 'subject("private:*") & trunk()..@'
In my config, those stack-scoped searches are:
jj wip
jj private
Direction matters
trunk()..@ means commits reachable from my current working copy that are not already in trunk. @..trunk() is the opposite direction and is usually not what I want for "my current work".
Promote it when it becomes real
At some point a WIP commit becomes real.
When I write <change> below, I usually copy the short change id from jj log.
First I rename it:
jj describe -r <change>
or directly:
jj describe -r <change> -m "docs: explain private commit workflow"
Then I move it where it belongs.
If it should sit on top of main:
jj rebase -r <change> -o main
If it should become part of an existing stack:
jj rebase -r <change> -o <bookmark>
If it is a stack of WIP commits:
jj rebase -s <first-wip-change> -o <bookmark>
Then I inspect it:
jj log -r main..@
jj diff -r <change>
With my alias, the first command is:
jj stack
And push it when it is ready:
jj git push -c <change>
If the promoted work is the last completed change, I usually use:
jj git push -c @-
Why this feels good
I do not need to decide up front whether an idea is real. I can give it a cheap name, keep moving, and promote it only after it proves useful.