6 ms·
It’s not just that it’s simpler, it’s that the primitives and interaction model are also strictly more powerful. A ton of extremely useful workflows that are an
by stouset 1y ago
It’s not just that it’s simpler, it’s that the primitives and interaction model are also strictly more powerful. A ton of extremely useful workflows that are an utter pain in the ass with git are absolutely trivial with jj.
One example is a series of dependent PRs. This is excruciating in git if you ever need to make a fix to an earlier PR because you have to manually rebase every subsequent change. It’s trivial in jj: you either fix the revision directly or you insert a new revision inbetween. The subsequent revisions are updated automatically. You don’t even have to think.
Another is splitting work into parallel branches. So often when I’m working on one area I end up making unrelated tweaks and improvements as I go. Pulling these out into their own branches is painful in git, so people just make omnibus branches that include a handful of unrelated work alongside the main task. In jj it’s basically zero work to split out the unrelated stuff onto a new branch off main, and it doesn’t require you to task-switch to a new branch. So I end up making lots of one-line PRs that are trivial to review whenever I’m doing deeper work.
- krackers 1y ago>you have to manually rebase every subsequent change What do you mean by this? You can do an interactive rebase in git as well. The real issue is non-trivial merge conflicts which is going to be an issue no matter you use.
- sunshowers 1y agogit rebase -i is a much worse experience than jj's autorebasing of descendants. For example, with git rebase -i you can't decide to do something else in the middle of the rebase — you're in that state until the rebase is completed or abandoned. Merge conflicts are also significantly better with jj because they don't interrupt the rest of your flow. And most importantly, the two features work together to create something greater than the sum of its parts. See my testimonial (first one) at https://jj-vcs.github.io/jj/latest/testimonials/#what-the-users-have-to-say https://jj-vcs.github.io/jj/latest/testimonials/#what-the-us...
- packetlost 1y ago> with git rebase -i you can't decide to do something else in the middle of the rebase You absolutely can, to some degree. At any point in an interactive rebase you can just make your changes and do a normal `git commit` then do `git rebase --continue` along on your merry way. Unless you're talking about suspending the rebase and like switching branches, messing around, and then resuming the rebase, which is kind of a weird thing to do.
- sunshowers 1y agoI do mean suspending the rebase and going to do something else, yes. It's a weird thing to do in git, because the conditions that git creates makes it weird. It is completely natural with jj, because jj doesn't have any modal states at all. (This is one of the key reasons jj is both simpler and more powerful than git — no modal states.)
- frizlab 1y agoModal states are actually good IMHO.
- sunshowers 1y agoI feel like I just outlined a situation where something that's weird in git is completely natural in jj. Maybe I miscommunicated?
- frizlab 1y agoI think you communicated well, probably I did not. > suspending the rebase and going to do something else This is what I find to be weird, personally. When doing a rebase, there’s no way I want to do something else in the middle of it, and having a modal state feels totally natural to me. At first approach (I read a (very good) intro[1]; I did not try), it seems there’s a lot of new things to learn (for instance the revsets language), for a very minimal gain, so I’m (still) gonna pass on it. It feels like jj is solving a lot of problems that do not exist, or are mostly solved with worktrees. That being said it’s true that everybody’s way of working is different, so I don’t know! Maybe jj will be picked up by the younger generation and it will become the new de facto standard. Time will tell… Personally, the current VCS tool I’d like to try now instead of jj is fossil. It seems much more interesting as it promises to allow bypassing GitHub/other forge completely by being the full forge itself. In these days, having ownership of one’s data feels primordial to me. [1] https://ofcr.se/jujutsu-merge-workflow https://ofcr.se/jujutsu-merge-workflow
- stouset 1y agoLet's say I have five commits in a row ready to go, but they should be reviewed and merged one-by-one. Upon review, I need to make a change to the first commit. How much work do you think this would be in git? How much of a pain in the ass do you think it would be if a later change conflicted with this earlier change? It is essentially zero work in jj. I `jj edit` the revision in question, make the change, and `jj push`.
- packetlost 1y agoIt's really not a lot at all. The weakness is in "forge" tools like GitHub that add a PR/changelist abstraction on top of git and don't support sequences of patches. If you're using just commits and maybe (mailed) patches you only do a single `git rebase` (with -i if you want) and you're done. Unless jj is literally magic and can automatically fix conflicts, I can't see how it would actually reduce the work involved in a meaningful way.
- plandis 1y agoAs far as I know, by default Git doesn’t enable the “reuse recorded resolution” feature so if you made a change to the first commit you’d have to manually do the same thing for any subsequent commits.
- packetlost 1y agoIf you have 5 different branches, sure. Again, the reason you create a bunch of branches for separate review is because that's what the "git forge" abstraction generally expects. It's not actually how code reviews are done by the people who wrote it. You can also just enable that feature (rerere).
- wredcoll 1y agoWhat is the "right" way to do it then? Also probably most of us are stuck with whatever git*.com supports anyways...
- deredede 1y ago> This is excruciating in git if you ever need to make a fix to an earlier PR because you have to manually rebase every subsequent change. Spreading the word about `git rebase --update-refs` that will automatically update any branches that point to commits along the path (very useful with stacked branches). It is less convenient than what jujutsu offers (you need to know the branches to update, where jujutsu automatically updates any dependency), but still a very useful if you don't want to or can't switch to another tool.
- nchmy 1y agoThere isn't really any "can't switch to another tool" when it comes to git + jj. You can use it today without anyone on your team knowing - other than that your PRs suddenly became much cleaner
- 1718627440 1y ago> The subsequent revisions are updated automatically How do you make sure, that a commit isn't changed under you, because someone thought, it would be a good idea to change an earlier revision? I think having immutable commits including all the previous history is a feature, not a bug.
- nchmy 1y agoJj treats any public/pushed commits/branches as immutable by default.
- 1718627440 1y agoHow does it know that? Does it also work, when I clone or pull instead? Is that only enforced on the committer side? I mean git also doesn't force push by default, but that still means someone else can do that and I need to notice it.
- nchmy 1y agoI don't have answers for you. But the docs are useful and people in their discord are helpful as well
- stouset 1y agoThere is a way to express which sets of revisions are immutable. This uses the revset feature which itself a whole amazing thing that hasn’t come up in the conversation yet. This is a mechanism by which you can concisely express and refer to entire sets of commits in your repo history, and lots of commands can operate on multiple revisions as easily as they can operate on one. Just like git, it is only enforced by the tool itself on the client side. But it’s safer in practice because `git push -f` is a common habit when you’re working on a branch by yourself and it’s easy to fat-finger that in the wrong place. I have only ever had to use `jj --ignore-immutable` when explicitly doing repo surgery. If you want branches like `main` to be truly immutable, you need to enforce that at the repo.
- MrJohz 1y ago