Comment by jakebasile
4 months ago
I just don't have enough pain points with Git to move to something new. I don't have a problem remembering the ~5 commands I need most on any given workday. Between stashes, branches, temporary commits I later rebase, and recently worktrees, I don't lack for anything in my usage. It's universally used across both my public and corporate life, and neither does anyone need to learn a new tool to interact with my code base, nor do I need to deal with possible inconsistencies by using a different frontend on my end.
It's cool that it exists, and it's impressive that it is built on top of git itself. If you (like the author) want to use it, then more power to you. But I have yet to be convinced by any of these articles that it is worth my time to try it since nearly all of them start from a point of "if you hate Git like me, then try this thing".
If anyone has a link to an article written from the point of view of "I love or at least tolerate git and have no real issues with it, here's why I like JJ," then I'd be glad to read it.
If you've ever lived in a world of stacked commits with develop on main (i.e. not gitflow, no feature branches), combined with code review for every commit, git will soon start to aggravate you. Git doesn't make rebasing a chain or tree of commits pleasant. Git records merge resolutions and can reuse them, but it doesn't do the same thing for rebases, making them more repetitive and tedious than they should be. When you address comments on earlier commits in a chain, you need to rebase after. Git's affordances for rebasing aren't great.
And when you rebase, the commits lose their identity since commit hashes are content-addressed, despite having an identity in people's minds - a new revision of a commit under review is usually logically the same unit of change, but git doesn't have a way of expressing this.
jj, as I understand it, addresses these pains directly.
> Git doesn't make rebasing a chain or tree of commits pleasant.
There's a semi-recent addition that makes it a single command, the --update-refs flag to rebase (along with the --rebase-merges flag, formerly called --preserve-merges).
> Any branches that are checked out in a worktree are not updated in this way.
Would be nice, if it would also have a flag to choose that behaviour.
> Git records merge resolutions and can reuse them, but it doesn't do the same thing for rebases
Since when does rerere not work with rebase anymore?
I think it does but rerere is not nearly as good as first class conflicts in jj
1 reply →
FWIW git-branchless, an extension to git, addresses many of these points without leaving git.
The best thing that could come out of jujitsu is git itself adopting the change-id system (which I believe I read somewhere is being considered). If you actually take time to learn your tools and how they're intended to be used, there's really not reason to learn jj IMO
git is both a (bad) UI and a protocol. Jujutsu is a UI on top of git (the protocol).
There's nothing wrong with taking the time to learn how to use a bad UI, especially if there's no other option. But don't mistake your personal mastery of git for evidence that it's better than jj.
In all likelihood, the git proposal you allude to would not extend further than adding a bit of persistent metadata that follows commits after "destructive" changes. And even then, it'd be imperatively backing into the change-as-commit-graph data model rather than coming by it honestly.
> If you actually take time to learn your tools and how they're intended to be used, there's really not reason to learn jj IMO
This is like saying if people take the time to learn curl, there's really no reason to learn Firefox.
And it doesn't suggest to me that you're all that familiar with jj!
- automatic rebasing! goodbye to N+1 rebases forever
- first-class conflict resolution that doesn't force you to stop the world and fix
- the revset/template languages: incredibly expressive; nothing like it in git
- undo literally any jj action; restore the repo to any previous state. try that with the reflog...
No amount of learning git nets you any of these things.
Small point of order, jj is a VCS with a pluggable backend, one of which is git. That’s a bit different than a UI on top of the git protocol.
6 replies →
Heres a great article about a powerful workflow that jj makes practical https://ofcr.se/jujutsu-merge-workflow/
Where jj shines is advanced workflows that aren’t practical with git. If you aren’t interested in those then it doesn’t give you as many benefits over git.
If you are breaking down your features into small PRs, stacking them, etc…, then jj is super helpful.
I’m also fine with git, and have used mercurial and p4 before. I think simplicity is better in this case. I do think with more and more generated code inflating the codebase with high velocity, we need to find a better way to merge conflicts.
I don't have major pain points with git either (mainly just that rebase merge conflicts can get awful to deal with), but I just love jj and I'm not looking back.
It turns out there were a lot of things that I was not doing with git because with git it would have been painful.
Now my PRs are split into human-sized commits that each contain a set of changes that make sense together, and I keep moving changes around during development to keep the history tidy, until it's time to send the pull request. If a commit introduces a typo, the typo fix should go into that commit so the typo never happened in the first place and you don't get reviews like "please fix this" and then "oh wait I see you fixed it in a later commit".
And sure, with git you could checkout the faulty commit, amend it, then amend -a and hope no one was looking, and rebase your dev branch onto the amended commit and it will often even work. Or rebase -i, sure -- have fun with it if the typo was 12 commits ago.
So I just never did that because augh.
With jj it's trivial. You just switch to that commit, fix the typo, and switch back to where you were. Or fix the typo where you were and squash the fix, and only the fix, into the commit that introduced it.
No more rebase hell. No more deleting the checkout and pulling it clean because things went sideways in a way that would be hell to fix manually -- jj takes snapshots after every mutation and rolling back is easy. No more squashing on merge to sweep the messy commit history under the carpet. No more juggling index and staged files and stashed files and all that messy business. Everything is just suspiciously straightforward. To think this could have been our lives all along!
And I'm not looking back.
It's not that I dislike git. It's just that I love jj.
> Now my PRs are split into human-sized commits that each contain a set of changes that make sense together, and I keep moving changes around during development to keep the history tidy, until it's time to send the pull request. If a commit introduces a typo, the typo fix should go into that commit so the typo never happened in the first place and you don't get reviews like "please fix this" and then "oh wait I see you fixed it in a later commit".
That's my workflow in Git. It is sometimes painful, but only because other people don't do that.
It is less work, if you use git --fixup=old-commit-hash and then use git rebase --autosquash. The --fixup step can even by automated, by using git-absorb, but this needs to be installed separately.
> You just switch to that commit, fix the typo, and switch back to where you were. Or fix the typo where you were and squash the fix, and only the fix, into the commit that introduced it.
That sounds the same in Git?
> No more deleting the checkout and pulling it clean because things went sideways in a way that would be hell to fix manually
When do you need to do that? The only case in which I messed up my repo, was when I had a harddrive crash and recovered commits manually from git objects, because the other files were corrupted.
> rolling back is easy.
Yes, that seams a bit easier, but reflog still exists.
> No more squashing on merge to sweep the messy commit history under the carpet.
This is just as well a stupid idea in Git and I hate that. This seams to be cultural and is not suggested by the tool itself.
> No more juggling index and staged files and stashed files
I find these useful, but you can also use Git without them. Just always use commit -a and commit instead of stashing.
> > You just switch to that commit, fix the typo, and switch back to where you were. Or fix the typo where you were and squash the fix, and only the fix, into the commit that introduced it.
> That sounds the same in Git?
I've always struggled with this myself, and would like to update my git knowledge. Can you walk me through the commands to do this? Let's say the commit id is `abcd1234` and it's 5 commits ago.
In JJ I'd do this:
Or if I was feeling more pedantic I'd do:
6 replies →
Of course! Likewise, you can do in C++ everything you can do in Rust. And yet Rust is there and fast growing in popularity. As it turns out, how to do things, and at the cost of what externalities, matters no less than what you can do.
15 replies →
I don't hate git, I like it fine and, until recently, used it exclusively on all my projects (I still use it non-exclusively). Here's an article that's written from that viewpoint:
https://www.stavros.io/posts/switch-to-jujutsu-already-a-tut...
That having been said, I didn't hate Subversion either. It was fine.
> I don't hate git
Idk man, the first two paragraphs of the article very much make it sound like you hate git.
> Over the past few years, I’ve been seeing people rave about Jujutsu, and I always wanted to try it, but it never seemed worth the trouble, even though I hate git.
Also:
> I don't hate git
but
> I have my trusty alias, fuckgit
Someone who doesn't hate git would have named this alias quite differently...
1 reply →
Fair enough, I'll clarify what I actually hate.
Yeah I definitely hated Subversion, which helped push me to try Git back in the day. Actually, back then I was an `hg` guy. That battle was lost long ago though.
I think you linked to the same post as OP, though?
I wrote the post, so that's a post from the perspective of someone who doesn't hate git :P
I used bzr after SVN, but my larger point is that it's all fine, the question was whether you want to go through some short-term learning for long-term gain, or if you want to keep using what you know. Either is fine, I'm still using vim as my editor, for example.
6 replies →
I wonder if there's a parallel universe where people are writing posts about Sapling and getting mercurial users to migrate to it.
1 reply →
Oh, if you’re an ex-hg guy, this makes this easier, then: jj is in many ways a renaissance for hg’s philosophy: https://ahal.ca/blog/2024/jujutsu-mercurial-haven/
I worked with SVN and I hated it, merging branches and dealing with conflict resolution on SVN was like getting stepped on the balls
For me the killer feature was distributed version control.
When I was an intern at GenericCorpo we had days we couldn't work because SVN was down. WTF was that?
I don’t hate git either but you’ll meet very few people who will claim its UX is optimal. JJ’s interaction model is much simpler than git’s, and the difficulty I found is that the better you know git, the harder it is to unlearn all its quirks.