I use jj for all my projects on github! It's really useful for my sort of workflow: chains of commits with easily-editable history. If you make a change back in time, you edit the previous commit (which puts you in a state similar to git's detached head), and any edits you make there are automatically carried forward (rebased) onto descendants. It feels way more natural, especially for newer users.
The killer feature that I love the most is a small one, but it's that commit messages can be made ahead of time rather than after-the-fact. So I can sit down at my desk, say
jj new -m "Work on XYZ feature"
then edit my code in the editor. When I'm finished, I move on to the next commit:
jj new -m "Working on UVW feature"
No more "oh no I accidentally started touching code and forgot to commit my work, so now I have to manually split two git commits;" it's a small way that the tooling encourages you to be intentional about your engineering philosophy.
> It feels way more natural, especially for newer users.
I have thought about this recently, and it feels like jj would be a lot easier to teach to new users than git.
For one, jj lets you work on things directly without having to worry about an index, while still giving you all the advantages of one if you're advanced enough to need that.
THe commands also feel a lot easier to explain than in git. For example, you use `edit` to change what commit you're working on, `restore` to copy a file from a commit to your working directory (and abandon your changes to it), and `abandon` to drop a commit completely. Meanwhile, git has `checkout`, `restore`, `switch`, `reset` and `reset --hard`, which all do various parts of one or more of these.
Reading the jj changelog is fun where you see them deprecate functions, acknowledging that they perform identical purposes. Beautiful to see this simplification that benefits all users going forward.
The one that stood out in my mind:
`jj checkout` and `jj merge` are both deprecated; use `jj new` instead to replace both of these commands in all instances.
Rationale: jj checkout and jj merge both implement identical functionality, which is a subset of jj new. checkout creates a new working copy commit on top of a single specified revision, i.e. with one parent. merge creates a new working copy commit on top of at least two specified revisions, i.e. with two or more parents.
The only difference between these commands and jj new, which also creates a new working copy commit, is that new can create a working copy commit on top of any arbitrary number of revisions, so it can handle both the previous cases at once. The only actual difference between these three commands is the command syntax and their name. These names were chosen to be familiar to users of other version control systems, but we instead encourage all users to adopt jj new instead; it is more general and easier to remember than both of these.
I feel like one of the reasons I see the problems with git more than many commenters on here is precisely because I often teach beginners who do not have a CS background.
I've yet to try jj, but in git, my flow is to start a new feature with a WIP commit and then to `--amend` it with every change. I usually have a running TODO list in the commit message body that I check off along the way.
Same. I love the power and flexibility. But, then again, I sometimes found myself spending a nontrivial amount of time planning my git maneuvers. That was a bit taxing. Either it took away from the focus on the objective, or it was enough of a chore that it I felt a little worn, especially during intense working sessions. I don't get that as much with jj.
jj was inspired by a bunch of internal Google tooling around their VCS, which was originally built on top of Perforce, so I'm not surprised the history shows through a little.
You can do that. But I mean there is literally a spot in the .git directory for the work-in-progress commit message. When you later do git commit -a or whatever, it pulls up the message.
The killer feature that I love the most is a small one, but it's that commit messages can be made ahead of time rather than after-the-fact. So I can sit down at my desk, say
then edit my code in the editor. When I'm finished, I move on to the next commit: No more "oh no I accidentally started touching code and forgot to commit my work, so now I have to manually split two git commits;" it's a small way that the tooling encourages you to be intentional about your engineering philosophy.