revert/shelf/undo/redo

John A Meinel john at arbash-meinel.com
Wed Oct 19 04:28:01 BST 2005


Martin Pool wrote:
> mpe's shelf plugin (also in bzrtools) is very cool, and i encourage
> people who have not yet used it to try it out.  It shows all the
> changed diff hunks in the working tree and lets you choose which ones
> you would like to keep, and the others are set aside into .bzr-shelf.
>
> We also have 'bzr revert' which undoes all changes to reset the
> directory back to the previous revision.  As has been recently
> discussed, this has some risk of destroying user data.  To fix the
> most immediate problem we should probably give revert an option that
> says whether newly-added files should be deleted or just unversioned.
>
> The Arch solution to this is more or less, that the "undo" command
> saves a changeset representing the uncommitted changes are stored to a
> file called (approximately) ,,undo-1, and then removes them.  They can
> be restored by just applying the changeset, which is what the redo
> command does.  You can have several of these files.  This is a rather
> elegant way to allow stacked undo operations on the working directory.
>  There should be less worry about deleting files or making backups
> from the revert command because any deleted content can be easily
> removed.
>
> So we could perhaps adopt this approach.

I think some sort of undo would be nice. I don't know that "shelve"
isn't sufficient for it, perhaps a "shelve --hunks" which lets you
decide what to shelve. (or an "undo --hunks" if you prefer that word).

I think at least one of the things that was blocking an implementation
was that Aaron wanted to see changesets get into the core so that when
you did "undo" it could create a real text-format changeset.

I did recently update my changeset plugin to at least be able to
*create* changesets with the new bzr v5 stuff. I haven't worked on being
able to read them yet.

And yes, my changeset plugin does currently expect there to be a full
revision existing, but you could also create a changeset against the
WorkingTree, I just felt for transmission purposes it was better to have
a real commit.

>
> I'd like to at least keep 'revert' as an alias.
>
> In practice 'tla undo' would sometimes fail because of trouble
> generating or applying the changeset, which is annoying because
> 'revert' should be a way to get back to a known state.  I don't see
> any in-principle problem in making it reliable; it's just a matter of
> testing.

I think there are specific reasons why "tla undo" could fail. In general
it required a lint clean tree, so if you were using taglines then
copying a file meant that there were two files with the same id. So
which one is the "official" one. (You could use heuristics, but
somewhere it always fails). Since bzr doesn't support taglines, that
failure is gone.

There are other ways that you could break linting with tla, that I don't
think are possible in bzr. tla required all files to mean something,
even if it was precious, unrecognized was (configurably) a lint failure.

>
> The changeset needs to keep track of any pending-merges (which I think
> can be done by the current code.)
>
> The 'redo' command to reverse an undo can potentially generate
> conflicts if the files have changed in the meantime.

My feeling is that "redo" would just be "merge this anonymous revision"
which exists as a changeset.

I know Aaron thought that undo could actually create a (named/unnamed)
revision snapshot of the current tree, and then create a changeset
against it, and unmerge it.

>
> It would be nice to factor out the hunk-picking parts of shelve and
> make them reusable by this and perhaps by 'commit --interactive'.
>
> It would be nice if both undo and redo could take a list of selected files.

Certainly. Lists of files, and possibly hunks inside those files as well
(for redo/undo/merge/commit could be nice).

>
> In the first cut it would be OK if there was not a stack but just a
> single undo slot.  If we do have a stack, eventually it might be nice
> to be able to redo them out of order.  (Or perhaps this gets too
> complex.)  I suppose people can always apply them by hand.

Well, in my mind a stack is the easy part:
for i in xrange(10000):
  fn = 'undo-%4.4d' % i
  if not os.path.exists(fn):
    break;
else:
  raise BzrError('Too many undo files')

>
> So to sum up:
>
>   bzr undo [FILE]
>      revert and save changes to given files or directories, or to the
> whole tree.
>      if the whole tree is reverted, also clears the list of pending merges.
>
>   bzr redo [FILE]
>      restore undone changes to selected files, or the whole tree.
>
> Any comments (particularly from people who might have used arch?)

I think making redo be file specific is a little bit tricky, but can be
done.

The other hard part is do you use pre-change or post-change names for
renames/deletes/etc.

If you delete a file, and rename another file over it, what do you do?

I believe later versions of baz allowed you to pass a flag suggesting
which inventory to look for files. (old vs new).

John
=:->

>
> --
> Martin
>
>

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 253 bytes
Desc: OpenPGP digital signature
Url : https://lists.ubuntu.com/archives/bazaar/attachments/20051018/e8b2e9aa/attachment.pgp 


More information about the bazaar mailing list