Jj Vs Git Habit

This is an LLM ass-isted document,
as are all in this subdirectory.

The setup in JjFirstTime makes jj git push work by itself — until fingers win and bare git commit runs instead. That happened here, twice, and the next push answered:

Warning: No bookmarks/tags found in the default push revset:
remote_bookmarks(remote=origin)..@
Nothing changed.

Same warning as before that setup, different disease: then the bookmark merely lagged one commit; now it was stranded six behind.

1. What bare Git actually did

In a colocated workspace jj keeps .git/HEAD detached, at the working-copy commit's parent1. Bare git commit therefore commits onto that detached head: no branch moves, the commits land outside master, and the next jj command swallows them as an import git head operation and stacks @ on top2. Three tells in the log:

  • jj op log shows the import git head entry, timed between the last push and the new commits;
  • the new commits carry the Git-config identity, not the jj one;
  • master sits far behind @, not exactly one behind.

The last one is the lasting damage: experimental-advance-branches only advances a bookmark standing at @-3, and after the import master no longer stands there. Every further jj commit widens the gap instead of closing it. Nothing is lost — the imported commits are ordinary ancestors of @ — they are simply unpushed, because a push only carries bookmarks inside remote_bookmarks(remote=origin)..@4.

2. The repair

jj bookmark set master -r @-            # forward move, no flag needed
jj git push --allow-empty-description   # empty messages are fine by preference

Push would otherwise refuse the undescribed commits on the way; describing or squashing them (see JjFirstTime, Caveats) is the alternative, not a must — and the flag itself can be aliased away (3).

@ is the living commit: not a pointer to one, the way Git's HEAD is — it is the working copy, as a commit. Exactly one exists per workspace, always; jj commit creates nothing, it finishes the commit being lived in (describes it, seals it) and spawns a fresh empty @ on top. Every jj command snapshots the files into @ first, so an "uncommitted change" cannot exist — only a commit still being edited. Identity is fluid (the change id survives each rewrite, the commit id does not), contents are not: every rewrite lands in jj op log. Hence @-: the last real commit. Sealing it is also the one instant experimental-advance-branches ever acts in, moving the bookmark from @- onto the commit being sealed — which is why, once master was stranded behind, no later jj commit could set it off: the moment had passed with the import.

3. Sparing the flag

There is no setting for --allow-empty-description; the opt-in is a flag only, not a config key5. The jj mechanism is an alias, and repo scope carries it — verified here by shadowing jj push with a bogus flag and watching jj git push receive it:

jj config set --repo aliases.push '["git", "push", "--allow-empty-description"]'

A bare jj push now pushes the empty messages; the explicit jj git push stays strict. Drop --repo to have it everywhere. Same caveat as the advance-branches setup: repo scope is per working copy, not committed to Git.

4. The habit

Colocation invites the relapse — every Git command keeps working, which is both its point and its trap6. What people do:

  • Starve the reflex. jj answers the read commands, jj commit -i replaces git commit -p, and the jj git surface is only fetch, push, clone. Making jj log the home screen leaves nothing to type git for7.
  • Make the accident cheap. A Git write surfaces in jj op log as an import git head / import git refs operation and is undone by jj undo or jj op restore2.
  • Or remove the option. jj git colocation disable hides the Git repository inside .jj/, after which bare Git commands stop working in the workspace altogether8. Training wheels off, by force.

TL;DR: jj bookmark set master -r @-.

October, 2026.

Footnotes:

1

Jujutsu documentation, Git compatibility, https://docs.jj-vcs.dev/latest/git-compatibility: a colocated workspace keeps Git's HEAD at the working-copy commit's parent. An r/git commenter calls the detached head "irrelevant in jj", just "the closest representation in git of what's happening", https://www.reddit.com/r/git/comments/1gx4j0w/friendly_reminder_to_try_out_jujutsu.

2

Same documentation page: interleaving jj and git commands raises the chance of branch conflicts and divergent change ids; Git-side changes appear in jj op log as import git refs operations and can be undone with jj undo / jj op restore.

3

Maintainer clarification in jj-vcs/jj discussion #3549, Feedback for the experimental advance-branches feature, https://github.com/jj-vcs/jj/discussions/3549; recorded in JjFirstTime.

4

Steve Klabnik, Steve's Jujutsu Tutorial — Responding to pull request feedback, https://steveklabnik.github.io/jujutsu-tutorial/sharing-code/updating-prs.html: jj new moves no bookmarks, so the push does nothing until jj bookmark set; jj-vcs/jj discussion #7363, How to fix "No bookmarks found in the default push revset", https://github.com/jj-vcs/jj/discussions/7363; and the jj bookmark set master -r @- ritual in renerocks.ai, Jujutsu (version control) - one week in, https://renerocks.ai/blog/jj-one-week-in.

5

No key for it in the configuration schema at v0.45.1, https://github.com/jj-vcs/jj/blob/v0.45.1/cli/src/config-schema.json, nor in the CLI reference, https://docs.jj-vcs.dev/latest/cli-reference; aliases (including arguments) are the sanctioned mechanism, Configuration, https://docs.jj-vcs.dev/latest/config.

6

zerowidth, What I've learned from jj, https://zerowidth.com/2025/what-ive-learned-from-jj: colocated mode keeps all Git commands working as training wheels, and rm -r .jj undoes jj wholesale.

7

Greg Hurrell, Jujutsu cheatsheet, https://wincent.dev/wiki/Jujutsu_cheatsheet: mixing git commit -p with jj git import bred orphan snapshots — "I should have been using jj ci -i instead"; and brtkwr.com, jj for Git Users, https://brtkwr.com/posts/2026-03-08-jj-for-git-users: don't force Git muscle memory, jj log is the home screen.

8

Jujutsu documentation, CLI reference, https://docs.jj-vcs.dev/latest/cli-reference, on jj git colocation disable and --no-colocate, which prevent "Git tools that are unaware of jj and regular Git commands from operating on the repo".