##// END OF EJS Templates
bookmarks: catch the proper exception for missing revisions...
Matt Mackall -
r16573:5983de86 2.2.1 stable
parent child Browse files
Show More
@@ -1,242 +1,242 b''
1 # Mercurial bookmark support code
1 # Mercurial bookmark support code
2 #
2 #
3 # Copyright 2008 David Soria Parra <dsp@php.net>
3 # Copyright 2008 David Soria Parra <dsp@php.net>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from mercurial.i18n import _
8 from mercurial.i18n import _
9 from mercurial.node import hex
9 from mercurial.node import hex
10 from mercurial import encoding, error, util
10 from mercurial import encoding, util
11 import errno, os
11 import errno, os
12
12
13 def valid(mark):
13 def valid(mark):
14 for c in (':', '\0', '\n', '\r'):
14 for c in (':', '\0', '\n', '\r'):
15 if c in mark:
15 if c in mark:
16 return False
16 return False
17 return True
17 return True
18
18
19 def read(repo):
19 def read(repo):
20 '''Parse .hg/bookmarks file and return a dictionary
20 '''Parse .hg/bookmarks file and return a dictionary
21
21
22 Bookmarks are stored as {HASH}\\s{NAME}\\n (localtags format) values
22 Bookmarks are stored as {HASH}\\s{NAME}\\n (localtags format) values
23 in the .hg/bookmarks file.
23 in the .hg/bookmarks file.
24 Read the file and return a (name=>nodeid) dictionary
24 Read the file and return a (name=>nodeid) dictionary
25 '''
25 '''
26 bookmarks = {}
26 bookmarks = {}
27 try:
27 try:
28 for line in repo.opener('bookmarks'):
28 for line in repo.opener('bookmarks'):
29 line = line.strip()
29 line = line.strip()
30 if not line:
30 if not line:
31 continue
31 continue
32 if ' ' not in line:
32 if ' ' not in line:
33 repo.ui.warn(_('malformed line in .hg/bookmarks: %r\n') % line)
33 repo.ui.warn(_('malformed line in .hg/bookmarks: %r\n') % line)
34 continue
34 continue
35 sha, refspec = line.split(' ', 1)
35 sha, refspec = line.split(' ', 1)
36 refspec = encoding.tolocal(refspec)
36 refspec = encoding.tolocal(refspec)
37 try:
37 try:
38 bookmarks[refspec] = repo.changelog.lookup(sha)
38 bookmarks[refspec] = repo.changelog.lookup(sha)
39 except error.RepoLookupError:
39 except LookupError:
40 pass
40 pass
41 except IOError, inst:
41 except IOError, inst:
42 if inst.errno != errno.ENOENT:
42 if inst.errno != errno.ENOENT:
43 raise
43 raise
44 return bookmarks
44 return bookmarks
45
45
46 def readcurrent(repo):
46 def readcurrent(repo):
47 '''Get the current bookmark
47 '''Get the current bookmark
48
48
49 If we use gittishsh branches we have a current bookmark that
49 If we use gittishsh branches we have a current bookmark that
50 we are on. This function returns the name of the bookmark. It
50 we are on. This function returns the name of the bookmark. It
51 is stored in .hg/bookmarks.current
51 is stored in .hg/bookmarks.current
52 '''
52 '''
53 mark = None
53 mark = None
54 try:
54 try:
55 file = repo.opener('bookmarks.current')
55 file = repo.opener('bookmarks.current')
56 except IOError, inst:
56 except IOError, inst:
57 if inst.errno != errno.ENOENT:
57 if inst.errno != errno.ENOENT:
58 raise
58 raise
59 return None
59 return None
60 try:
60 try:
61 # No readline() in posixfile_nt, reading everything is cheap
61 # No readline() in posixfile_nt, reading everything is cheap
62 mark = encoding.tolocal((file.readlines() or [''])[0])
62 mark = encoding.tolocal((file.readlines() or [''])[0])
63 if mark == '' or mark not in repo._bookmarks:
63 if mark == '' or mark not in repo._bookmarks:
64 mark = None
64 mark = None
65 finally:
65 finally:
66 file.close()
66 file.close()
67 return mark
67 return mark
68
68
69 def write(repo):
69 def write(repo):
70 '''Write bookmarks
70 '''Write bookmarks
71
71
72 Write the given bookmark => hash dictionary to the .hg/bookmarks file
72 Write the given bookmark => hash dictionary to the .hg/bookmarks file
73 in a format equal to those of localtags.
73 in a format equal to those of localtags.
74
74
75 We also store a backup of the previous state in undo.bookmarks that
75 We also store a backup of the previous state in undo.bookmarks that
76 can be copied back on rollback.
76 can be copied back on rollback.
77 '''
77 '''
78 refs = repo._bookmarks
78 refs = repo._bookmarks
79
79
80 if repo._bookmarkcurrent not in refs:
80 if repo._bookmarkcurrent not in refs:
81 setcurrent(repo, None)
81 setcurrent(repo, None)
82 for mark in refs.keys():
82 for mark in refs.keys():
83 if not valid(mark):
83 if not valid(mark):
84 raise util.Abort(_("bookmark '%s' contains illegal "
84 raise util.Abort(_("bookmark '%s' contains illegal "
85 "character" % mark))
85 "character" % mark))
86
86
87 wlock = repo.wlock()
87 wlock = repo.wlock()
88 try:
88 try:
89
89
90 file = repo.opener('bookmarks', 'w', atomictemp=True)
90 file = repo.opener('bookmarks', 'w', atomictemp=True)
91 for refspec, node in refs.iteritems():
91 for refspec, node in refs.iteritems():
92 file.write("%s %s\n" % (hex(node), encoding.fromlocal(refspec)))
92 file.write("%s %s\n" % (hex(node), encoding.fromlocal(refspec)))
93 file.close()
93 file.close()
94
94
95 # touch 00changelog.i so hgweb reloads bookmarks (no lock needed)
95 # touch 00changelog.i so hgweb reloads bookmarks (no lock needed)
96 try:
96 try:
97 os.utime(repo.sjoin('00changelog.i'), None)
97 os.utime(repo.sjoin('00changelog.i'), None)
98 except OSError:
98 except OSError:
99 pass
99 pass
100
100
101 finally:
101 finally:
102 wlock.release()
102 wlock.release()
103
103
104 def setcurrent(repo, mark):
104 def setcurrent(repo, mark):
105 '''Set the name of the bookmark that we are currently on
105 '''Set the name of the bookmark that we are currently on
106
106
107 Set the name of the bookmark that we are on (hg update <bookmark>).
107 Set the name of the bookmark that we are on (hg update <bookmark>).
108 The name is recorded in .hg/bookmarks.current
108 The name is recorded in .hg/bookmarks.current
109 '''
109 '''
110 current = repo._bookmarkcurrent
110 current = repo._bookmarkcurrent
111 if current == mark:
111 if current == mark:
112 return
112 return
113
113
114 if mark not in repo._bookmarks:
114 if mark not in repo._bookmarks:
115 mark = ''
115 mark = ''
116 if not valid(mark):
116 if not valid(mark):
117 raise util.Abort(_("bookmark '%s' contains illegal "
117 raise util.Abort(_("bookmark '%s' contains illegal "
118 "character" % mark))
118 "character" % mark))
119
119
120 wlock = repo.wlock()
120 wlock = repo.wlock()
121 try:
121 try:
122 file = repo.opener('bookmarks.current', 'w', atomictemp=True)
122 file = repo.opener('bookmarks.current', 'w', atomictemp=True)
123 file.write(encoding.fromlocal(mark))
123 file.write(encoding.fromlocal(mark))
124 file.close()
124 file.close()
125 finally:
125 finally:
126 wlock.release()
126 wlock.release()
127 repo._bookmarkcurrent = mark
127 repo._bookmarkcurrent = mark
128
128
129 def unsetcurrent(repo):
129 def unsetcurrent(repo):
130 wlock = repo.wlock()
130 wlock = repo.wlock()
131 try:
131 try:
132 try:
132 try:
133 util.unlink(repo.join('bookmarks.current'))
133 util.unlink(repo.join('bookmarks.current'))
134 repo._bookmarkcurrent = None
134 repo._bookmarkcurrent = None
135 except OSError, inst:
135 except OSError, inst:
136 if inst.errno != errno.ENOENT:
136 if inst.errno != errno.ENOENT:
137 raise
137 raise
138 finally:
138 finally:
139 wlock.release()
139 wlock.release()
140
140
141 def updatecurrentbookmark(repo, oldnode, curbranch):
141 def updatecurrentbookmark(repo, oldnode, curbranch):
142 try:
142 try:
143 return update(repo, oldnode, repo.branchtags()[curbranch])
143 return update(repo, oldnode, repo.branchtags()[curbranch])
144 except KeyError:
144 except KeyError:
145 if curbranch == "default": # no default branch!
145 if curbranch == "default": # no default branch!
146 return update(repo, oldnode, repo.lookup("tip"))
146 return update(repo, oldnode, repo.lookup("tip"))
147 else:
147 else:
148 raise util.Abort(_("branch %s not found") % curbranch)
148 raise util.Abort(_("branch %s not found") % curbranch)
149
149
150 def update(repo, parents, node):
150 def update(repo, parents, node):
151 marks = repo._bookmarks
151 marks = repo._bookmarks
152 update = False
152 update = False
153 mark = repo._bookmarkcurrent
153 mark = repo._bookmarkcurrent
154 if mark and marks[mark] in parents:
154 if mark and marks[mark] in parents:
155 old = repo[marks[mark]]
155 old = repo[marks[mark]]
156 new = repo[node]
156 new = repo[node]
157 if new in old.descendants():
157 if new in old.descendants():
158 marks[mark] = new.node()
158 marks[mark] = new.node()
159 update = True
159 update = True
160 if update:
160 if update:
161 repo._writebookmarks(marks)
161 repo._writebookmarks(marks)
162 return update
162 return update
163
163
164 def listbookmarks(repo):
164 def listbookmarks(repo):
165 # We may try to list bookmarks on a repo type that does not
165 # We may try to list bookmarks on a repo type that does not
166 # support it (e.g., statichttprepository).
166 # support it (e.g., statichttprepository).
167 marks = getattr(repo, '_bookmarks', {})
167 marks = getattr(repo, '_bookmarks', {})
168
168
169 d = {}
169 d = {}
170 for k, v in marks.iteritems():
170 for k, v in marks.iteritems():
171 # don't expose local divergent bookmarks
171 # don't expose local divergent bookmarks
172 if '@' not in k or k.endswith('@'):
172 if '@' not in k or k.endswith('@'):
173 d[k] = hex(v)
173 d[k] = hex(v)
174 return d
174 return d
175
175
176 def pushbookmark(repo, key, old, new):
176 def pushbookmark(repo, key, old, new):
177 w = repo.wlock()
177 w = repo.wlock()
178 try:
178 try:
179 marks = repo._bookmarks
179 marks = repo._bookmarks
180 if hex(marks.get(key, '')) != old:
180 if hex(marks.get(key, '')) != old:
181 return False
181 return False
182 if new == '':
182 if new == '':
183 del marks[key]
183 del marks[key]
184 else:
184 else:
185 if new not in repo:
185 if new not in repo:
186 return False
186 return False
187 marks[key] = repo[new].node()
187 marks[key] = repo[new].node()
188 write(repo)
188 write(repo)
189 return True
189 return True
190 finally:
190 finally:
191 w.release()
191 w.release()
192
192
193 def updatefromremote(ui, repo, remote, path):
193 def updatefromremote(ui, repo, remote, path):
194 ui.debug("checking for updated bookmarks\n")
194 ui.debug("checking for updated bookmarks\n")
195 rb = remote.listkeys('bookmarks')
195 rb = remote.listkeys('bookmarks')
196 changed = False
196 changed = False
197 for k in rb.keys():
197 for k in rb.keys():
198 if k in repo._bookmarks:
198 if k in repo._bookmarks:
199 nr, nl = rb[k], repo._bookmarks[k]
199 nr, nl = rb[k], repo._bookmarks[k]
200 if nr in repo:
200 if nr in repo:
201 cr = repo[nr]
201 cr = repo[nr]
202 cl = repo[nl]
202 cl = repo[nl]
203 if cl.rev() >= cr.rev():
203 if cl.rev() >= cr.rev():
204 continue
204 continue
205 if cr in cl.descendants():
205 if cr in cl.descendants():
206 repo._bookmarks[k] = cr.node()
206 repo._bookmarks[k] = cr.node()
207 changed = True
207 changed = True
208 ui.status(_("updating bookmark %s\n") % k)
208 ui.status(_("updating bookmark %s\n") % k)
209 else:
209 else:
210 # find a unique @ suffix
210 # find a unique @ suffix
211 for x in range(1, 100):
211 for x in range(1, 100):
212 n = '%s@%d' % (k, x)
212 n = '%s@%d' % (k, x)
213 if n not in repo._bookmarks:
213 if n not in repo._bookmarks:
214 break
214 break
215 # try to use an @pathalias suffix
215 # try to use an @pathalias suffix
216 # if an @pathalias already exists, we overwrite (update) it
216 # if an @pathalias already exists, we overwrite (update) it
217 for p, u in ui.configitems("paths"):
217 for p, u in ui.configitems("paths"):
218 if path == u:
218 if path == u:
219 n = '%s@%s' % (k, p)
219 n = '%s@%s' % (k, p)
220
220
221 repo._bookmarks[n] = cr.node()
221 repo._bookmarks[n] = cr.node()
222 changed = True
222 changed = True
223 ui.warn(_("divergent bookmark %s stored as %s\n") % (k, n))
223 ui.warn(_("divergent bookmark %s stored as %s\n") % (k, n))
224
224
225 if changed:
225 if changed:
226 write(repo)
226 write(repo)
227
227
228 def diff(ui, repo, remote):
228 def diff(ui, repo, remote):
229 ui.status(_("searching for changed bookmarks\n"))
229 ui.status(_("searching for changed bookmarks\n"))
230
230
231 lmarks = repo.listkeys('bookmarks')
231 lmarks = repo.listkeys('bookmarks')
232 rmarks = remote.listkeys('bookmarks')
232 rmarks = remote.listkeys('bookmarks')
233
233
234 diff = sorted(set(rmarks) - set(lmarks))
234 diff = sorted(set(rmarks) - set(lmarks))
235 for k in diff:
235 for k in diff:
236 mark = ui.debugflag and rmarks[k] or rmarks[k][:12]
236 mark = ui.debugflag and rmarks[k] or rmarks[k][:12]
237 ui.write(" %-25s %s\n" % (k, mark))
237 ui.write(" %-25s %s\n" % (k, mark))
238
238
239 if len(diff) <= 0:
239 if len(diff) <= 0:
240 ui.status(_("no changed bookmarks found\n"))
240 ui.status(_("no changed bookmarks found\n"))
241 return 1
241 return 1
242 return 0
242 return 0
@@ -1,373 +1,378 b''
1 $ hg init
1 $ hg init
2
2
3 no bookmarks
3 no bookmarks
4
4
5 $ hg bookmarks
5 $ hg bookmarks
6 no bookmarks set
6 no bookmarks set
7
7
8 bookmark rev -1
8 bookmark rev -1
9
9
10 $ hg bookmark X
10 $ hg bookmark X
11
11
12 list bookmarks
12 list bookmarks
13
13
14 $ hg bookmarks
14 $ hg bookmarks
15 * X -1:000000000000
15 * X -1:000000000000
16
16
17 list bookmarks with color
17 list bookmarks with color
18
18
19 $ hg --config extensions.color= --config color.mode=ansi \
19 $ hg --config extensions.color= --config color.mode=ansi \
20 > bookmarks --color=always
20 > bookmarks --color=always
21 \x1b[0;32m * X -1:000000000000\x1b[0m (esc)
21 \x1b[0;32m * X -1:000000000000\x1b[0m (esc)
22
22
23 $ echo a > a
23 $ echo a > a
24 $ hg add a
24 $ hg add a
25 $ hg commit -m 0
25 $ hg commit -m 0
26
26
27 bookmark X moved to rev 0
27 bookmark X moved to rev 0
28
28
29 $ hg bookmarks
29 $ hg bookmarks
30 * X 0:f7b1eb17ad24
30 * X 0:f7b1eb17ad24
31
31
32 look up bookmark
32 look up bookmark
33
33
34 $ hg log -r X
34 $ hg log -r X
35 changeset: 0:f7b1eb17ad24
35 changeset: 0:f7b1eb17ad24
36 bookmark: X
36 bookmark: X
37 tag: tip
37 tag: tip
38 user: test
38 user: test
39 date: Thu Jan 01 00:00:00 1970 +0000
39 date: Thu Jan 01 00:00:00 1970 +0000
40 summary: 0
40 summary: 0
41
41
42
42
43 second bookmark for rev 0
43 second bookmark for rev 0
44
44
45 $ hg bookmark X2
45 $ hg bookmark X2
46
46
47 bookmark rev -1 again
47 bookmark rev -1 again
48
48
49 $ hg bookmark -r null Y
49 $ hg bookmark -r null Y
50
50
51 list bookmarks
51 list bookmarks
52
52
53 $ hg bookmarks
53 $ hg bookmarks
54 X 0:f7b1eb17ad24
54 X 0:f7b1eb17ad24
55 * X2 0:f7b1eb17ad24
55 * X2 0:f7b1eb17ad24
56 Y -1:000000000000
56 Y -1:000000000000
57
57
58 $ echo b > b
58 $ echo b > b
59 $ hg add b
59 $ hg add b
60 $ hg commit -m 1
60 $ hg commit -m 1
61
61
62 bookmarks revset
62 bookmarks revset
63
63
64 $ hg log -r 'bookmark()'
64 $ hg log -r 'bookmark()'
65 changeset: 0:f7b1eb17ad24
65 changeset: 0:f7b1eb17ad24
66 bookmark: X
66 bookmark: X
67 user: test
67 user: test
68 date: Thu Jan 01 00:00:00 1970 +0000
68 date: Thu Jan 01 00:00:00 1970 +0000
69 summary: 0
69 summary: 0
70
70
71 changeset: 1:925d80f479bb
71 changeset: 1:925d80f479bb
72 bookmark: X2
72 bookmark: X2
73 tag: tip
73 tag: tip
74 user: test
74 user: test
75 date: Thu Jan 01 00:00:00 1970 +0000
75 date: Thu Jan 01 00:00:00 1970 +0000
76 summary: 1
76 summary: 1
77
77
78 $ hg log -r 'bookmark(Y)'
78 $ hg log -r 'bookmark(Y)'
79 $ hg log -r 'bookmark(X2)'
79 $ hg log -r 'bookmark(X2)'
80 changeset: 1:925d80f479bb
80 changeset: 1:925d80f479bb
81 bookmark: X2
81 bookmark: X2
82 tag: tip
82 tag: tip
83 user: test
83 user: test
84 date: Thu Jan 01 00:00:00 1970 +0000
84 date: Thu Jan 01 00:00:00 1970 +0000
85 summary: 1
85 summary: 1
86
86
87 $ hg log -r 'bookmark(unknown)'
87 $ hg log -r 'bookmark(unknown)'
88 abort: bookmark 'unknown' does not exist
88 abort: bookmark 'unknown' does not exist
89 [255]
89 [255]
90
90
91 $ hg help revsets | grep 'bookmark('
91 $ hg help revsets | grep 'bookmark('
92 "bookmark([name])"
92 "bookmark([name])"
93
93
94 bookmarks X and X2 moved to rev 1, Y at rev -1
94 bookmarks X and X2 moved to rev 1, Y at rev -1
95
95
96 $ hg bookmarks
96 $ hg bookmarks
97 X 0:f7b1eb17ad24
97 X 0:f7b1eb17ad24
98 * X2 1:925d80f479bb
98 * X2 1:925d80f479bb
99 Y -1:000000000000
99 Y -1:000000000000
100
100
101 bookmark rev 0 again
101 bookmark rev 0 again
102
102
103 $ hg bookmark -r 0 Z
103 $ hg bookmark -r 0 Z
104
104
105 $ hg update X
105 $ hg update X
106 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
106 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
107 $ echo c > c
107 $ echo c > c
108 $ hg add c
108 $ hg add c
109 $ hg commit -m 2
109 $ hg commit -m 2
110 created new head
110 created new head
111
111
112 bookmarks X moved to rev 2, Y at rev -1, Z at rev 0
112 bookmarks X moved to rev 2, Y at rev -1, Z at rev 0
113
113
114 $ hg bookmarks
114 $ hg bookmarks
115 * X 2:db815d6d32e6
115 * X 2:db815d6d32e6
116 X2 1:925d80f479bb
116 X2 1:925d80f479bb
117 Y -1:000000000000
117 Y -1:000000000000
118 Z 0:f7b1eb17ad24
118 Z 0:f7b1eb17ad24
119
119
120 rename nonexistent bookmark
120 rename nonexistent bookmark
121
121
122 $ hg bookmark -m A B
122 $ hg bookmark -m A B
123 abort: bookmark 'A' does not exist
123 abort: bookmark 'A' does not exist
124 [255]
124 [255]
125
125
126 rename to existent bookmark
126 rename to existent bookmark
127
127
128 $ hg bookmark -m X Y
128 $ hg bookmark -m X Y
129 abort: bookmark 'Y' already exists (use -f to force)
129 abort: bookmark 'Y' already exists (use -f to force)
130 [255]
130 [255]
131
131
132 force rename to existent bookmark
132 force rename to existent bookmark
133
133
134 $ hg bookmark -f -m X Y
134 $ hg bookmark -f -m X Y
135
135
136 list bookmarks
136 list bookmarks
137
137
138 $ hg bookmark
138 $ hg bookmark
139 X2 1:925d80f479bb
139 X2 1:925d80f479bb
140 * Y 2:db815d6d32e6
140 * Y 2:db815d6d32e6
141 Z 0:f7b1eb17ad24
141 Z 0:f7b1eb17ad24
142
142
143 rename without new name
143 rename without new name
144
144
145 $ hg bookmark -m Y
145 $ hg bookmark -m Y
146 abort: new bookmark name required
146 abort: new bookmark name required
147 [255]
147 [255]
148
148
149 delete without name
149 delete without name
150
150
151 $ hg bookmark -d
151 $ hg bookmark -d
152 abort: bookmark name required
152 abort: bookmark name required
153 [255]
153 [255]
154
154
155 delete nonexistent bookmark
155 delete nonexistent bookmark
156
156
157 $ hg bookmark -d A
157 $ hg bookmark -d A
158 abort: bookmark 'A' does not exist
158 abort: bookmark 'A' does not exist
159 [255]
159 [255]
160
160
161 bookmark name with spaces should be stripped
161 bookmark name with spaces should be stripped
162
162
163 $ hg bookmark ' x y '
163 $ hg bookmark ' x y '
164
164
165 list bookmarks
165 list bookmarks
166
166
167 $ hg bookmarks
167 $ hg bookmarks
168 X2 1:925d80f479bb
168 X2 1:925d80f479bb
169 Y 2:db815d6d32e6
169 Y 2:db815d6d32e6
170 Z 0:f7b1eb17ad24
170 Z 0:f7b1eb17ad24
171 * x y 2:db815d6d32e6
171 * x y 2:db815d6d32e6
172
172
173 look up stripped bookmark name
173 look up stripped bookmark name
174
174
175 $ hg log -r '"x y"'
175 $ hg log -r '"x y"'
176 changeset: 2:db815d6d32e6
176 changeset: 2:db815d6d32e6
177 bookmark: Y
177 bookmark: Y
178 bookmark: x y
178 bookmark: x y
179 tag: tip
179 tag: tip
180 parent: 0:f7b1eb17ad24
180 parent: 0:f7b1eb17ad24
181 user: test
181 user: test
182 date: Thu Jan 01 00:00:00 1970 +0000
182 date: Thu Jan 01 00:00:00 1970 +0000
183 summary: 2
183 summary: 2
184
184
185
185
186 reject bookmark name with newline
186 reject bookmark name with newline
187
187
188 $ hg bookmark '
188 $ hg bookmark '
189 > '
189 > '
190 abort: bookmark name cannot contain newlines
190 abort: bookmark name cannot contain newlines
191 [255]
191 [255]
192
192
193 bookmark with existing name
193 bookmark with existing name
194
194
195 $ hg bookmark Z
195 $ hg bookmark Z
196 abort: bookmark 'Z' already exists (use -f to force)
196 abort: bookmark 'Z' already exists (use -f to force)
197 [255]
197 [255]
198
198
199 force bookmark with existing name
199 force bookmark with existing name
200
200
201 $ hg bookmark -f Z
201 $ hg bookmark -f Z
202
202
203 list bookmarks
203 list bookmarks
204
204
205 $ hg bookmark
205 $ hg bookmark
206 X2 1:925d80f479bb
206 X2 1:925d80f479bb
207 Y 2:db815d6d32e6
207 Y 2:db815d6d32e6
208 * Z 2:db815d6d32e6
208 * Z 2:db815d6d32e6
209 x y 2:db815d6d32e6
209 x y 2:db815d6d32e6
210
210
211 revision but no bookmark name
211 revision but no bookmark name
212
212
213 $ hg bookmark -r .
213 $ hg bookmark -r .
214 abort: bookmark name required
214 abort: bookmark name required
215 [255]
215 [255]
216
216
217 bookmark name with whitespace only
217 bookmark name with whitespace only
218
218
219 $ hg bookmark ' '
219 $ hg bookmark ' '
220 abort: bookmark names cannot consist entirely of whitespace
220 abort: bookmark names cannot consist entirely of whitespace
221 [255]
221 [255]
222
222
223 invalid bookmark
223 invalid bookmark
224
224
225 $ hg bookmark 'foo:bar'
225 $ hg bookmark 'foo:bar'
226 abort: bookmark 'foo:bar' contains illegal character
226 abort: bookmark 'foo:bar' contains illegal character
227 [255]
227 [255]
228
228
229 the bookmark extension should be ignored now that it is part of core
229 the bookmark extension should be ignored now that it is part of core
230
230
231 $ echo "[extensions]" >> $HGRCPATH
231 $ echo "[extensions]" >> $HGRCPATH
232 $ echo "bookmarks=" >> $HGRCPATH
232 $ echo "bookmarks=" >> $HGRCPATH
233 $ hg bookmarks
233 $ hg bookmarks
234 X2 1:925d80f479bb
234 X2 1:925d80f479bb
235 Y 2:db815d6d32e6
235 Y 2:db815d6d32e6
236 * Z 2:db815d6d32e6
236 * Z 2:db815d6d32e6
237 x y 2:db815d6d32e6
237 x y 2:db815d6d32e6
238
238
239 test summary
239 test summary
240
240
241 $ hg summary
241 $ hg summary
242 parent: 2:db815d6d32e6 tip
242 parent: 2:db815d6d32e6 tip
243 2
243 2
244 branch: default
244 branch: default
245 bookmarks: *Z Y x y
245 bookmarks: *Z Y x y
246 commit: (clean)
246 commit: (clean)
247 update: 1 new changesets, 2 branch heads (merge)
247 update: 1 new changesets, 2 branch heads (merge)
248
248
249 test id
249 test id
250
250
251 $ hg id
251 $ hg id
252 db815d6d32e6 tip Y/Z/x y
252 db815d6d32e6 tip Y/Z/x y
253
253
254 test rollback
254 test rollback
255
255
256 $ echo foo > f1
256 $ echo foo > f1
257 $ hg ci -Amr
257 $ hg ci -Amr
258 adding f1
258 adding f1
259 $ hg bookmark -f Y -r 1
259 $ hg bookmark -f Y -r 1
260 $ hg bookmark -f Z -r 1
260 $ hg bookmark -f Z -r 1
261 $ hg rollback
261 $ hg rollback
262 repository tip rolled back to revision 2 (undo commit)
262 repository tip rolled back to revision 2 (undo commit)
263 working directory now based on revision 2
263 working directory now based on revision 2
264 $ hg bookmarks
264 $ hg bookmarks
265 X2 1:925d80f479bb
265 X2 1:925d80f479bb
266 Y 2:db815d6d32e6
266 Y 2:db815d6d32e6
267 * Z 2:db815d6d32e6
267 * Z 2:db815d6d32e6
268 x y 2:db815d6d32e6
268 x y 2:db815d6d32e6
269
269
270 test clone
270 test clone
271
271
272 $ hg bookmark -r 2 -i @
272 $ hg bookmark -r 2 -i @
273 $ hg bookmark -r 2 -i a@
273 $ hg bookmark -r 2 -i a@
274 $ hg bookmarks
274 $ hg bookmarks
275 @ 2:db815d6d32e6
275 @ 2:db815d6d32e6
276 X2 1:925d80f479bb
276 X2 1:925d80f479bb
277 Y 2:db815d6d32e6
277 Y 2:db815d6d32e6
278 * Z 2:db815d6d32e6
278 * Z 2:db815d6d32e6
279 a@ 2:db815d6d32e6
279 a@ 2:db815d6d32e6
280 x y 2:db815d6d32e6
280 x y 2:db815d6d32e6
281 $ hg clone . cloned-bookmarks
281 $ hg clone . cloned-bookmarks
282 updating to branch default
282 updating to branch default
283 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
283 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
284 $ hg -R cloned-bookmarks bookmarks
284 $ hg -R cloned-bookmarks bookmarks
285 @ 2:db815d6d32e6
285 @ 2:db815d6d32e6
286 X2 1:925d80f479bb
286 X2 1:925d80f479bb
287 Y 2:db815d6d32e6
287 Y 2:db815d6d32e6
288 Z 2:db815d6d32e6
288 Z 2:db815d6d32e6
289 a@ 2:db815d6d32e6
289 a@ 2:db815d6d32e6
290 x y 2:db815d6d32e6
290 x y 2:db815d6d32e6
291
291
292 test clone with pull protocol
292 test clone with pull protocol
293
293
294 $ hg clone --pull . cloned-bookmarks-pull
294 $ hg clone --pull . cloned-bookmarks-pull
295 requesting all changes
295 requesting all changes
296 adding changesets
296 adding changesets
297 adding manifests
297 adding manifests
298 adding file changes
298 adding file changes
299 added 3 changesets with 3 changes to 3 files (+1 heads)
299 added 3 changesets with 3 changes to 3 files (+1 heads)
300 updating to branch default
300 updating to branch default
301 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
301 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
302 $ hg -R cloned-bookmarks-pull bookmarks
302 $ hg -R cloned-bookmarks-pull bookmarks
303 @ 2:db815d6d32e6
303 @ 2:db815d6d32e6
304 X2 1:925d80f479bb
304 X2 1:925d80f479bb
305 Y 2:db815d6d32e6
305 Y 2:db815d6d32e6
306 Z 2:db815d6d32e6
306 Z 2:db815d6d32e6
307 a@ 2:db815d6d32e6
307 a@ 2:db815d6d32e6
308 x y 2:db815d6d32e6
308 x y 2:db815d6d32e6
309
309
310 $ hg bookmark -d @
310 $ hg bookmark -d @
311 $ hg bookmark -d a@
311 $ hg bookmark -d a@
312
312
313 test clone with a specific revision
313 test clone with a specific revision
314
314
315 $ hg clone -r 925d80 . cloned-bookmarks-rev
315 $ hg clone -r 925d80 . cloned-bookmarks-rev
316 adding changesets
316 adding changesets
317 adding manifests
317 adding manifests
318 adding file changes
318 adding file changes
319 added 2 changesets with 2 changes to 2 files
319 added 2 changesets with 2 changes to 2 files
320 updating to branch default
320 updating to branch default
321 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
321 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
322 $ hg -R cloned-bookmarks-rev bookmarks
322 $ hg -R cloned-bookmarks-rev bookmarks
323 X2 1:925d80f479bb
323 X2 1:925d80f479bb
324
324
325 create bundle with two heads
325 create bundle with two heads
326
326
327 $ hg clone . tobundle
327 $ hg clone . tobundle
328 updating to branch default
328 updating to branch default
329 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
329 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
330 $ echo x > tobundle/x
330 $ echo x > tobundle/x
331 $ hg -R tobundle add tobundle/x
331 $ hg -R tobundle add tobundle/x
332 $ hg -R tobundle commit -m'x'
332 $ hg -R tobundle commit -m'x'
333 $ hg -R tobundle update -r -2
333 $ hg -R tobundle update -r -2
334 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
334 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
335 $ echo y > tobundle/y
335 $ echo y > tobundle/y
336 $ hg -R tobundle branch test
336 $ hg -R tobundle branch test
337 marked working directory as branch test
337 marked working directory as branch test
338 (branches are permanent and global, did you want a bookmark?)
338 (branches are permanent and global, did you want a bookmark?)
339 $ hg -R tobundle add tobundle/y
339 $ hg -R tobundle add tobundle/y
340 $ hg -R tobundle commit -m'y'
340 $ hg -R tobundle commit -m'y'
341 $ hg -R tobundle bundle tobundle.hg
341 $ hg -R tobundle bundle tobundle.hg
342 searching for changes
342 searching for changes
343 2 changesets found
343 2 changesets found
344 $ hg unbundle tobundle.hg
344 $ hg unbundle tobundle.hg
345 adding changesets
345 adding changesets
346 adding manifests
346 adding manifests
347 adding file changes
347 adding file changes
348 added 2 changesets with 2 changes to 2 files (+1 heads)
348 added 2 changesets with 2 changes to 2 files (+1 heads)
349 (run 'hg heads' to see heads, 'hg merge' to merge)
349 (run 'hg heads' to see heads, 'hg merge' to merge)
350 $ hg update
350 $ hg update
351 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
351 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
352 $ hg bookmarks
352 $ hg bookmarks
353 X2 1:925d80f479bb
353 X2 1:925d80f479bb
354 Y 2:db815d6d32e6
354 Y 2:db815d6d32e6
355 * Z 3:125c9a1d6df6
355 * Z 3:125c9a1d6df6
356 x y 2:db815d6d32e6
356 x y 2:db815d6d32e6
357
357
358 test wrongly formated bookmark
358 test wrongly formated bookmark
359
359
360 $ echo '' >> .hg/bookmarks
360 $ echo '' >> .hg/bookmarks
361 $ hg bookmarks
361 $ hg bookmarks
362 X2 1:925d80f479bb
362 X2 1:925d80f479bb
363 Y 2:db815d6d32e6
363 Y 2:db815d6d32e6
364 * Z 3:125c9a1d6df6
364 * Z 3:125c9a1d6df6
365 x y 2:db815d6d32e6
365 x y 2:db815d6d32e6
366 $ echo "Ican'thasformatedlines" >> .hg/bookmarks
366 $ echo "Ican'thasformatedlines" >> .hg/bookmarks
367 $ hg bookmarks
367 $ hg bookmarks
368 malformed line in .hg/bookmarks: "Ican'thasformatedlines"
368 malformed line in .hg/bookmarks: "Ican'thasformatedlines"
369 X2 1:925d80f479bb
369 X2 1:925d80f479bb
370 Y 2:db815d6d32e6
370 Y 2:db815d6d32e6
371 * Z 3:125c9a1d6df6
371 * Z 3:125c9a1d6df6
372 x y 2:db815d6d32e6
372 x y 2:db815d6d32e6
373
373
374 test missing revisions
375
376 $ echo "925d80f479bc z" > .hg/bookmarks
377 $ hg book
378 no bookmarks set
General Comments 0
You need to be logged in to leave comments. Login now