Skip to content

cli+tui: make repeated but undos work#13695

Merged
davidpdrsn merged 1 commit into
masterfrom
dp-repeat-undo
May 8, 2026
Merged

cli+tui: make repeated but undos work#13695
davidpdrsn merged 1 commit into
masterfrom
dp-repeat-undo

Conversation

@davidpdrsn
Copy link
Copy Markdown
Contributor

@davidpdrsn davidpdrsn commented May 7, 2026

Previously, if you ran but undo and then but undo again, you'd undo the undo. Thats not intended and instead, what we want to do is undo the operation before the previous undo, basically walking backwards in history. This makes but undo do that.

How it works

I find the undo target by walking from newest to oldest through the oplog and counting how many undos we see. For each undo we see, we skip one non-undo entry. When we're at 0, we know the target is the next entry.

Example when all undos are at the top

                                    (n=0)
[UNDO]   <- skip one real operation (n=1)
[UNDO]   <- skip one real operation (n=2)
[REWORD] <- skipped                 (n=1)
[REWORD] <- skipped                 (n=0)
[REWORD] <- target                  take this!

And with undos mixed with other operations

                                         (n=0)
[UNDO]   <- skip one real operation      (n=1)
[REWORD] <- skipped                      (n=0)
[UNDO]   <- skip one more real operation (n=1)
[REWORD] <- skipped                      (n=0)
[REWORD] <- target                       take this!

Undoing but oplog restore

I want but oplog restore to be treated differently from but undo, i.e., if you run but oplog restore and then but undo, then we should undo the restore. The restore shouldn't be counted as an undo.

This required changing OperationKind, which previously used RestoreFromSnapshot for both undos and restores. I've added a new RestoreFromSnapshotViaUndo variant that is used for undos so we can tell them apart from explicit restores. That means old undo entries will be categorized as restores, but I don't think there is anything we can do about that.

but redo

We also want to add but redo to walk forwards in the oplog. I'm pretty confident we can use the same general strategy to support that as well, but if someone disagrees, I'd like to know 😊 since this introduces data changes. I want to make sure we don't need to make further changes when we do but redo. I might wait to merge this until I have a working but redo implementation as well.

Iterating the oplog

Before, we had ctx.list_snapshots(), which returned a Vec<Snapshot> and required passing a limit on how many oplog entries to retrieve. I've changed that to instead be ctx.snapshots_iter(), which returns a lazy iterator. We need this because we don't know specifically how far to walk back to find the undo target, so we cannot provide a limit upfront.

One small behavior change here is that when iterating from a specific oplog commit, that commit isn't included, whereas before it would be. I think this behavior is more appropriate for pagination since clients can just pass the last commit and get exactly the next page to render. There was even a TODO about that in the Svelte app.

GUI changes

The new OperationKind did require some changes in Svelte land, which I'm really not familiar with, so I would like some extra eyes on that.

@github-actions github-actions Bot added rust Pull requests that update Rust code CLI The command-line program `but` labels May 7, 2026
@davidpdrsn davidpdrsn force-pushed the dp-repeat-undo branch 9 times, most recently from e32a85f to adb6018 Compare May 7, 2026 14:57
Comment thread crates/gitbutler-oplog/src/oplog.rs Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the oplog/undo plumbing so repeated but undo walks further back in history (instead of undoing the previous undo), and introduces a lazy snapshot iterator to support traversing the oplog without a pre-known limit. It also attempts to distinguish “undo restores” from explicit but oplog restore operations via new restore/oplog kinds.

Changes:

  • Added lazy snapshot traversal (snapshots_iter) and updated callers/tests away from list_snapshots(limit, ...).
  • Added RestoreKind / new OperationKind variants and wired them through restore APIs.
  • Added undo-target selection logic (get_undo_target_snapshot) and new CLI tests for repeated undo.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
crates/gitbutler-oplog/src/oplog.rs Replaces eager snapshot listing with an iterator; adds RestoreKind; updates restore snapshot recording.
crates/gitbutler-oplog/src/lib.rs Re-exports RestoreKind.
crates/gitbutler-oplog/src/entry.rs Splits restore operation kinds and adds backward-compatible parsing for legacy trailer values.
crates/gitbutler-branch-actions/tests/branch-actions/virtual_branches/oplog.rs Migrates tests from list_snapshots to snapshots_iter and updates restore signature.
crates/but/tests/but/command/undo.rs Adds CLI tests for repeated undo and explicit restore undo behavior.
crates/but/src/command/legacy/status/tui/mod.rs Switches undo flow to get_undo_target_snapshot and passes restore kind.
crates/but/src/command/legacy/rub/squash.rs Updates restore signature on squash rollback path.
crates/but/src/command/legacy/oplog.rs Migrates oplog list to iterator; switches undo to get_undo_target_snapshot; updates restore API calls.
crates/but-api/src/legacy/oplog.rs Implements iterator wrapper + undo-target logic; introduces API-level RestoreKind; updates restore API signature.

Comment thread crates/gitbutler-oplog/src/oplog.rs Outdated
Comment thread crates/gitbutler-oplog/src/oplog.rs Outdated
Comment thread crates/but-api/src/legacy/oplog.rs Outdated
Comment thread crates/but-api/src/legacy/oplog.rs Outdated
Comment thread crates/but/src/command/legacy/oplog.rs Outdated
Comment thread crates/but/tests/but/command/undo.rs
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.

Comment thread crates/gitbutler-oplog/src/oplog.rs Outdated
Comment thread crates/but-api/src/legacy/oplog.rs
Comment thread crates/gitbutler-oplog/src/oplog.rs Outdated
Comment thread crates/but-api/src/legacy/oplog.rs Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.

Comment thread crates/but-api/src/legacy/oplog.rs
Comment thread crates/gitbutler-oplog/src/entry.rs Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.

Comment thread crates/gitbutler-oplog/src/entry.rs Outdated
Comment thread crates/but/tests/but/command/undo.rs
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 5 comments.

Comment thread crates/gitbutler-oplog/src/oplog.rs Outdated
Comment thread crates/gitbutler-oplog/src/oplog.rs
Comment thread crates/but-api/src/legacy/oplog.rs
Comment thread crates/gitbutler-branch-actions/tests/branch-actions/virtual_branches/oplog.rs Outdated
Comment thread crates/but-api/src/legacy/oplog.rs
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 1 comment.

Comment thread crates/gitbutler-oplog/src/oplog.rs Outdated
@davidpdrsn davidpdrsn force-pushed the dp-repeat-undo branch 2 times, most recently from d7b7913 to 2122715 Compare May 7, 2026 17:38
@davidpdrsn davidpdrsn marked this pull request as ready for review May 7, 2026 17:55
@davidpdrsn davidpdrsn requested review from Copilot, krlvi, mtsgrd and slarse May 7, 2026 17:55
@davidpdrsn davidpdrsn changed the title cli: make repeated but undos work cli,tui: make repeated but undos work May 7, 2026
@davidpdrsn davidpdrsn changed the title cli,tui: make repeated but undos work cli+tui: make repeated but undos work May 7, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 1 comment.

Comment thread crates/but-api/src/legacy/oplog.rs
@mtsgrd mtsgrd changed the title cli+tui: make repeated but undos work Fix PR/MR base branches going stale after pushing stacks May 7, 2026
@slarse slarse changed the title Fix PR/MR base branches going stale after pushing stacks cli+tui: make repeated but undos work May 8, 2026
Comment thread crates/but-api/src/legacy/oplog.rs
Comment thread crates/but/tests/but/command/undo.rs
Comment thread crates/gitbutler-oplog/src/oplog.rs
@mtsgrd
Copy link
Copy Markdown
Contributor

mtsgrd commented May 8, 2026

lgtm

Copilot AI review requested due to automatic review settings May 8, 2026 11:13
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated no new comments.

@davidpdrsn davidpdrsn merged commit 94e3d2a into master May 8, 2026
40 checks passed
@davidpdrsn davidpdrsn deleted the dp-repeat-undo branch May 8, 2026 14:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLI The command-line program `but` @gitbutler/desktop rust Pull requests that update Rust code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants