- History you haven't pushed yet, or
- Bookmarks that you're tracking (meaning you're actively working on these branches), except "main"
History behind "main" or behind any untracked remote bookmark is immutable by default.
If you want to move "main" or any remote bookmark to a commit that isn't a descendant, you have to use `--allow-backwards`. If you want to edit one of these commits, you can use `--ignore-immutable`. Using either of these options is like a `push -f` in git terminology.
You don't have to pass an explicit --force, nor an explicit lease-related argument. As you say, rewriting the commits underlying changes happens frequently, so this would otherwise be pretty annoying.
There's also `jj git push --dry-run` to preview which branches would be updated in what way.
By default that’s only the main branch and untracked remote branches. For me that makes sense as I’m generally fine with constantly rewriting my feature branches.
However, if you want it to e.g. block you from rewriting anything that you’ve already pushed to the remote, you can set it to treat anything that’s pushed to the remote as immutable, too, as another commenter described [0].
The operation log makes jj quite safe. There's a command to restore the entire working copy + history to an earlier state in case you screw something up. Even this operation log is itself versioned, so you can undo the undo if you screwed the undo up, ad infinitum. :)
`jj git push` does an equivalent to `--force-with-lease`, so if there are remote commits that are later than what your current bookmark points to, it won't overwrite them. You can `jj git fetch`, it'll update your bookmark, and you can choose to put your new commits onto the updated sequence of commits wherever they belong.