https://github.com/acarapetis/jj-pre-push
Run pre-commit.com before `jj git push`
https://github.com/acarapetis/jj-pre-push
git jj jujutsu pre-commit vcs
Last synced: 2 months ago
JSON representation
Run pre-commit.com before `jj git push`
- Host: GitHub
- URL: https://github.com/acarapetis/jj-pre-push
- Owner: acarapetis
- License: apache-2.0
- Created: 2025-07-24T10:54:29.000Z (4 months ago)
- Default Branch: main
- Last Pushed: 2025-08-05T23:56:52.000Z (3 months ago)
- Last Synced: 2025-09-06T09:53:27.285Z (2 months ago)
- Topics: git, jj, jujutsu, pre-commit, vcs
- Language: Python
- Homepage:
- Size: 30.3 KB
- Stars: 15
- Watchers: 1
- Forks: 1
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# jj-pre-push
[](https://pypi.org/project/jj-pre-push/)
A _very limited_ integration between [jj](https://jj-vcs.github.io) and
[pre-commit](https://pre-commit.com/) allowing you to run your pre-push hooks in a
colocated jj/git repository.
I don't expect this to last forever, it's just a stopgap until some jj-native mechanism
arrives that can take over.
Prior art:
-
- Various comments on
## Usage
Use `jj-pre-push push` (or an alias - personally I use `jj push`) as a replacement for
`jj git push`. It takes all the same arguments, and does the following:
1. Determines which bookmarks the corresponding `jj git push` will update on the remote,
and how they would change.
2. For each of these bookmarks in turn:
- Checks out the bookmark to the working copy
- Runs the pre-push hooks defined in your .pre-commit-config.yaml on the same set of
files pre-commit would when pushing the same change. (For existing branches that's
the files touched in the range `old`...`new`; for new branches it's the files
touched in all ancestors of `new` that aren't present on the remote.)
- Reports any failures; and if any files were modified reports the change ID(s) in which
these modifications can be found.
3. If all hooks succeeded on all branches, executes `jj git push` with the arguments
provided; otherwise nothing is pushed.
4. Returns the working copy to its original change.
If there is no .pre-commit-config.yaml in your workspace root, `jj-pre-push push`
immediately delegates to `jj git push`.
By default `jj-pre-push` produces no console output of its own unless hooks fail. If
you'd like to see more details about what's happening, you can use `jj-pre-push
--log-level=INFO push`.
## Installation
If you have [uv](https://docs.astral.sh/uv/) installed and you're planning to use an
alias anyway, you can avoid explicitly installing at all with `uvx`, e.g. with this jj
configuration for `jj push`:
```toml
[aliases]
push = ["util", "exec", "--", "uvx", "jj-pre-push", "push"]
```
Otherwise, install the PyPI package `jj-pre-push` in whichever way you prefer; e.g. `uv tool
install jj-pre-push` or `pip install jj-pre-push`, and use `jj-pre-push push` as
described earlier.
## Usage with jjui
If you're a [jjui](https://github.com/idursun/jjui) fan (I think maybe you should be!),
here's an example `jjui/config.toml` snippet showing how you can define custom commands
to invoke jj-pre-push: one to perform the default `jj push`, and one to push the
bookmarks attached to the change you have currently selected in the UI.
```toml
[custom_commands]
"jj push" = { key = ["p"], args = ["push"] }
"jj push selected bookmark(s)" = { key = ["P"], args = ["push", "-r", "$change_id"] }
```
Note that these depend upon the `jj push` alias defined in the previous section.