% no bookmarks
no bookmarks set
% bookmark rev -1
% list bookmarks
* X -1:000000000000
% bookmark X moved to rev 0
* X 0:f7b1eb17ad24
% look up bookmark
changeset: 0:f7b1eb17ad24
tag: X
tag: tip
user: test
date: Thu Jan 01 00:00:00 1970 +0000
summary: 0
% second bookmark for rev 0
% bookmark rev -1 again
% list bookmarks
* X2 0:f7b1eb17ad24
* X 0:f7b1eb17ad24
Y -1:000000000000
% bookmarks X and X2 moved to rev 1, Y at rev -1
* X2 1:925d80f479bb
* X 1:925d80f479bb
Y -1:000000000000
% bookmark rev 0 again
% bookmarks X and X2 moved to rev 2, Y at rev -1, Z at rev 0
* X2 2:0316ce92851d
* X 2:0316ce92851d
Z 0:f7b1eb17ad24
Y -1:000000000000
% rename nonexistent bookmark
abort: a bookmark of this name does not exist
% rename to existent bookmark
abort: a bookmark of the same name already exists
% force rename to existent bookmark
% list bookmarks
* X2 2:0316ce92851d
* Y 2:0316ce92851d
Z 0:f7b1eb17ad24
% rename without new name
abort: new bookmark name required
% delete without name
abort: bookmark name required
% delete nonexistent bookmark
abort: a bookmark of this name does not exist
% bookmark name with spaces should be stripped
% list bookmarks
* X2 2:0316ce92851d
* Y 2:0316ce92851d
Z 0:f7b1eb17ad24
* x y 2:0316ce92851d
% look up stripped bookmark name
changeset: 2:0316ce92851d
tag: X2
tag: Y
tag: tip
tag: x y
user: test
date: Thu Jan 01 00:00:00 1970 +0000
summary: 2
% reject bookmark name with newline
abort: bookmark name cannot contain newlines
% bookmark with existing name
abort: a bookmark of the same name already exists
% force bookmark with existing name
% list bookmarks
* X2 2:0316ce92851d
* Y 2:0316ce92851d
* Z 2:0316ce92851d
* x y 2:0316ce92851d
% revision but no bookmark name
abort: bookmark name required