-
Notifications
You must be signed in to change notification settings - Fork 349
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
FR: jj undo ergonomics #3700
Comments
Why make them different? Oh, I suppose the top-level |
I'm actually starting to question if |
No, |
Think of it like |
To reword the FR a bit: Improve the ergonomics of
I think that this alternative would be layering violation in UI terms, as imo |
Would this have any impact on #3428 ( |
The higher level |
I think I would recommend removing |
Are you saying that By the way, I find the suggestion of making |
I agree with this, but still think that
That sounds great and should make the implementation simpler as it can just shell out to |
I have found I'm not 100% sure what I am also not sure what a new and fancy Here's the write-up about the old Emacs behavior (or what I think it was) I'd like to suggest the old Emacs behavior for consideration: if the op log is at
the first
Now, if you did another undo, it would undo A. If you do any operation D other than undo (or redo), however, the op log becomes
Now, if you start undoing, you will first undo D, then you'll undo "undo B", then you'll undo "undo A", and so on. The advantage of this is that it works well with an append-only op log, There are some disadvantages, most notably: what do we do if "operation D" is an unexpected non-user-initiated operation, such as snapshotting? |
I think we should be able to fix the Emacs use-case you mentioned with separately tagging the |
Here’s a nice exposition of a completely linear undo feature that never loses history, even as you perform new changes on top of undos; all past states remain accessible at all times: Resolving the Great Undo-Redo Quandary. I don’t know if it would work for Jujutsu, but we should at least consider and internalize its lessons when thinking about this. (It’s possible Emacs has behaviour similar to this; I’m not sure.) |
Just spent a couple min trying to repeatedly |
jj-fzf has an implementation of jj undo along the jj op log: screencast Since that makes it easy to test how far multi-step undo can be pushed, I tested it a couple of times and ran into cases that cannot be undone:
So unless there was a way to reliably linearize the op log, endless undo (redo) doesn't really work in practice. |
I think it would be a mistake to remove
Let people get excited by
Is this a fundamental requirement of the op log? I don't know the data structures so I don't know if it's actually feasible, but if the "current operation" could be a pointer to an old operation, instead of always being the head, then I think undo/redo would be way easier to handle:
This would create the semantics I think people expect:
If it's not feasible, then I think we'd essentially need to store the undo tree alongside the op log to achieve the following:
|
And btw, just emitting a warning when you |
I would say that it is. @tim-janik just reminded me of this message from me: #3455 (comment). I think that provides some useful context. |
I'm wondering if a variation of @jennings 's idea might be viable: Let's start with the oplog If the current operation is not undo/redo, $ jj undo
Undid operation C: frobnicate the repo
Do `jj undo --again` to undo operation B: prepare for frobnication Now, our oplog consists of 4 operations: When the current operation is an undo, I'd forbid
We could also have The motivation for requiring Update: To relate this back to Stephen's idea, conceptually this stores a pointer to another oplog operation inside the oplog record of the undo operation. We could keep the oplog the same as it is now, and parse the undo pointer from the description of the oplog operation, or we could add a new field to the oplog proto that would only be populated for undo/redo operations and point to the operation being undone/redone. Footnotes
|
I sort of like Ilya's plan, but not this part
because the default would be @ and that should make sense, and novices are the ones most likely to do undo twice so it should have an intuitive result, and sometimes you just want to undo the undo. |
@ilyagr's solution seems reasonable to me.
I see this concern, but I don't think the user will appreciate the difference. If I understand correctly, only one of
The initial version could parse the operation description, but we might eventually want this to be some kind of structured metadata, either part of the operation itself or linked to it (like git notes). |
In the meantime, I have updated the jj-fzf undo implementation following @jennings suggestion to use a marker instead of the (slightly involved) procedure I described earlier:
That alone works well enough for reliable multi-step undo, as long as the operation history is linear. If the operation history fans out (due to concurrent repository changes), there is no reliable way to reconstruct older repository states, AFAICS. And Below is a screenshot of the op log in jj-fzf after 8 consecutive undo operations (all marked ⋯ together with their respective undo operations). We have been having that in place for a couple weeks and the experiences so far are: All in all, I'm quite happy how undo/restore work in the jj-fzf op log view now. As for the
And then, leave it at that. As stated above, more than a handful of successive undo ops are probably best left to UI tools with a live view, or are an indication that you probably want to use |
I like the article posted in this comment above: #3700 (comment) -- I think the current operation log in jj is pretty close to what it's describing. The one major change to jujutsu would just be what the other comments have been saying. To summarize:
I softly disagree with the idea that it's okay for the command-line to be hard to understand, because GUI tools will "pick up the slack". This is one of the many problems that makes git irritating to both newbies and power users. The CLI tools can be "basic" but they should be simple, understandable, and complete. If they're hard to understand or use, people may bounce before getting around to trying GUI tools. |
I didn't understand the proposal in that article. In particular, why does the "type one character; undo" sequence double the undo stack?
I thought the article suggested recording the undo as its own operation instead of moving the pointer back (like we already do). Also see my comment above.
I think we all agree. |
Admittedly I didn't try to understand the specific encodings & optimizations they were using for their text editor. I read it as an enhancement of "canonical undo/redo" which allows undo-of-an-undo. This may be the wrong place for a lengthy description, but I was talking to a UX friend about it this morning, and it seems like word processors perform undo/redo like this:
After 2 undo (command-Z):
Redo (shift-command-Z) twice will still work to bring back "the sleeping cat", or if you start typing "purring" here, the redo stack is lost forever, and you have:
I think the GURQ proposal is to behave the same way except to track the undo operations at the end (as jujutsu already does).
After two "undo" commands, the tree is back at the first commit:
Doing a new operation bumps the undo pointer to the end of the operation log again so that future undo/redo will treat the previous undo's (undone's?) as operations themselves, which can be navigated through.
Yes, I think it does both:
|
Thanks for explaining. I still don't understand the exponential stuff, but maybe we don't need to understand it. One idea is to make Perhaps a more reliable way is to record which operation was undone by which other operation. Then we would instead scan backwards until we find an operation that's not an undo and is not itself undone by a later operation. |
Is your feature request related to a problem? Please describe.
The current behavior of the jj undo command does not seem to be what users intuitively expect. Currently if you run
jj undo
twice in a row it has the same behavior asjj op undo
, it returns you to the same place you were when you started. undo + undo = no change.Describe the solution you'd like
I'd like to preserve the ergonomics of the underlying
jj op undo
command (as suggested by @PhilipMetzger on Discord), but have the higher leveljj undo
command track if a user immediately undoes an undo and warn them.Describe alternatives you've considered
Alternatively, the jj undo command could keep track of where you are in the undo log ctrl-Z style. That probably implies a redo command as well?
The text was updated successfully, but these errors were encountered: