(fwd) bzr shelve feedback
Ivan Krstic
krstic at fas.harvard.edu
Sat Nov 26 22:16:54 GMT 2005
[Sorry, long.]
Michael Ellerman wrote:
> I'm pretty down on the idea of "undo" generally, because I'm not convinced we
> can actually make it do what users want:
Well, we probably can, it's just not easy.
> # bzr init
> # bzr add file.txt
> # echo "hello world" > file.txt
> # bzr ci -m "Add file.txt"
> # bzr rename file.txt different.txt
> # echo "a year's work" >> different.txt
> # echo "another year's work" >> different.txt
> # bzr rename different.txt really_different.txt
To continue your example, here's a purely prototypical UI:
$ bzr actions
-- Undo history ('bzr undo' undoes topmost action):
1 rename different.txt -> really_different.txt 4 minutes ago
2 modify different.txt 6 minutes ago
3 rename file.txt -> different.txt 5 hours ago
4 commit revno. 1441 Yesterday, 3:53 PM
5 add file.txt Yesterday, 3:55 PM
$ bzr undo -v
bzr: undoing 'rename different.txt -> really_different.txt'
from 4 minutes ago
$ bzr actions
-- Undo history ('bzr undo' undoes topmost action):
1 modify different.txt 7 minutes ago
2 rename file.txt -> different.txt 5 hours ago
3 commit revno. 1441 Yesterday, 3:53 PM
4 add file.txt Yesterday, 3:55 PM
-- Redo history ('bzr redo' redoes topmost action):
1 rename different.txt -> really_different.txt 1 minute ago
$ bzr undo --to-last-commit
bzr: undoing 'modify different.txt' from 8 minutes ago
undoing 'rename file.txt -> different.txt' from 5 hours ago
$ bzr pull
$ bzr actions
-- Undo history ('bzr undo' undoes topmost action):
1 pull 3 minutes ago
2 commit revno. 1441 Yesterday, 3:53 PM
3 add file.txt Yesterday, 3:55 PM
-- Redo history ('bzr redo' redoes topmost action):
1 rename file.txt -> different.txt 3 minutes ago
2 modify different.txt 3 minutes ago
3 rename different.txt -> really_different.txt 5 minutes ago
$ bzr redo --count 3
The finer point here is that you could have your undo history go back to
the moment you ran 'init' on a directory, whereas your redo history is
cleared on every commit -- but stored, so that if you undo the commit,
you get back the previous commit's whole redo history. Basically,
implementing this gives you the ability to fast-forward and rewind to an
arbitrary point in the branch's history, with very fine granularity. And
speaking as a user, this rocks. A whole lot.
A problem that comes up is non-linear undo/redo, which is very useful
with unrelated changes. Consider the above. That 'redo --count 3' tries
to apply the user's modifications to 'different.txt', conflicts all over
the place with the pulled tree, and puts a bunch of herringbone markers
in place before complaining to, say, Brad.
Brad freaks out, and wants to get his tree back to the (uncommitted)
state he had it in before pulling from upstream. There are two options:
1) Tell Brad 'too bad', because he really ought to have committed his
changes locally before pulling from upstream, or
2) Allow non-linear undo/redo, e.g., after the 'bzr redo --count 3' above:
$ bzr actions
-- Undo history ('bzr undo' undoes topmost action):
1 rename different.txt -> really_different.txt 1 minute ago
2 modify different.txt [CONFLICT] 1 minute ago
3 rename file.txt -> different.txt 1 minute ago
4 pull 3 minutes ago
5 commit revno. 1441 Yesterday, 3:53 PM
6 add file.txt Yesterday, 3:55 PM
$ bzr undo 4 -v
bzr: undoing 'pull' from 3 minutes ago
This introduces dependency issues, as doing 'undo 3' instead of 'undo 4'
above should obviously fail, because you can't undo 3 without undoing 1
and 2 first. However, such non-linear undo/redo would only have to work
up until the last commit, and its dependency resolution is relatively
straightforward, I think.
> Undo what?
>
> 1. Rename really_different.txt back to different.txt?
> 2. Remove "another year's work" from different.txt?
> NB. bzr _can't_ do that, but a (naive?) user might expect it to, Microsoft
> word can right?
> 3. Remove "a year's work" from different.txt?
> 4. Rename different.txt back to file.txt?
> 5. Set different.txt back to the commited content "hello world" ?
There are reasonable and unreasonable use cases for undo. bzr is not a
text editor, and sane users don't expect it to be, so I don't think we
should care at all about 2 in your list. I think most bzr operations can
have a reasonable, history-based undo, however.
> Users are also going to expect undo to be able to undo a commit, merge, pull
> etc. What if we're asked to undo a push?
If we desired to, I think we could support undo for all of them. Push is
trickier, but certainly not insurmountable.
Doing proper undo/redo just means more bookkeeping, since now you
suddenly get to keep a bunch of extra working tree snapshots around.
Storage-wise, I suspect this is reasonably cheap in weaves, and it can
be optimized either by saying that a branch only allows undo/redo up
until the last commit, or by having a maintenance command that allows
purging snapshots for old revisions (thus collapsing their undo/redo
histories).
Thoughts? Brad, would something like this make you and the LP guys happy?
(Please don't pounce on the actual 'actions' example above: it's merely
there as an example. The question is whether we want to do this at all,
and only if we do, what it would look like.)
--
Ivan Krstic <krstic at fas.harvard.edu> | 0x147C722D
More information about the bazaar
mailing list