-
Notifications
You must be signed in to change notification settings - Fork 746
docs: Add Jujutsu for Git experts #7754
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
02711aa
to
10dd898
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just 2 nits from me. I think it's mentioned elsewhere too, but no stashing + no index + the working copy being a commit obviously has big ramifications on uniformity in workflows. For example, I would personally not know how to split a stash in git, but in jj this is trivial.
docs/git-experts.md
Outdated
|
||
TODO: Acknowledge `git rebase --update-refs` | ||
|
||
## Undo is easier than searching the reflog |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would say "is more powerful than the reflog" to focus more appropriately, it's about ease of use and power, but you want to focus on power first for a git audience.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's more powerful than "the reflog", meaning the reflog of HEAD, but in general it's just different. I find myself using the reflog for non-HEAD refs all the time even though I have jujutsu, because AFAICT jujutsu has no way to query "list all the commits that this ref pointed to", which makes it hard to tell e.g. which versions of PRs I've seen before.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BTW, if I can do this, with jj's rich output, timestamps, summary of what operation triggered the change, etc., I would be thrilled to learn this! But the current text doesn't say how.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct, we don't have a simple way of walking the operation log filtered to a specific ref yet. #2871 is the FR specifically for doing that for the working copy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated the section title. The body text seems to already support the "more powerful" claim, so I didn't change anything there for now.
|
||
TODO: show `jj op log -p`, `jj op diff` | ||
|
||
## Conflict resolution can be deferred |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is a big one that we'll have to iterate on, a lot of people want to see something more concrete here. like they don't get the "well you can just do it later" without more details. I had a good example of this somewhere recently and now I've lost it, ugh...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was an example I read (I don't see it in the docs) that explained how a command could generate a conflict which is then resolved automatically in the next command, which is the best case for deferring.
See Advantages in the docs for scenarios to form an example around.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added one paragraph about the "need to go fix a critical bug" situation, and then a second paragraph for, "I did another rebase and it resolved all the conflicts for me". What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's somewhat rare that the "rebase again resolves conflicts" is very useful in practice. I'm not sure it's going to convince many. Perhaps it will be more confusing that it's helpful.
I wonder if this paragraph should be about the conflict algebra (probably without using that term). If it is, I think I would rank 3 things it provides like this:
- Rebase/merge always succeeds, so we can always rebase descendants
- We can define the changes in a merge commit well
- Conflicts resolutions can be deferred
My point is that I think deferring conflict resolution is actually less important as a feature. Just a thought; feel free to ignore.
10dd898
to
9af648b
Compare
docs/git-experts.md
Outdated
|
||
TODO: Show example | ||
|
||
TODO: show `jj op log -p`, `jj op diff` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe mention jj evolog
also
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
People love the evolog but I don't personally use it that much, so I might have trouble writing about it. I added a section but it's probably not very compelling. What do you think?
7712344
to
a401a5f
Compare
a401a5f
to
c991044
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor points
Because Jujutsu records the inputs to conflicts, not just conflict markers, it | ||
can sometimes automatically resolve conflicts after a rebase. When performing | ||
several rebases in sequence, some conflicts may be introduced by one and then | ||
later automatically resolved by another, without any manual effort to resolve | ||
the conflicts. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: this paragraph should reference that this makes Git's rerere functionality obsolete since it is built in
You can leave a commit in a conflicted state, continue other work, and return | ||
later. This reduces the cost of context switching when resolving a large number | ||
of conflicts. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An advantage of this is that you can rebase like really old work on top of trunk()
support without ever needing to solve it, I currently do that for Noah's Topic branch
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do that too. I wonder if that sounds like a benefit, though. I imagine the rebuttal: "If the conflict isn't resolved, you can't use the branch, so why bother even rebasing it?"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I think this is something we can let people discover later. They'll likely even discover it on their own.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if that sounds like a benefit, though. I imagine the rebuttal: "If the conflict isn't resolved, you can't use the branch, so why bother even rebasing it?"
I mean having the ability to revive any patch from the past of a codebase is to me a big plus. But your rebuttal is correct though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I came here to suggest a similar thing; I have a rebase-all
alias that I use often, so I'm rebasing all of my branches. This lets me continue to work on a non-conflicted branch, and know which ones I'll need to fix later. Hard to describe this without getting into the alias, though...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! I think this looks good enough as a start. I think it's good to get it merges in roughly the current shape so we can all help improve it when we see a need. But please address the existing review comments. My approval is not meant as a dismissal of their feedback, of course.
side-by-side. If you find a situation that's easier with Git, run the `git` | ||
command and return to `jj` when you're done. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Add "Also please file a feature request" or similar?
workflows it improves without losing access to the Git commands and tools you | ||
already know. | ||
|
||
## Automatic and safer history editing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should probably mention the staging area somewhere. I don't know if that would be part of this section or somewhere else. Feel free to just leave a TODO if you agree.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would make it a section right above this one, it's going to be the largest change that someone runs into immediately.
If you frequently amend, reorder, or squash commits, Jujutsu can often perform | ||
the same operations in fewer commands. | ||
|
||
Suppose you want to amend an older commit and squash it into earlier history. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This sentence sounds a bit redundant to me because "amend an older commit" and "squash into earlier history" sounds like about the same thing. Maybe "Suppose you want to amend some changes in the working copy into an older commit" or something like that?
You can leave a commit in a conflicted state, continue other work, and return | ||
later. This reduces the cost of context switching when resolving a large number | ||
of conflicts. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I think this is something we can let people discover later. They'll likely even discover it on their own.
|
||
TODO: show `jj op log -p`, `jj op diff` | ||
|
||
## Conflict resolution can be deferred |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's somewhat rare that the "rebase again resolves conflicts" is very useful in practice. I'm not sure it's going to convince many. Perhaps it will be more confusing that it's helpful.
I wonder if this paragraph should be about the conflict algebra (probably without using that term). If it is, I think I would rank 3 things it provides like this:
- Rebase/merge always succeeds, so we can always rebase descendants
- We can define the changes in a merge commit well
- Conflicts resolutions can be deferred
My point is that I think deferring conflict resolution is actually less important as a feature. Just a thought; feel free to ignore.
|
||
## Git can be used side-by-side in the same repository | ||
|
||
Jujutsu repositories are colocated by default, so you can use `jj` and `git` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would skip the colocated jargon and just talk about how they're next to each other.
|
||
Jujutsu repositories are colocated by default, so you can use `jj` and `git` | ||
side-by-side. If you find a situation that's easier with Git, run the `git` | ||
command and return to `jj` when you're done. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we have worries about destructive git commands in this case? I don't want to get too into the weeds right at the start, though...
workflows it improves without losing access to the Git commands and tools you | ||
already know. | ||
|
||
## Automatic and safer history editing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would make it a section right above this one, it's going to be the largest change that someone runs into immediately.
You can leave a commit in a conflicted state, continue other work, and return | ||
later. This reduces the cost of context switching when resolving a large number | ||
of conflicts. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I came here to suggest a similar thing; I have a rebase-all
alias that I use often, so I'm rebasing all of my branches. This lets me continue to work on a non-conflicted branch, and know which ones I'll need to fix later. Hard to describe this without getting into the alias, though...
Checklist
If applicable:
CHANGELOG.md
README.md
,docs/
,demos/
)cli/src/config-schema.json
)