Skip to content
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

UX of universal undo feature (discussion) #3726

Closed
krlvi opened this issue May 7, 2024 · 21 comments
Closed

UX of universal undo feature (discussion) #3726

krlvi opened this issue May 7, 2024 · 21 comments
Assignees
Labels
feedback requested Feedback was requested to help resolve the issue new feature An entirely new featuer UX/UI Focusing on user satisfaction, usability, and overall experience

Comments

@krlvi
Copy link
Member

krlvi commented May 7, 2024

Background

We want to create a user interface for programmers using GitButler to be able to undo and redo changes they make with GitButler as well as changes in the repository. This includes:

  • changes to files in the working directory
  • changes to the gitbutler state (e.g. create a branch, commit, move stuff around etc)

This is similar to "Command/Control-Z" but more flexible. Some applications like Photoshop (and even VSCode) have the notion of an "undo history" - this is what we are aiming for.

Snapshots

The GitButler application already has the concept of a "snapshot". A snapshot represents the complete state of the project at a specific point in time.

Using a snapshot, a user can put their project in the exact state it was in when the snapshot was taken. (i.e. functions as a time-machine)

NB: Snapshots are currently feature flagged. To enable snapshots edit the
'/Users/<username>/Library/Application Support/com.gitbutler.app/projects.json' file, setting "enable_snapshots": true on the project for which you want to enable this for. Then, in the app, the snapshots UI is toggled with Cmd+Shift+H

When are snapshots created?

Snapshot creation is triggered under the following conditions:

  • When an "updating" action is pefrormed in the GitButler application (e.g. creating a branch, commit, moving files between branches, deleting a branch or a hunk, amending commits etc.)
  • Immediatelly after restoring to a previous snapshot (more on restoring later)
  • After a number a number of file changes have been made in the working directory (defaults to 20 modified lines of code, configurable as default_snapshot_lines_threshold)

What does a snapshot contain?

A snapshot has everything needed to restore the project to a given state, therefore a lot of content can in theory be extracted. Currently, when listing snapshots the following structure is available on the API:

pub struct Snapshot {
    /// The sha of the commit that represents the snapshot
    pub id: String,
    /// Snapshot creation time in epoch milliseconds
    pub created_at: i64,
    /// The number of working directory lines added in the snapshot
    pub lines_added: usize,
    /// The number of working directory lines removed in the snapshot
    pub lines_removed: usize,
    /// The list of working directory files that were changed in the snapshot
    pub files_changed: Vec<PathBuf>,
    /// Snapshot details as persisted in the commit message
    pub details: Option<SnapshotDetails>,
}
pub struct SnapshotDetails {
    /// The version of the snapshot format
    pub version: Version,
    /// The type of operation that was performed just before the snapshot was created
    pub operation: OperationType,
    /// The title / lablel of the snapshot
    pub title: String,
    /// Additional text describing the snapshot
    pub body: Option<String>,
    /// Additional key value pairs that describe the snapshot
    pub trailers: Vec<Trailer>,
}

Link to the Operation types available.

Think of OperationType as "what triggered this snapshot to be created".

Most operations on the GitButler API create snapshots, and they are reflected by the OperationType enum.

  • If a snapshot is created as a result of restoring to a previous snapshot, the OperationType will be RestoreFromSnapshot.

  • If a snapshot is created as a result of simply performing a number of file changes in the working directory, the OperationType will be FileChanges.

Trailers:

Trailers are key-value pairs that can be used to store additional information about the snapshot.

Depending on what triggered a snapshot, there may be additional informatio saved in a trailer. Currently this only applies to snapshots triggered by a restore operation (RestoreFromSnapshot). Those snapshots contain a trailer with the key restored_from for which the value is the sha of the snapshot that was restored from.

In the future we can add additional info to trailers, specific to the operation that triggered the snapshot. For example moved_from and moved_to for snapshots triggered by a move operation, or old_name and new_name for snapshots triggered by a rename operation.

Restoring to a snapshot

Restoring to a snapshot is trigered by the user with an api call.

Restoring sets the state of the project to the state it was in when the snapshot was taken.

This means that restoring is not an undo of the change in the snapshot but timetravel to that snapshot.

Whenever a restore operation is performed, it is followed by a new snapshot creation with the RestoreFromSnapshot type/trigger (and it contains a restored_from trailer referring to the id of the snapshot that was restored from).

How are snapshots saved and restored?

Out of scope for this UX discussion, check the code in
https://github.com/gitbutlerapp/gitbutler/blob/master/crates/gitbutler-core/src/ops/oplog.rs

Snapshot history visualized

The app currently has is a mock UI for visualizing the snapshot history while we are designing a proper UI for this. The following is an illustration of the view snapshot history (1), restore to a snapshot (2) and restore back (3) uses cases.

View snapshot history

1
  • 1.1 This is the most recent snapshot, which was triggered by updating the branch name. Between this snapshot and the previous one there were no project file changes (no files changes and zero lines added or removed).

    Note that it does not make sense to restore to this snapshot as it is the current state

  • 1.2 This snapshot was triggered after a commit was created. Again no changes to the project files were made as compared to the snapshot that preceeded it.
  • 1.3 This snapshot was created as a result of file changes that occured in the working directory (e.g. writing code in VSCode). By default, a FileChanges snapshot is triggered when there is at least 20 lines of added + removed code, as compared to the previous snapshot. (In the screenshot the threshold is configured to a smaller value)

Restore to a snapshot

Let's restore to snapshot adc6d74 (This is the state after the file changes were made but before the commit was created). Now the project looks the way it before the commit was created (as reflected in the rest of the UI). The branch name also looks the way it did before it was renamed.
2

  • 2.1 After restoring to adc6d74 the newest snapshot is of trigger type RestoreFromSnapshot and contains a reference to the snapshot that it was restored from.
  • 2.2 This is the same snapshot as in 1.1 but since we restored to a previous one it is not in our state. If the users wants they can still choose to restore to the sate of this snapshot.
  • 2.3 Similarly, this is the same snapshot as 1.2 but we restored to a point before it.
  • 2.4 This is the snapshot that 2.1 restores to, so the state is identical

In this scenario 2, as far as UX is concerned we could conceptually "gray out" the snapshots 2.2 and 2.3 because with 2.1 we have time traveled to 2.4. Of course this could be achieved by also collapsing / hiding those entries.

It is important to note that the snapshots in between (2.2 and 2.3) are still valid and can be restored to (we could disallow that if it makes for a more clear UX).

Undoing the undo

Let's say that the restore operation from (2) was a mistake and lets restore to the point where we started from in (1). This means restoring to the snapshot that was flagged as "current" in the begining - df89e5c. Here's how that looks like:
3

  • 3.1 After restoring, a new snapshot with RestoreFromSnapshot trigger is created, referencing df89e5c from 1.1.
  • 3.2 This is the previous restore snapshot, which is no longer in our state.
  • 3.3 This is the snapshot that 3.1 restores to, and the state is identical to what we have in 3.1.

Questions

  • Is there a better way of rendering the Restores?
  • What happens if there are multiple restores - do we collapse the entries that are "skipped" with an option to expand the block?
  • When there are nested restores (e.g. restore to a snapshot, then restore to another snapshot within) can we compute the snapshots that are not in the current state and gray them out?
  • How should an "CMD+Z" functionality operate? Should it restore to the previous snapshot (so if pressed multiple times it cycles), or should it restore to the previous snapshot that was not a restore operation (so if pressed multiple times it goes back in history)?

Getting the details of a specific snapshot

It is possible to get the diff of a specific snapshot with the snapshot_diff command. This will get a diff between the state of the workdir (project files) in the snapshot and the state of the workdir in the snapshot before it.

Note that some snapshots represent changes to app state (for example name change of virtual branches) and in those cases, the working directory is the same as the previous snapshot.

UX needs

For now, we wanna facilitate the following:

  • Have the ability to undo an action that was just performed (e.g. deleted a branch or discarded the changes in a file)
  • Have the ability to recover from a broken state that GitButler entered due to a bug.
  • Have the ability to recover work that was accidentally lost (e.g. fat-fingered something in the IDE/editor without noticing)
  • Have the ability to set a "checkpoint" (e.g. a bookmark) and easily restore back to it. For example if I am about to do something risky/experimental, it would be nice to be able to mark a snapshot in a way that I can easily find it in the pile of snapshots later.

To achieve all of that we need to be able present information in a way that is glance-able and easy to understand. We wanna make it visually clear what the different operations were and when they occured. When restoring, it should be clear to what point the user is restoring to.

Challenges

  • In some cases there can be many snapshots, which appear very similar (e.g. spammy)
  • It may not be clear that restoring to a snapshot is not an undo of the changes in it but a timetravel to that point.
  • When restoring to a snapshot that says CreatedCommit it may be unclear if that means that I will restore to a point before or after the commit was created.
  • When the user has restored to a snapshot, it may be non-obvious that this creates a new entry on the snapshots stack.
  • When there is a RestoreFromSnapshot snapshot entry, it may be non-obvious that all the snapshots that are between it and the one it restored from are not part of the current state (but can be restored to).

Lets discuss 💬

Similar to #3121, the purpose of this GH issue is to invite a discussion and maybe go over some drafts / ideas that come up. @schacon @mtsgrd @PavelLaptev @Qix- @Caleb-T-Owens let me know if I have missed something

@krlvi krlvi pinned this issue May 7, 2024
@krlvi krlvi added new feature An entirely new featuer UX/UI Focusing on user satisfaction, usability, and overall experience feedback requested Feedback was requested to help resolve the issue labels May 7, 2024
@PavelLaptev
Copy link
Contributor

@krlvi I see this feature working like Git history, where we don't erase previous steps, but instead create a 'revert' snapshot that keeps track of changes, unlike traditional undo/redo (similar to the Photoshop example below):

Screen.Recording.2024-05-08.at.15.47.24.mov

Should we even track or show spammy operations like setting the default branch or reordering branches? These don't have as much impact as file changes or branch deletions, so maybe we shouldn't focus on them and show them at all.

Alternatively, we could allow simple operations like branch reordering and setting the default branch to be undone with Ctrl+Z, but keep the rest in the history/timeline sidebar. Because some operations we need in short term like set default branch" and some for long distance like "file changes" or "branch deleted".

Because some operations are critical and involve large changes, we shouldn't allow going back with 'Ctrl+Z' or in this case automatically show the sidebar, so a user wouldn't do it blindly. Also, with 'Ctrl+Z', you wouldn't see a previous step erased—you'd just see a new snapshot at the top. That's why I suggest not treating this like a regular undo/redo function—it could be confusing.

image

Since some operations look noisy and not that useful, I'd prefer not to see them at all. For example

pub enum OperationType {
    CreateCommit,
    CreateBranch,
    SetBaseBranch,
    MergeUpstream,
    UpdateWorkspaceBase,
    MoveHunk,
    UpdateBranchName,
//  UpdateBranchNotes, // not in use
//    ReorderBranches,  // not really valuable in history
//    SelectDefaultVirtualBranch, // not really valuable in history
    UpdateBranchRemoteName,
    GenericBranchUpdate,
    DeleteBranch,
    ApplyBranch,
    DiscardHunk,
    DiscardFile,
    AmendCommit,
    UndoCommit,
    UnapplyBranch,
    CherryPick,
    SquashCommit,
    UpdateCommitMessage,
    MoveCommit,
    RestoreFromSnapshot,
    ReorderCommit,
//    InsertBlankCommit,  // what is usecase to display this in history?
    MoveCommitFile,
    FileChanges,
    #[default]
    Unknown,
}

@slingshotvfx
Copy link

Just an average user here, but I have a couple initial thoughts:

The photoshop history comparison is exactly how I'd expect this feature to work when you describe it in GitButler. However, an important note is that undo (ctrl+z) in photoshop traverses back up the history list, and redo goes forward, until you make a change, then the 'undone' changes are thrown away. For example, if you undo three times and are three levels back in history, but then draw on the canvas, a new history item is created which overwrites the three "future" history items and you can no longer redo.

This differs from what is being pitched in Gitbutler, where undo-ing wouldn't really travel back up the history list but would instead add a new history entry. I guess the history would be more of a forking tree in GitButler, rather than a one dimensional list.

I like the idea of not ever overwriting "undo-ed" changes, but from a complexity standpoint I agree with @PavelLaptev that I wouldn't necessarily treat this as an undo feature in the traditional sense and I'm not sure I'd map it to ctrl+z.

As a user, for undo/redo, I think I'd expect to be able to ctrl+z ten times and end up at a state I was in ten actions ago, without cluttering the snapshots or commits with a bunch of "revert" changes. But, a non-destructive 'snapshot' sidebar seems super useful as well. Not to feature creep, but I wonder if it's worth having both functions, a more simple ctrl+z/undo/redo that is potentially destructive to quickly undo mis-clicks and typos, and a more in-depth snapshot sidebar that tracks every change ever made for when you need to dig through the history for more complex operations.

How should an "CMD+Z" functionality operate? Should it restore to the previous snapshot (so if pressed multiple times it cycles), or should it restore to the previous snapshot that was not a restore operation (so if pressed multiple times it goes back in history)?

Personally, I would expect (and want) repeated cmd+Z presses to traverse back in history.

Currently there is no API go get the specific "diff" or details of a snapshot, but this is something we could easily implement, such that when a snapshot is clicked on in the UI, we can show how the files changed in it

Personally I think this is critical. It seems like there will be hundreds of snapshots generated, and for this tool to be useful at all I think I'd need a UI to see the specific differences that restoring to this snapshot would apply. Another common use case for me would be to view snapshots without necessarily restoring them -- I might have started writing some code, changed my mind and deleted it, written different code, changed my mind back, but then want to go back to that snapshot and be able to copy/paste the code I deleted into my current working file without resetting the whole file to that snapshot. If that makes sense.

Anyway, that's just my two cents. Very excited about this feature and gitbutler in general, it really solves a ton of friction I've had trying to use git personally.

@PavelLaptev
Copy link
Contributor

Thanks for your feedback on this, @slingshotvfx.

I agree about separating snapshots from undo/redo. Figma provides a good example of this:

  1. In Figma, you can undo actions with "Ctrl + Z" many times, and these changes are often very small (e.g., moving a shape 1px to the left 30 times). Figma tracks every minor adjustment.
  2. Figma also has a History feature, which is a list of snapshots. These snapshots are taken based on a certain number of changes or specific actions, such as publishing a library that affects many files.

Figma example

Additionally, I agree with @slingshotvfx about previewing file changes. This is crucial, especially if you need to go far back in the history.

I think @krlvi sees this feature as more of a short memory track, where you wouldn't necessarily try to restore something from months ago. I tend to agree, because having extensive history within a Git GUI feels like creating "Git inside Git." I can hardly imagine a case where you'd need to restore a project state from three months ago.

Also, the deeper you go into snapshot history, the more likely you'll encounter artifacts, mismatches, or conflicts. I'm not sure if we should restrict how far back you can go in the snapshot history, but I doubt that older snapshots hold much value. Currently, there are no limits.

As a first step, I suggest focusing on implementing "snapshots." This seems more valuable than "undo/redo" with "Ctrl + Z."

@PavelLaptev
Copy link
Contributor

I've created a draft of the history sideview:

image

@krlvi
Copy link
Member Author

krlvi commented May 9, 2024

I love the design @PavelLaptev!

You raise very good points @slingshotvfx @PavelLaptev. Regarding the spammy nature of certain actions we could either skip creating those, or we could just filter them out from the UI (in case we change our mind later).

Somehow I suspect that the most "spammy" snapshot will be FileChanges though. It is possible to configure how dense / frequent those are created. The threshold of "updated lines since last snapshot" defaults to 20, and maybe we can add a little slider or config for it - should that be in the settings or directly in the history?

Regarding Cmd+Z i agree that we don't wanna break the expectations ppl have, maybe we can ship the history without a hotkey and then think how to do this properly as we iterate

@krlvi
Copy link
Member Author

krlvi commented May 9, 2024

ah, also, about previewing a specific snapshot I will try to have something implemented this week @PavelLaptev @slingshotvfx

@krlvi
Copy link
Member Author

krlvi commented May 9, 2024

Okay, I implemented an endpoint for getting the diff of a specific snapshot (#3740), and updated the top comment here

Getting the details of a specific snapshot
It is possible to get the diff of a specific snapshot with the snapshot_diff command. This will get a diff between the state of the workdir (project files) in the snapshot and the state of the workdir in the snapshot before it.

Note that some snapshots represent changes to app state (for example name change of virtual branches) and in those cases, the working directory is the same as the previous snapshot.

This will give you the diffs that that specific snapshot has, compared to the snapshot before it. Here's an example usage in the mock UI, it only prints the content in the console https://github.com/gitbutlerapp/gitbutler/blob/master/app/src/lib/components/History.svelte#L97

@PavelLaptev i guess when we display that, a primary use case is the ability to copy-paste

@Caleb-T-Owens
Copy link
Contributor

Caleb-T-Owens commented May 9, 2024

I've chosen not to read through the existing conversation and to just give wholly my own thoughts on the matter.

My ideals for this feature

  • I shouldn't have to look at the snapshot log 98% of the time.
    • Looking at the git reflog scares the majority of my colleagues, so let's not build v2!
  • The operations that get undone and redone should be GitButler operations, not VSCode operations (atomic insertion and deletion of text)
  • The operations should be predictable and not require any UI to show me what changes are going to be undone when I hit Cmd+z
    • If I need to hit Cmd+z 4 times to undo 80 lines of code and have a UI that pops up to show me a diff each time, that is going to be incredibly slow and cumbersome

What is the Cmd+z and Shift+Cmd+z behaviour that I expect?

In vim:

  • u undoes a vim operation (That is inserting some text, performing a deletion, moving something, etc...)
  • U redoes the previously undid operation.

In text editors

  • Cmd+z Undoes the last word operation (IE undoes a word insert or a word removal)
  • Shift+Cmd+z Does the reverse

In design tools

  • Cmd-z Undoes the last operation (Translation, Object addition, Transformation, etc...)
  • Shift-Cmd-z Again, does the reverse

What is the behaviour that I expect from GitButler?

My expectation is that GitButler's Cmd+z and Shift+Cmd+z will undo and redo operations performed inside of the GitButler app.

I however do not expect that GitButler's Cmd+z and Shift+Cmd+z will undo and redo text that I have written incrementally. I will have no feedback of what text may or may not have been undone or how much text will be undone. If I want to undo text changes, I will do those in my text editor. (Or use a future code replay tool from GitButler). When we know we can have super fine control, using snapshotting for code changes feels like using a hammer.

The basic case

A typical use-case of GitButler might be creating a new vbranch, dragging a commit to that new vbranch, and moving a particular hunk into its own new commit. I've illustrated that timeline below:
Screenshot 2024-05-09 at 19 48 45

If I were to hit Cmd-z three times, I would expect to end up with a blank vbranch:
Screenshot 2024-05-09 at 19 51 35

If I were to hit Shift-Cmd-z twice, I would then expect to back to the state where I have a blank commit ready to move changes into it:
Screenshot 2024-05-09 at 19 53 14

Under this basic case, it would suffice to have a snapshot taken after each GitButler operation like so:
Screenshot 2024-05-09 at 19 56 32

In my undo and redo example, we would:

  • (undo) Go from snapshot D to C
  • (undo) Go from snapshot C to B
  • (undo) Go from snapshot B to A
  • (redo) Go from snapshot A to B
  • (redo) Go from snapshot B to C

Handling text changes changes

In the above scenario, we didn't make text changes. If it's not GitButler's Cmd+z and Shift+Cmd+z to handle incremental text changes, what do I do?

Let's take a look at an updated scenario, where between creating the VBranch and moving the commit, I make some file changes, and between creating the blank commit and moving the hunk, we also make some more file changes. I've illustrated this below:

Screenshot 2024-05-09 at 20 36 28

If I were to hit Cmd+z four times, I would expect the following to happen:

  • The hunk gets moved back out of the blank commit
  • All the file changes get undone
  • The blank commit gets removed
  • The commit gets moved back

Illustrated below:
Screenshot 2024-05-09 at 20 40 50

If I were to then hit Shift+Cmd+Z three times, I would expect to end up with the blank commit and my files changed back to how they were before I moved the hunk, as illustrated below:
Screenshot 2024-05-09 at 20 42 25

How do we take the snapshots for this?

We can follow two rules:

  • Always take a snapshot after a GitButler operation
  • If there have been text changes before a GitButler operation, take a snapshot before the operation.

For this scenario, it would take snapshots in the following manner:
Screenshot 2024-05-09 at 20 45 03

What about if there have been text changes after the last GitButler operation?

In this case, we would create a snapshot before undoing the file changes.

What UI?

Given this scheme, undoing and redoing should be predictable (We won't need to visually show users what bits of text should be undone because it's a simple rule of "All the text since the last GitButler operation").

This scheme also removes the worry about "spammy" snapshots because we can predictably create them around GitButler operations.

@PavelLaptev
Copy link
Contributor

@Caleb-T-Owens thanks for the explanation. In "Undo/Redo" context, I think it makes sense.
For the History sideview I like the approach to capture file changes every X changes.

@PavelLaptev i guess when we display that, a primary use case is the ability to copy-paste

@krlvi thanks for adding this, I'll check it out and see how we can design this.

@Caleb-T-Owens
Copy link
Contributor

Caleb-T-Owens commented May 10, 2024

Hi @PavelLaptev, I've now gone through the full discussion.

Revert Snapshots.

I've seen revert snapshots mentioned a couple of times, and I know they're currently implemented in the app too, but I don't understand why they're needed. I would appreciate me if someone could help my understanding as to why they're beneficial.

In my current mental model, they just don't seem helpful.

If my snapshot history looks like:

  • Snapshot 1
  • Snapshot 2
  • Snapshot 3

If I restore to Snapshot 2, Snapshot 3 is still there to go back to the future to.

The only time we need to make a new snapshot before going back to a previous time is if there have been text changes or untracked operations made since the last snapshot was taken

The History View

Out of the gate; it looks very cool, and I can see how the incremental changes in there are helpful. I think the main thing that I'm interested in is how will this play into things like code replay in the long run

I do however think that we should try to get Undo/Redo working will enough that this doesn't need to be used instead of Cmd+z

@PavelLaptev
Copy link
Contributor

PavelLaptev commented May 10, 2024

@Caleb-T-Owens, I see the "History" feature as something different from just "Undo/Redo." It's more like snapshots or versions of my current project.

image

When I restore a Snapshot 1, the app shouldn't erase or overwrite any existing snapshots. Instead, it should create a new snapshot/version on top of it. This creates a "new" state of the project that comes from Snapshot 1. It's useful when you're experimenting with different changes but still want to keep a stable version to fall back to. For example, you might want to bring back or just check some code you deleted a day or week ago.

Another reason it should work this way, in my opinion, is that it's more "foolproof." Restoring versions could cause unpredictable errors due to conflicts or edge cases. If restoring Snapshot 1 doesn't work for some reason, I can still go back to Snapshot 3. It also ensures that users can't accidentally erase or damage their current code, adding a safety net.

While snapshots give more extensive control and flexibility, they shouldn't replace the basic Undo/Redo (Cmd+Z/Cmd+Shift+Z) functionality. Ideally, Undo/Redo handles simple day-to-day corrections, while revert snapshots offer broader restoration options.

An example of this approach is Figma. They have "Undo/Redo" for basic corrections, plus a "History" feature where it creates new versions without deleting old ones. Here are some screenshots showing how Figma does it:

image

The difference between Figma's "Undo/Redo" and "History":

  • "Undo/Redo" is local to your current session.
  • "History" is shared among everyone working on the project.

image

@Caleb-T-Owens
Copy link
Contributor

@PavelLaptev

When I restore a Snapshot 1, the app shouldn't erase or overwrite any existing snapshots. Instead, it should create a new snapshot/version on top of it. This creates a "new" state of the project that comes from Snapshot 1. It's useful when you're experimenting with different changes but still want to keep a stable version to fall back to. For example, you might want to bring back or just check some code you deleted a day or week ago.

Rather than getting rid of that snapshot 2 and 3, couldn't we just grey them out so you can then jump back to them?

The thing I struggle with revert snapshots is that you end up with several snapshots which don't have a linear history.

Screenshot 2024-05-10 at 16 48 41

@PavelLaptev
Copy link
Contributor

@Caleb-T-Owens, how will it work if I jump back to an earlier point in history and then make new changes? Does it overwrite the existing history or it will look like this?

image

@Caleb-T-Owens
Copy link
Contributor

@PavelLaptev I think it would be important to still let the user have access to the alternate timeline, so I think if we did like that, but perhaps if there is an expandy/accordion button which can show/hide the alternate history

Screenshot 2024-05-10 at 18 04 02

@Caleb-T-Owens
Copy link
Contributor

If you were to go to a snapshot in a forked history, that forked history would become the main timeline, and the other would then be displayed as a forked history

@PavelLaptev
Copy link
Contributor

PavelLaptev commented May 10, 2024

I see, is that how the flow should look like @Caleb-T-Owens?

image

Link to figma if you need to edit this

@schacon
Copy link
Member

schacon commented May 11, 2024

I would rather not do forked history. I think that becomes quite complicated both from a data and UI perspective. I would much rather simply add the revert to the top of the timeline. It's always a simple history of "what did my working directory look like".

If you look at Jujutsu, they have something similar. If you run jj undo it just goes back to the last version, so running it multiple times goes back and forth between two versions. It's less fancy, but I'm really fine with this. If you are going to go back, you can pull up the timeline and find the version relatively easily, probably generally by timestamp.

To be honest, I'm not sure that cmd-z is needed. It may actually be confusing even if it worked how we imagined it here. I think if you want to undo something, it's a little slower but much clearer to simply pick a time in the past on your timeline and revert to that, which pushes it on the top of your timeline. Just a simple history of your working state. It's easier to comprehend, a simpler UI and simpler to implement.

@PavelLaptev
Copy link
Contributor

I'm good with starting with something easy that already works, and make it better progressively. For the design, here's what I'm thinking. I'm also thinking about adding the ability to fold or unfold the 'gray' area.

image

Link to this design in Figma

@krlvi
Copy link
Member Author

krlvi commented May 11, 2024

i also agree with the idea of keeping it simple for the first iteration so that we can see how it feels during usage. @PavelLaptev i like the designs, just curious - how does one trigger the "restore" from a snapshot as well as "preview" it?

(btw, note that not all snapshots can be previewed, only the ones that have file changes - for example "File changes" or "Update base" or "Delete branch (if it had file changes)" etc

@PavelLaptev
Copy link
Contributor

@krlvi, that's what I'll check during development.
To keep the appearance clean, I plan to hide these buttons and reveal them when hovered over. Additionally, I aim to open the diff preview when clicking on the file changes box.

@krlvi
Copy link
Member Author

krlvi commented Jun 1, 2024

@krlvi krlvi closed this as completed Jun 1, 2024
@krlvi krlvi unpinned this issue Jun 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feedback requested Feedback was requested to help resolve the issue new feature An entirely new featuer UX/UI Focusing on user satisfaction, usability, and overall experience
Projects
None yet
Development

No branches or pull requests

5 participants