7 ms·
Jjui – A Nice TUI for Jujutsu
- skeptrune 1y agoHardcore embodies building tools that make you happy. I'm personally fine with git, but it's inspiring to see so many people willing to experiment and build an ecosystem around a new VCS.
- anticodon 1y agoMy only and biggest pain point with Git is that it requires a lot of manual merging even in a small project. You have several branches that are several weeks/months old and they touch the same set of files. Eventually, when they'll be approved for merging, you'll have to manually resolve lots of conflicts in all of them, and do that repeatedly. rerere is supposed to at least save you from repeating repeating same merges in every branch you rebase, but in my experience it never helps. Unfortunately, as far as I understand, jj won't help with issue of unnecessary manual merges either.
- cube2222 1y agoMerges / conflict resolution in jj generally work much better than in git. When rebasing a big branch in git with conflicts, you usually end up having to manually resolve conflicts in multiple commits in a row - in jj you just have to resolve the conflict in the first conflicted change, and it usually adapts subsequent changes automatically. Overall, rebasing branches with conflicts used to be a chore for me with git, and is now mostly a nothing-burger. Of course, I don't know the exact details of your scenario, so I'm not sure if it'd help, but I'd say it's worth trying, esp. if it's a common pain-point for you.
- cowsandmilk 1y agoIs this the case even with rerere in git?
- mtndew4brkfst 1y agoMy anecdotal experience is that I indirectly need/benefit from rerere much less often because I'm not usually resolving the same specific conflict more than once. I fix it the one time and then jj is rebasing a whole lineage for me, starting from the early commits, not from the single-branch leaves. That way I don't get "I rebased one branch and fixed this one already, but now I have to do it again for a second branch that shared the same conflicted commit as the first." By contrast, git rebase --update-refs does not handle sibling branches but detaches them instead, and git replay hasn't had much TLC for UX yet. Plus, the last time I tried replay it was still obliterating commit signatures. https://git.github.io/htmldocs/git-replay.html https://git.github.io/htmldocs/git-replay.html
- viraptor 1y agoThis doesn't seem related to git or jj. If you have a conflict, you have a conflict. It's a social issue, not a software one. No software can resolve all code conflicts without people making final decisions. You can help the situation by automatically pinging people to refresh their old branches though.
- silvanocerza 1y agoAh, this is nice! I've been testing out Jujutsu this weekend and this will come in handy. I still need to wrap my head around the different overflow and this might make it easier.
- endtime 1y agoLooks like a nice project! Will try it out next week. In the meantime, I'll share my thoughts on jj in general, since I assume most readers here won't have tried jj. I started using jj a few months ago. I had used Fig previously when I was at Google, but then spent over 2.5 years just using git, and using jj was like riding a bike. It's more or less exactly what I want it to be and I use it as much as I can. That said, here are some of my pain points (despite all of which I do still prefer jj to git): * No GitHub PR sync for stacks. Managing stacked diffs locally is great, but (a better version of) Sapling's PR syncing would be a huge value add. This is somewhat of a pain point for me directly, but even more so a weakness when I've tried to evangelize jj internally as a viable "stacked diff" solution (e.g. to be blessed by our eng tools team). Someone familiar and comfortable with Sapling (or just skeptical of jj) can easily point to this feature gap in a way that pretty much ends the conversation. * I wish the native backend supported pushing/pulling changes. I want to be able to switch between working from my laptop and my workstation, and doing that through pushing to and pulling from GitHub is obviously lossy of jj history. Manually copying the .jj directory seems to work if I'm careful and do everything correctly (i.e. make sure both clones have equivalent working copy state when I copy .jj), but this feels brittle and it's easy to mess up. * If you forget to start a new rev before you (or your LLM) touch the repo, it's a little bit of a pain to go back and split the changes into a new rev. * Some of the more mature repos I've worked with have tooling/scripts/tests/etc. that seem to look for or rely on the presence of .git (perhaps indirectly). Perhaps I could have gotten around this with colocated repos (i.e. `git clone` and then `jj git init --colocate`), but in at least one case I just gave up on using jj for a given repo and just made a separate git clone. I'm not sure this is really jj's fault so much as a practical compatibility gap with git (again, possibly entirely solved by using `--colocate`).
- bjackman 1y ago> No GitHub PR sync for stacks FWIW, I think the fact that you need client support for this is a bizarre shortcoming of GitHub. If GitHub just let you review individual commits like Gerrit does, the concept of "PR stacking" would be unnecessary (as it is with Gerrit). The model of "a PR is just a blob of changes" is a weird baby's toy version of a code review tool IMO!
- cube2222 1y agoThis looks like a very decent TUI! I'm pretty happy with the CLI (especially since in fish it has extensive auto-complete), but if one is not content with that, this seems very nice. I've written about JJ[0] when I was starting to use it, and now, a couple months in, it's become an indispensable part of my workflow. Git really does feel clunky now (even though I never had major problems back when using it), whenever I see it used - with jj being compatible with it, fortunately I don't have to ever use it myself anymore. Historically I never cared much about my git history (and always squashed PRs) - now I find myself occasionally using empty changes with good descriptions to just write out a sort of todo-list on my branch (kinda CDD, as in Change-Driven Development :) ), and it's overall much cleaner. I've always used a ton of stashes with git for various experiments and in-progress work, now that's just normal local-only jj changes. Also solves the very unpleasant problem of rebasing stashes. If you're reading this comment section thinking about whether it's worth trying jj out, I would strongly suggest you give it a go! [0]: https://kubamartin.com/posts/introduction-to-the-jujutsu-vcs/ https://kubamartin.com/posts/introduction-to-the-jujutsu-vcs...
- ttoinou 1y agoFirst time I ever hear about CDD but I’m already loving it
- stavros 1y agoI wanted to say I love your guide, it's at just the right level of detail for someone who's familiar with git, without bogging you down with lots of small things. Thank you!
- cube2222 1y agoThanks for the kind words, appreciate it a lot! > for someone who's familiar with git, without bogging you down with lots of small things That was my goal, so I'm really glad it worked out :)
- sam_goody 1y agoNo really related, but I'm surprised that jj has no good GUI. With so much VC money chasing so many established niches (eg bun -> node), and so much potential growth for jj - especially considering it has so much dev interest, and has the advantage of not requiring lock-in [a jj repo can be converted to a regular git repo].
- arccy 1y agowell it's probably a good thing jj isn't vc funded.
- KerrAvon 1y agoyeah, it would have to be jammed to the gills with AI, sensibly or not, to be vc-funded
- dmit 1y agoThere's https://github.com/keanemind/jjk https://github.com/keanemind/jjk for VSCode users. There are also tickets to add jj support in Helix and Zed, so that's promising.
- Macha 1y agojj as effectively used is a git UI. There's an experimental self-hosted backend that nobody uses (and is disabled in release builds), and there's a piper backend in Google, which is enough that people call it a VCS of its own rather than a git UI, but there's nothing stopping some other tool building the same primitives on top of git directly without jj as an intermediate layer. As I understand it, to some extent, that is GitButler.
- ejpir 1y agogot a link to it?:)
- steveklabnik 1y agohttps://gitbutler.com/ https://gitbutler.com/
- account-5 1y agoI've still not found anything as easy and complete, feature-wise, as fossil. What is jj trying to solve over git, assuming it's more a replacement for git.
- andrewaylett 1y agoIt's not so much a git replacement, as a whole new porcelain on top of the same plumbing. JJ uses the git binary and maintains a git repository. In co-located mode, the jj working copy is a git working copy. If you use regular git tooling it might be a bit uncertain why you're in detached head mode, but all read-only tooling will work without any problems and if you write to the repo jj will do its best to absorb your manual changes cleanly.
- dmit 1y agoA small note here: even though the public version of jj only supports the Git backend right now (I believe there's also support for whatever Google's using internally?), it's designed to be backend-agnostic. So potentially, in the future it could grow its own native backend that could solve some of Git's pain points -- support for huge repositories, native large file storage, etc.
- steveklabnik 1y agoYes, Google has a backend that some people there are using.
- aseipp 1y agoTo be clear, Jujutsu is not "porcelain" in the (somewhat archaic) Git sense of "high level tools built on low level tools". We do not share any code with the git project. Jujutsu uses Git as a storage layer, i.e. the direct on disk representation. The algorithms and user interface are all completely written from scratch, on top of this. You could also write e.g. a Mercurial backend to Jujutsu and it would operate similarly, but using revlog storage vs Git's content addressed store. > JJ uses the git binary That's a relatively recent phenomenon. The git binary is used only to fetch and push objects. Previously we used libgit2. Why do this? Because replicating all of git and OpenSSH's feature support for every little random auth flow/crypto algorithm/hardware token/whatever is a battle that can't be won. It's ultimately smarter to just have an uglier interface between the two parts (invoking a command line vs using an API) to make the end-user experience significantly better. When working with Git objects, jj uses the Gitoxide rust library to natively manage the Git store and upstream Git is not used at all.
- flsaflkelfe 1y ago[dead]
- mtndew4brkfst 1y agoI was a Magit user for most of a decade and I deeply missed it when I first switched to jj. I still think something like it would be a huge boon for the community and I hope one comes to fruition eventually, but in an editor-agnostic form like matklad suggests here: https://matklad.github.io/2024/12/13/majjit-lsp.html https://matklad.github.io/2024/12/13/majjit-lsp.html With that yearning in mind, jjui is the jj TUI I like best so far having tried them all. It's snappy, has useful and intuitive keybinds and presents them well, and good stability so far. Doesn't quite seem to like it if I resize the surrounding zellij/terminal pane while it's open though. Lazyjj was a little laggy and crash-prone for me on all of the same repos, and jj-fzf is a tragic pile of bash so I can't recommend ever using that.
- dcre 1y agoBeautiful work. I tried other jj TUIs and found them clunky and counterintuitive. This one feels like they took the output of jj log and simply made it interactive. That said, I switched to jj after using GitUp https://gitup.co/ https://gitup.co/ for many years, and I was pretty surprised not to really miss it when using the jj CLI. The things I liked most about GitUp are all covered by the jj CLI pretty well: - Undo - Interactive staging (well, in jj the analogue is interactive split with jj split -i) - Feeling like you’re manipulating the DAG directly, picking this up and plopping it down over here (jj rebase) Notably, jj already builds in a TUI for the spots where interactivity is most beneficial.