##// END OF EJS Templates
bookmarks: adjust exception type so present(bookmark(.)) works as expected
Yuya Nishihara -
r39340:fc54a290 default
parent child Browse files
Show More
@@ -1,968 +1,968 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 __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import errno
10 import errno
11 import struct
11 import struct
12
12
13 from .i18n import _
13 from .i18n import _
14 from .node import (
14 from .node import (
15 bin,
15 bin,
16 hex,
16 hex,
17 short,
17 short,
18 wdirid,
18 wdirid,
19 )
19 )
20 from . import (
20 from . import (
21 encoding,
21 encoding,
22 error,
22 error,
23 obsutil,
23 obsutil,
24 pycompat,
24 pycompat,
25 scmutil,
25 scmutil,
26 txnutil,
26 txnutil,
27 util,
27 util,
28 )
28 )
29
29
30 # label constants
30 # label constants
31 # until 3.5, bookmarks.current was the advertised name, not
31 # until 3.5, bookmarks.current was the advertised name, not
32 # bookmarks.active, so we must use both to avoid breaking old
32 # bookmarks.active, so we must use both to avoid breaking old
33 # custom styles
33 # custom styles
34 activebookmarklabel = 'bookmarks.active bookmarks.current'
34 activebookmarklabel = 'bookmarks.active bookmarks.current'
35
35
36 def _getbkfile(repo):
36 def _getbkfile(repo):
37 """Hook so that extensions that mess with the store can hook bm storage.
37 """Hook so that extensions that mess with the store can hook bm storage.
38
38
39 For core, this just handles wether we should see pending
39 For core, this just handles wether we should see pending
40 bookmarks or the committed ones. Other extensions (like share)
40 bookmarks or the committed ones. Other extensions (like share)
41 may need to tweak this behavior further.
41 may need to tweak this behavior further.
42 """
42 """
43 fp, pending = txnutil.trypending(repo.root, repo.vfs, 'bookmarks')
43 fp, pending = txnutil.trypending(repo.root, repo.vfs, 'bookmarks')
44 return fp
44 return fp
45
45
46 class bmstore(object):
46 class bmstore(object):
47 """Storage for bookmarks.
47 """Storage for bookmarks.
48
48
49 This object should do all bookmark-related reads and writes, so
49 This object should do all bookmark-related reads and writes, so
50 that it's fairly simple to replace the storage underlying
50 that it's fairly simple to replace the storage underlying
51 bookmarks without having to clone the logic surrounding
51 bookmarks without having to clone the logic surrounding
52 bookmarks. This type also should manage the active bookmark, if
52 bookmarks. This type also should manage the active bookmark, if
53 any.
53 any.
54
54
55 This particular bmstore implementation stores bookmarks as
55 This particular bmstore implementation stores bookmarks as
56 {hash}\s{name}\n (the same format as localtags) in
56 {hash}\s{name}\n (the same format as localtags) in
57 .hg/bookmarks. The mapping is stored as {name: nodeid}.
57 .hg/bookmarks. The mapping is stored as {name: nodeid}.
58 """
58 """
59
59
60 def __init__(self, repo):
60 def __init__(self, repo):
61 self._repo = repo
61 self._repo = repo
62 self._refmap = refmap = {} # refspec: node
62 self._refmap = refmap = {} # refspec: node
63 self._nodemap = nodemap = {} # node: sorted([refspec, ...])
63 self._nodemap = nodemap = {} # node: sorted([refspec, ...])
64 self._clean = True
64 self._clean = True
65 self._aclean = True
65 self._aclean = True
66 nm = repo.changelog.nodemap
66 nm = repo.changelog.nodemap
67 tonode = bin # force local lookup
67 tonode = bin # force local lookup
68 try:
68 try:
69 with _getbkfile(repo) as bkfile:
69 with _getbkfile(repo) as bkfile:
70 for line in bkfile:
70 for line in bkfile:
71 line = line.strip()
71 line = line.strip()
72 if not line:
72 if not line:
73 continue
73 continue
74 try:
74 try:
75 sha, refspec = line.split(' ', 1)
75 sha, refspec = line.split(' ', 1)
76 node = tonode(sha)
76 node = tonode(sha)
77 if node in nm:
77 if node in nm:
78 refspec = encoding.tolocal(refspec)
78 refspec = encoding.tolocal(refspec)
79 refmap[refspec] = node
79 refmap[refspec] = node
80 nrefs = nodemap.get(node)
80 nrefs = nodemap.get(node)
81 if nrefs is None:
81 if nrefs is None:
82 nodemap[node] = [refspec]
82 nodemap[node] = [refspec]
83 else:
83 else:
84 nrefs.append(refspec)
84 nrefs.append(refspec)
85 if nrefs[-2] > refspec:
85 if nrefs[-2] > refspec:
86 # bookmarks weren't sorted before 4.5
86 # bookmarks weren't sorted before 4.5
87 nrefs.sort()
87 nrefs.sort()
88 except (TypeError, ValueError):
88 except (TypeError, ValueError):
89 # TypeError:
89 # TypeError:
90 # - bin(...)
90 # - bin(...)
91 # ValueError:
91 # ValueError:
92 # - node in nm, for non-20-bytes entry
92 # - node in nm, for non-20-bytes entry
93 # - split(...), for string without ' '
93 # - split(...), for string without ' '
94 repo.ui.warn(_('malformed line in .hg/bookmarks: %r\n')
94 repo.ui.warn(_('malformed line in .hg/bookmarks: %r\n')
95 % pycompat.bytestr(line))
95 % pycompat.bytestr(line))
96 except IOError as inst:
96 except IOError as inst:
97 if inst.errno != errno.ENOENT:
97 if inst.errno != errno.ENOENT:
98 raise
98 raise
99 self._active = _readactive(repo, self)
99 self._active = _readactive(repo, self)
100
100
101 @property
101 @property
102 def active(self):
102 def active(self):
103 return self._active
103 return self._active
104
104
105 @active.setter
105 @active.setter
106 def active(self, mark):
106 def active(self, mark):
107 if mark is not None and mark not in self._refmap:
107 if mark is not None and mark not in self._refmap:
108 raise AssertionError('bookmark %s does not exist!' % mark)
108 raise AssertionError('bookmark %s does not exist!' % mark)
109
109
110 self._active = mark
110 self._active = mark
111 self._aclean = False
111 self._aclean = False
112
112
113 def __len__(self):
113 def __len__(self):
114 return len(self._refmap)
114 return len(self._refmap)
115
115
116 def __iter__(self):
116 def __iter__(self):
117 return iter(self._refmap)
117 return iter(self._refmap)
118
118
119 def iteritems(self):
119 def iteritems(self):
120 return self._refmap.iteritems()
120 return self._refmap.iteritems()
121
121
122 def items(self):
122 def items(self):
123 return self._refmap.items()
123 return self._refmap.items()
124
124
125 # TODO: maybe rename to allnames()?
125 # TODO: maybe rename to allnames()?
126 def keys(self):
126 def keys(self):
127 return self._refmap.keys()
127 return self._refmap.keys()
128
128
129 # TODO: maybe rename to allnodes()? but nodes would have to be deduplicated
129 # TODO: maybe rename to allnodes()? but nodes would have to be deduplicated
130 # could be self._nodemap.keys()
130 # could be self._nodemap.keys()
131 def values(self):
131 def values(self):
132 return self._refmap.values()
132 return self._refmap.values()
133
133
134 def __contains__(self, mark):
134 def __contains__(self, mark):
135 return mark in self._refmap
135 return mark in self._refmap
136
136
137 def __getitem__(self, mark):
137 def __getitem__(self, mark):
138 return self._refmap[mark]
138 return self._refmap[mark]
139
139
140 def get(self, mark, default=None):
140 def get(self, mark, default=None):
141 return self._refmap.get(mark, default)
141 return self._refmap.get(mark, default)
142
142
143 def _set(self, mark, node):
143 def _set(self, mark, node):
144 self._clean = False
144 self._clean = False
145 if mark in self._refmap:
145 if mark in self._refmap:
146 self._del(mark)
146 self._del(mark)
147 self._refmap[mark] = node
147 self._refmap[mark] = node
148 nrefs = self._nodemap.get(node)
148 nrefs = self._nodemap.get(node)
149 if nrefs is None:
149 if nrefs is None:
150 self._nodemap[node] = [mark]
150 self._nodemap[node] = [mark]
151 else:
151 else:
152 nrefs.append(mark)
152 nrefs.append(mark)
153 nrefs.sort()
153 nrefs.sort()
154
154
155 def _del(self, mark):
155 def _del(self, mark):
156 self._clean = False
156 self._clean = False
157 node = self._refmap.pop(mark)
157 node = self._refmap.pop(mark)
158 nrefs = self._nodemap[node]
158 nrefs = self._nodemap[node]
159 if len(nrefs) == 1:
159 if len(nrefs) == 1:
160 assert nrefs[0] == mark
160 assert nrefs[0] == mark
161 del self._nodemap[node]
161 del self._nodemap[node]
162 else:
162 else:
163 nrefs.remove(mark)
163 nrefs.remove(mark)
164
164
165 def names(self, node):
165 def names(self, node):
166 """Return a sorted list of bookmarks pointing to the specified node"""
166 """Return a sorted list of bookmarks pointing to the specified node"""
167 return self._nodemap.get(node, [])
167 return self._nodemap.get(node, [])
168
168
169 def changectx(self, mark):
169 def changectx(self, mark):
170 node = self._refmap[mark]
170 node = self._refmap[mark]
171 return self._repo[node]
171 return self._repo[node]
172
172
173 def applychanges(self, repo, tr, changes):
173 def applychanges(self, repo, tr, changes):
174 """Apply a list of changes to bookmarks
174 """Apply a list of changes to bookmarks
175 """
175 """
176 bmchanges = tr.changes.get('bookmarks')
176 bmchanges = tr.changes.get('bookmarks')
177 for name, node in changes:
177 for name, node in changes:
178 old = self._refmap.get(name)
178 old = self._refmap.get(name)
179 if node is None:
179 if node is None:
180 self._del(name)
180 self._del(name)
181 else:
181 else:
182 self._set(name, node)
182 self._set(name, node)
183 if bmchanges is not None:
183 if bmchanges is not None:
184 # if a previous value exist preserve the "initial" value
184 # if a previous value exist preserve the "initial" value
185 previous = bmchanges.get(name)
185 previous = bmchanges.get(name)
186 if previous is not None:
186 if previous is not None:
187 old = previous[0]
187 old = previous[0]
188 bmchanges[name] = (old, node)
188 bmchanges[name] = (old, node)
189 self._recordchange(tr)
189 self._recordchange(tr)
190
190
191 def _recordchange(self, tr):
191 def _recordchange(self, tr):
192 """record that bookmarks have been changed in a transaction
192 """record that bookmarks have been changed in a transaction
193
193
194 The transaction is then responsible for updating the file content."""
194 The transaction is then responsible for updating the file content."""
195 tr.addfilegenerator('bookmarks', ('bookmarks',), self._write,
195 tr.addfilegenerator('bookmarks', ('bookmarks',), self._write,
196 location='plain')
196 location='plain')
197 tr.hookargs['bookmark_moved'] = '1'
197 tr.hookargs['bookmark_moved'] = '1'
198
198
199 def _writerepo(self, repo):
199 def _writerepo(self, repo):
200 """Factored out for extensibility"""
200 """Factored out for extensibility"""
201 rbm = repo._bookmarks
201 rbm = repo._bookmarks
202 if rbm.active not in self._refmap:
202 if rbm.active not in self._refmap:
203 rbm.active = None
203 rbm.active = None
204 rbm._writeactive()
204 rbm._writeactive()
205
205
206 with repo.wlock():
206 with repo.wlock():
207 file_ = repo.vfs('bookmarks', 'w', atomictemp=True,
207 file_ = repo.vfs('bookmarks', 'w', atomictemp=True,
208 checkambig=True)
208 checkambig=True)
209 try:
209 try:
210 self._write(file_)
210 self._write(file_)
211 except: # re-raises
211 except: # re-raises
212 file_.discard()
212 file_.discard()
213 raise
213 raise
214 finally:
214 finally:
215 file_.close()
215 file_.close()
216
216
217 def _writeactive(self):
217 def _writeactive(self):
218 if self._aclean:
218 if self._aclean:
219 return
219 return
220 with self._repo.wlock():
220 with self._repo.wlock():
221 if self._active is not None:
221 if self._active is not None:
222 f = self._repo.vfs('bookmarks.current', 'w', atomictemp=True,
222 f = self._repo.vfs('bookmarks.current', 'w', atomictemp=True,
223 checkambig=True)
223 checkambig=True)
224 try:
224 try:
225 f.write(encoding.fromlocal(self._active))
225 f.write(encoding.fromlocal(self._active))
226 finally:
226 finally:
227 f.close()
227 f.close()
228 else:
228 else:
229 self._repo.vfs.tryunlink('bookmarks.current')
229 self._repo.vfs.tryunlink('bookmarks.current')
230 self._aclean = True
230 self._aclean = True
231
231
232 def _write(self, fp):
232 def _write(self, fp):
233 for name, node in sorted(self._refmap.iteritems()):
233 for name, node in sorted(self._refmap.iteritems()):
234 fp.write("%s %s\n" % (hex(node), encoding.fromlocal(name)))
234 fp.write("%s %s\n" % (hex(node), encoding.fromlocal(name)))
235 self._clean = True
235 self._clean = True
236 self._repo.invalidatevolatilesets()
236 self._repo.invalidatevolatilesets()
237
237
238 def expandname(self, bname):
238 def expandname(self, bname):
239 if bname == '.':
239 if bname == '.':
240 if self.active:
240 if self.active:
241 return self.active
241 return self.active
242 else:
242 else:
243 raise error.Abort(_("no active bookmark"))
243 raise error.RepoLookupError(_("no active bookmark"))
244 return bname
244 return bname
245
245
246 def checkconflict(self, mark, force=False, target=None):
246 def checkconflict(self, mark, force=False, target=None):
247 """check repo for a potential clash of mark with an existing bookmark,
247 """check repo for a potential clash of mark with an existing bookmark,
248 branch, or hash
248 branch, or hash
249
249
250 If target is supplied, then check that we are moving the bookmark
250 If target is supplied, then check that we are moving the bookmark
251 forward.
251 forward.
252
252
253 If force is supplied, then forcibly move the bookmark to a new commit
253 If force is supplied, then forcibly move the bookmark to a new commit
254 regardless if it is a move forward.
254 regardless if it is a move forward.
255
255
256 If divergent bookmark are to be deleted, they will be returned as list.
256 If divergent bookmark are to be deleted, they will be returned as list.
257 """
257 """
258 cur = self._repo['.'].node()
258 cur = self._repo['.'].node()
259 if mark in self._refmap and not force:
259 if mark in self._refmap and not force:
260 if target:
260 if target:
261 if self._refmap[mark] == target and target == cur:
261 if self._refmap[mark] == target and target == cur:
262 # re-activating a bookmark
262 # re-activating a bookmark
263 return []
263 return []
264 rev = self._repo[target].rev()
264 rev = self._repo[target].rev()
265 anc = self._repo.changelog.ancestors([rev])
265 anc = self._repo.changelog.ancestors([rev])
266 bmctx = self.changectx(mark)
266 bmctx = self.changectx(mark)
267 divs = [self._refmap[b] for b in self._refmap
267 divs = [self._refmap[b] for b in self._refmap
268 if b.split('@', 1)[0] == mark.split('@', 1)[0]]
268 if b.split('@', 1)[0] == mark.split('@', 1)[0]]
269
269
270 # allow resolving a single divergent bookmark even if moving
270 # allow resolving a single divergent bookmark even if moving
271 # the bookmark across branches when a revision is specified
271 # the bookmark across branches when a revision is specified
272 # that contains a divergent bookmark
272 # that contains a divergent bookmark
273 if bmctx.rev() not in anc and target in divs:
273 if bmctx.rev() not in anc and target in divs:
274 return divergent2delete(self._repo, [target], mark)
274 return divergent2delete(self._repo, [target], mark)
275
275
276 deletefrom = [b for b in divs
276 deletefrom = [b for b in divs
277 if self._repo[b].rev() in anc or b == target]
277 if self._repo[b].rev() in anc or b == target]
278 delbms = divergent2delete(self._repo, deletefrom, mark)
278 delbms = divergent2delete(self._repo, deletefrom, mark)
279 if validdest(self._repo, bmctx, self._repo[target]):
279 if validdest(self._repo, bmctx, self._repo[target]):
280 self._repo.ui.status(
280 self._repo.ui.status(
281 _("moving bookmark '%s' forward from %s\n") %
281 _("moving bookmark '%s' forward from %s\n") %
282 (mark, short(bmctx.node())))
282 (mark, short(bmctx.node())))
283 return delbms
283 return delbms
284 raise error.Abort(_("bookmark '%s' already exists "
284 raise error.Abort(_("bookmark '%s' already exists "
285 "(use -f to force)") % mark)
285 "(use -f to force)") % mark)
286 if ((mark in self._repo.branchmap() or
286 if ((mark in self._repo.branchmap() or
287 mark == self._repo.dirstate.branch()) and not force):
287 mark == self._repo.dirstate.branch()) and not force):
288 raise error.Abort(
288 raise error.Abort(
289 _("a bookmark cannot have the name of an existing branch"))
289 _("a bookmark cannot have the name of an existing branch"))
290 if len(mark) > 3 and not force:
290 if len(mark) > 3 and not force:
291 try:
291 try:
292 shadowhash = scmutil.isrevsymbol(self._repo, mark)
292 shadowhash = scmutil.isrevsymbol(self._repo, mark)
293 except error.LookupError: # ambiguous identifier
293 except error.LookupError: # ambiguous identifier
294 shadowhash = False
294 shadowhash = False
295 if shadowhash:
295 if shadowhash:
296 self._repo.ui.warn(
296 self._repo.ui.warn(
297 _("bookmark %s matches a changeset hash\n"
297 _("bookmark %s matches a changeset hash\n"
298 "(did you leave a -r out of an 'hg bookmark' "
298 "(did you leave a -r out of an 'hg bookmark' "
299 "command?)\n")
299 "command?)\n")
300 % mark)
300 % mark)
301 return []
301 return []
302
302
303 def _readactive(repo, marks):
303 def _readactive(repo, marks):
304 """
304 """
305 Get the active bookmark. We can have an active bookmark that updates
305 Get the active bookmark. We can have an active bookmark that updates
306 itself as we commit. This function returns the name of that bookmark.
306 itself as we commit. This function returns the name of that bookmark.
307 It is stored in .hg/bookmarks.current
307 It is stored in .hg/bookmarks.current
308 """
308 """
309 mark = None
309 mark = None
310 try:
310 try:
311 file = repo.vfs('bookmarks.current')
311 file = repo.vfs('bookmarks.current')
312 except IOError as inst:
312 except IOError as inst:
313 if inst.errno != errno.ENOENT:
313 if inst.errno != errno.ENOENT:
314 raise
314 raise
315 return None
315 return None
316 try:
316 try:
317 # No readline() in osutil.posixfile, reading everything is
317 # No readline() in osutil.posixfile, reading everything is
318 # cheap.
318 # cheap.
319 # Note that it's possible for readlines() here to raise
319 # Note that it's possible for readlines() here to raise
320 # IOError, since we might be reading the active mark over
320 # IOError, since we might be reading the active mark over
321 # static-http which only tries to load the file when we try
321 # static-http which only tries to load the file when we try
322 # to read from it.
322 # to read from it.
323 mark = encoding.tolocal((file.readlines() or [''])[0])
323 mark = encoding.tolocal((file.readlines() or [''])[0])
324 if mark == '' or mark not in marks:
324 if mark == '' or mark not in marks:
325 mark = None
325 mark = None
326 except IOError as inst:
326 except IOError as inst:
327 if inst.errno != errno.ENOENT:
327 if inst.errno != errno.ENOENT:
328 raise
328 raise
329 return None
329 return None
330 finally:
330 finally:
331 file.close()
331 file.close()
332 return mark
332 return mark
333
333
334 def activate(repo, mark):
334 def activate(repo, mark):
335 """
335 """
336 Set the given bookmark to be 'active', meaning that this bookmark will
336 Set the given bookmark to be 'active', meaning that this bookmark will
337 follow new commits that are made.
337 follow new commits that are made.
338 The name is recorded in .hg/bookmarks.current
338 The name is recorded in .hg/bookmarks.current
339 """
339 """
340 repo._bookmarks.active = mark
340 repo._bookmarks.active = mark
341 repo._bookmarks._writeactive()
341 repo._bookmarks._writeactive()
342
342
343 def deactivate(repo):
343 def deactivate(repo):
344 """
344 """
345 Unset the active bookmark in this repository.
345 Unset the active bookmark in this repository.
346 """
346 """
347 repo._bookmarks.active = None
347 repo._bookmarks.active = None
348 repo._bookmarks._writeactive()
348 repo._bookmarks._writeactive()
349
349
350 def isactivewdirparent(repo):
350 def isactivewdirparent(repo):
351 """
351 """
352 Tell whether the 'active' bookmark (the one that follows new commits)
352 Tell whether the 'active' bookmark (the one that follows new commits)
353 points to one of the parents of the current working directory (wdir).
353 points to one of the parents of the current working directory (wdir).
354
354
355 While this is normally the case, it can on occasion be false; for example,
355 While this is normally the case, it can on occasion be false; for example,
356 immediately after a pull, the active bookmark can be moved to point
356 immediately after a pull, the active bookmark can be moved to point
357 to a place different than the wdir. This is solved by running `hg update`.
357 to a place different than the wdir. This is solved by running `hg update`.
358 """
358 """
359 mark = repo._activebookmark
359 mark = repo._activebookmark
360 marks = repo._bookmarks
360 marks = repo._bookmarks
361 parents = [p.node() for p in repo[None].parents()]
361 parents = [p.node() for p in repo[None].parents()]
362 return (mark in marks and marks[mark] in parents)
362 return (mark in marks and marks[mark] in parents)
363
363
364 def divergent2delete(repo, deletefrom, bm):
364 def divergent2delete(repo, deletefrom, bm):
365 """find divergent versions of bm on nodes in deletefrom.
365 """find divergent versions of bm on nodes in deletefrom.
366
366
367 the list of bookmark to delete."""
367 the list of bookmark to delete."""
368 todelete = []
368 todelete = []
369 marks = repo._bookmarks
369 marks = repo._bookmarks
370 divergent = [b for b in marks if b.split('@', 1)[0] == bm.split('@', 1)[0]]
370 divergent = [b for b in marks if b.split('@', 1)[0] == bm.split('@', 1)[0]]
371 for mark in divergent:
371 for mark in divergent:
372 if mark == '@' or '@' not in mark:
372 if mark == '@' or '@' not in mark:
373 # can't be divergent by definition
373 # can't be divergent by definition
374 continue
374 continue
375 if mark and marks[mark] in deletefrom:
375 if mark and marks[mark] in deletefrom:
376 if mark != bm:
376 if mark != bm:
377 todelete.append(mark)
377 todelete.append(mark)
378 return todelete
378 return todelete
379
379
380 def headsforactive(repo):
380 def headsforactive(repo):
381 """Given a repo with an active bookmark, return divergent bookmark nodes.
381 """Given a repo with an active bookmark, return divergent bookmark nodes.
382
382
383 Args:
383 Args:
384 repo: A repository with an active bookmark.
384 repo: A repository with an active bookmark.
385
385
386 Returns:
386 Returns:
387 A list of binary node ids that is the full list of other
387 A list of binary node ids that is the full list of other
388 revisions with bookmarks divergent from the active bookmark. If
388 revisions with bookmarks divergent from the active bookmark. If
389 there were no divergent bookmarks, then this list will contain
389 there were no divergent bookmarks, then this list will contain
390 only one entry.
390 only one entry.
391 """
391 """
392 if not repo._activebookmark:
392 if not repo._activebookmark:
393 raise ValueError(
393 raise ValueError(
394 'headsforactive() only makes sense with an active bookmark')
394 'headsforactive() only makes sense with an active bookmark')
395 name = repo._activebookmark.split('@', 1)[0]
395 name = repo._activebookmark.split('@', 1)[0]
396 heads = []
396 heads = []
397 for mark, n in repo._bookmarks.iteritems():
397 for mark, n in repo._bookmarks.iteritems():
398 if mark.split('@', 1)[0] == name:
398 if mark.split('@', 1)[0] == name:
399 heads.append(n)
399 heads.append(n)
400 return heads
400 return heads
401
401
402 def calculateupdate(ui, repo):
402 def calculateupdate(ui, repo):
403 '''Return a tuple (activemark, movemarkfrom) indicating the active bookmark
403 '''Return a tuple (activemark, movemarkfrom) indicating the active bookmark
404 and where to move the active bookmark from, if needed.'''
404 and where to move the active bookmark from, if needed.'''
405 checkout, movemarkfrom = None, None
405 checkout, movemarkfrom = None, None
406 activemark = repo._activebookmark
406 activemark = repo._activebookmark
407 if isactivewdirparent(repo):
407 if isactivewdirparent(repo):
408 movemarkfrom = repo['.'].node()
408 movemarkfrom = repo['.'].node()
409 elif activemark:
409 elif activemark:
410 ui.status(_("updating to active bookmark %s\n") % activemark)
410 ui.status(_("updating to active bookmark %s\n") % activemark)
411 checkout = activemark
411 checkout = activemark
412 return (checkout, movemarkfrom)
412 return (checkout, movemarkfrom)
413
413
414 def update(repo, parents, node):
414 def update(repo, parents, node):
415 deletefrom = parents
415 deletefrom = parents
416 marks = repo._bookmarks
416 marks = repo._bookmarks
417 active = marks.active
417 active = marks.active
418 if not active:
418 if not active:
419 return False
419 return False
420
420
421 bmchanges = []
421 bmchanges = []
422 if marks[active] in parents:
422 if marks[active] in parents:
423 new = repo[node]
423 new = repo[node]
424 divs = [marks.changectx(b) for b in marks
424 divs = [marks.changectx(b) for b in marks
425 if b.split('@', 1)[0] == active.split('@', 1)[0]]
425 if b.split('@', 1)[0] == active.split('@', 1)[0]]
426 anc = repo.changelog.ancestors([new.rev()])
426 anc = repo.changelog.ancestors([new.rev()])
427 deletefrom = [b.node() for b in divs if b.rev() in anc or b == new]
427 deletefrom = [b.node() for b in divs if b.rev() in anc or b == new]
428 if validdest(repo, marks.changectx(active), new):
428 if validdest(repo, marks.changectx(active), new):
429 bmchanges.append((active, new.node()))
429 bmchanges.append((active, new.node()))
430
430
431 for bm in divergent2delete(repo, deletefrom, active):
431 for bm in divergent2delete(repo, deletefrom, active):
432 bmchanges.append((bm, None))
432 bmchanges.append((bm, None))
433
433
434 if bmchanges:
434 if bmchanges:
435 with repo.lock(), repo.transaction('bookmark') as tr:
435 with repo.lock(), repo.transaction('bookmark') as tr:
436 marks.applychanges(repo, tr, bmchanges)
436 marks.applychanges(repo, tr, bmchanges)
437 return bool(bmchanges)
437 return bool(bmchanges)
438
438
439 def listbinbookmarks(repo):
439 def listbinbookmarks(repo):
440 # We may try to list bookmarks on a repo type that does not
440 # We may try to list bookmarks on a repo type that does not
441 # support it (e.g., statichttprepository).
441 # support it (e.g., statichttprepository).
442 marks = getattr(repo, '_bookmarks', {})
442 marks = getattr(repo, '_bookmarks', {})
443
443
444 hasnode = repo.changelog.hasnode
444 hasnode = repo.changelog.hasnode
445 for k, v in marks.iteritems():
445 for k, v in marks.iteritems():
446 # don't expose local divergent bookmarks
446 # don't expose local divergent bookmarks
447 if hasnode(v) and ('@' not in k or k.endswith('@')):
447 if hasnode(v) and ('@' not in k or k.endswith('@')):
448 yield k, v
448 yield k, v
449
449
450 def listbookmarks(repo):
450 def listbookmarks(repo):
451 d = {}
451 d = {}
452 for book, node in listbinbookmarks(repo):
452 for book, node in listbinbookmarks(repo):
453 d[book] = hex(node)
453 d[book] = hex(node)
454 return d
454 return d
455
455
456 def pushbookmark(repo, key, old, new):
456 def pushbookmark(repo, key, old, new):
457 with repo.wlock(), repo.lock(), repo.transaction('bookmarks') as tr:
457 with repo.wlock(), repo.lock(), repo.transaction('bookmarks') as tr:
458 marks = repo._bookmarks
458 marks = repo._bookmarks
459 existing = hex(marks.get(key, ''))
459 existing = hex(marks.get(key, ''))
460 if existing != old and existing != new:
460 if existing != old and existing != new:
461 return False
461 return False
462 if new == '':
462 if new == '':
463 changes = [(key, None)]
463 changes = [(key, None)]
464 else:
464 else:
465 if new not in repo:
465 if new not in repo:
466 return False
466 return False
467 changes = [(key, repo[new].node())]
467 changes = [(key, repo[new].node())]
468 marks.applychanges(repo, tr, changes)
468 marks.applychanges(repo, tr, changes)
469 return True
469 return True
470
470
471 def comparebookmarks(repo, srcmarks, dstmarks, targets=None):
471 def comparebookmarks(repo, srcmarks, dstmarks, targets=None):
472 '''Compare bookmarks between srcmarks and dstmarks
472 '''Compare bookmarks between srcmarks and dstmarks
473
473
474 This returns tuple "(addsrc, adddst, advsrc, advdst, diverge,
474 This returns tuple "(addsrc, adddst, advsrc, advdst, diverge,
475 differ, invalid)", each are list of bookmarks below:
475 differ, invalid)", each are list of bookmarks below:
476
476
477 :addsrc: added on src side (removed on dst side, perhaps)
477 :addsrc: added on src side (removed on dst side, perhaps)
478 :adddst: added on dst side (removed on src side, perhaps)
478 :adddst: added on dst side (removed on src side, perhaps)
479 :advsrc: advanced on src side
479 :advsrc: advanced on src side
480 :advdst: advanced on dst side
480 :advdst: advanced on dst side
481 :diverge: diverge
481 :diverge: diverge
482 :differ: changed, but changeset referred on src is unknown on dst
482 :differ: changed, but changeset referred on src is unknown on dst
483 :invalid: unknown on both side
483 :invalid: unknown on both side
484 :same: same on both side
484 :same: same on both side
485
485
486 Each elements of lists in result tuple is tuple "(bookmark name,
486 Each elements of lists in result tuple is tuple "(bookmark name,
487 changeset ID on source side, changeset ID on destination
487 changeset ID on source side, changeset ID on destination
488 side)". Each changeset IDs are 40 hexadecimal digit string or
488 side)". Each changeset IDs are 40 hexadecimal digit string or
489 None.
489 None.
490
490
491 Changeset IDs of tuples in "addsrc", "adddst", "differ" or
491 Changeset IDs of tuples in "addsrc", "adddst", "differ" or
492 "invalid" list may be unknown for repo.
492 "invalid" list may be unknown for repo.
493
493
494 If "targets" is specified, only bookmarks listed in it are
494 If "targets" is specified, only bookmarks listed in it are
495 examined.
495 examined.
496 '''
496 '''
497
497
498 if targets:
498 if targets:
499 bset = set(targets)
499 bset = set(targets)
500 else:
500 else:
501 srcmarkset = set(srcmarks)
501 srcmarkset = set(srcmarks)
502 dstmarkset = set(dstmarks)
502 dstmarkset = set(dstmarks)
503 bset = srcmarkset | dstmarkset
503 bset = srcmarkset | dstmarkset
504
504
505 results = ([], [], [], [], [], [], [], [])
505 results = ([], [], [], [], [], [], [], [])
506 addsrc = results[0].append
506 addsrc = results[0].append
507 adddst = results[1].append
507 adddst = results[1].append
508 advsrc = results[2].append
508 advsrc = results[2].append
509 advdst = results[3].append
509 advdst = results[3].append
510 diverge = results[4].append
510 diverge = results[4].append
511 differ = results[5].append
511 differ = results[5].append
512 invalid = results[6].append
512 invalid = results[6].append
513 same = results[7].append
513 same = results[7].append
514
514
515 for b in sorted(bset):
515 for b in sorted(bset):
516 if b not in srcmarks:
516 if b not in srcmarks:
517 if b in dstmarks:
517 if b in dstmarks:
518 adddst((b, None, dstmarks[b]))
518 adddst((b, None, dstmarks[b]))
519 else:
519 else:
520 invalid((b, None, None))
520 invalid((b, None, None))
521 elif b not in dstmarks:
521 elif b not in dstmarks:
522 addsrc((b, srcmarks[b], None))
522 addsrc((b, srcmarks[b], None))
523 else:
523 else:
524 scid = srcmarks[b]
524 scid = srcmarks[b]
525 dcid = dstmarks[b]
525 dcid = dstmarks[b]
526 if scid == dcid:
526 if scid == dcid:
527 same((b, scid, dcid))
527 same((b, scid, dcid))
528 elif scid in repo and dcid in repo:
528 elif scid in repo and dcid in repo:
529 sctx = repo[scid]
529 sctx = repo[scid]
530 dctx = repo[dcid]
530 dctx = repo[dcid]
531 if sctx.rev() < dctx.rev():
531 if sctx.rev() < dctx.rev():
532 if validdest(repo, sctx, dctx):
532 if validdest(repo, sctx, dctx):
533 advdst((b, scid, dcid))
533 advdst((b, scid, dcid))
534 else:
534 else:
535 diverge((b, scid, dcid))
535 diverge((b, scid, dcid))
536 else:
536 else:
537 if validdest(repo, dctx, sctx):
537 if validdest(repo, dctx, sctx):
538 advsrc((b, scid, dcid))
538 advsrc((b, scid, dcid))
539 else:
539 else:
540 diverge((b, scid, dcid))
540 diverge((b, scid, dcid))
541 else:
541 else:
542 # it is too expensive to examine in detail, in this case
542 # it is too expensive to examine in detail, in this case
543 differ((b, scid, dcid))
543 differ((b, scid, dcid))
544
544
545 return results
545 return results
546
546
547 def _diverge(ui, b, path, localmarks, remotenode):
547 def _diverge(ui, b, path, localmarks, remotenode):
548 '''Return appropriate diverged bookmark for specified ``path``
548 '''Return appropriate diverged bookmark for specified ``path``
549
549
550 This returns None, if it is failed to assign any divergent
550 This returns None, if it is failed to assign any divergent
551 bookmark name.
551 bookmark name.
552
552
553 This reuses already existing one with "@number" suffix, if it
553 This reuses already existing one with "@number" suffix, if it
554 refers ``remotenode``.
554 refers ``remotenode``.
555 '''
555 '''
556 if b == '@':
556 if b == '@':
557 b = ''
557 b = ''
558 # try to use an @pathalias suffix
558 # try to use an @pathalias suffix
559 # if an @pathalias already exists, we overwrite (update) it
559 # if an @pathalias already exists, we overwrite (update) it
560 if path.startswith("file:"):
560 if path.startswith("file:"):
561 path = util.url(path).path
561 path = util.url(path).path
562 for p, u in ui.configitems("paths"):
562 for p, u in ui.configitems("paths"):
563 if u.startswith("file:"):
563 if u.startswith("file:"):
564 u = util.url(u).path
564 u = util.url(u).path
565 if path == u:
565 if path == u:
566 return '%s@%s' % (b, p)
566 return '%s@%s' % (b, p)
567
567
568 # assign a unique "@number" suffix newly
568 # assign a unique "@number" suffix newly
569 for x in range(1, 100):
569 for x in range(1, 100):
570 n = '%s@%d' % (b, x)
570 n = '%s@%d' % (b, x)
571 if n not in localmarks or localmarks[n] == remotenode:
571 if n not in localmarks or localmarks[n] == remotenode:
572 return n
572 return n
573
573
574 return None
574 return None
575
575
576 def unhexlifybookmarks(marks):
576 def unhexlifybookmarks(marks):
577 binremotemarks = {}
577 binremotemarks = {}
578 for name, node in marks.items():
578 for name, node in marks.items():
579 binremotemarks[name] = bin(node)
579 binremotemarks[name] = bin(node)
580 return binremotemarks
580 return binremotemarks
581
581
582 _binaryentry = struct.Struct('>20sH')
582 _binaryentry = struct.Struct('>20sH')
583
583
584 def binaryencode(bookmarks):
584 def binaryencode(bookmarks):
585 """encode a '(bookmark, node)' iterable into a binary stream
585 """encode a '(bookmark, node)' iterable into a binary stream
586
586
587 the binary format is:
587 the binary format is:
588
588
589 <node><bookmark-length><bookmark-name>
589 <node><bookmark-length><bookmark-name>
590
590
591 :node: is a 20 bytes binary node,
591 :node: is a 20 bytes binary node,
592 :bookmark-length: an unsigned short,
592 :bookmark-length: an unsigned short,
593 :bookmark-name: the name of the bookmark (of length <bookmark-length>)
593 :bookmark-name: the name of the bookmark (of length <bookmark-length>)
594
594
595 wdirid (all bits set) will be used as a special value for "missing"
595 wdirid (all bits set) will be used as a special value for "missing"
596 """
596 """
597 binarydata = []
597 binarydata = []
598 for book, node in bookmarks:
598 for book, node in bookmarks:
599 if not node: # None or ''
599 if not node: # None or ''
600 node = wdirid
600 node = wdirid
601 binarydata.append(_binaryentry.pack(node, len(book)))
601 binarydata.append(_binaryentry.pack(node, len(book)))
602 binarydata.append(book)
602 binarydata.append(book)
603 return ''.join(binarydata)
603 return ''.join(binarydata)
604
604
605 def binarydecode(stream):
605 def binarydecode(stream):
606 """decode a binary stream into an '(bookmark, node)' iterable
606 """decode a binary stream into an '(bookmark, node)' iterable
607
607
608 the binary format is:
608 the binary format is:
609
609
610 <node><bookmark-length><bookmark-name>
610 <node><bookmark-length><bookmark-name>
611
611
612 :node: is a 20 bytes binary node,
612 :node: is a 20 bytes binary node,
613 :bookmark-length: an unsigned short,
613 :bookmark-length: an unsigned short,
614 :bookmark-name: the name of the bookmark (of length <bookmark-length>))
614 :bookmark-name: the name of the bookmark (of length <bookmark-length>))
615
615
616 wdirid (all bits set) will be used as a special value for "missing"
616 wdirid (all bits set) will be used as a special value for "missing"
617 """
617 """
618 entrysize = _binaryentry.size
618 entrysize = _binaryentry.size
619 books = []
619 books = []
620 while True:
620 while True:
621 entry = stream.read(entrysize)
621 entry = stream.read(entrysize)
622 if len(entry) < entrysize:
622 if len(entry) < entrysize:
623 if entry:
623 if entry:
624 raise error.Abort(_('bad bookmark stream'))
624 raise error.Abort(_('bad bookmark stream'))
625 break
625 break
626 node, length = _binaryentry.unpack(entry)
626 node, length = _binaryentry.unpack(entry)
627 bookmark = stream.read(length)
627 bookmark = stream.read(length)
628 if len(bookmark) < length:
628 if len(bookmark) < length:
629 if entry:
629 if entry:
630 raise error.Abort(_('bad bookmark stream'))
630 raise error.Abort(_('bad bookmark stream'))
631 if node == wdirid:
631 if node == wdirid:
632 node = None
632 node = None
633 books.append((bookmark, node))
633 books.append((bookmark, node))
634 return books
634 return books
635
635
636 def updatefromremote(ui, repo, remotemarks, path, trfunc, explicit=()):
636 def updatefromremote(ui, repo, remotemarks, path, trfunc, explicit=()):
637 ui.debug("checking for updated bookmarks\n")
637 ui.debug("checking for updated bookmarks\n")
638 localmarks = repo._bookmarks
638 localmarks = repo._bookmarks
639 (addsrc, adddst, advsrc, advdst, diverge, differ, invalid, same
639 (addsrc, adddst, advsrc, advdst, diverge, differ, invalid, same
640 ) = comparebookmarks(repo, remotemarks, localmarks)
640 ) = comparebookmarks(repo, remotemarks, localmarks)
641
641
642 status = ui.status
642 status = ui.status
643 warn = ui.warn
643 warn = ui.warn
644 if ui.configbool('ui', 'quietbookmarkmove'):
644 if ui.configbool('ui', 'quietbookmarkmove'):
645 status = warn = ui.debug
645 status = warn = ui.debug
646
646
647 explicit = set(explicit)
647 explicit = set(explicit)
648 changed = []
648 changed = []
649 for b, scid, dcid in addsrc:
649 for b, scid, dcid in addsrc:
650 if scid in repo: # add remote bookmarks for changes we already have
650 if scid in repo: # add remote bookmarks for changes we already have
651 changed.append((b, scid, status,
651 changed.append((b, scid, status,
652 _("adding remote bookmark %s\n") % (b)))
652 _("adding remote bookmark %s\n") % (b)))
653 elif b in explicit:
653 elif b in explicit:
654 explicit.remove(b)
654 explicit.remove(b)
655 ui.warn(_("remote bookmark %s points to locally missing %s\n")
655 ui.warn(_("remote bookmark %s points to locally missing %s\n")
656 % (b, hex(scid)[:12]))
656 % (b, hex(scid)[:12]))
657
657
658 for b, scid, dcid in advsrc:
658 for b, scid, dcid in advsrc:
659 changed.append((b, scid, status,
659 changed.append((b, scid, status,
660 _("updating bookmark %s\n") % (b)))
660 _("updating bookmark %s\n") % (b)))
661 # remove normal movement from explicit set
661 # remove normal movement from explicit set
662 explicit.difference_update(d[0] for d in changed)
662 explicit.difference_update(d[0] for d in changed)
663
663
664 for b, scid, dcid in diverge:
664 for b, scid, dcid in diverge:
665 if b in explicit:
665 if b in explicit:
666 explicit.discard(b)
666 explicit.discard(b)
667 changed.append((b, scid, status,
667 changed.append((b, scid, status,
668 _("importing bookmark %s\n") % (b)))
668 _("importing bookmark %s\n") % (b)))
669 else:
669 else:
670 db = _diverge(ui, b, path, localmarks, scid)
670 db = _diverge(ui, b, path, localmarks, scid)
671 if db:
671 if db:
672 changed.append((db, scid, warn,
672 changed.append((db, scid, warn,
673 _("divergent bookmark %s stored as %s\n") %
673 _("divergent bookmark %s stored as %s\n") %
674 (b, db)))
674 (b, db)))
675 else:
675 else:
676 warn(_("warning: failed to assign numbered name "
676 warn(_("warning: failed to assign numbered name "
677 "to divergent bookmark %s\n") % (b))
677 "to divergent bookmark %s\n") % (b))
678 for b, scid, dcid in adddst + advdst:
678 for b, scid, dcid in adddst + advdst:
679 if b in explicit:
679 if b in explicit:
680 explicit.discard(b)
680 explicit.discard(b)
681 changed.append((b, scid, status,
681 changed.append((b, scid, status,
682 _("importing bookmark %s\n") % (b)))
682 _("importing bookmark %s\n") % (b)))
683 for b, scid, dcid in differ:
683 for b, scid, dcid in differ:
684 if b in explicit:
684 if b in explicit:
685 explicit.remove(b)
685 explicit.remove(b)
686 ui.warn(_("remote bookmark %s points to locally missing %s\n")
686 ui.warn(_("remote bookmark %s points to locally missing %s\n")
687 % (b, hex(scid)[:12]))
687 % (b, hex(scid)[:12]))
688
688
689 if changed:
689 if changed:
690 tr = trfunc()
690 tr = trfunc()
691 changes = []
691 changes = []
692 for b, node, writer, msg in sorted(changed):
692 for b, node, writer, msg in sorted(changed):
693 changes.append((b, node))
693 changes.append((b, node))
694 writer(msg)
694 writer(msg)
695 localmarks.applychanges(repo, tr, changes)
695 localmarks.applychanges(repo, tr, changes)
696
696
697 def incoming(ui, repo, peer):
697 def incoming(ui, repo, peer):
698 '''Show bookmarks incoming from other to repo
698 '''Show bookmarks incoming from other to repo
699 '''
699 '''
700 ui.status(_("searching for changed bookmarks\n"))
700 ui.status(_("searching for changed bookmarks\n"))
701
701
702 with peer.commandexecutor() as e:
702 with peer.commandexecutor() as e:
703 remotemarks = unhexlifybookmarks(e.callcommand('listkeys', {
703 remotemarks = unhexlifybookmarks(e.callcommand('listkeys', {
704 'namespace': 'bookmarks',
704 'namespace': 'bookmarks',
705 }).result())
705 }).result())
706
706
707 r = comparebookmarks(repo, remotemarks, repo._bookmarks)
707 r = comparebookmarks(repo, remotemarks, repo._bookmarks)
708 addsrc, adddst, advsrc, advdst, diverge, differ, invalid, same = r
708 addsrc, adddst, advsrc, advdst, diverge, differ, invalid, same = r
709
709
710 incomings = []
710 incomings = []
711 if ui.debugflag:
711 if ui.debugflag:
712 getid = lambda id: id
712 getid = lambda id: id
713 else:
713 else:
714 getid = lambda id: id[:12]
714 getid = lambda id: id[:12]
715 if ui.verbose:
715 if ui.verbose:
716 def add(b, id, st):
716 def add(b, id, st):
717 incomings.append(" %-25s %s %s\n" % (b, getid(id), st))
717 incomings.append(" %-25s %s %s\n" % (b, getid(id), st))
718 else:
718 else:
719 def add(b, id, st):
719 def add(b, id, st):
720 incomings.append(" %-25s %s\n" % (b, getid(id)))
720 incomings.append(" %-25s %s\n" % (b, getid(id)))
721 for b, scid, dcid in addsrc:
721 for b, scid, dcid in addsrc:
722 # i18n: "added" refers to a bookmark
722 # i18n: "added" refers to a bookmark
723 add(b, hex(scid), _('added'))
723 add(b, hex(scid), _('added'))
724 for b, scid, dcid in advsrc:
724 for b, scid, dcid in advsrc:
725 # i18n: "advanced" refers to a bookmark
725 # i18n: "advanced" refers to a bookmark
726 add(b, hex(scid), _('advanced'))
726 add(b, hex(scid), _('advanced'))
727 for b, scid, dcid in diverge:
727 for b, scid, dcid in diverge:
728 # i18n: "diverged" refers to a bookmark
728 # i18n: "diverged" refers to a bookmark
729 add(b, hex(scid), _('diverged'))
729 add(b, hex(scid), _('diverged'))
730 for b, scid, dcid in differ:
730 for b, scid, dcid in differ:
731 # i18n: "changed" refers to a bookmark
731 # i18n: "changed" refers to a bookmark
732 add(b, hex(scid), _('changed'))
732 add(b, hex(scid), _('changed'))
733
733
734 if not incomings:
734 if not incomings:
735 ui.status(_("no changed bookmarks found\n"))
735 ui.status(_("no changed bookmarks found\n"))
736 return 1
736 return 1
737
737
738 for s in sorted(incomings):
738 for s in sorted(incomings):
739 ui.write(s)
739 ui.write(s)
740
740
741 return 0
741 return 0
742
742
743 def outgoing(ui, repo, other):
743 def outgoing(ui, repo, other):
744 '''Show bookmarks outgoing from repo to other
744 '''Show bookmarks outgoing from repo to other
745 '''
745 '''
746 ui.status(_("searching for changed bookmarks\n"))
746 ui.status(_("searching for changed bookmarks\n"))
747
747
748 remotemarks = unhexlifybookmarks(other.listkeys('bookmarks'))
748 remotemarks = unhexlifybookmarks(other.listkeys('bookmarks'))
749 r = comparebookmarks(repo, repo._bookmarks, remotemarks)
749 r = comparebookmarks(repo, repo._bookmarks, remotemarks)
750 addsrc, adddst, advsrc, advdst, diverge, differ, invalid, same = r
750 addsrc, adddst, advsrc, advdst, diverge, differ, invalid, same = r
751
751
752 outgoings = []
752 outgoings = []
753 if ui.debugflag:
753 if ui.debugflag:
754 getid = lambda id: id
754 getid = lambda id: id
755 else:
755 else:
756 getid = lambda id: id[:12]
756 getid = lambda id: id[:12]
757 if ui.verbose:
757 if ui.verbose:
758 def add(b, id, st):
758 def add(b, id, st):
759 outgoings.append(" %-25s %s %s\n" % (b, getid(id), st))
759 outgoings.append(" %-25s %s %s\n" % (b, getid(id), st))
760 else:
760 else:
761 def add(b, id, st):
761 def add(b, id, st):
762 outgoings.append(" %-25s %s\n" % (b, getid(id)))
762 outgoings.append(" %-25s %s\n" % (b, getid(id)))
763 for b, scid, dcid in addsrc:
763 for b, scid, dcid in addsrc:
764 # i18n: "added refers to a bookmark
764 # i18n: "added refers to a bookmark
765 add(b, hex(scid), _('added'))
765 add(b, hex(scid), _('added'))
766 for b, scid, dcid in adddst:
766 for b, scid, dcid in adddst:
767 # i18n: "deleted" refers to a bookmark
767 # i18n: "deleted" refers to a bookmark
768 add(b, ' ' * 40, _('deleted'))
768 add(b, ' ' * 40, _('deleted'))
769 for b, scid, dcid in advsrc:
769 for b, scid, dcid in advsrc:
770 # i18n: "advanced" refers to a bookmark
770 # i18n: "advanced" refers to a bookmark
771 add(b, hex(scid), _('advanced'))
771 add(b, hex(scid), _('advanced'))
772 for b, scid, dcid in diverge:
772 for b, scid, dcid in diverge:
773 # i18n: "diverged" refers to a bookmark
773 # i18n: "diverged" refers to a bookmark
774 add(b, hex(scid), _('diverged'))
774 add(b, hex(scid), _('diverged'))
775 for b, scid, dcid in differ:
775 for b, scid, dcid in differ:
776 # i18n: "changed" refers to a bookmark
776 # i18n: "changed" refers to a bookmark
777 add(b, hex(scid), _('changed'))
777 add(b, hex(scid), _('changed'))
778
778
779 if not outgoings:
779 if not outgoings:
780 ui.status(_("no changed bookmarks found\n"))
780 ui.status(_("no changed bookmarks found\n"))
781 return 1
781 return 1
782
782
783 for s in sorted(outgoings):
783 for s in sorted(outgoings):
784 ui.write(s)
784 ui.write(s)
785
785
786 return 0
786 return 0
787
787
788 def summary(repo, peer):
788 def summary(repo, peer):
789 '''Compare bookmarks between repo and other for "hg summary" output
789 '''Compare bookmarks between repo and other for "hg summary" output
790
790
791 This returns "(# of incoming, # of outgoing)" tuple.
791 This returns "(# of incoming, # of outgoing)" tuple.
792 '''
792 '''
793 with peer.commandexecutor() as e:
793 with peer.commandexecutor() as e:
794 remotemarks = unhexlifybookmarks(e.callcommand('listkeys', {
794 remotemarks = unhexlifybookmarks(e.callcommand('listkeys', {
795 'namespace': 'bookmarks',
795 'namespace': 'bookmarks',
796 }).result())
796 }).result())
797
797
798 r = comparebookmarks(repo, remotemarks, repo._bookmarks)
798 r = comparebookmarks(repo, remotemarks, repo._bookmarks)
799 addsrc, adddst, advsrc, advdst, diverge, differ, invalid, same = r
799 addsrc, adddst, advsrc, advdst, diverge, differ, invalid, same = r
800 return (len(addsrc), len(adddst))
800 return (len(addsrc), len(adddst))
801
801
802 def validdest(repo, old, new):
802 def validdest(repo, old, new):
803 """Is the new bookmark destination a valid update from the old one"""
803 """Is the new bookmark destination a valid update from the old one"""
804 repo = repo.unfiltered()
804 repo = repo.unfiltered()
805 if old == new:
805 if old == new:
806 # Old == new -> nothing to update.
806 # Old == new -> nothing to update.
807 return False
807 return False
808 elif not old:
808 elif not old:
809 # old is nullrev, anything is valid.
809 # old is nullrev, anything is valid.
810 # (new != nullrev has been excluded by the previous check)
810 # (new != nullrev has been excluded by the previous check)
811 return True
811 return True
812 elif repo.obsstore:
812 elif repo.obsstore:
813 return new.node() in obsutil.foreground(repo, [old.node()])
813 return new.node() in obsutil.foreground(repo, [old.node()])
814 else:
814 else:
815 # still an independent clause as it is lazier (and therefore faster)
815 # still an independent clause as it is lazier (and therefore faster)
816 return old.isancestorof(new)
816 return old.isancestorof(new)
817
817
818 def checkformat(repo, mark):
818 def checkformat(repo, mark):
819 """return a valid version of a potential bookmark name
819 """return a valid version of a potential bookmark name
820
820
821 Raises an abort error if the bookmark name is not valid.
821 Raises an abort error if the bookmark name is not valid.
822 """
822 """
823 mark = mark.strip()
823 mark = mark.strip()
824 if not mark:
824 if not mark:
825 raise error.Abort(_("bookmark names cannot consist entirely of "
825 raise error.Abort(_("bookmark names cannot consist entirely of "
826 "whitespace"))
826 "whitespace"))
827 scmutil.checknewlabel(repo, mark, 'bookmark')
827 scmutil.checknewlabel(repo, mark, 'bookmark')
828 return mark
828 return mark
829
829
830 def delete(repo, tr, names):
830 def delete(repo, tr, names):
831 """remove a mark from the bookmark store
831 """remove a mark from the bookmark store
832
832
833 Raises an abort error if mark does not exist.
833 Raises an abort error if mark does not exist.
834 """
834 """
835 marks = repo._bookmarks
835 marks = repo._bookmarks
836 changes = []
836 changes = []
837 for mark in names:
837 for mark in names:
838 if mark not in marks:
838 if mark not in marks:
839 raise error.Abort(_("bookmark '%s' does not exist") % mark)
839 raise error.Abort(_("bookmark '%s' does not exist") % mark)
840 if mark == repo._activebookmark:
840 if mark == repo._activebookmark:
841 deactivate(repo)
841 deactivate(repo)
842 changes.append((mark, None))
842 changes.append((mark, None))
843 marks.applychanges(repo, tr, changes)
843 marks.applychanges(repo, tr, changes)
844
844
845 def rename(repo, tr, old, new, force=False, inactive=False):
845 def rename(repo, tr, old, new, force=False, inactive=False):
846 """rename a bookmark from old to new
846 """rename a bookmark from old to new
847
847
848 If force is specified, then the new name can overwrite an existing
848 If force is specified, then the new name can overwrite an existing
849 bookmark.
849 bookmark.
850
850
851 If inactive is specified, then do not activate the new bookmark.
851 If inactive is specified, then do not activate the new bookmark.
852
852
853 Raises an abort error if old is not in the bookmark store.
853 Raises an abort error if old is not in the bookmark store.
854 """
854 """
855 marks = repo._bookmarks
855 marks = repo._bookmarks
856 mark = checkformat(repo, new)
856 mark = checkformat(repo, new)
857 if old not in marks:
857 if old not in marks:
858 raise error.Abort(_("bookmark '%s' does not exist") % old)
858 raise error.Abort(_("bookmark '%s' does not exist") % old)
859 changes = []
859 changes = []
860 for bm in marks.checkconflict(mark, force):
860 for bm in marks.checkconflict(mark, force):
861 changes.append((bm, None))
861 changes.append((bm, None))
862 changes.extend([(mark, marks[old]), (old, None)])
862 changes.extend([(mark, marks[old]), (old, None)])
863 marks.applychanges(repo, tr, changes)
863 marks.applychanges(repo, tr, changes)
864 if repo._activebookmark == old and not inactive:
864 if repo._activebookmark == old and not inactive:
865 activate(repo, mark)
865 activate(repo, mark)
866
866
867 def addbookmarks(repo, tr, names, rev=None, force=False, inactive=False):
867 def addbookmarks(repo, tr, names, rev=None, force=False, inactive=False):
868 """add a list of bookmarks
868 """add a list of bookmarks
869
869
870 If force is specified, then the new name can overwrite an existing
870 If force is specified, then the new name can overwrite an existing
871 bookmark.
871 bookmark.
872
872
873 If inactive is specified, then do not activate any bookmark. Otherwise, the
873 If inactive is specified, then do not activate any bookmark. Otherwise, the
874 first bookmark is activated.
874 first bookmark is activated.
875
875
876 Raises an abort error if old is not in the bookmark store.
876 Raises an abort error if old is not in the bookmark store.
877 """
877 """
878 marks = repo._bookmarks
878 marks = repo._bookmarks
879 cur = repo['.'].node()
879 cur = repo['.'].node()
880 newact = None
880 newact = None
881 changes = []
881 changes = []
882 hiddenrev = None
882 hiddenrev = None
883
883
884 # unhide revs if any
884 # unhide revs if any
885 if rev:
885 if rev:
886 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
886 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
887
887
888 for mark in names:
888 for mark in names:
889 mark = checkformat(repo, mark)
889 mark = checkformat(repo, mark)
890 if newact is None:
890 if newact is None:
891 newact = mark
891 newact = mark
892 if inactive and mark == repo._activebookmark:
892 if inactive and mark == repo._activebookmark:
893 deactivate(repo)
893 deactivate(repo)
894 return
894 return
895 tgt = cur
895 tgt = cur
896 if rev:
896 if rev:
897 ctx = scmutil.revsingle(repo, rev)
897 ctx = scmutil.revsingle(repo, rev)
898 if ctx.hidden():
898 if ctx.hidden():
899 hiddenrev = ctx.hex()[:12]
899 hiddenrev = ctx.hex()[:12]
900 tgt = ctx.node()
900 tgt = ctx.node()
901 for bm in marks.checkconflict(mark, force, tgt):
901 for bm in marks.checkconflict(mark, force, tgt):
902 changes.append((bm, None))
902 changes.append((bm, None))
903 changes.append((mark, tgt))
903 changes.append((mark, tgt))
904
904
905 if hiddenrev:
905 if hiddenrev:
906 repo.ui.warn(_("bookmarking hidden changeset %s\n") % hiddenrev)
906 repo.ui.warn(_("bookmarking hidden changeset %s\n") % hiddenrev)
907
907
908 if ctx.obsolete():
908 if ctx.obsolete():
909 msg = obsutil._getfilteredreason(repo, "%s" % hiddenrev, ctx)
909 msg = obsutil._getfilteredreason(repo, "%s" % hiddenrev, ctx)
910 repo.ui.warn("(%s)\n" % msg)
910 repo.ui.warn("(%s)\n" % msg)
911
911
912 marks.applychanges(repo, tr, changes)
912 marks.applychanges(repo, tr, changes)
913 if not inactive and cur == marks[newact] and not rev:
913 if not inactive and cur == marks[newact] and not rev:
914 activate(repo, newact)
914 activate(repo, newact)
915 elif cur != tgt and newact == repo._activebookmark:
915 elif cur != tgt and newact == repo._activebookmark:
916 deactivate(repo)
916 deactivate(repo)
917
917
918 def _printbookmarks(ui, repo, bmarks, **opts):
918 def _printbookmarks(ui, repo, bmarks, **opts):
919 """private method to print bookmarks
919 """private method to print bookmarks
920
920
921 Provides a way for extensions to control how bookmarks are printed (e.g.
921 Provides a way for extensions to control how bookmarks are printed (e.g.
922 prepend or postpend names)
922 prepend or postpend names)
923 """
923 """
924 opts = pycompat.byteskwargs(opts)
924 opts = pycompat.byteskwargs(opts)
925 fm = ui.formatter('bookmarks', opts)
925 fm = ui.formatter('bookmarks', opts)
926 contexthint = fm.contexthint('bookmark rev node active')
926 contexthint = fm.contexthint('bookmark rev node active')
927 hexfn = fm.hexfunc
927 hexfn = fm.hexfunc
928 if len(bmarks) == 0 and fm.isplain():
928 if len(bmarks) == 0 and fm.isplain():
929 ui.status(_("no bookmarks set\n"))
929 ui.status(_("no bookmarks set\n"))
930 for bmark, (n, prefix, label) in sorted(bmarks.iteritems()):
930 for bmark, (n, prefix, label) in sorted(bmarks.iteritems()):
931 fm.startitem()
931 fm.startitem()
932 if 'ctx' in contexthint:
932 if 'ctx' in contexthint:
933 fm.context(ctx=repo[n])
933 fm.context(ctx=repo[n])
934 if not ui.quiet:
934 if not ui.quiet:
935 fm.plain(' %s ' % prefix, label=label)
935 fm.plain(' %s ' % prefix, label=label)
936 fm.write('bookmark', '%s', bmark, label=label)
936 fm.write('bookmark', '%s', bmark, label=label)
937 pad = " " * (25 - encoding.colwidth(bmark))
937 pad = " " * (25 - encoding.colwidth(bmark))
938 fm.condwrite(not ui.quiet, 'rev node', pad + ' %d:%s',
938 fm.condwrite(not ui.quiet, 'rev node', pad + ' %d:%s',
939 repo.changelog.rev(n), hexfn(n), label=label)
939 repo.changelog.rev(n), hexfn(n), label=label)
940 fm.data(active=(activebookmarklabel in label))
940 fm.data(active=(activebookmarklabel in label))
941 fm.plain('\n')
941 fm.plain('\n')
942 fm.end()
942 fm.end()
943
943
944 def printbookmarks(ui, repo, **opts):
944 def printbookmarks(ui, repo, **opts):
945 """print bookmarks to a formatter
945 """print bookmarks to a formatter
946
946
947 Provides a way for extensions to control how bookmarks are printed.
947 Provides a way for extensions to control how bookmarks are printed.
948 """
948 """
949 marks = repo._bookmarks
949 marks = repo._bookmarks
950 bmarks = {}
950 bmarks = {}
951 for bmark, n in sorted(marks.iteritems()):
951 for bmark, n in sorted(marks.iteritems()):
952 active = repo._activebookmark
952 active = repo._activebookmark
953 if bmark == active:
953 if bmark == active:
954 prefix, label = '*', activebookmarklabel
954 prefix, label = '*', activebookmarklabel
955 else:
955 else:
956 prefix, label = ' ', ''
956 prefix, label = ' ', ''
957
957
958 bmarks[bmark] = (n, prefix, label)
958 bmarks[bmark] = (n, prefix, label)
959 _printbookmarks(ui, repo, bmarks, **opts)
959 _printbookmarks(ui, repo, bmarks, **opts)
960
960
961 def preparehookargs(name, old, new):
961 def preparehookargs(name, old, new):
962 if new is None:
962 if new is None:
963 new = ''
963 new = ''
964 if old is None:
964 if old is None:
965 old = ''
965 old = ''
966 return {'bookmark': name,
966 return {'bookmark': name,
967 'node': hex(new),
967 'node': hex(new),
968 'oldnode': hex(old)}
968 'oldnode': hex(old)}
@@ -1,1277 +1,1277 b''
1 #testcases b2-pushkey b2-binary
1 #testcases b2-pushkey b2-binary
2
2
3 #if b2-pushkey
3 #if b2-pushkey
4 $ cat << EOF >> $HGRCPATH
4 $ cat << EOF >> $HGRCPATH
5 > [devel]
5 > [devel]
6 > legacy.exchange=bookmarks
6 > legacy.exchange=bookmarks
7 > EOF
7 > EOF
8 #endif
8 #endif
9
9
10 #require serve
10 #require serve
11
11
12 $ cat << EOF >> $HGRCPATH
12 $ cat << EOF >> $HGRCPATH
13 > [ui]
13 > [ui]
14 > logtemplate={rev}:{node|short} {desc|firstline}
14 > logtemplate={rev}:{node|short} {desc|firstline}
15 > [phases]
15 > [phases]
16 > publish=False
16 > publish=False
17 > [experimental]
17 > [experimental]
18 > evolution.createmarkers=True
18 > evolution.createmarkers=True
19 > evolution.exchange=True
19 > evolution.exchange=True
20 > EOF
20 > EOF
21
21
22 $ cat > $TESTTMP/hook.sh <<'EOF'
22 $ cat > $TESTTMP/hook.sh <<'EOF'
23 > echo "test-hook-bookmark: $HG_BOOKMARK: $HG_OLDNODE -> $HG_NODE"
23 > echo "test-hook-bookmark: $HG_BOOKMARK: $HG_OLDNODE -> $HG_NODE"
24 > EOF
24 > EOF
25 $ TESTHOOK="hooks.txnclose-bookmark.test=sh $TESTTMP/hook.sh"
25 $ TESTHOOK="hooks.txnclose-bookmark.test=sh $TESTTMP/hook.sh"
26
26
27 initialize
27 initialize
28
28
29 $ hg init a
29 $ hg init a
30 $ cd a
30 $ cd a
31 $ echo 'test' > test
31 $ echo 'test' > test
32 $ hg commit -Am'test'
32 $ hg commit -Am'test'
33 adding test
33 adding test
34
34
35 set bookmarks
35 set bookmarks
36
36
37 $ hg bookmark X
37 $ hg bookmark X
38 $ hg bookmark Y
38 $ hg bookmark Y
39 $ hg bookmark Z
39 $ hg bookmark Z
40
40
41 import bookmark by name
41 import bookmark by name
42
42
43 $ hg init ../b
43 $ hg init ../b
44 $ cd ../b
44 $ cd ../b
45 $ hg book Y
45 $ hg book Y
46 $ hg book
46 $ hg book
47 * Y -1:000000000000
47 * Y -1:000000000000
48 $ hg pull ../a --config "$TESTHOOK"
48 $ hg pull ../a --config "$TESTHOOK"
49 pulling from ../a
49 pulling from ../a
50 requesting all changes
50 requesting all changes
51 adding changesets
51 adding changesets
52 adding manifests
52 adding manifests
53 adding file changes
53 adding file changes
54 added 1 changesets with 1 changes to 1 files
54 added 1 changesets with 1 changes to 1 files
55 adding remote bookmark X
55 adding remote bookmark X
56 updating bookmark Y
56 updating bookmark Y
57 adding remote bookmark Z
57 adding remote bookmark Z
58 new changesets 4e3505fd9583
58 new changesets 4e3505fd9583
59 test-hook-bookmark: X: -> 4e3505fd95835d721066b76e75dbb8cc554d7f77
59 test-hook-bookmark: X: -> 4e3505fd95835d721066b76e75dbb8cc554d7f77
60 test-hook-bookmark: Y: 0000000000000000000000000000000000000000 -> 4e3505fd95835d721066b76e75dbb8cc554d7f77
60 test-hook-bookmark: Y: 0000000000000000000000000000000000000000 -> 4e3505fd95835d721066b76e75dbb8cc554d7f77
61 test-hook-bookmark: Z: -> 4e3505fd95835d721066b76e75dbb8cc554d7f77
61 test-hook-bookmark: Z: -> 4e3505fd95835d721066b76e75dbb8cc554d7f77
62 (run 'hg update' to get a working copy)
62 (run 'hg update' to get a working copy)
63 $ hg bookmarks
63 $ hg bookmarks
64 X 0:4e3505fd9583
64 X 0:4e3505fd9583
65 * Y 0:4e3505fd9583
65 * Y 0:4e3505fd9583
66 Z 0:4e3505fd9583
66 Z 0:4e3505fd9583
67 $ hg debugpushkey ../a namespaces
67 $ hg debugpushkey ../a namespaces
68 bookmarks
68 bookmarks
69 namespaces
69 namespaces
70 obsolete
70 obsolete
71 phases
71 phases
72 $ hg debugpushkey ../a bookmarks
72 $ hg debugpushkey ../a bookmarks
73 X 4e3505fd95835d721066b76e75dbb8cc554d7f77
73 X 4e3505fd95835d721066b76e75dbb8cc554d7f77
74 Y 4e3505fd95835d721066b76e75dbb8cc554d7f77
74 Y 4e3505fd95835d721066b76e75dbb8cc554d7f77
75 Z 4e3505fd95835d721066b76e75dbb8cc554d7f77
75 Z 4e3505fd95835d721066b76e75dbb8cc554d7f77
76
76
77 delete the bookmark to re-pull it
77 delete the bookmark to re-pull it
78
78
79 $ hg book -d X
79 $ hg book -d X
80 $ hg pull -B X ../a
80 $ hg pull -B X ../a
81 pulling from ../a
81 pulling from ../a
82 no changes found
82 no changes found
83 adding remote bookmark X
83 adding remote bookmark X
84
84
85 finally no-op pull
85 finally no-op pull
86
86
87 $ hg pull -B X ../a
87 $ hg pull -B X ../a
88 pulling from ../a
88 pulling from ../a
89 no changes found
89 no changes found
90 $ hg bookmark
90 $ hg bookmark
91 X 0:4e3505fd9583
91 X 0:4e3505fd9583
92 * Y 0:4e3505fd9583
92 * Y 0:4e3505fd9583
93 Z 0:4e3505fd9583
93 Z 0:4e3505fd9583
94
94
95 export bookmark by name
95 export bookmark by name
96
96
97 $ hg bookmark W
97 $ hg bookmark W
98 $ hg bookmark foo
98 $ hg bookmark foo
99 $ hg bookmark foobar
99 $ hg bookmark foobar
100 $ hg push -B W ../a
100 $ hg push -B W ../a
101 pushing to ../a
101 pushing to ../a
102 searching for changes
102 searching for changes
103 no changes found
103 no changes found
104 exporting bookmark W
104 exporting bookmark W
105 [1]
105 [1]
106 $ hg -R ../a bookmarks
106 $ hg -R ../a bookmarks
107 W -1:000000000000
107 W -1:000000000000
108 X 0:4e3505fd9583
108 X 0:4e3505fd9583
109 Y 0:4e3505fd9583
109 Y 0:4e3505fd9583
110 * Z 0:4e3505fd9583
110 * Z 0:4e3505fd9583
111
111
112 delete a remote bookmark
112 delete a remote bookmark
113
113
114 $ hg book -d W
114 $ hg book -d W
115
115
116 #if b2-pushkey
116 #if b2-pushkey
117
117
118 $ hg push -B W ../a --config "$TESTHOOK" --debug --config devel.bundle2.debug=yes
118 $ hg push -B W ../a --config "$TESTHOOK" --debug --config devel.bundle2.debug=yes
119 pushing to ../a
119 pushing to ../a
120 query 1; heads
120 query 1; heads
121 searching for changes
121 searching for changes
122 all remote heads known locally
122 all remote heads known locally
123 listing keys for "phases"
123 listing keys for "phases"
124 checking for updated bookmarks
124 checking for updated bookmarks
125 listing keys for "bookmarks"
125 listing keys for "bookmarks"
126 no changes found
126 no changes found
127 bundle2-output-bundle: "HG20", 4 parts total
127 bundle2-output-bundle: "HG20", 4 parts total
128 bundle2-output: start emission of HG20 stream
128 bundle2-output: start emission of HG20 stream
129 bundle2-output: bundle parameter:
129 bundle2-output: bundle parameter:
130 bundle2-output: start of parts
130 bundle2-output: start of parts
131 bundle2-output: bundle part: "replycaps"
131 bundle2-output: bundle part: "replycaps"
132 bundle2-output-part: "replycaps" 222 bytes payload
132 bundle2-output-part: "replycaps" 222 bytes payload
133 bundle2-output: part 0: "REPLYCAPS"
133 bundle2-output: part 0: "REPLYCAPS"
134 bundle2-output: header chunk size: 16
134 bundle2-output: header chunk size: 16
135 bundle2-output: payload chunk size: 222
135 bundle2-output: payload chunk size: 222
136 bundle2-output: closing payload chunk
136 bundle2-output: closing payload chunk
137 bundle2-output: bundle part: "check:bookmarks"
137 bundle2-output: bundle part: "check:bookmarks"
138 bundle2-output-part: "check:bookmarks" 23 bytes payload
138 bundle2-output-part: "check:bookmarks" 23 bytes payload
139 bundle2-output: part 1: "CHECK:BOOKMARKS"
139 bundle2-output: part 1: "CHECK:BOOKMARKS"
140 bundle2-output: header chunk size: 22
140 bundle2-output: header chunk size: 22
141 bundle2-output: payload chunk size: 23
141 bundle2-output: payload chunk size: 23
142 bundle2-output: closing payload chunk
142 bundle2-output: closing payload chunk
143 bundle2-output: bundle part: "check:phases"
143 bundle2-output: bundle part: "check:phases"
144 bundle2-output-part: "check:phases" 24 bytes payload
144 bundle2-output-part: "check:phases" 24 bytes payload
145 bundle2-output: part 2: "CHECK:PHASES"
145 bundle2-output: part 2: "CHECK:PHASES"
146 bundle2-output: header chunk size: 19
146 bundle2-output: header chunk size: 19
147 bundle2-output: payload chunk size: 24
147 bundle2-output: payload chunk size: 24
148 bundle2-output: closing payload chunk
148 bundle2-output: closing payload chunk
149 bundle2-output: bundle part: "pushkey"
149 bundle2-output: bundle part: "pushkey"
150 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
150 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
151 bundle2-output: part 3: "PUSHKEY"
151 bundle2-output: part 3: "PUSHKEY"
152 bundle2-output: header chunk size: 90
152 bundle2-output: header chunk size: 90
153 bundle2-output: closing payload chunk
153 bundle2-output: closing payload chunk
154 bundle2-output: end of bundle
154 bundle2-output: end of bundle
155 bundle2-input: start processing of HG20 stream
155 bundle2-input: start processing of HG20 stream
156 bundle2-input: reading bundle2 stream parameters
156 bundle2-input: reading bundle2 stream parameters
157 bundle2-input-bundle: with-transaction
157 bundle2-input-bundle: with-transaction
158 bundle2-input: start extraction of bundle2 parts
158 bundle2-input: start extraction of bundle2 parts
159 bundle2-input: part header size: 16
159 bundle2-input: part header size: 16
160 bundle2-input: part type: "REPLYCAPS"
160 bundle2-input: part type: "REPLYCAPS"
161 bundle2-input: part id: "0"
161 bundle2-input: part id: "0"
162 bundle2-input: part parameters: 0
162 bundle2-input: part parameters: 0
163 bundle2-input: found a handler for part replycaps
163 bundle2-input: found a handler for part replycaps
164 bundle2-input-part: "replycaps" supported
164 bundle2-input-part: "replycaps" supported
165 bundle2-input: payload chunk size: 222
165 bundle2-input: payload chunk size: 222
166 bundle2-input: payload chunk size: 0
166 bundle2-input: payload chunk size: 0
167 bundle2-input-part: total payload size 222
167 bundle2-input-part: total payload size 222
168 bundle2-input: part header size: 22
168 bundle2-input: part header size: 22
169 bundle2-input: part type: "CHECK:BOOKMARKS"
169 bundle2-input: part type: "CHECK:BOOKMARKS"
170 bundle2-input: part id: "1"
170 bundle2-input: part id: "1"
171 bundle2-input: part parameters: 0
171 bundle2-input: part parameters: 0
172 bundle2-input: found a handler for part check:bookmarks
172 bundle2-input: found a handler for part check:bookmarks
173 bundle2-input-part: "check:bookmarks" supported
173 bundle2-input-part: "check:bookmarks" supported
174 bundle2-input: payload chunk size: 23
174 bundle2-input: payload chunk size: 23
175 bundle2-input: payload chunk size: 0
175 bundle2-input: payload chunk size: 0
176 bundle2-input-part: total payload size 23
176 bundle2-input-part: total payload size 23
177 bundle2-input: part header size: 19
177 bundle2-input: part header size: 19
178 bundle2-input: part type: "CHECK:PHASES"
178 bundle2-input: part type: "CHECK:PHASES"
179 bundle2-input: part id: "2"
179 bundle2-input: part id: "2"
180 bundle2-input: part parameters: 0
180 bundle2-input: part parameters: 0
181 bundle2-input: found a handler for part check:phases
181 bundle2-input: found a handler for part check:phases
182 bundle2-input-part: "check:phases" supported
182 bundle2-input-part: "check:phases" supported
183 bundle2-input: payload chunk size: 24
183 bundle2-input: payload chunk size: 24
184 bundle2-input: payload chunk size: 0
184 bundle2-input: payload chunk size: 0
185 bundle2-input-part: total payload size 24
185 bundle2-input-part: total payload size 24
186 bundle2-input: part header size: 90
186 bundle2-input: part header size: 90
187 bundle2-input: part type: "PUSHKEY"
187 bundle2-input: part type: "PUSHKEY"
188 bundle2-input: part id: "3"
188 bundle2-input: part id: "3"
189 bundle2-input: part parameters: 4
189 bundle2-input: part parameters: 4
190 bundle2-input: found a handler for part pushkey
190 bundle2-input: found a handler for part pushkey
191 bundle2-input-part: "pushkey" (params: 4 mandatory) supported
191 bundle2-input-part: "pushkey" (params: 4 mandatory) supported
192 pushing key for "bookmarks:W"
192 pushing key for "bookmarks:W"
193 bundle2-input: payload chunk size: 0
193 bundle2-input: payload chunk size: 0
194 bundle2-input: part header size: 0
194 bundle2-input: part header size: 0
195 bundle2-input: end of bundle2 stream
195 bundle2-input: end of bundle2 stream
196 bundle2-input-bundle: 3 parts total
196 bundle2-input-bundle: 3 parts total
197 running hook txnclose-bookmark.test: sh $TESTTMP/hook.sh
197 running hook txnclose-bookmark.test: sh $TESTTMP/hook.sh
198 test-hook-bookmark: W: 0000000000000000000000000000000000000000 ->
198 test-hook-bookmark: W: 0000000000000000000000000000000000000000 ->
199 bundle2-output-bundle: "HG20", 1 parts total
199 bundle2-output-bundle: "HG20", 1 parts total
200 bundle2-output: start emission of HG20 stream
200 bundle2-output: start emission of HG20 stream
201 bundle2-output: bundle parameter:
201 bundle2-output: bundle parameter:
202 bundle2-output: start of parts
202 bundle2-output: start of parts
203 bundle2-output: bundle part: "reply:pushkey"
203 bundle2-output: bundle part: "reply:pushkey"
204 bundle2-output-part: "reply:pushkey" (params: 0 advisory) empty payload
204 bundle2-output-part: "reply:pushkey" (params: 0 advisory) empty payload
205 bundle2-output: part 0: "REPLY:PUSHKEY"
205 bundle2-output: part 0: "REPLY:PUSHKEY"
206 bundle2-output: header chunk size: 43
206 bundle2-output: header chunk size: 43
207 bundle2-output: closing payload chunk
207 bundle2-output: closing payload chunk
208 bundle2-output: end of bundle
208 bundle2-output: end of bundle
209 bundle2-input: start processing of HG20 stream
209 bundle2-input: start processing of HG20 stream
210 bundle2-input: reading bundle2 stream parameters
210 bundle2-input: reading bundle2 stream parameters
211 bundle2-input-bundle: no-transaction
211 bundle2-input-bundle: no-transaction
212 bundle2-input: start extraction of bundle2 parts
212 bundle2-input: start extraction of bundle2 parts
213 bundle2-input: part header size: 43
213 bundle2-input: part header size: 43
214 bundle2-input: part type: "REPLY:PUSHKEY"
214 bundle2-input: part type: "REPLY:PUSHKEY"
215 bundle2-input: part id: "0"
215 bundle2-input: part id: "0"
216 bundle2-input: part parameters: 2
216 bundle2-input: part parameters: 2
217 bundle2-input: found a handler for part reply:pushkey
217 bundle2-input: found a handler for part reply:pushkey
218 bundle2-input-part: "reply:pushkey" (params: 0 advisory) supported
218 bundle2-input-part: "reply:pushkey" (params: 0 advisory) supported
219 bundle2-input: payload chunk size: 0
219 bundle2-input: payload chunk size: 0
220 bundle2-input: part header size: 0
220 bundle2-input: part header size: 0
221 bundle2-input: end of bundle2 stream
221 bundle2-input: end of bundle2 stream
222 bundle2-input-bundle: 0 parts total
222 bundle2-input-bundle: 0 parts total
223 deleting remote bookmark W
223 deleting remote bookmark W
224 listing keys for "phases"
224 listing keys for "phases"
225 [1]
225 [1]
226
226
227 #endif
227 #endif
228 #if b2-binary
228 #if b2-binary
229
229
230 $ hg push -B W ../a --config "$TESTHOOK" --debug --config devel.bundle2.debug=yes
230 $ hg push -B W ../a --config "$TESTHOOK" --debug --config devel.bundle2.debug=yes
231 pushing to ../a
231 pushing to ../a
232 query 1; heads
232 query 1; heads
233 searching for changes
233 searching for changes
234 all remote heads known locally
234 all remote heads known locally
235 listing keys for "phases"
235 listing keys for "phases"
236 checking for updated bookmarks
236 checking for updated bookmarks
237 listing keys for "bookmarks"
237 listing keys for "bookmarks"
238 no changes found
238 no changes found
239 bundle2-output-bundle: "HG20", 4 parts total
239 bundle2-output-bundle: "HG20", 4 parts total
240 bundle2-output: start emission of HG20 stream
240 bundle2-output: start emission of HG20 stream
241 bundle2-output: bundle parameter:
241 bundle2-output: bundle parameter:
242 bundle2-output: start of parts
242 bundle2-output: start of parts
243 bundle2-output: bundle part: "replycaps"
243 bundle2-output: bundle part: "replycaps"
244 bundle2-output-part: "replycaps" 222 bytes payload
244 bundle2-output-part: "replycaps" 222 bytes payload
245 bundle2-output: part 0: "REPLYCAPS"
245 bundle2-output: part 0: "REPLYCAPS"
246 bundle2-output: header chunk size: 16
246 bundle2-output: header chunk size: 16
247 bundle2-output: payload chunk size: 222
247 bundle2-output: payload chunk size: 222
248 bundle2-output: closing payload chunk
248 bundle2-output: closing payload chunk
249 bundle2-output: bundle part: "check:bookmarks"
249 bundle2-output: bundle part: "check:bookmarks"
250 bundle2-output-part: "check:bookmarks" 23 bytes payload
250 bundle2-output-part: "check:bookmarks" 23 bytes payload
251 bundle2-output: part 1: "CHECK:BOOKMARKS"
251 bundle2-output: part 1: "CHECK:BOOKMARKS"
252 bundle2-output: header chunk size: 22
252 bundle2-output: header chunk size: 22
253 bundle2-output: payload chunk size: 23
253 bundle2-output: payload chunk size: 23
254 bundle2-output: closing payload chunk
254 bundle2-output: closing payload chunk
255 bundle2-output: bundle part: "check:phases"
255 bundle2-output: bundle part: "check:phases"
256 bundle2-output-part: "check:phases" 24 bytes payload
256 bundle2-output-part: "check:phases" 24 bytes payload
257 bundle2-output: part 2: "CHECK:PHASES"
257 bundle2-output: part 2: "CHECK:PHASES"
258 bundle2-output: header chunk size: 19
258 bundle2-output: header chunk size: 19
259 bundle2-output: payload chunk size: 24
259 bundle2-output: payload chunk size: 24
260 bundle2-output: closing payload chunk
260 bundle2-output: closing payload chunk
261 bundle2-output: bundle part: "bookmarks"
261 bundle2-output: bundle part: "bookmarks"
262 bundle2-output-part: "bookmarks" 23 bytes payload
262 bundle2-output-part: "bookmarks" 23 bytes payload
263 bundle2-output: part 3: "BOOKMARKS"
263 bundle2-output: part 3: "BOOKMARKS"
264 bundle2-output: header chunk size: 16
264 bundle2-output: header chunk size: 16
265 bundle2-output: payload chunk size: 23
265 bundle2-output: payload chunk size: 23
266 bundle2-output: closing payload chunk
266 bundle2-output: closing payload chunk
267 bundle2-output: end of bundle
267 bundle2-output: end of bundle
268 bundle2-input: start processing of HG20 stream
268 bundle2-input: start processing of HG20 stream
269 bundle2-input: reading bundle2 stream parameters
269 bundle2-input: reading bundle2 stream parameters
270 bundle2-input-bundle: with-transaction
270 bundle2-input-bundle: with-transaction
271 bundle2-input: start extraction of bundle2 parts
271 bundle2-input: start extraction of bundle2 parts
272 bundle2-input: part header size: 16
272 bundle2-input: part header size: 16
273 bundle2-input: part type: "REPLYCAPS"
273 bundle2-input: part type: "REPLYCAPS"
274 bundle2-input: part id: "0"
274 bundle2-input: part id: "0"
275 bundle2-input: part parameters: 0
275 bundle2-input: part parameters: 0
276 bundle2-input: found a handler for part replycaps
276 bundle2-input: found a handler for part replycaps
277 bundle2-input-part: "replycaps" supported
277 bundle2-input-part: "replycaps" supported
278 bundle2-input: payload chunk size: 222
278 bundle2-input: payload chunk size: 222
279 bundle2-input: payload chunk size: 0
279 bundle2-input: payload chunk size: 0
280 bundle2-input-part: total payload size 222
280 bundle2-input-part: total payload size 222
281 bundle2-input: part header size: 22
281 bundle2-input: part header size: 22
282 bundle2-input: part type: "CHECK:BOOKMARKS"
282 bundle2-input: part type: "CHECK:BOOKMARKS"
283 bundle2-input: part id: "1"
283 bundle2-input: part id: "1"
284 bundle2-input: part parameters: 0
284 bundle2-input: part parameters: 0
285 bundle2-input: found a handler for part check:bookmarks
285 bundle2-input: found a handler for part check:bookmarks
286 bundle2-input-part: "check:bookmarks" supported
286 bundle2-input-part: "check:bookmarks" supported
287 bundle2-input: payload chunk size: 23
287 bundle2-input: payload chunk size: 23
288 bundle2-input: payload chunk size: 0
288 bundle2-input: payload chunk size: 0
289 bundle2-input-part: total payload size 23
289 bundle2-input-part: total payload size 23
290 bundle2-input: part header size: 19
290 bundle2-input: part header size: 19
291 bundle2-input: part type: "CHECK:PHASES"
291 bundle2-input: part type: "CHECK:PHASES"
292 bundle2-input: part id: "2"
292 bundle2-input: part id: "2"
293 bundle2-input: part parameters: 0
293 bundle2-input: part parameters: 0
294 bundle2-input: found a handler for part check:phases
294 bundle2-input: found a handler for part check:phases
295 bundle2-input-part: "check:phases" supported
295 bundle2-input-part: "check:phases" supported
296 bundle2-input: payload chunk size: 24
296 bundle2-input: payload chunk size: 24
297 bundle2-input: payload chunk size: 0
297 bundle2-input: payload chunk size: 0
298 bundle2-input-part: total payload size 24
298 bundle2-input-part: total payload size 24
299 bundle2-input: part header size: 16
299 bundle2-input: part header size: 16
300 bundle2-input: part type: "BOOKMARKS"
300 bundle2-input: part type: "BOOKMARKS"
301 bundle2-input: part id: "3"
301 bundle2-input: part id: "3"
302 bundle2-input: part parameters: 0
302 bundle2-input: part parameters: 0
303 bundle2-input: found a handler for part bookmarks
303 bundle2-input: found a handler for part bookmarks
304 bundle2-input-part: "bookmarks" supported
304 bundle2-input-part: "bookmarks" supported
305 bundle2-input: payload chunk size: 23
305 bundle2-input: payload chunk size: 23
306 bundle2-input: payload chunk size: 0
306 bundle2-input: payload chunk size: 0
307 bundle2-input-part: total payload size 23
307 bundle2-input-part: total payload size 23
308 bundle2-input: part header size: 0
308 bundle2-input: part header size: 0
309 bundle2-input: end of bundle2 stream
309 bundle2-input: end of bundle2 stream
310 bundle2-input-bundle: 3 parts total
310 bundle2-input-bundle: 3 parts total
311 running hook txnclose-bookmark.test: sh $TESTTMP/hook.sh
311 running hook txnclose-bookmark.test: sh $TESTTMP/hook.sh
312 test-hook-bookmark: W: 0000000000000000000000000000000000000000 ->
312 test-hook-bookmark: W: 0000000000000000000000000000000000000000 ->
313 bundle2-output-bundle: "HG20", 0 parts total
313 bundle2-output-bundle: "HG20", 0 parts total
314 bundle2-output: start emission of HG20 stream
314 bundle2-output: start emission of HG20 stream
315 bundle2-output: bundle parameter:
315 bundle2-output: bundle parameter:
316 bundle2-output: start of parts
316 bundle2-output: start of parts
317 bundle2-output: end of bundle
317 bundle2-output: end of bundle
318 bundle2-input: start processing of HG20 stream
318 bundle2-input: start processing of HG20 stream
319 bundle2-input: reading bundle2 stream parameters
319 bundle2-input: reading bundle2 stream parameters
320 bundle2-input-bundle: no-transaction
320 bundle2-input-bundle: no-transaction
321 bundle2-input: start extraction of bundle2 parts
321 bundle2-input: start extraction of bundle2 parts
322 bundle2-input: part header size: 0
322 bundle2-input: part header size: 0
323 bundle2-input: end of bundle2 stream
323 bundle2-input: end of bundle2 stream
324 bundle2-input-bundle: 0 parts total
324 bundle2-input-bundle: 0 parts total
325 deleting remote bookmark W
325 deleting remote bookmark W
326 listing keys for "phases"
326 listing keys for "phases"
327 [1]
327 [1]
328
328
329 #endif
329 #endif
330
330
331 export the active bookmark
331 export the active bookmark
332
332
333 $ hg bookmark V
333 $ hg bookmark V
334 $ hg push -B . ../a
334 $ hg push -B . ../a
335 pushing to ../a
335 pushing to ../a
336 searching for changes
336 searching for changes
337 no changes found
337 no changes found
338 exporting bookmark V
338 exporting bookmark V
339 [1]
339 [1]
340
340
341 exporting the active bookmark with 'push -B .'
341 exporting the active bookmark with 'push -B .'
342 demand that one of the bookmarks is activated
342 demand that one of the bookmarks is activated
343
343
344 $ hg update -r default
344 $ hg update -r default
345 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
345 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
346 (leaving bookmark V)
346 (leaving bookmark V)
347 $ hg push -B . ../a
347 $ hg push -B . ../a
348 abort: no active bookmark
348 abort: no active bookmark!
349 [255]
349 [255]
350 $ hg update -r V
350 $ hg update -r V
351 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
351 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
352 (activating bookmark V)
352 (activating bookmark V)
353
353
354 delete the bookmark
354 delete the bookmark
355
355
356 $ hg book -d V
356 $ hg book -d V
357 $ hg push -B V ../a
357 $ hg push -B V ../a
358 pushing to ../a
358 pushing to ../a
359 searching for changes
359 searching for changes
360 no changes found
360 no changes found
361 deleting remote bookmark V
361 deleting remote bookmark V
362 [1]
362 [1]
363 $ hg up foobar
363 $ hg up foobar
364 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
364 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
365 (activating bookmark foobar)
365 (activating bookmark foobar)
366
366
367 push/pull name that doesn't exist
367 push/pull name that doesn't exist
368
368
369 $ hg push -B badname ../a
369 $ hg push -B badname ../a
370 pushing to ../a
370 pushing to ../a
371 searching for changes
371 searching for changes
372 bookmark badname does not exist on the local or remote repository!
372 bookmark badname does not exist on the local or remote repository!
373 no changes found
373 no changes found
374 [2]
374 [2]
375 $ hg pull -B anotherbadname ../a
375 $ hg pull -B anotherbadname ../a
376 pulling from ../a
376 pulling from ../a
377 abort: remote bookmark anotherbadname not found!
377 abort: remote bookmark anotherbadname not found!
378 [255]
378 [255]
379
379
380 divergent bookmarks
380 divergent bookmarks
381
381
382 $ cd ../a
382 $ cd ../a
383 $ echo c1 > f1
383 $ echo c1 > f1
384 $ hg ci -Am1
384 $ hg ci -Am1
385 adding f1
385 adding f1
386 $ hg book -f @
386 $ hg book -f @
387 $ hg book -f X
387 $ hg book -f X
388 $ hg book
388 $ hg book
389 @ 1:0d2164f0ce0d
389 @ 1:0d2164f0ce0d
390 * X 1:0d2164f0ce0d
390 * X 1:0d2164f0ce0d
391 Y 0:4e3505fd9583
391 Y 0:4e3505fd9583
392 Z 1:0d2164f0ce0d
392 Z 1:0d2164f0ce0d
393
393
394 $ cd ../b
394 $ cd ../b
395 $ hg up
395 $ hg up
396 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
396 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
397 updating bookmark foobar
397 updating bookmark foobar
398 $ echo c2 > f2
398 $ echo c2 > f2
399 $ hg ci -Am2
399 $ hg ci -Am2
400 adding f2
400 adding f2
401 $ hg book -if @
401 $ hg book -if @
402 $ hg book -if X
402 $ hg book -if X
403 $ hg book
403 $ hg book
404 @ 1:9b140be10808
404 @ 1:9b140be10808
405 X 1:9b140be10808
405 X 1:9b140be10808
406 Y 0:4e3505fd9583
406 Y 0:4e3505fd9583
407 Z 0:4e3505fd9583
407 Z 0:4e3505fd9583
408 foo -1:000000000000
408 foo -1:000000000000
409 * foobar 1:9b140be10808
409 * foobar 1:9b140be10808
410
410
411 $ hg pull --config paths.foo=../a foo --config "$TESTHOOK"
411 $ hg pull --config paths.foo=../a foo --config "$TESTHOOK"
412 pulling from $TESTTMP/a
412 pulling from $TESTTMP/a
413 searching for changes
413 searching for changes
414 adding changesets
414 adding changesets
415 adding manifests
415 adding manifests
416 adding file changes
416 adding file changes
417 added 1 changesets with 1 changes to 1 files (+1 heads)
417 added 1 changesets with 1 changes to 1 files (+1 heads)
418 divergent bookmark @ stored as @foo
418 divergent bookmark @ stored as @foo
419 divergent bookmark X stored as X@foo
419 divergent bookmark X stored as X@foo
420 updating bookmark Z
420 updating bookmark Z
421 new changesets 0d2164f0ce0d
421 new changesets 0d2164f0ce0d
422 test-hook-bookmark: @foo: -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
422 test-hook-bookmark: @foo: -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
423 test-hook-bookmark: X@foo: -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
423 test-hook-bookmark: X@foo: -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
424 test-hook-bookmark: Z: 4e3505fd95835d721066b76e75dbb8cc554d7f77 -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
424 test-hook-bookmark: Z: 4e3505fd95835d721066b76e75dbb8cc554d7f77 -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
425 (run 'hg heads' to see heads, 'hg merge' to merge)
425 (run 'hg heads' to see heads, 'hg merge' to merge)
426 $ hg book
426 $ hg book
427 @ 1:9b140be10808
427 @ 1:9b140be10808
428 @foo 2:0d2164f0ce0d
428 @foo 2:0d2164f0ce0d
429 X 1:9b140be10808
429 X 1:9b140be10808
430 X@foo 2:0d2164f0ce0d
430 X@foo 2:0d2164f0ce0d
431 Y 0:4e3505fd9583
431 Y 0:4e3505fd9583
432 Z 2:0d2164f0ce0d
432 Z 2:0d2164f0ce0d
433 foo -1:000000000000
433 foo -1:000000000000
434 * foobar 1:9b140be10808
434 * foobar 1:9b140be10808
435
435
436 (test that too many divergence of bookmark)
436 (test that too many divergence of bookmark)
437
437
438 $ $PYTHON $TESTDIR/seq.py 1 100 | while read i; do hg bookmarks -r 000000000000 "X@${i}"; done
438 $ $PYTHON $TESTDIR/seq.py 1 100 | while read i; do hg bookmarks -r 000000000000 "X@${i}"; done
439 $ hg pull ../a
439 $ hg pull ../a
440 pulling from ../a
440 pulling from ../a
441 searching for changes
441 searching for changes
442 no changes found
442 no changes found
443 warning: failed to assign numbered name to divergent bookmark X
443 warning: failed to assign numbered name to divergent bookmark X
444 divergent bookmark @ stored as @1
444 divergent bookmark @ stored as @1
445 $ hg bookmarks | grep '^ X' | grep -v ':000000000000'
445 $ hg bookmarks | grep '^ X' | grep -v ':000000000000'
446 X 1:9b140be10808
446 X 1:9b140be10808
447 X@foo 2:0d2164f0ce0d
447 X@foo 2:0d2164f0ce0d
448
448
449 (test that remotely diverged bookmarks are reused if they aren't changed)
449 (test that remotely diverged bookmarks are reused if they aren't changed)
450
450
451 $ hg bookmarks | grep '^ @'
451 $ hg bookmarks | grep '^ @'
452 @ 1:9b140be10808
452 @ 1:9b140be10808
453 @1 2:0d2164f0ce0d
453 @1 2:0d2164f0ce0d
454 @foo 2:0d2164f0ce0d
454 @foo 2:0d2164f0ce0d
455 $ hg pull ../a
455 $ hg pull ../a
456 pulling from ../a
456 pulling from ../a
457 searching for changes
457 searching for changes
458 no changes found
458 no changes found
459 warning: failed to assign numbered name to divergent bookmark X
459 warning: failed to assign numbered name to divergent bookmark X
460 divergent bookmark @ stored as @1
460 divergent bookmark @ stored as @1
461 $ hg bookmarks | grep '^ @'
461 $ hg bookmarks | grep '^ @'
462 @ 1:9b140be10808
462 @ 1:9b140be10808
463 @1 2:0d2164f0ce0d
463 @1 2:0d2164f0ce0d
464 @foo 2:0d2164f0ce0d
464 @foo 2:0d2164f0ce0d
465
465
466 $ $PYTHON $TESTDIR/seq.py 1 100 | while read i; do hg bookmarks -d "X@${i}"; done
466 $ $PYTHON $TESTDIR/seq.py 1 100 | while read i; do hg bookmarks -d "X@${i}"; done
467 $ hg bookmarks -d "@1"
467 $ hg bookmarks -d "@1"
468
468
469 $ hg push -f ../a
469 $ hg push -f ../a
470 pushing to ../a
470 pushing to ../a
471 searching for changes
471 searching for changes
472 adding changesets
472 adding changesets
473 adding manifests
473 adding manifests
474 adding file changes
474 adding file changes
475 added 1 changesets with 1 changes to 1 files (+1 heads)
475 added 1 changesets with 1 changes to 1 files (+1 heads)
476 $ hg -R ../a book
476 $ hg -R ../a book
477 @ 1:0d2164f0ce0d
477 @ 1:0d2164f0ce0d
478 * X 1:0d2164f0ce0d
478 * X 1:0d2164f0ce0d
479 Y 0:4e3505fd9583
479 Y 0:4e3505fd9583
480 Z 1:0d2164f0ce0d
480 Z 1:0d2164f0ce0d
481
481
482 explicit pull should overwrite the local version (issue4439)
482 explicit pull should overwrite the local version (issue4439)
483
483
484 $ hg update -r X
484 $ hg update -r X
485 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
485 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
486 (activating bookmark X)
486 (activating bookmark X)
487 $ hg pull --config paths.foo=../a foo -B . --config "$TESTHOOK"
487 $ hg pull --config paths.foo=../a foo -B . --config "$TESTHOOK"
488 pulling from $TESTTMP/a
488 pulling from $TESTTMP/a
489 no changes found
489 no changes found
490 divergent bookmark @ stored as @foo
490 divergent bookmark @ stored as @foo
491 importing bookmark X
491 importing bookmark X
492 test-hook-bookmark: @foo: 0d2164f0ce0d8f1d6f94351eba04b794909be66c -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
492 test-hook-bookmark: @foo: 0d2164f0ce0d8f1d6f94351eba04b794909be66c -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
493 test-hook-bookmark: X: 9b140be1080824d768c5a4691a564088eede71f9 -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
493 test-hook-bookmark: X: 9b140be1080824d768c5a4691a564088eede71f9 -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
494
494
495 reinstall state for further testing:
495 reinstall state for further testing:
496
496
497 $ hg book -fr 9b140be10808 X
497 $ hg book -fr 9b140be10808 X
498
498
499 revsets should not ignore divergent bookmarks
499 revsets should not ignore divergent bookmarks
500
500
501 $ hg bookmark -fr 1 Z
501 $ hg bookmark -fr 1 Z
502 $ hg log -r 'bookmark()' --template '{rev}:{node|short} {bookmarks}\n'
502 $ hg log -r 'bookmark()' --template '{rev}:{node|short} {bookmarks}\n'
503 0:4e3505fd9583 Y
503 0:4e3505fd9583 Y
504 1:9b140be10808 @ X Z foobar
504 1:9b140be10808 @ X Z foobar
505 2:0d2164f0ce0d @foo X@foo
505 2:0d2164f0ce0d @foo X@foo
506 $ hg log -r 'bookmark("X@foo")' --template '{rev}:{node|short} {bookmarks}\n'
506 $ hg log -r 'bookmark("X@foo")' --template '{rev}:{node|short} {bookmarks}\n'
507 2:0d2164f0ce0d @foo X@foo
507 2:0d2164f0ce0d @foo X@foo
508 $ hg log -r 'bookmark("re:X@foo")' --template '{rev}:{node|short} {bookmarks}\n'
508 $ hg log -r 'bookmark("re:X@foo")' --template '{rev}:{node|short} {bookmarks}\n'
509 2:0d2164f0ce0d @foo X@foo
509 2:0d2164f0ce0d @foo X@foo
510
510
511 update a remote bookmark from a non-head to a head
511 update a remote bookmark from a non-head to a head
512
512
513 $ hg up -q Y
513 $ hg up -q Y
514 $ echo c3 > f2
514 $ echo c3 > f2
515 $ hg ci -Am3
515 $ hg ci -Am3
516 adding f2
516 adding f2
517 created new head
517 created new head
518 $ hg push ../a --config "$TESTHOOK"
518 $ hg push ../a --config "$TESTHOOK"
519 pushing to ../a
519 pushing to ../a
520 searching for changes
520 searching for changes
521 adding changesets
521 adding changesets
522 adding manifests
522 adding manifests
523 adding file changes
523 adding file changes
524 added 1 changesets with 1 changes to 1 files (+1 heads)
524 added 1 changesets with 1 changes to 1 files (+1 heads)
525 test-hook-bookmark: Y: 4e3505fd95835d721066b76e75dbb8cc554d7f77 -> f6fc62dde3c0771e29704af56ba4d8af77abcc2f
525 test-hook-bookmark: Y: 4e3505fd95835d721066b76e75dbb8cc554d7f77 -> f6fc62dde3c0771e29704af56ba4d8af77abcc2f
526 updating bookmark Y
526 updating bookmark Y
527 $ hg -R ../a book
527 $ hg -R ../a book
528 @ 1:0d2164f0ce0d
528 @ 1:0d2164f0ce0d
529 * X 1:0d2164f0ce0d
529 * X 1:0d2164f0ce0d
530 Y 3:f6fc62dde3c0
530 Y 3:f6fc62dde3c0
531 Z 1:0d2164f0ce0d
531 Z 1:0d2164f0ce0d
532
532
533 update a bookmark in the middle of a client pulling changes
533 update a bookmark in the middle of a client pulling changes
534
534
535 $ cd ..
535 $ cd ..
536 $ hg clone -q a pull-race
536 $ hg clone -q a pull-race
537
537
538 We want to use http because it is stateless and therefore more susceptible to
538 We want to use http because it is stateless and therefore more susceptible to
539 race conditions
539 race conditions
540
540
541 $ hg serve -R pull-race -p $HGPORT -d --pid-file=pull-race.pid -E main-error.log
541 $ hg serve -R pull-race -p $HGPORT -d --pid-file=pull-race.pid -E main-error.log
542 $ cat pull-race.pid >> $DAEMON_PIDS
542 $ cat pull-race.pid >> $DAEMON_PIDS
543
543
544 $ cat <<EOF > $TESTTMP/out_makecommit.sh
544 $ cat <<EOF > $TESTTMP/out_makecommit.sh
545 > #!/bin/sh
545 > #!/bin/sh
546 > hg ci -Am5
546 > hg ci -Am5
547 > echo committed in pull-race
547 > echo committed in pull-race
548 > EOF
548 > EOF
549
549
550 $ hg clone -q http://localhost:$HGPORT/ pull-race2 --config "$TESTHOOK"
550 $ hg clone -q http://localhost:$HGPORT/ pull-race2 --config "$TESTHOOK"
551 test-hook-bookmark: @: -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
551 test-hook-bookmark: @: -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
552 test-hook-bookmark: X: -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
552 test-hook-bookmark: X: -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
553 test-hook-bookmark: Y: -> f6fc62dde3c0771e29704af56ba4d8af77abcc2f
553 test-hook-bookmark: Y: -> f6fc62dde3c0771e29704af56ba4d8af77abcc2f
554 test-hook-bookmark: Z: -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
554 test-hook-bookmark: Z: -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
555 $ cd pull-race
555 $ cd pull-race
556 $ hg up -q Y
556 $ hg up -q Y
557 $ echo c4 > f2
557 $ echo c4 > f2
558 $ hg ci -Am4
558 $ hg ci -Am4
559 $ echo c5 > f3
559 $ echo c5 > f3
560 $ cat <<EOF > .hg/hgrc
560 $ cat <<EOF > .hg/hgrc
561 > [hooks]
561 > [hooks]
562 > outgoing.makecommit = sh $TESTTMP/out_makecommit.sh
562 > outgoing.makecommit = sh $TESTTMP/out_makecommit.sh
563 > EOF
563 > EOF
564
564
565 (new config needs a server restart)
565 (new config needs a server restart)
566
566
567 $ cd ..
567 $ cd ..
568 $ killdaemons.py
568 $ killdaemons.py
569 $ hg serve -R pull-race -p $HGPORT -d --pid-file=pull-race.pid -E main-error.log
569 $ hg serve -R pull-race -p $HGPORT -d --pid-file=pull-race.pid -E main-error.log
570 $ cat pull-race.pid >> $DAEMON_PIDS
570 $ cat pull-race.pid >> $DAEMON_PIDS
571 $ cd pull-race2
571 $ cd pull-race2
572 $ hg -R $TESTTMP/pull-race book
572 $ hg -R $TESTTMP/pull-race book
573 @ 1:0d2164f0ce0d
573 @ 1:0d2164f0ce0d
574 X 1:0d2164f0ce0d
574 X 1:0d2164f0ce0d
575 * Y 4:b0a5eff05604
575 * Y 4:b0a5eff05604
576 Z 1:0d2164f0ce0d
576 Z 1:0d2164f0ce0d
577 $ hg pull
577 $ hg pull
578 pulling from http://localhost:$HGPORT/
578 pulling from http://localhost:$HGPORT/
579 searching for changes
579 searching for changes
580 adding changesets
580 adding changesets
581 adding manifests
581 adding manifests
582 adding file changes
582 adding file changes
583 added 1 changesets with 1 changes to 1 files
583 added 1 changesets with 1 changes to 1 files
584 updating bookmark Y
584 updating bookmark Y
585 new changesets b0a5eff05604
585 new changesets b0a5eff05604
586 (run 'hg update' to get a working copy)
586 (run 'hg update' to get a working copy)
587 $ hg book
587 $ hg book
588 * @ 1:0d2164f0ce0d
588 * @ 1:0d2164f0ce0d
589 X 1:0d2164f0ce0d
589 X 1:0d2164f0ce0d
590 Y 4:b0a5eff05604
590 Y 4:b0a5eff05604
591 Z 1:0d2164f0ce0d
591 Z 1:0d2164f0ce0d
592
592
593 Update a bookmark right after the initial lookup -B (issue4689)
593 Update a bookmark right after the initial lookup -B (issue4689)
594
594
595 $ echo c6 > ../pull-race/f3 # to be committed during the race
595 $ echo c6 > ../pull-race/f3 # to be committed during the race
596 $ cat <<EOF > $TESTTMP/listkeys_makecommit.sh
596 $ cat <<EOF > $TESTTMP/listkeys_makecommit.sh
597 > #!/bin/sh
597 > #!/bin/sh
598 > if hg st | grep -q M; then
598 > if hg st | grep -q M; then
599 > hg commit -m race
599 > hg commit -m race
600 > echo committed in pull-race
600 > echo committed in pull-race
601 > else
601 > else
602 > exit 0
602 > exit 0
603 > fi
603 > fi
604 > EOF
604 > EOF
605 $ cat <<EOF > ../pull-race/.hg/hgrc
605 $ cat <<EOF > ../pull-race/.hg/hgrc
606 > [hooks]
606 > [hooks]
607 > # If anything to commit, commit it right after the first key listing used
607 > # If anything to commit, commit it right after the first key listing used
608 > # during lookup. This makes the commit appear before the actual getbundle
608 > # during lookup. This makes the commit appear before the actual getbundle
609 > # call.
609 > # call.
610 > listkeys.makecommit= sh $TESTTMP/listkeys_makecommit.sh
610 > listkeys.makecommit= sh $TESTTMP/listkeys_makecommit.sh
611 > EOF
611 > EOF
612
612
613 (new config need server restart)
613 (new config need server restart)
614
614
615 $ killdaemons.py
615 $ killdaemons.py
616 $ hg serve -R ../pull-race -p $HGPORT -d --pid-file=../pull-race.pid -E main-error.log
616 $ hg serve -R ../pull-race -p $HGPORT -d --pid-file=../pull-race.pid -E main-error.log
617 $ cat ../pull-race.pid >> $DAEMON_PIDS
617 $ cat ../pull-race.pid >> $DAEMON_PIDS
618
618
619 $ hg -R $TESTTMP/pull-race book
619 $ hg -R $TESTTMP/pull-race book
620 @ 1:0d2164f0ce0d
620 @ 1:0d2164f0ce0d
621 X 1:0d2164f0ce0d
621 X 1:0d2164f0ce0d
622 * Y 5:35d1ef0a8d1b
622 * Y 5:35d1ef0a8d1b
623 Z 1:0d2164f0ce0d
623 Z 1:0d2164f0ce0d
624 $ hg update -r Y
624 $ hg update -r Y
625 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
625 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
626 (activating bookmark Y)
626 (activating bookmark Y)
627 $ hg pull -B .
627 $ hg pull -B .
628 pulling from http://localhost:$HGPORT/
628 pulling from http://localhost:$HGPORT/
629 searching for changes
629 searching for changes
630 adding changesets
630 adding changesets
631 adding manifests
631 adding manifests
632 adding file changes
632 adding file changes
633 added 1 changesets with 1 changes to 1 files
633 added 1 changesets with 1 changes to 1 files
634 updating bookmark Y
634 updating bookmark Y
635 new changesets 35d1ef0a8d1b
635 new changesets 35d1ef0a8d1b
636 (run 'hg update' to get a working copy)
636 (run 'hg update' to get a working copy)
637 $ hg book
637 $ hg book
638 @ 1:0d2164f0ce0d
638 @ 1:0d2164f0ce0d
639 X 1:0d2164f0ce0d
639 X 1:0d2164f0ce0d
640 * Y 5:35d1ef0a8d1b
640 * Y 5:35d1ef0a8d1b
641 Z 1:0d2164f0ce0d
641 Z 1:0d2164f0ce0d
642
642
643 (done with this section of the test)
643 (done with this section of the test)
644
644
645 $ killdaemons.py
645 $ killdaemons.py
646 $ cd ../b
646 $ cd ../b
647
647
648 diverging a remote bookmark fails
648 diverging a remote bookmark fails
649
649
650 $ hg up -q 4e3505fd9583
650 $ hg up -q 4e3505fd9583
651 $ echo c4 > f2
651 $ echo c4 > f2
652 $ hg ci -Am4
652 $ hg ci -Am4
653 adding f2
653 adding f2
654 created new head
654 created new head
655 $ echo c5 > f2
655 $ echo c5 > f2
656 $ hg ci -Am5
656 $ hg ci -Am5
657 $ hg log -G
657 $ hg log -G
658 @ 5:c922c0139ca0 5
658 @ 5:c922c0139ca0 5
659 |
659 |
660 o 4:4efff6d98829 4
660 o 4:4efff6d98829 4
661 |
661 |
662 | o 3:f6fc62dde3c0 3
662 | o 3:f6fc62dde3c0 3
663 |/
663 |/
664 | o 2:0d2164f0ce0d 1
664 | o 2:0d2164f0ce0d 1
665 |/
665 |/
666 | o 1:9b140be10808 2
666 | o 1:9b140be10808 2
667 |/
667 |/
668 o 0:4e3505fd9583 test
668 o 0:4e3505fd9583 test
669
669
670
670
671 $ hg book -f Y
671 $ hg book -f Y
672
672
673 $ cat <<EOF > ../a/.hg/hgrc
673 $ cat <<EOF > ../a/.hg/hgrc
674 > [web]
674 > [web]
675 > push_ssl = false
675 > push_ssl = false
676 > allow_push = *
676 > allow_push = *
677 > EOF
677 > EOF
678
678
679 $ hg serve -R ../a -p $HGPORT2 -d --pid-file=../hg2.pid
679 $ hg serve -R ../a -p $HGPORT2 -d --pid-file=../hg2.pid
680 $ cat ../hg2.pid >> $DAEMON_PIDS
680 $ cat ../hg2.pid >> $DAEMON_PIDS
681
681
682 $ hg push http://localhost:$HGPORT2/
682 $ hg push http://localhost:$HGPORT2/
683 pushing to http://localhost:$HGPORT2/
683 pushing to http://localhost:$HGPORT2/
684 searching for changes
684 searching for changes
685 abort: push creates new remote head c922c0139ca0 with bookmark 'Y'!
685 abort: push creates new remote head c922c0139ca0 with bookmark 'Y'!
686 (merge or see 'hg help push' for details about pushing new heads)
686 (merge or see 'hg help push' for details about pushing new heads)
687 [255]
687 [255]
688 $ hg -R ../a book
688 $ hg -R ../a book
689 @ 1:0d2164f0ce0d
689 @ 1:0d2164f0ce0d
690 * X 1:0d2164f0ce0d
690 * X 1:0d2164f0ce0d
691 Y 3:f6fc62dde3c0
691 Y 3:f6fc62dde3c0
692 Z 1:0d2164f0ce0d
692 Z 1:0d2164f0ce0d
693
693
694
694
695 Unrelated marker does not alter the decision
695 Unrelated marker does not alter the decision
696
696
697 $ hg debugobsolete aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
697 $ hg debugobsolete aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
698 $ hg push http://localhost:$HGPORT2/
698 $ hg push http://localhost:$HGPORT2/
699 pushing to http://localhost:$HGPORT2/
699 pushing to http://localhost:$HGPORT2/
700 searching for changes
700 searching for changes
701 abort: push creates new remote head c922c0139ca0 with bookmark 'Y'!
701 abort: push creates new remote head c922c0139ca0 with bookmark 'Y'!
702 (merge or see 'hg help push' for details about pushing new heads)
702 (merge or see 'hg help push' for details about pushing new heads)
703 [255]
703 [255]
704 $ hg -R ../a book
704 $ hg -R ../a book
705 @ 1:0d2164f0ce0d
705 @ 1:0d2164f0ce0d
706 * X 1:0d2164f0ce0d
706 * X 1:0d2164f0ce0d
707 Y 3:f6fc62dde3c0
707 Y 3:f6fc62dde3c0
708 Z 1:0d2164f0ce0d
708 Z 1:0d2164f0ce0d
709
709
710 Update to a successor works
710 Update to a successor works
711
711
712 $ hg id --debug -r 3
712 $ hg id --debug -r 3
713 f6fc62dde3c0771e29704af56ba4d8af77abcc2f
713 f6fc62dde3c0771e29704af56ba4d8af77abcc2f
714 $ hg id --debug -r 4
714 $ hg id --debug -r 4
715 4efff6d98829d9c824c621afd6e3f01865f5439f
715 4efff6d98829d9c824c621afd6e3f01865f5439f
716 $ hg id --debug -r 5
716 $ hg id --debug -r 5
717 c922c0139ca03858f655e4a2af4dd02796a63969 tip Y
717 c922c0139ca03858f655e4a2af4dd02796a63969 tip Y
718 $ hg debugobsolete f6fc62dde3c0771e29704af56ba4d8af77abcc2f cccccccccccccccccccccccccccccccccccccccc
718 $ hg debugobsolete f6fc62dde3c0771e29704af56ba4d8af77abcc2f cccccccccccccccccccccccccccccccccccccccc
719 obsoleted 1 changesets
719 obsoleted 1 changesets
720 $ hg debugobsolete cccccccccccccccccccccccccccccccccccccccc 4efff6d98829d9c824c621afd6e3f01865f5439f
720 $ hg debugobsolete cccccccccccccccccccccccccccccccccccccccc 4efff6d98829d9c824c621afd6e3f01865f5439f
721 $ hg push http://localhost:$HGPORT2/
721 $ hg push http://localhost:$HGPORT2/
722 pushing to http://localhost:$HGPORT2/
722 pushing to http://localhost:$HGPORT2/
723 searching for changes
723 searching for changes
724 remote: adding changesets
724 remote: adding changesets
725 remote: adding manifests
725 remote: adding manifests
726 remote: adding file changes
726 remote: adding file changes
727 remote: added 2 changesets with 2 changes to 1 files (+1 heads)
727 remote: added 2 changesets with 2 changes to 1 files (+1 heads)
728 remote: 2 new obsolescence markers
728 remote: 2 new obsolescence markers
729 remote: obsoleted 1 changesets
729 remote: obsoleted 1 changesets
730 updating bookmark Y
730 updating bookmark Y
731 $ hg -R ../a book
731 $ hg -R ../a book
732 @ 1:0d2164f0ce0d
732 @ 1:0d2164f0ce0d
733 * X 1:0d2164f0ce0d
733 * X 1:0d2164f0ce0d
734 Y 5:c922c0139ca0
734 Y 5:c922c0139ca0
735 Z 1:0d2164f0ce0d
735 Z 1:0d2164f0ce0d
736
736
737 hgweb
737 hgweb
738
738
739 $ cat <<EOF > .hg/hgrc
739 $ cat <<EOF > .hg/hgrc
740 > [web]
740 > [web]
741 > push_ssl = false
741 > push_ssl = false
742 > allow_push = *
742 > allow_push = *
743 > EOF
743 > EOF
744
744
745 $ hg serve -p $HGPORT -d --pid-file=../hg.pid -E errors.log
745 $ hg serve -p $HGPORT -d --pid-file=../hg.pid -E errors.log
746 $ cat ../hg.pid >> $DAEMON_PIDS
746 $ cat ../hg.pid >> $DAEMON_PIDS
747 $ cd ../a
747 $ cd ../a
748
748
749 $ hg debugpushkey http://localhost:$HGPORT/ namespaces
749 $ hg debugpushkey http://localhost:$HGPORT/ namespaces
750 bookmarks
750 bookmarks
751 namespaces
751 namespaces
752 obsolete
752 obsolete
753 phases
753 phases
754 $ hg debugpushkey http://localhost:$HGPORT/ bookmarks
754 $ hg debugpushkey http://localhost:$HGPORT/ bookmarks
755 @ 9b140be1080824d768c5a4691a564088eede71f9
755 @ 9b140be1080824d768c5a4691a564088eede71f9
756 X 9b140be1080824d768c5a4691a564088eede71f9
756 X 9b140be1080824d768c5a4691a564088eede71f9
757 Y c922c0139ca03858f655e4a2af4dd02796a63969
757 Y c922c0139ca03858f655e4a2af4dd02796a63969
758 Z 9b140be1080824d768c5a4691a564088eede71f9
758 Z 9b140be1080824d768c5a4691a564088eede71f9
759 foo 0000000000000000000000000000000000000000
759 foo 0000000000000000000000000000000000000000
760 foobar 9b140be1080824d768c5a4691a564088eede71f9
760 foobar 9b140be1080824d768c5a4691a564088eede71f9
761 $ hg out -B http://localhost:$HGPORT/
761 $ hg out -B http://localhost:$HGPORT/
762 comparing with http://localhost:$HGPORT/
762 comparing with http://localhost:$HGPORT/
763 searching for changed bookmarks
763 searching for changed bookmarks
764 @ 0d2164f0ce0d
764 @ 0d2164f0ce0d
765 X 0d2164f0ce0d
765 X 0d2164f0ce0d
766 Z 0d2164f0ce0d
766 Z 0d2164f0ce0d
767 foo
767 foo
768 foobar
768 foobar
769 $ hg push -B Z http://localhost:$HGPORT/
769 $ hg push -B Z http://localhost:$HGPORT/
770 pushing to http://localhost:$HGPORT/
770 pushing to http://localhost:$HGPORT/
771 searching for changes
771 searching for changes
772 no changes found
772 no changes found
773 updating bookmark Z
773 updating bookmark Z
774 [1]
774 [1]
775 $ hg book -d Z
775 $ hg book -d Z
776 $ hg in -B http://localhost:$HGPORT/
776 $ hg in -B http://localhost:$HGPORT/
777 comparing with http://localhost:$HGPORT/
777 comparing with http://localhost:$HGPORT/
778 searching for changed bookmarks
778 searching for changed bookmarks
779 @ 9b140be10808
779 @ 9b140be10808
780 X 9b140be10808
780 X 9b140be10808
781 Z 0d2164f0ce0d
781 Z 0d2164f0ce0d
782 foo 000000000000
782 foo 000000000000
783 foobar 9b140be10808
783 foobar 9b140be10808
784 $ hg pull -B Z http://localhost:$HGPORT/
784 $ hg pull -B Z http://localhost:$HGPORT/
785 pulling from http://localhost:$HGPORT/
785 pulling from http://localhost:$HGPORT/
786 no changes found
786 no changes found
787 divergent bookmark @ stored as @1
787 divergent bookmark @ stored as @1
788 divergent bookmark X stored as X@1
788 divergent bookmark X stored as X@1
789 adding remote bookmark Z
789 adding remote bookmark Z
790 adding remote bookmark foo
790 adding remote bookmark foo
791 adding remote bookmark foobar
791 adding remote bookmark foobar
792 $ hg clone http://localhost:$HGPORT/ cloned-bookmarks
792 $ hg clone http://localhost:$HGPORT/ cloned-bookmarks
793 requesting all changes
793 requesting all changes
794 adding changesets
794 adding changesets
795 adding manifests
795 adding manifests
796 adding file changes
796 adding file changes
797 added 5 changesets with 5 changes to 3 files (+2 heads)
797 added 5 changesets with 5 changes to 3 files (+2 heads)
798 2 new obsolescence markers
798 2 new obsolescence markers
799 new changesets 4e3505fd9583:c922c0139ca0
799 new changesets 4e3505fd9583:c922c0139ca0
800 updating to bookmark @
800 updating to bookmark @
801 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
801 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
802 $ hg -R cloned-bookmarks bookmarks
802 $ hg -R cloned-bookmarks bookmarks
803 * @ 1:9b140be10808
803 * @ 1:9b140be10808
804 X 1:9b140be10808
804 X 1:9b140be10808
805 Y 4:c922c0139ca0
805 Y 4:c922c0139ca0
806 Z 2:0d2164f0ce0d
806 Z 2:0d2164f0ce0d
807 foo -1:000000000000
807 foo -1:000000000000
808 foobar 1:9b140be10808
808 foobar 1:9b140be10808
809
809
810 $ cd ..
810 $ cd ..
811
811
812 Test to show result of bookmarks comparison
812 Test to show result of bookmarks comparison
813
813
814 $ mkdir bmcomparison
814 $ mkdir bmcomparison
815 $ cd bmcomparison
815 $ cd bmcomparison
816
816
817 $ hg init source
817 $ hg init source
818 $ hg -R source debugbuilddag '+2*2*3*4'
818 $ hg -R source debugbuilddag '+2*2*3*4'
819 $ hg -R source log -G --template '{rev}:{node|short}'
819 $ hg -R source log -G --template '{rev}:{node|short}'
820 o 4:e7bd5218ca15
820 o 4:e7bd5218ca15
821 |
821 |
822 | o 3:6100d3090acf
822 | o 3:6100d3090acf
823 |/
823 |/
824 | o 2:fa942426a6fd
824 | o 2:fa942426a6fd
825 |/
825 |/
826 | o 1:66f7d451a68b
826 | o 1:66f7d451a68b
827 |/
827 |/
828 o 0:1ea73414a91b
828 o 0:1ea73414a91b
829
829
830 $ hg -R source bookmarks -r 0 SAME
830 $ hg -R source bookmarks -r 0 SAME
831 $ hg -R source bookmarks -r 0 ADV_ON_REPO1
831 $ hg -R source bookmarks -r 0 ADV_ON_REPO1
832 $ hg -R source bookmarks -r 0 ADV_ON_REPO2
832 $ hg -R source bookmarks -r 0 ADV_ON_REPO2
833 $ hg -R source bookmarks -r 0 DIFF_ADV_ON_REPO1
833 $ hg -R source bookmarks -r 0 DIFF_ADV_ON_REPO1
834 $ hg -R source bookmarks -r 0 DIFF_ADV_ON_REPO2
834 $ hg -R source bookmarks -r 0 DIFF_ADV_ON_REPO2
835 $ hg -R source bookmarks -r 1 DIVERGED
835 $ hg -R source bookmarks -r 1 DIVERGED
836
836
837 $ hg clone -U source repo1
837 $ hg clone -U source repo1
838
838
839 (test that incoming/outgoing exit with 1, if there is no bookmark to
839 (test that incoming/outgoing exit with 1, if there is no bookmark to
840 be exchanged)
840 be exchanged)
841
841
842 $ hg -R repo1 incoming -B
842 $ hg -R repo1 incoming -B
843 comparing with $TESTTMP/bmcomparison/source
843 comparing with $TESTTMP/bmcomparison/source
844 searching for changed bookmarks
844 searching for changed bookmarks
845 no changed bookmarks found
845 no changed bookmarks found
846 [1]
846 [1]
847 $ hg -R repo1 outgoing -B
847 $ hg -R repo1 outgoing -B
848 comparing with $TESTTMP/bmcomparison/source
848 comparing with $TESTTMP/bmcomparison/source
849 searching for changed bookmarks
849 searching for changed bookmarks
850 no changed bookmarks found
850 no changed bookmarks found
851 [1]
851 [1]
852
852
853 $ hg -R repo1 bookmarks -f -r 1 ADD_ON_REPO1
853 $ hg -R repo1 bookmarks -f -r 1 ADD_ON_REPO1
854 $ hg -R repo1 bookmarks -f -r 2 ADV_ON_REPO1
854 $ hg -R repo1 bookmarks -f -r 2 ADV_ON_REPO1
855 $ hg -R repo1 bookmarks -f -r 3 DIFF_ADV_ON_REPO1
855 $ hg -R repo1 bookmarks -f -r 3 DIFF_ADV_ON_REPO1
856 $ hg -R repo1 bookmarks -f -r 3 DIFF_DIVERGED
856 $ hg -R repo1 bookmarks -f -r 3 DIFF_DIVERGED
857 $ hg -R repo1 -q --config extensions.mq= strip 4
857 $ hg -R repo1 -q --config extensions.mq= strip 4
858 $ hg -R repo1 log -G --template '{node|short} ({bookmarks})'
858 $ hg -R repo1 log -G --template '{node|short} ({bookmarks})'
859 o 6100d3090acf (DIFF_ADV_ON_REPO1 DIFF_DIVERGED)
859 o 6100d3090acf (DIFF_ADV_ON_REPO1 DIFF_DIVERGED)
860 |
860 |
861 | o fa942426a6fd (ADV_ON_REPO1)
861 | o fa942426a6fd (ADV_ON_REPO1)
862 |/
862 |/
863 | o 66f7d451a68b (ADD_ON_REPO1 DIVERGED)
863 | o 66f7d451a68b (ADD_ON_REPO1 DIVERGED)
864 |/
864 |/
865 o 1ea73414a91b (ADV_ON_REPO2 DIFF_ADV_ON_REPO2 SAME)
865 o 1ea73414a91b (ADV_ON_REPO2 DIFF_ADV_ON_REPO2 SAME)
866
866
867
867
868 $ hg clone -U source repo2
868 $ hg clone -U source repo2
869 $ hg -R repo2 bookmarks -f -r 1 ADD_ON_REPO2
869 $ hg -R repo2 bookmarks -f -r 1 ADD_ON_REPO2
870 $ hg -R repo2 bookmarks -f -r 1 ADV_ON_REPO2
870 $ hg -R repo2 bookmarks -f -r 1 ADV_ON_REPO2
871 $ hg -R repo2 bookmarks -f -r 2 DIVERGED
871 $ hg -R repo2 bookmarks -f -r 2 DIVERGED
872 $ hg -R repo2 bookmarks -f -r 4 DIFF_ADV_ON_REPO2
872 $ hg -R repo2 bookmarks -f -r 4 DIFF_ADV_ON_REPO2
873 $ hg -R repo2 bookmarks -f -r 4 DIFF_DIVERGED
873 $ hg -R repo2 bookmarks -f -r 4 DIFF_DIVERGED
874 $ hg -R repo2 -q --config extensions.mq= strip 3
874 $ hg -R repo2 -q --config extensions.mq= strip 3
875 $ hg -R repo2 log -G --template '{node|short} ({bookmarks})'
875 $ hg -R repo2 log -G --template '{node|short} ({bookmarks})'
876 o e7bd5218ca15 (DIFF_ADV_ON_REPO2 DIFF_DIVERGED)
876 o e7bd5218ca15 (DIFF_ADV_ON_REPO2 DIFF_DIVERGED)
877 |
877 |
878 | o fa942426a6fd (DIVERGED)
878 | o fa942426a6fd (DIVERGED)
879 |/
879 |/
880 | o 66f7d451a68b (ADD_ON_REPO2 ADV_ON_REPO2)
880 | o 66f7d451a68b (ADD_ON_REPO2 ADV_ON_REPO2)
881 |/
881 |/
882 o 1ea73414a91b (ADV_ON_REPO1 DIFF_ADV_ON_REPO1 SAME)
882 o 1ea73414a91b (ADV_ON_REPO1 DIFF_ADV_ON_REPO1 SAME)
883
883
884
884
885 (test that difference of bookmarks between repositories are fully shown)
885 (test that difference of bookmarks between repositories are fully shown)
886
886
887 $ hg -R repo1 incoming -B repo2 -v
887 $ hg -R repo1 incoming -B repo2 -v
888 comparing with repo2
888 comparing with repo2
889 searching for changed bookmarks
889 searching for changed bookmarks
890 ADD_ON_REPO2 66f7d451a68b added
890 ADD_ON_REPO2 66f7d451a68b added
891 ADV_ON_REPO2 66f7d451a68b advanced
891 ADV_ON_REPO2 66f7d451a68b advanced
892 DIFF_ADV_ON_REPO2 e7bd5218ca15 changed
892 DIFF_ADV_ON_REPO2 e7bd5218ca15 changed
893 DIFF_DIVERGED e7bd5218ca15 changed
893 DIFF_DIVERGED e7bd5218ca15 changed
894 DIVERGED fa942426a6fd diverged
894 DIVERGED fa942426a6fd diverged
895 $ hg -R repo1 outgoing -B repo2 -v
895 $ hg -R repo1 outgoing -B repo2 -v
896 comparing with repo2
896 comparing with repo2
897 searching for changed bookmarks
897 searching for changed bookmarks
898 ADD_ON_REPO1 66f7d451a68b added
898 ADD_ON_REPO1 66f7d451a68b added
899 ADD_ON_REPO2 deleted
899 ADD_ON_REPO2 deleted
900 ADV_ON_REPO1 fa942426a6fd advanced
900 ADV_ON_REPO1 fa942426a6fd advanced
901 DIFF_ADV_ON_REPO1 6100d3090acf advanced
901 DIFF_ADV_ON_REPO1 6100d3090acf advanced
902 DIFF_ADV_ON_REPO2 1ea73414a91b changed
902 DIFF_ADV_ON_REPO2 1ea73414a91b changed
903 DIFF_DIVERGED 6100d3090acf changed
903 DIFF_DIVERGED 6100d3090acf changed
904 DIVERGED 66f7d451a68b diverged
904 DIVERGED 66f7d451a68b diverged
905
905
906 $ hg -R repo2 incoming -B repo1 -v
906 $ hg -R repo2 incoming -B repo1 -v
907 comparing with repo1
907 comparing with repo1
908 searching for changed bookmarks
908 searching for changed bookmarks
909 ADD_ON_REPO1 66f7d451a68b added
909 ADD_ON_REPO1 66f7d451a68b added
910 ADV_ON_REPO1 fa942426a6fd advanced
910 ADV_ON_REPO1 fa942426a6fd advanced
911 DIFF_ADV_ON_REPO1 6100d3090acf changed
911 DIFF_ADV_ON_REPO1 6100d3090acf changed
912 DIFF_DIVERGED 6100d3090acf changed
912 DIFF_DIVERGED 6100d3090acf changed
913 DIVERGED 66f7d451a68b diverged
913 DIVERGED 66f7d451a68b diverged
914 $ hg -R repo2 outgoing -B repo1 -v
914 $ hg -R repo2 outgoing -B repo1 -v
915 comparing with repo1
915 comparing with repo1
916 searching for changed bookmarks
916 searching for changed bookmarks
917 ADD_ON_REPO1 deleted
917 ADD_ON_REPO1 deleted
918 ADD_ON_REPO2 66f7d451a68b added
918 ADD_ON_REPO2 66f7d451a68b added
919 ADV_ON_REPO2 66f7d451a68b advanced
919 ADV_ON_REPO2 66f7d451a68b advanced
920 DIFF_ADV_ON_REPO1 1ea73414a91b changed
920 DIFF_ADV_ON_REPO1 1ea73414a91b changed
921 DIFF_ADV_ON_REPO2 e7bd5218ca15 advanced
921 DIFF_ADV_ON_REPO2 e7bd5218ca15 advanced
922 DIFF_DIVERGED e7bd5218ca15 changed
922 DIFF_DIVERGED e7bd5218ca15 changed
923 DIVERGED fa942426a6fd diverged
923 DIVERGED fa942426a6fd diverged
924
924
925 $ cd ..
925 $ cd ..
926
926
927 Pushing a bookmark should only push the changes required by that
927 Pushing a bookmark should only push the changes required by that
928 bookmark, not all outgoing changes:
928 bookmark, not all outgoing changes:
929 $ hg clone http://localhost:$HGPORT/ addmarks
929 $ hg clone http://localhost:$HGPORT/ addmarks
930 requesting all changes
930 requesting all changes
931 adding changesets
931 adding changesets
932 adding manifests
932 adding manifests
933 adding file changes
933 adding file changes
934 added 5 changesets with 5 changes to 3 files (+2 heads)
934 added 5 changesets with 5 changes to 3 files (+2 heads)
935 2 new obsolescence markers
935 2 new obsolescence markers
936 new changesets 4e3505fd9583:c922c0139ca0
936 new changesets 4e3505fd9583:c922c0139ca0
937 updating to bookmark @
937 updating to bookmark @
938 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
938 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
939 $ cd addmarks
939 $ cd addmarks
940 $ echo foo > foo
940 $ echo foo > foo
941 $ hg add foo
941 $ hg add foo
942 $ hg commit -m 'add foo'
942 $ hg commit -m 'add foo'
943 $ echo bar > bar
943 $ echo bar > bar
944 $ hg add bar
944 $ hg add bar
945 $ hg commit -m 'add bar'
945 $ hg commit -m 'add bar'
946 $ hg co "tip^"
946 $ hg co "tip^"
947 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
947 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
948 (leaving bookmark @)
948 (leaving bookmark @)
949 $ hg book add-foo
949 $ hg book add-foo
950 $ hg book -r tip add-bar
950 $ hg book -r tip add-bar
951 Note: this push *must* push only a single changeset, as that's the point
951 Note: this push *must* push only a single changeset, as that's the point
952 of this test.
952 of this test.
953 $ hg push -B add-foo --traceback
953 $ hg push -B add-foo --traceback
954 pushing to http://localhost:$HGPORT/
954 pushing to http://localhost:$HGPORT/
955 searching for changes
955 searching for changes
956 remote: adding changesets
956 remote: adding changesets
957 remote: adding manifests
957 remote: adding manifests
958 remote: adding file changes
958 remote: adding file changes
959 remote: added 1 changesets with 1 changes to 1 files
959 remote: added 1 changesets with 1 changes to 1 files
960 exporting bookmark add-foo
960 exporting bookmark add-foo
961
961
962 pushing a new bookmark on a new head does not require -f if -B is specified
962 pushing a new bookmark on a new head does not require -f if -B is specified
963
963
964 $ hg up -q X
964 $ hg up -q X
965 $ hg book W
965 $ hg book W
966 $ echo c5 > f2
966 $ echo c5 > f2
967 $ hg ci -Am5
967 $ hg ci -Am5
968 created new head
968 created new head
969 $ hg push -B .
969 $ hg push -B .
970 pushing to http://localhost:$HGPORT/
970 pushing to http://localhost:$HGPORT/
971 searching for changes
971 searching for changes
972 remote: adding changesets
972 remote: adding changesets
973 remote: adding manifests
973 remote: adding manifests
974 remote: adding file changes
974 remote: adding file changes
975 remote: added 1 changesets with 1 changes to 1 files (+1 heads)
975 remote: added 1 changesets with 1 changes to 1 files (+1 heads)
976 exporting bookmark W
976 exporting bookmark W
977 $ hg -R ../b id -r W
977 $ hg -R ../b id -r W
978 cc978a373a53 tip W
978 cc978a373a53 tip W
979
979
980 pushing an existing but divergent bookmark with -B still requires -f
980 pushing an existing but divergent bookmark with -B still requires -f
981
981
982 $ hg clone -q . ../r
982 $ hg clone -q . ../r
983 $ hg up -q X
983 $ hg up -q X
984 $ echo 1 > f2
984 $ echo 1 > f2
985 $ hg ci -qAml
985 $ hg ci -qAml
986
986
987 $ cd ../r
987 $ cd ../r
988 $ hg up -q X
988 $ hg up -q X
989 $ echo 2 > f2
989 $ echo 2 > f2
990 $ hg ci -qAmr
990 $ hg ci -qAmr
991 $ hg push -B X
991 $ hg push -B X
992 pushing to $TESTTMP/addmarks
992 pushing to $TESTTMP/addmarks
993 searching for changes
993 searching for changes
994 remote has heads on branch 'default' that are not known locally: a2a606d9ff1b
994 remote has heads on branch 'default' that are not known locally: a2a606d9ff1b
995 abort: push creates new remote head 54694f811df9 with bookmark 'X'!
995 abort: push creates new remote head 54694f811df9 with bookmark 'X'!
996 (pull and merge or see 'hg help push' for details about pushing new heads)
996 (pull and merge or see 'hg help push' for details about pushing new heads)
997 [255]
997 [255]
998 $ cd ../addmarks
998 $ cd ../addmarks
999
999
1000 Check summary output for incoming/outgoing bookmarks
1000 Check summary output for incoming/outgoing bookmarks
1001
1001
1002 $ hg bookmarks -d X
1002 $ hg bookmarks -d X
1003 $ hg bookmarks -d Y
1003 $ hg bookmarks -d Y
1004 $ hg summary --remote | grep '^remote:'
1004 $ hg summary --remote | grep '^remote:'
1005 remote: *, 2 incoming bookmarks, 1 outgoing bookmarks (glob)
1005 remote: *, 2 incoming bookmarks, 1 outgoing bookmarks (glob)
1006
1006
1007 $ cd ..
1007 $ cd ..
1008
1008
1009 pushing an unchanged bookmark should result in no changes
1009 pushing an unchanged bookmark should result in no changes
1010
1010
1011 $ hg init unchanged-a
1011 $ hg init unchanged-a
1012 $ hg init unchanged-b
1012 $ hg init unchanged-b
1013 $ cd unchanged-a
1013 $ cd unchanged-a
1014 $ echo initial > foo
1014 $ echo initial > foo
1015 $ hg commit -A -m initial
1015 $ hg commit -A -m initial
1016 adding foo
1016 adding foo
1017 $ hg bookmark @
1017 $ hg bookmark @
1018 $ hg push -B @ ../unchanged-b
1018 $ hg push -B @ ../unchanged-b
1019 pushing to ../unchanged-b
1019 pushing to ../unchanged-b
1020 searching for changes
1020 searching for changes
1021 adding changesets
1021 adding changesets
1022 adding manifests
1022 adding manifests
1023 adding file changes
1023 adding file changes
1024 added 1 changesets with 1 changes to 1 files
1024 added 1 changesets with 1 changes to 1 files
1025 exporting bookmark @
1025 exporting bookmark @
1026
1026
1027 $ hg push -B @ ../unchanged-b
1027 $ hg push -B @ ../unchanged-b
1028 pushing to ../unchanged-b
1028 pushing to ../unchanged-b
1029 searching for changes
1029 searching for changes
1030 no changes found
1030 no changes found
1031 [1]
1031 [1]
1032
1032
1033 Pushing a really long bookmark should work fine (issue5165)
1033 Pushing a really long bookmark should work fine (issue5165)
1034 ===============================================
1034 ===============================================
1035
1035
1036 #if b2-binary
1036 #if b2-binary
1037 >>> with open('longname', 'w') as f:
1037 >>> with open('longname', 'w') as f:
1038 ... f.write('wat' * 100) and None
1038 ... f.write('wat' * 100) and None
1039 $ hg book `cat longname`
1039 $ hg book `cat longname`
1040 $ hg push -B `cat longname` ../unchanged-b
1040 $ hg push -B `cat longname` ../unchanged-b
1041 pushing to ../unchanged-b
1041 pushing to ../unchanged-b
1042 searching for changes
1042 searching for changes
1043 no changes found
1043 no changes found
1044 exporting bookmark (wat){100} (re)
1044 exporting bookmark (wat){100} (re)
1045 [1]
1045 [1]
1046 $ hg -R ../unchanged-b book --delete `cat longname`
1046 $ hg -R ../unchanged-b book --delete `cat longname`
1047
1047
1048 Test again but forcing bundle2 exchange to make sure that doesn't regress.
1048 Test again but forcing bundle2 exchange to make sure that doesn't regress.
1049
1049
1050 $ hg push -B `cat longname` ../unchanged-b --config devel.legacy.exchange=bundle1
1050 $ hg push -B `cat longname` ../unchanged-b --config devel.legacy.exchange=bundle1
1051 pushing to ../unchanged-b
1051 pushing to ../unchanged-b
1052 searching for changes
1052 searching for changes
1053 no changes found
1053 no changes found
1054 exporting bookmark (wat){100} (re)
1054 exporting bookmark (wat){100} (re)
1055 [1]
1055 [1]
1056 $ hg -R ../unchanged-b book --delete `cat longname`
1056 $ hg -R ../unchanged-b book --delete `cat longname`
1057 $ hg book --delete `cat longname`
1057 $ hg book --delete `cat longname`
1058 $ hg co @
1058 $ hg co @
1059 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1059 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1060 (activating bookmark @)
1060 (activating bookmark @)
1061 #endif
1061 #endif
1062
1062
1063 Check hook preventing push (issue4455)
1063 Check hook preventing push (issue4455)
1064 ======================================
1064 ======================================
1065
1065
1066 $ hg bookmarks
1066 $ hg bookmarks
1067 * @ 0:55482a6fb4b1
1067 * @ 0:55482a6fb4b1
1068 $ hg log -G
1068 $ hg log -G
1069 @ 0:55482a6fb4b1 initial
1069 @ 0:55482a6fb4b1 initial
1070
1070
1071 $ hg init ../issue4455-dest
1071 $ hg init ../issue4455-dest
1072 $ hg push ../issue4455-dest # changesets only
1072 $ hg push ../issue4455-dest # changesets only
1073 pushing to ../issue4455-dest
1073 pushing to ../issue4455-dest
1074 searching for changes
1074 searching for changes
1075 adding changesets
1075 adding changesets
1076 adding manifests
1076 adding manifests
1077 adding file changes
1077 adding file changes
1078 added 1 changesets with 1 changes to 1 files
1078 added 1 changesets with 1 changes to 1 files
1079 $ cat >> .hg/hgrc << EOF
1079 $ cat >> .hg/hgrc << EOF
1080 > [paths]
1080 > [paths]
1081 > local=../issue4455-dest/
1081 > local=../issue4455-dest/
1082 > ssh=ssh://user@dummy/issue4455-dest
1082 > ssh=ssh://user@dummy/issue4455-dest
1083 > http=http://localhost:$HGPORT/
1083 > http=http://localhost:$HGPORT/
1084 > [ui]
1084 > [ui]
1085 > ssh=$PYTHON "$TESTDIR/dummyssh"
1085 > ssh=$PYTHON "$TESTDIR/dummyssh"
1086 > EOF
1086 > EOF
1087 $ cat >> ../issue4455-dest/.hg/hgrc << EOF
1087 $ cat >> ../issue4455-dest/.hg/hgrc << EOF
1088 > [hooks]
1088 > [hooks]
1089 > prepushkey=false
1089 > prepushkey=false
1090 > [web]
1090 > [web]
1091 > push_ssl = false
1091 > push_ssl = false
1092 > allow_push = *
1092 > allow_push = *
1093 > EOF
1093 > EOF
1094 $ killdaemons.py
1094 $ killdaemons.py
1095 $ hg serve -R ../issue4455-dest -p $HGPORT -d --pid-file=../issue4455.pid -E ../issue4455-error.log
1095 $ hg serve -R ../issue4455-dest -p $HGPORT -d --pid-file=../issue4455.pid -E ../issue4455-error.log
1096 $ cat ../issue4455.pid >> $DAEMON_PIDS
1096 $ cat ../issue4455.pid >> $DAEMON_PIDS
1097
1097
1098 Local push
1098 Local push
1099 ----------
1099 ----------
1100
1100
1101 #if b2-pushkey
1101 #if b2-pushkey
1102
1102
1103 $ hg push -B @ local
1103 $ hg push -B @ local
1104 pushing to $TESTTMP/issue4455-dest
1104 pushing to $TESTTMP/issue4455-dest
1105 searching for changes
1105 searching for changes
1106 no changes found
1106 no changes found
1107 pushkey-abort: prepushkey hook exited with status 1
1107 pushkey-abort: prepushkey hook exited with status 1
1108 abort: exporting bookmark @ failed!
1108 abort: exporting bookmark @ failed!
1109 [255]
1109 [255]
1110
1110
1111 #endif
1111 #endif
1112 #if b2-binary
1112 #if b2-binary
1113
1113
1114 $ hg push -B @ local
1114 $ hg push -B @ local
1115 pushing to $TESTTMP/issue4455-dest
1115 pushing to $TESTTMP/issue4455-dest
1116 searching for changes
1116 searching for changes
1117 no changes found
1117 no changes found
1118 abort: prepushkey hook exited with status 1
1118 abort: prepushkey hook exited with status 1
1119 [255]
1119 [255]
1120
1120
1121 #endif
1121 #endif
1122
1122
1123 $ hg -R ../issue4455-dest/ bookmarks
1123 $ hg -R ../issue4455-dest/ bookmarks
1124 no bookmarks set
1124 no bookmarks set
1125
1125
1126 Using ssh
1126 Using ssh
1127 ---------
1127 ---------
1128
1128
1129 #if b2-pushkey
1129 #if b2-pushkey
1130
1130
1131 $ hg push -B @ ssh # bundle2+
1131 $ hg push -B @ ssh # bundle2+
1132 pushing to ssh://user@dummy/issue4455-dest
1132 pushing to ssh://user@dummy/issue4455-dest
1133 searching for changes
1133 searching for changes
1134 no changes found
1134 no changes found
1135 remote: pushkey-abort: prepushkey hook exited with status 1
1135 remote: pushkey-abort: prepushkey hook exited with status 1
1136 abort: exporting bookmark @ failed!
1136 abort: exporting bookmark @ failed!
1137 [255]
1137 [255]
1138
1138
1139 $ hg -R ../issue4455-dest/ bookmarks
1139 $ hg -R ../issue4455-dest/ bookmarks
1140 no bookmarks set
1140 no bookmarks set
1141
1141
1142 $ hg push -B @ ssh --config devel.legacy.exchange=bundle1
1142 $ hg push -B @ ssh --config devel.legacy.exchange=bundle1
1143 pushing to ssh://user@dummy/issue4455-dest
1143 pushing to ssh://user@dummy/issue4455-dest
1144 searching for changes
1144 searching for changes
1145 no changes found
1145 no changes found
1146 remote: pushkey-abort: prepushkey hook exited with status 1
1146 remote: pushkey-abort: prepushkey hook exited with status 1
1147 exporting bookmark @ failed!
1147 exporting bookmark @ failed!
1148 [1]
1148 [1]
1149
1149
1150 #endif
1150 #endif
1151 #if b2-binary
1151 #if b2-binary
1152
1152
1153 $ hg push -B @ ssh # bundle2+
1153 $ hg push -B @ ssh # bundle2+
1154 pushing to ssh://user@dummy/issue4455-dest
1154 pushing to ssh://user@dummy/issue4455-dest
1155 searching for changes
1155 searching for changes
1156 no changes found
1156 no changes found
1157 remote: prepushkey hook exited with status 1
1157 remote: prepushkey hook exited with status 1
1158 abort: push failed on remote
1158 abort: push failed on remote
1159 [255]
1159 [255]
1160
1160
1161 #endif
1161 #endif
1162
1162
1163 $ hg -R ../issue4455-dest/ bookmarks
1163 $ hg -R ../issue4455-dest/ bookmarks
1164 no bookmarks set
1164 no bookmarks set
1165
1165
1166 Using http
1166 Using http
1167 ----------
1167 ----------
1168
1168
1169 #if b2-pushkey
1169 #if b2-pushkey
1170 $ hg push -B @ http # bundle2+
1170 $ hg push -B @ http # bundle2+
1171 pushing to http://localhost:$HGPORT/
1171 pushing to http://localhost:$HGPORT/
1172 searching for changes
1172 searching for changes
1173 no changes found
1173 no changes found
1174 remote: pushkey-abort: prepushkey hook exited with status 1
1174 remote: pushkey-abort: prepushkey hook exited with status 1
1175 abort: exporting bookmark @ failed!
1175 abort: exporting bookmark @ failed!
1176 [255]
1176 [255]
1177
1177
1178 $ hg -R ../issue4455-dest/ bookmarks
1178 $ hg -R ../issue4455-dest/ bookmarks
1179 no bookmarks set
1179 no bookmarks set
1180
1180
1181 $ hg push -B @ http --config devel.legacy.exchange=bundle1
1181 $ hg push -B @ http --config devel.legacy.exchange=bundle1
1182 pushing to http://localhost:$HGPORT/
1182 pushing to http://localhost:$HGPORT/
1183 searching for changes
1183 searching for changes
1184 no changes found
1184 no changes found
1185 remote: pushkey-abort: prepushkey hook exited with status 1
1185 remote: pushkey-abort: prepushkey hook exited with status 1
1186 exporting bookmark @ failed!
1186 exporting bookmark @ failed!
1187 [1]
1187 [1]
1188
1188
1189 #endif
1189 #endif
1190
1190
1191 #if b2-binary
1191 #if b2-binary
1192
1192
1193 $ hg push -B @ ssh # bundle2+
1193 $ hg push -B @ ssh # bundle2+
1194 pushing to ssh://user@dummy/issue4455-dest
1194 pushing to ssh://user@dummy/issue4455-dest
1195 searching for changes
1195 searching for changes
1196 no changes found
1196 no changes found
1197 remote: prepushkey hook exited with status 1
1197 remote: prepushkey hook exited with status 1
1198 abort: push failed on remote
1198 abort: push failed on remote
1199 [255]
1199 [255]
1200
1200
1201 #endif
1201 #endif
1202
1202
1203 $ hg -R ../issue4455-dest/ bookmarks
1203 $ hg -R ../issue4455-dest/ bookmarks
1204 no bookmarks set
1204 no bookmarks set
1205
1205
1206 $ cd ..
1206 $ cd ..
1207
1207
1208 Test that pre-pushkey compat for bookmark works as expected (issue5777)
1208 Test that pre-pushkey compat for bookmark works as expected (issue5777)
1209
1209
1210 $ cat << EOF >> $HGRCPATH
1210 $ cat << EOF >> $HGRCPATH
1211 > [ui]
1211 > [ui]
1212 > ssh="$PYTHON" "$TESTDIR/dummyssh"
1212 > ssh="$PYTHON" "$TESTDIR/dummyssh"
1213 > [server]
1213 > [server]
1214 > bookmarks-pushkey-compat = yes
1214 > bookmarks-pushkey-compat = yes
1215 > EOF
1215 > EOF
1216
1216
1217 $ hg init server
1217 $ hg init server
1218 $ echo foo > server/a
1218 $ echo foo > server/a
1219 $ hg -R server book foo
1219 $ hg -R server book foo
1220 $ hg -R server commit -Am a
1220 $ hg -R server commit -Am a
1221 adding a
1221 adding a
1222 $ hg clone ssh://user@dummy/server client
1222 $ hg clone ssh://user@dummy/server client
1223 requesting all changes
1223 requesting all changes
1224 adding changesets
1224 adding changesets
1225 adding manifests
1225 adding manifests
1226 adding file changes
1226 adding file changes
1227 added 1 changesets with 1 changes to 1 files
1227 added 1 changesets with 1 changes to 1 files
1228 new changesets 79513d0d7716
1228 new changesets 79513d0d7716
1229 updating to branch default
1229 updating to branch default
1230 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1230 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1231
1231
1232 Forbid bookmark move on the server
1232 Forbid bookmark move on the server
1233
1233
1234 $ cat << EOF >> $TESTDIR/no-bm-move.sh
1234 $ cat << EOF >> $TESTDIR/no-bm-move.sh
1235 > #!/bin/sh
1235 > #!/bin/sh
1236 > echo \$HG_NAMESPACE | grep -v bookmarks
1236 > echo \$HG_NAMESPACE | grep -v bookmarks
1237 > EOF
1237 > EOF
1238 $ cat << EOF >> server/.hg/hgrc
1238 $ cat << EOF >> server/.hg/hgrc
1239 > [hooks]
1239 > [hooks]
1240 > prepushkey.no-bm-move= sh $TESTDIR/no-bm-move.sh
1240 > prepushkey.no-bm-move= sh $TESTDIR/no-bm-move.sh
1241 > EOF
1241 > EOF
1242
1242
1243 pushing changeset is okay
1243 pushing changeset is okay
1244
1244
1245 $ echo bar >> client/a
1245 $ echo bar >> client/a
1246 $ hg -R client commit -m b
1246 $ hg -R client commit -m b
1247 $ hg -R client push
1247 $ hg -R client push
1248 pushing to ssh://user@dummy/server
1248 pushing to ssh://user@dummy/server
1249 searching for changes
1249 searching for changes
1250 remote: adding changesets
1250 remote: adding changesets
1251 remote: adding manifests
1251 remote: adding manifests
1252 remote: adding file changes
1252 remote: adding file changes
1253 remote: added 1 changesets with 1 changes to 1 files
1253 remote: added 1 changesets with 1 changes to 1 files
1254
1254
1255 attempt to move the bookmark is rejected
1255 attempt to move the bookmark is rejected
1256
1256
1257 $ hg -R client book foo -r .
1257 $ hg -R client book foo -r .
1258 moving bookmark 'foo' forward from 79513d0d7716
1258 moving bookmark 'foo' forward from 79513d0d7716
1259
1259
1260 #if b2-pushkey
1260 #if b2-pushkey
1261 $ hg -R client push
1261 $ hg -R client push
1262 pushing to ssh://user@dummy/server
1262 pushing to ssh://user@dummy/server
1263 searching for changes
1263 searching for changes
1264 no changes found
1264 no changes found
1265 remote: pushkey-abort: prepushkey.no-bm-move hook exited with status 1
1265 remote: pushkey-abort: prepushkey.no-bm-move hook exited with status 1
1266 abort: updating bookmark foo failed!
1266 abort: updating bookmark foo failed!
1267 [255]
1267 [255]
1268 #endif
1268 #endif
1269 #if b2-binary
1269 #if b2-binary
1270 $ hg -R client push
1270 $ hg -R client push
1271 pushing to ssh://user@dummy/server
1271 pushing to ssh://user@dummy/server
1272 searching for changes
1272 searching for changes
1273 no changes found
1273 no changes found
1274 remote: prepushkey.no-bm-move hook exited with status 1
1274 remote: prepushkey.no-bm-move hook exited with status 1
1275 abort: push failed on remote
1275 abort: push failed on remote
1276 [255]
1276 [255]
1277 #endif
1277 #endif
@@ -1,1216 +1,1213 b''
1
1
2 $ hg init repo
2 $ hg init repo
3 $ cd repo
3 $ cd repo
4
4
5 $ cat > $TESTTMP/hook.sh <<'EOF'
5 $ cat > $TESTTMP/hook.sh <<'EOF'
6 > echo "test-hook-bookmark: $HG_BOOKMARK: $HG_OLDNODE -> $HG_NODE"
6 > echo "test-hook-bookmark: $HG_BOOKMARK: $HG_OLDNODE -> $HG_NODE"
7 > EOF
7 > EOF
8 $ TESTHOOK="hooks.txnclose-bookmark.test=sh $TESTTMP/hook.sh"
8 $ TESTHOOK="hooks.txnclose-bookmark.test=sh $TESTTMP/hook.sh"
9
9
10 no bookmarks
10 no bookmarks
11
11
12 $ hg bookmarks
12 $ hg bookmarks
13 no bookmarks set
13 no bookmarks set
14
14
15 $ hg bookmarks -Tjson
15 $ hg bookmarks -Tjson
16 [
16 [
17 ]
17 ]
18
18
19 bookmark rev -1
19 bookmark rev -1
20
20
21 $ hg bookmark X --config "$TESTHOOK"
21 $ hg bookmark X --config "$TESTHOOK"
22 test-hook-bookmark: X: -> 0000000000000000000000000000000000000000
22 test-hook-bookmark: X: -> 0000000000000000000000000000000000000000
23
23
24 list bookmarks
24 list bookmarks
25
25
26 $ hg bookmarks
26 $ hg bookmarks
27 * X -1:000000000000
27 * X -1:000000000000
28
28
29 list bookmarks with color
29 list bookmarks with color
30
30
31 $ hg --config extensions.color= --config color.mode=ansi \
31 $ hg --config extensions.color= --config color.mode=ansi \
32 > bookmarks --color=always
32 > bookmarks --color=always
33 \x1b[0;32m * \x1b[0m\x1b[0;32mX\x1b[0m\x1b[0;32m -1:000000000000\x1b[0m (esc)
33 \x1b[0;32m * \x1b[0m\x1b[0;32mX\x1b[0m\x1b[0;32m -1:000000000000\x1b[0m (esc)
34
34
35 $ echo a > a
35 $ echo a > a
36 $ hg add a
36 $ hg add a
37 $ hg commit -m 0 --config "$TESTHOOK"
37 $ hg commit -m 0 --config "$TESTHOOK"
38 test-hook-bookmark: X: 0000000000000000000000000000000000000000 -> f7b1eb17ad24730a1651fccd46c43826d1bbc2ac
38 test-hook-bookmark: X: 0000000000000000000000000000000000000000 -> f7b1eb17ad24730a1651fccd46c43826d1bbc2ac
39
39
40 bookmark X moved to rev 0
40 bookmark X moved to rev 0
41
41
42 $ hg bookmarks
42 $ hg bookmarks
43 * X 0:f7b1eb17ad24
43 * X 0:f7b1eb17ad24
44
44
45 look up bookmark
45 look up bookmark
46
46
47 $ hg log -r X
47 $ hg log -r X
48 changeset: 0:f7b1eb17ad24
48 changeset: 0:f7b1eb17ad24
49 bookmark: X
49 bookmark: X
50 tag: tip
50 tag: tip
51 user: test
51 user: test
52 date: Thu Jan 01 00:00:00 1970 +0000
52 date: Thu Jan 01 00:00:00 1970 +0000
53 summary: 0
53 summary: 0
54
54
55
55
56 second bookmark for rev 0, command should work even with ui.strict on
56 second bookmark for rev 0, command should work even with ui.strict on
57
57
58 $ hg --config ui.strict=1 bookmark X2 --config "$TESTHOOK"
58 $ hg --config ui.strict=1 bookmark X2 --config "$TESTHOOK"
59 test-hook-bookmark: X2: -> f7b1eb17ad24730a1651fccd46c43826d1bbc2ac
59 test-hook-bookmark: X2: -> f7b1eb17ad24730a1651fccd46c43826d1bbc2ac
60
60
61 bookmark rev -1 again
61 bookmark rev -1 again
62
62
63 $ hg bookmark -r null Y
63 $ hg bookmark -r null Y
64
64
65 list bookmarks
65 list bookmarks
66
66
67 $ hg bookmarks
67 $ hg bookmarks
68 X 0:f7b1eb17ad24
68 X 0:f7b1eb17ad24
69 * X2 0:f7b1eb17ad24
69 * X2 0:f7b1eb17ad24
70 Y -1:000000000000
70 Y -1:000000000000
71 $ hg log -T '{bookmarks % "{rev} {bookmark}\n"}'
71 $ hg log -T '{bookmarks % "{rev} {bookmark}\n"}'
72 0 X
72 0 X
73 0 X2
73 0 X2
74
74
75 $ echo b > b
75 $ echo b > b
76 $ hg add b
76 $ hg add b
77 $ hg commit -m 1 --config "$TESTHOOK"
77 $ hg commit -m 1 --config "$TESTHOOK"
78 test-hook-bookmark: X2: f7b1eb17ad24730a1651fccd46c43826d1bbc2ac -> 925d80f479bb026b0fb3deb27503780b13f74123
78 test-hook-bookmark: X2: f7b1eb17ad24730a1651fccd46c43826d1bbc2ac -> 925d80f479bb026b0fb3deb27503780b13f74123
79
79
80 $ hg bookmarks -T '{rev}:{node|shortest} {bookmark} {desc|firstline}\n'
80 $ hg bookmarks -T '{rev}:{node|shortest} {bookmark} {desc|firstline}\n'
81 0:f7b1 X 0
81 0:f7b1 X 0
82 1:925d X2 1
82 1:925d X2 1
83 -1:0000 Y
83 -1:0000 Y
84
84
85 $ hg bookmarks -Tjson
85 $ hg bookmarks -Tjson
86 [
86 [
87 {
87 {
88 "active": false,
88 "active": false,
89 "bookmark": "X",
89 "bookmark": "X",
90 "node": "f7b1eb17ad24730a1651fccd46c43826d1bbc2ac",
90 "node": "f7b1eb17ad24730a1651fccd46c43826d1bbc2ac",
91 "rev": 0
91 "rev": 0
92 },
92 },
93 {
93 {
94 "active": true,
94 "active": true,
95 "bookmark": "X2",
95 "bookmark": "X2",
96 "node": "925d80f479bb026b0fb3deb27503780b13f74123",
96 "node": "925d80f479bb026b0fb3deb27503780b13f74123",
97 "rev": 1
97 "rev": 1
98 },
98 },
99 {
99 {
100 "active": false,
100 "active": false,
101 "bookmark": "Y",
101 "bookmark": "Y",
102 "node": "0000000000000000000000000000000000000000",
102 "node": "0000000000000000000000000000000000000000",
103 "rev": -1
103 "rev": -1
104 }
104 }
105 ]
105 ]
106
106
107 bookmarks revset
107 bookmarks revset
108
108
109 $ hg log -r 'bookmark()'
109 $ hg log -r 'bookmark()'
110 changeset: 0:f7b1eb17ad24
110 changeset: 0:f7b1eb17ad24
111 bookmark: X
111 bookmark: X
112 user: test
112 user: test
113 date: Thu Jan 01 00:00:00 1970 +0000
113 date: Thu Jan 01 00:00:00 1970 +0000
114 summary: 0
114 summary: 0
115
115
116 changeset: 1:925d80f479bb
116 changeset: 1:925d80f479bb
117 bookmark: X2
117 bookmark: X2
118 tag: tip
118 tag: tip
119 user: test
119 user: test
120 date: Thu Jan 01 00:00:00 1970 +0000
120 date: Thu Jan 01 00:00:00 1970 +0000
121 summary: 1
121 summary: 1
122
122
123 $ hg log -r 'bookmark(Y)'
123 $ hg log -r 'bookmark(Y)'
124 $ hg log -r 'bookmark(X2)'
124 $ hg log -r 'bookmark(X2)'
125 changeset: 1:925d80f479bb
125 changeset: 1:925d80f479bb
126 bookmark: X2
126 bookmark: X2
127 tag: tip
127 tag: tip
128 user: test
128 user: test
129 date: Thu Jan 01 00:00:00 1970 +0000
129 date: Thu Jan 01 00:00:00 1970 +0000
130 summary: 1
130 summary: 1
131
131
132 $ hg log -r 'bookmark("re:X")'
132 $ hg log -r 'bookmark("re:X")'
133 changeset: 0:f7b1eb17ad24
133 changeset: 0:f7b1eb17ad24
134 bookmark: X
134 bookmark: X
135 user: test
135 user: test
136 date: Thu Jan 01 00:00:00 1970 +0000
136 date: Thu Jan 01 00:00:00 1970 +0000
137 summary: 0
137 summary: 0
138
138
139 changeset: 1:925d80f479bb
139 changeset: 1:925d80f479bb
140 bookmark: X2
140 bookmark: X2
141 tag: tip
141 tag: tip
142 user: test
142 user: test
143 date: Thu Jan 01 00:00:00 1970 +0000
143 date: Thu Jan 01 00:00:00 1970 +0000
144 summary: 1
144 summary: 1
145
145
146 $ hg log -r 'bookmark("literal:X")'
146 $ hg log -r 'bookmark("literal:X")'
147 changeset: 0:f7b1eb17ad24
147 changeset: 0:f7b1eb17ad24
148 bookmark: X
148 bookmark: X
149 user: test
149 user: test
150 date: Thu Jan 01 00:00:00 1970 +0000
150 date: Thu Jan 01 00:00:00 1970 +0000
151 summary: 0
151 summary: 0
152
152
153
153
154 "." is expanded to the active bookmark:
154 "." is expanded to the active bookmark:
155
155
156 $ hg log -r 'bookmark(.)'
156 $ hg log -r 'bookmark(.)'
157 changeset: 1:925d80f479bb
157 changeset: 1:925d80f479bb
158 bookmark: X2
158 bookmark: X2
159 tag: tip
159 tag: tip
160 user: test
160 user: test
161 date: Thu Jan 01 00:00:00 1970 +0000
161 date: Thu Jan 01 00:00:00 1970 +0000
162 summary: 1
162 summary: 1
163
163
164
164
165 but "literal:." is not since "." seems not a literal bookmark:
165 but "literal:." is not since "." seems not a literal bookmark:
166
166
167 $ hg log -r 'bookmark("literal:.")'
167 $ hg log -r 'bookmark("literal:.")'
168 abort: bookmark '.' does not exist!
168 abort: bookmark '.' does not exist!
169 [255]
169 [255]
170
170
171 "." should fail if there's no active bookmark:
171 "." should fail if there's no active bookmark:
172
172
173 $ hg bookmark --inactive
173 $ hg bookmark --inactive
174 $ hg log -r 'bookmark(.)'
174 $ hg log -r 'bookmark(.)'
175 abort: no active bookmark
175 abort: no active bookmark!
176 [255]
176 [255]
177 BUG: this should be resolved to an empty set:
178 $ hg log -r 'present(bookmark(.))'
177 $ hg log -r 'present(bookmark(.))'
179 abort: no active bookmark
180 [255]
181
178
182 $ hg log -r 'bookmark(unknown)'
179 $ hg log -r 'bookmark(unknown)'
183 abort: bookmark 'unknown' does not exist!
180 abort: bookmark 'unknown' does not exist!
184 [255]
181 [255]
185 $ hg log -r 'bookmark("literal:unknown")'
182 $ hg log -r 'bookmark("literal:unknown")'
186 abort: bookmark 'unknown' does not exist!
183 abort: bookmark 'unknown' does not exist!
187 [255]
184 [255]
188 $ hg log -r 'bookmark("re:unknown")'
185 $ hg log -r 'bookmark("re:unknown")'
189 abort: no bookmarks exist that match 'unknown'!
186 abort: no bookmarks exist that match 'unknown'!
190 [255]
187 [255]
191 $ hg log -r 'present(bookmark("literal:unknown"))'
188 $ hg log -r 'present(bookmark("literal:unknown"))'
192 $ hg log -r 'present(bookmark("re:unknown"))'
189 $ hg log -r 'present(bookmark("re:unknown"))'
193
190
194 $ hg help revsets | grep 'bookmark('
191 $ hg help revsets | grep 'bookmark('
195 "bookmark([name])"
192 "bookmark([name])"
196
193
197 reactivate "X2"
194 reactivate "X2"
198
195
199 $ hg update X2
196 $ hg update X2
200 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
197 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
201 (activating bookmark X2)
198 (activating bookmark X2)
202
199
203 bookmarks X and X2 moved to rev 1, Y at rev -1
200 bookmarks X and X2 moved to rev 1, Y at rev -1
204
201
205 $ hg bookmarks
202 $ hg bookmarks
206 X 0:f7b1eb17ad24
203 X 0:f7b1eb17ad24
207 * X2 1:925d80f479bb
204 * X2 1:925d80f479bb
208 Y -1:000000000000
205 Y -1:000000000000
209
206
210 bookmark rev 0 again
207 bookmark rev 0 again
211
208
212 $ hg bookmark -r 0 Z
209 $ hg bookmark -r 0 Z
213
210
214 $ hg update X
211 $ hg update X
215 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
212 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
216 (activating bookmark X)
213 (activating bookmark X)
217 $ echo c > c
214 $ echo c > c
218 $ hg add c
215 $ hg add c
219 $ hg commit -m 2
216 $ hg commit -m 2
220 created new head
217 created new head
221
218
222 bookmarks X moved to rev 2, Y at rev -1, Z at rev 0
219 bookmarks X moved to rev 2, Y at rev -1, Z at rev 0
223
220
224 $ hg bookmarks
221 $ hg bookmarks
225 * X 2:db815d6d32e6
222 * X 2:db815d6d32e6
226 X2 1:925d80f479bb
223 X2 1:925d80f479bb
227 Y -1:000000000000
224 Y -1:000000000000
228 Z 0:f7b1eb17ad24
225 Z 0:f7b1eb17ad24
229
226
230 rename nonexistent bookmark
227 rename nonexistent bookmark
231
228
232 $ hg bookmark -m A B
229 $ hg bookmark -m A B
233 abort: bookmark 'A' does not exist
230 abort: bookmark 'A' does not exist
234 [255]
231 [255]
235
232
236 rename to existent bookmark
233 rename to existent bookmark
237
234
238 $ hg bookmark -m X Y
235 $ hg bookmark -m X Y
239 abort: bookmark 'Y' already exists (use -f to force)
236 abort: bookmark 'Y' already exists (use -f to force)
240 [255]
237 [255]
241
238
242 force rename to existent bookmark
239 force rename to existent bookmark
243
240
244 $ hg bookmark -f -m X Y
241 $ hg bookmark -f -m X Y
245
242
246 rename bookmark using .
243 rename bookmark using .
247
244
248 $ hg book rename-me
245 $ hg book rename-me
249 $ hg book -m . renamed --config "$TESTHOOK"
246 $ hg book -m . renamed --config "$TESTHOOK"
250 test-hook-bookmark: rename-me: db815d6d32e69058eadefc8cffbad37675707975 ->
247 test-hook-bookmark: rename-me: db815d6d32e69058eadefc8cffbad37675707975 ->
251 test-hook-bookmark: renamed: -> db815d6d32e69058eadefc8cffbad37675707975
248 test-hook-bookmark: renamed: -> db815d6d32e69058eadefc8cffbad37675707975
252 $ hg bookmark
249 $ hg bookmark
253 X2 1:925d80f479bb
250 X2 1:925d80f479bb
254 Y 2:db815d6d32e6
251 Y 2:db815d6d32e6
255 Z 0:f7b1eb17ad24
252 Z 0:f7b1eb17ad24
256 * renamed 2:db815d6d32e6
253 * renamed 2:db815d6d32e6
257 $ hg up -q Y
254 $ hg up -q Y
258 $ hg book -d renamed --config "$TESTHOOK"
255 $ hg book -d renamed --config "$TESTHOOK"
259 test-hook-bookmark: renamed: db815d6d32e69058eadefc8cffbad37675707975 ->
256 test-hook-bookmark: renamed: db815d6d32e69058eadefc8cffbad37675707975 ->
260
257
261 rename bookmark using . with no active bookmark
258 rename bookmark using . with no active bookmark
262
259
263 $ hg book rename-me
260 $ hg book rename-me
264 $ hg book -i rename-me
261 $ hg book -i rename-me
265 $ hg book -m . renamed
262 $ hg book -m . renamed
266 abort: no active bookmark
263 abort: no active bookmark!
267 [255]
264 [255]
268 $ hg up -q Y
265 $ hg up -q Y
269 $ hg book -d rename-me
266 $ hg book -d rename-me
270
267
271 delete bookmark using .
268 delete bookmark using .
272
269
273 $ hg book delete-me
270 $ hg book delete-me
274 $ hg book -d .
271 $ hg book -d .
275 $ hg bookmark
272 $ hg bookmark
276 X2 1:925d80f479bb
273 X2 1:925d80f479bb
277 Y 2:db815d6d32e6
274 Y 2:db815d6d32e6
278 Z 0:f7b1eb17ad24
275 Z 0:f7b1eb17ad24
279 $ hg up -q Y
276 $ hg up -q Y
280
277
281 delete bookmark using . with no active bookmark
278 delete bookmark using . with no active bookmark
282
279
283 $ hg book delete-me
280 $ hg book delete-me
284 $ hg book -i delete-me
281 $ hg book -i delete-me
285 $ hg book -d .
282 $ hg book -d .
286 abort: no active bookmark
283 abort: no active bookmark!
287 [255]
284 [255]
288 $ hg up -q Y
285 $ hg up -q Y
289 $ hg book -d delete-me
286 $ hg book -d delete-me
290
287
291 list bookmarks
288 list bookmarks
292
289
293 $ hg bookmark
290 $ hg bookmark
294 X2 1:925d80f479bb
291 X2 1:925d80f479bb
295 * Y 2:db815d6d32e6
292 * Y 2:db815d6d32e6
296 Z 0:f7b1eb17ad24
293 Z 0:f7b1eb17ad24
297
294
298 bookmarks from a revset
295 bookmarks from a revset
299 $ hg bookmark -r '.^1' REVSET
296 $ hg bookmark -r '.^1' REVSET
300 $ hg bookmark -r ':tip' TIP
297 $ hg bookmark -r ':tip' TIP
301 $ hg up -q TIP
298 $ hg up -q TIP
302 $ hg bookmarks
299 $ hg bookmarks
303 REVSET 0:f7b1eb17ad24
300 REVSET 0:f7b1eb17ad24
304 * TIP 2:db815d6d32e6
301 * TIP 2:db815d6d32e6
305 X2 1:925d80f479bb
302 X2 1:925d80f479bb
306 Y 2:db815d6d32e6
303 Y 2:db815d6d32e6
307 Z 0:f7b1eb17ad24
304 Z 0:f7b1eb17ad24
308
305
309 $ hg bookmark -d REVSET
306 $ hg bookmark -d REVSET
310 $ hg bookmark -d TIP
307 $ hg bookmark -d TIP
311
308
312 rename without new name or multiple names
309 rename without new name or multiple names
313
310
314 $ hg bookmark -m Y
311 $ hg bookmark -m Y
315 abort: new bookmark name required
312 abort: new bookmark name required
316 [255]
313 [255]
317 $ hg bookmark -m Y Y2 Y3
314 $ hg bookmark -m Y Y2 Y3
318 abort: only one new bookmark name allowed
315 abort: only one new bookmark name allowed
319 [255]
316 [255]
320
317
321 delete without name
318 delete without name
322
319
323 $ hg bookmark -d
320 $ hg bookmark -d
324 abort: bookmark name required
321 abort: bookmark name required
325 [255]
322 [255]
326
323
327 delete nonexistent bookmark
324 delete nonexistent bookmark
328
325
329 $ hg bookmark -d A
326 $ hg bookmark -d A
330 abort: bookmark 'A' does not exist
327 abort: bookmark 'A' does not exist
331 [255]
328 [255]
332
329
333 bookmark name with spaces should be stripped
330 bookmark name with spaces should be stripped
334
331
335 $ hg bookmark ' x y '
332 $ hg bookmark ' x y '
336
333
337 list bookmarks
334 list bookmarks
338
335
339 $ hg bookmarks
336 $ hg bookmarks
340 X2 1:925d80f479bb
337 X2 1:925d80f479bb
341 Y 2:db815d6d32e6
338 Y 2:db815d6d32e6
342 Z 0:f7b1eb17ad24
339 Z 0:f7b1eb17ad24
343 * x y 2:db815d6d32e6
340 * x y 2:db815d6d32e6
344 $ hg log -T '{bookmarks % "{rev} {bookmark}\n"}'
341 $ hg log -T '{bookmarks % "{rev} {bookmark}\n"}'
345 2 Y
342 2 Y
346 2 x y
343 2 x y
347 1 X2
344 1 X2
348 0 Z
345 0 Z
349
346
350 look up stripped bookmark name
347 look up stripped bookmark name
351
348
352 $ hg log -r '"x y"'
349 $ hg log -r '"x y"'
353 changeset: 2:db815d6d32e6
350 changeset: 2:db815d6d32e6
354 bookmark: Y
351 bookmark: Y
355 bookmark: x y
352 bookmark: x y
356 tag: tip
353 tag: tip
357 parent: 0:f7b1eb17ad24
354 parent: 0:f7b1eb17ad24
358 user: test
355 user: test
359 date: Thu Jan 01 00:00:00 1970 +0000
356 date: Thu Jan 01 00:00:00 1970 +0000
360 summary: 2
357 summary: 2
361
358
362
359
363 reject bookmark name with newline
360 reject bookmark name with newline
364
361
365 $ hg bookmark '
362 $ hg bookmark '
366 > '
363 > '
367 abort: bookmark names cannot consist entirely of whitespace
364 abort: bookmark names cannot consist entirely of whitespace
368 [255]
365 [255]
369
366
370 $ hg bookmark -m Z '
367 $ hg bookmark -m Z '
371 > '
368 > '
372 abort: bookmark names cannot consist entirely of whitespace
369 abort: bookmark names cannot consist entirely of whitespace
373 [255]
370 [255]
374
371
375 bookmark with reserved name
372 bookmark with reserved name
376
373
377 $ hg bookmark tip
374 $ hg bookmark tip
378 abort: the name 'tip' is reserved
375 abort: the name 'tip' is reserved
379 [255]
376 [255]
380
377
381 $ hg bookmark .
378 $ hg bookmark .
382 abort: the name '.' is reserved
379 abort: the name '.' is reserved
383 [255]
380 [255]
384
381
385 $ hg bookmark null
382 $ hg bookmark null
386 abort: the name 'null' is reserved
383 abort: the name 'null' is reserved
387 [255]
384 [255]
388
385
389
386
390 bookmark with existing name
387 bookmark with existing name
391
388
392 $ hg bookmark X2
389 $ hg bookmark X2
393 abort: bookmark 'X2' already exists (use -f to force)
390 abort: bookmark 'X2' already exists (use -f to force)
394 [255]
391 [255]
395
392
396 $ hg bookmark -m Y Z
393 $ hg bookmark -m Y Z
397 abort: bookmark 'Z' already exists (use -f to force)
394 abort: bookmark 'Z' already exists (use -f to force)
398 [255]
395 [255]
399
396
400 bookmark with name of branch
397 bookmark with name of branch
401
398
402 $ hg bookmark default
399 $ hg bookmark default
403 abort: a bookmark cannot have the name of an existing branch
400 abort: a bookmark cannot have the name of an existing branch
404 [255]
401 [255]
405
402
406 $ hg bookmark -m Y default
403 $ hg bookmark -m Y default
407 abort: a bookmark cannot have the name of an existing branch
404 abort: a bookmark cannot have the name of an existing branch
408 [255]
405 [255]
409
406
410 bookmark with integer name
407 bookmark with integer name
411
408
412 $ hg bookmark 10
409 $ hg bookmark 10
413 abort: cannot use an integer as a name
410 abort: cannot use an integer as a name
414 [255]
411 [255]
415
412
416 bookmark with a name that matches a node id
413 bookmark with a name that matches a node id
417 $ hg bookmark 925d80f479bb db815d6d32e6 --config "$TESTHOOK"
414 $ hg bookmark 925d80f479bb db815d6d32e6 --config "$TESTHOOK"
418 bookmark 925d80f479bb matches a changeset hash
415 bookmark 925d80f479bb matches a changeset hash
419 (did you leave a -r out of an 'hg bookmark' command?)
416 (did you leave a -r out of an 'hg bookmark' command?)
420 bookmark db815d6d32e6 matches a changeset hash
417 bookmark db815d6d32e6 matches a changeset hash
421 (did you leave a -r out of an 'hg bookmark' command?)
418 (did you leave a -r out of an 'hg bookmark' command?)
422 test-hook-bookmark: 925d80f479bb: -> db815d6d32e69058eadefc8cffbad37675707975
419 test-hook-bookmark: 925d80f479bb: -> db815d6d32e69058eadefc8cffbad37675707975
423 test-hook-bookmark: db815d6d32e6: -> db815d6d32e69058eadefc8cffbad37675707975
420 test-hook-bookmark: db815d6d32e6: -> db815d6d32e69058eadefc8cffbad37675707975
424 $ hg bookmark -d 925d80f479bb
421 $ hg bookmark -d 925d80f479bb
425 $ hg bookmark -d db815d6d32e6
422 $ hg bookmark -d db815d6d32e6
426
423
427 $ cd ..
424 $ cd ..
428
425
429 bookmark with a name that matches an ambiguous node id
426 bookmark with a name that matches an ambiguous node id
430
427
431 $ hg init ambiguous
428 $ hg init ambiguous
432 $ cd ambiguous
429 $ cd ambiguous
433 $ echo 0 > a
430 $ echo 0 > a
434 $ hg ci -qAm 0
431 $ hg ci -qAm 0
435 $ for i in 1057 2857 4025; do
432 $ for i in 1057 2857 4025; do
436 > hg up -q 0
433 > hg up -q 0
437 > echo $i > a
434 > echo $i > a
438 > hg ci -qm $i
435 > hg ci -qm $i
439 > done
436 > done
440 $ hg up -q null
437 $ hg up -q null
441 $ hg log -r0: -T '{rev}:{node}\n'
438 $ hg log -r0: -T '{rev}:{node}\n'
442 0:b4e73ffab476aa0ee32ed81ca51e07169844bc6a
439 0:b4e73ffab476aa0ee32ed81ca51e07169844bc6a
443 1:c56256a09cd28e5764f32e8e2810d0f01e2e357a
440 1:c56256a09cd28e5764f32e8e2810d0f01e2e357a
444 2:c5623987d205cd6d9d8389bfc40fff9dbb670b48
441 2:c5623987d205cd6d9d8389bfc40fff9dbb670b48
445 3:c562ddd9c94164376c20b86b0b4991636a3bf84f
442 3:c562ddd9c94164376c20b86b0b4991636a3bf84f
446
443
447 $ hg bookmark -r0 c562
444 $ hg bookmark -r0 c562
448 $ hg bookmarks
445 $ hg bookmarks
449 c562 0:b4e73ffab476
446 c562 0:b4e73ffab476
450
447
451 $ cd ..
448 $ cd ..
452
449
453 incompatible options
450 incompatible options
454
451
455 $ cd repo
452 $ cd repo
456
453
457 $ hg bookmark -m Y -d Z
454 $ hg bookmark -m Y -d Z
458 abort: --delete and --rename are incompatible
455 abort: --delete and --rename are incompatible
459 [255]
456 [255]
460
457
461 $ hg bookmark -r 1 -d Z
458 $ hg bookmark -r 1 -d Z
462 abort: --rev is incompatible with --delete
459 abort: --rev is incompatible with --delete
463 [255]
460 [255]
464
461
465 $ hg bookmark -r 1 -m Z Y
462 $ hg bookmark -r 1 -m Z Y
466 abort: --rev is incompatible with --rename
463 abort: --rev is incompatible with --rename
467 [255]
464 [255]
468
465
469 force bookmark with existing name
466 force bookmark with existing name
470
467
471 $ hg bookmark -f X2 --config "$TESTHOOK"
468 $ hg bookmark -f X2 --config "$TESTHOOK"
472 test-hook-bookmark: X2: 925d80f479bb026b0fb3deb27503780b13f74123 -> db815d6d32e69058eadefc8cffbad37675707975
469 test-hook-bookmark: X2: 925d80f479bb026b0fb3deb27503780b13f74123 -> db815d6d32e69058eadefc8cffbad37675707975
473
470
474 force bookmark back to where it was, should deactivate it
471 force bookmark back to where it was, should deactivate it
475
472
476 $ hg bookmark -fr1 X2
473 $ hg bookmark -fr1 X2
477 $ hg bookmarks
474 $ hg bookmarks
478 X2 1:925d80f479bb
475 X2 1:925d80f479bb
479 Y 2:db815d6d32e6
476 Y 2:db815d6d32e6
480 Z 0:f7b1eb17ad24
477 Z 0:f7b1eb17ad24
481 x y 2:db815d6d32e6
478 x y 2:db815d6d32e6
482
479
483 forward bookmark to descendant without --force
480 forward bookmark to descendant without --force
484
481
485 $ hg bookmark Z
482 $ hg bookmark Z
486 moving bookmark 'Z' forward from f7b1eb17ad24
483 moving bookmark 'Z' forward from f7b1eb17ad24
487
484
488 list bookmarks
485 list bookmarks
489
486
490 $ hg bookmark
487 $ hg bookmark
491 X2 1:925d80f479bb
488 X2 1:925d80f479bb
492 Y 2:db815d6d32e6
489 Y 2:db815d6d32e6
493 * Z 2:db815d6d32e6
490 * Z 2:db815d6d32e6
494 x y 2:db815d6d32e6
491 x y 2:db815d6d32e6
495 $ hg log -T '{bookmarks % "{rev} {bookmark}\n"}'
492 $ hg log -T '{bookmarks % "{rev} {bookmark}\n"}'
496 2 Y
493 2 Y
497 2 Z
494 2 Z
498 2 x y
495 2 x y
499 1 X2
496 1 X2
500
497
501 revision but no bookmark name
498 revision but no bookmark name
502
499
503 $ hg bookmark -r .
500 $ hg bookmark -r .
504 abort: bookmark name required
501 abort: bookmark name required
505 [255]
502 [255]
506
503
507 bookmark name with whitespace only
504 bookmark name with whitespace only
508
505
509 $ hg bookmark ' '
506 $ hg bookmark ' '
510 abort: bookmark names cannot consist entirely of whitespace
507 abort: bookmark names cannot consist entirely of whitespace
511 [255]
508 [255]
512
509
513 $ hg bookmark -m Y ' '
510 $ hg bookmark -m Y ' '
514 abort: bookmark names cannot consist entirely of whitespace
511 abort: bookmark names cannot consist entirely of whitespace
515 [255]
512 [255]
516
513
517 invalid bookmark
514 invalid bookmark
518
515
519 $ hg bookmark 'foo:bar'
516 $ hg bookmark 'foo:bar'
520 abort: ':' cannot be used in a name
517 abort: ':' cannot be used in a name
521 [255]
518 [255]
522
519
523 $ hg bookmark 'foo
520 $ hg bookmark 'foo
524 > bar'
521 > bar'
525 abort: '\n' cannot be used in a name
522 abort: '\n' cannot be used in a name
526 [255]
523 [255]
527
524
528 the bookmark extension should be ignored now that it is part of core
525 the bookmark extension should be ignored now that it is part of core
529
526
530 $ echo "[extensions]" >> $HGRCPATH
527 $ echo "[extensions]" >> $HGRCPATH
531 $ echo "bookmarks=" >> $HGRCPATH
528 $ echo "bookmarks=" >> $HGRCPATH
532 $ hg bookmarks
529 $ hg bookmarks
533 X2 1:925d80f479bb
530 X2 1:925d80f479bb
534 Y 2:db815d6d32e6
531 Y 2:db815d6d32e6
535 * Z 2:db815d6d32e6
532 * Z 2:db815d6d32e6
536 x y 2:db815d6d32e6
533 x y 2:db815d6d32e6
537
534
538 test summary
535 test summary
539
536
540 $ hg summary
537 $ hg summary
541 parent: 2:db815d6d32e6 tip
538 parent: 2:db815d6d32e6 tip
542 2
539 2
543 branch: default
540 branch: default
544 bookmarks: *Z Y x y
541 bookmarks: *Z Y x y
545 commit: (clean)
542 commit: (clean)
546 update: 1 new changesets, 2 branch heads (merge)
543 update: 1 new changesets, 2 branch heads (merge)
547 phases: 3 draft
544 phases: 3 draft
548
545
549 test id
546 test id
550
547
551 $ hg id
548 $ hg id
552 db815d6d32e6 tip Y/Z/x y
549 db815d6d32e6 tip Y/Z/x y
553
550
554 test rollback
551 test rollback
555
552
556 $ echo foo > f1
553 $ echo foo > f1
557 $ hg bookmark tmp-rollback
554 $ hg bookmark tmp-rollback
558 $ hg ci -Amr
555 $ hg ci -Amr
559 adding f1
556 adding f1
560 $ hg bookmarks
557 $ hg bookmarks
561 X2 1:925d80f479bb
558 X2 1:925d80f479bb
562 Y 2:db815d6d32e6
559 Y 2:db815d6d32e6
563 Z 2:db815d6d32e6
560 Z 2:db815d6d32e6
564 * tmp-rollback 3:2bf5cfec5864
561 * tmp-rollback 3:2bf5cfec5864
565 x y 2:db815d6d32e6
562 x y 2:db815d6d32e6
566 $ hg rollback
563 $ hg rollback
567 repository tip rolled back to revision 2 (undo commit)
564 repository tip rolled back to revision 2 (undo commit)
568 working directory now based on revision 2
565 working directory now based on revision 2
569 $ hg bookmarks
566 $ hg bookmarks
570 X2 1:925d80f479bb
567 X2 1:925d80f479bb
571 Y 2:db815d6d32e6
568 Y 2:db815d6d32e6
572 Z 2:db815d6d32e6
569 Z 2:db815d6d32e6
573 * tmp-rollback 2:db815d6d32e6
570 * tmp-rollback 2:db815d6d32e6
574 x y 2:db815d6d32e6
571 x y 2:db815d6d32e6
575 $ hg bookmark -f Z -r 1
572 $ hg bookmark -f Z -r 1
576 $ hg rollback
573 $ hg rollback
577 repository tip rolled back to revision 2 (undo bookmark)
574 repository tip rolled back to revision 2 (undo bookmark)
578 $ hg bookmarks
575 $ hg bookmarks
579 X2 1:925d80f479bb
576 X2 1:925d80f479bb
580 Y 2:db815d6d32e6
577 Y 2:db815d6d32e6
581 Z 2:db815d6d32e6
578 Z 2:db815d6d32e6
582 * tmp-rollback 2:db815d6d32e6
579 * tmp-rollback 2:db815d6d32e6
583 x y 2:db815d6d32e6
580 x y 2:db815d6d32e6
584 $ hg bookmark -d tmp-rollback
581 $ hg bookmark -d tmp-rollback
585
582
586 activate bookmark on working dir parent without --force
583 activate bookmark on working dir parent without --force
587
584
588 $ hg bookmark --inactive Z
585 $ hg bookmark --inactive Z
589 $ hg bookmark Z
586 $ hg bookmark Z
590
587
591 test clone
588 test clone
592
589
593 $ hg bookmark -r 2 -i @
590 $ hg bookmark -r 2 -i @
594 $ hg bookmark -r 2 -i a@
591 $ hg bookmark -r 2 -i a@
595 $ hg bookmarks
592 $ hg bookmarks
596 @ 2:db815d6d32e6
593 @ 2:db815d6d32e6
597 X2 1:925d80f479bb
594 X2 1:925d80f479bb
598 Y 2:db815d6d32e6
595 Y 2:db815d6d32e6
599 * Z 2:db815d6d32e6
596 * Z 2:db815d6d32e6
600 a@ 2:db815d6d32e6
597 a@ 2:db815d6d32e6
601 x y 2:db815d6d32e6
598 x y 2:db815d6d32e6
602 $ hg clone . cloned-bookmarks
599 $ hg clone . cloned-bookmarks
603 updating to bookmark @
600 updating to bookmark @
604 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
601 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
605 $ hg -R cloned-bookmarks bookmarks
602 $ hg -R cloned-bookmarks bookmarks
606 * @ 2:db815d6d32e6
603 * @ 2:db815d6d32e6
607 X2 1:925d80f479bb
604 X2 1:925d80f479bb
608 Y 2:db815d6d32e6
605 Y 2:db815d6d32e6
609 Z 2:db815d6d32e6
606 Z 2:db815d6d32e6
610 a@ 2:db815d6d32e6
607 a@ 2:db815d6d32e6
611 x y 2:db815d6d32e6
608 x y 2:db815d6d32e6
612
609
613 test clone with pull protocol
610 test clone with pull protocol
614
611
615 $ hg clone --pull . cloned-bookmarks-pull
612 $ hg clone --pull . cloned-bookmarks-pull
616 requesting all changes
613 requesting all changes
617 adding changesets
614 adding changesets
618 adding manifests
615 adding manifests
619 adding file changes
616 adding file changes
620 added 3 changesets with 3 changes to 3 files (+1 heads)
617 added 3 changesets with 3 changes to 3 files (+1 heads)
621 new changesets f7b1eb17ad24:db815d6d32e6
618 new changesets f7b1eb17ad24:db815d6d32e6
622 updating to bookmark @
619 updating to bookmark @
623 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
620 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
624 $ hg -R cloned-bookmarks-pull bookmarks
621 $ hg -R cloned-bookmarks-pull bookmarks
625 * @ 2:db815d6d32e6
622 * @ 2:db815d6d32e6
626 X2 1:925d80f479bb
623 X2 1:925d80f479bb
627 Y 2:db815d6d32e6
624 Y 2:db815d6d32e6
628 Z 2:db815d6d32e6
625 Z 2:db815d6d32e6
629 a@ 2:db815d6d32e6
626 a@ 2:db815d6d32e6
630 x y 2:db815d6d32e6
627 x y 2:db815d6d32e6
631
628
632 delete multiple bookmarks at once
629 delete multiple bookmarks at once
633
630
634 $ hg bookmark -d @ a@
631 $ hg bookmark -d @ a@
635
632
636 test clone with a bookmark named "default" (issue3677)
633 test clone with a bookmark named "default" (issue3677)
637
634
638 $ hg bookmark -r 1 -f -i default
635 $ hg bookmark -r 1 -f -i default
639 $ hg clone . cloned-bookmark-default
636 $ hg clone . cloned-bookmark-default
640 updating to branch default
637 updating to branch default
641 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
638 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
642 $ hg -R cloned-bookmark-default bookmarks
639 $ hg -R cloned-bookmark-default bookmarks
643 X2 1:925d80f479bb
640 X2 1:925d80f479bb
644 Y 2:db815d6d32e6
641 Y 2:db815d6d32e6
645 Z 2:db815d6d32e6
642 Z 2:db815d6d32e6
646 default 1:925d80f479bb
643 default 1:925d80f479bb
647 x y 2:db815d6d32e6
644 x y 2:db815d6d32e6
648 $ hg -R cloned-bookmark-default parents -q
645 $ hg -R cloned-bookmark-default parents -q
649 2:db815d6d32e6
646 2:db815d6d32e6
650 $ hg bookmark -d default
647 $ hg bookmark -d default
651
648
652 test clone with a specific revision
649 test clone with a specific revision
653
650
654 $ hg clone -r 925d80 . cloned-bookmarks-rev
651 $ hg clone -r 925d80 . cloned-bookmarks-rev
655 adding changesets
652 adding changesets
656 adding manifests
653 adding manifests
657 adding file changes
654 adding file changes
658 added 2 changesets with 2 changes to 2 files
655 added 2 changesets with 2 changes to 2 files
659 new changesets f7b1eb17ad24:925d80f479bb
656 new changesets f7b1eb17ad24:925d80f479bb
660 updating to branch default
657 updating to branch default
661 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
658 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
662 $ hg -R cloned-bookmarks-rev bookmarks
659 $ hg -R cloned-bookmarks-rev bookmarks
663 X2 1:925d80f479bb
660 X2 1:925d80f479bb
664
661
665 test clone with update to a bookmark
662 test clone with update to a bookmark
666
663
667 $ hg clone -u Z . ../cloned-bookmarks-update
664 $ hg clone -u Z . ../cloned-bookmarks-update
668 updating to branch default
665 updating to branch default
669 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
666 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
670 $ hg -R ../cloned-bookmarks-update bookmarks
667 $ hg -R ../cloned-bookmarks-update bookmarks
671 X2 1:925d80f479bb
668 X2 1:925d80f479bb
672 Y 2:db815d6d32e6
669 Y 2:db815d6d32e6
673 * Z 2:db815d6d32e6
670 * Z 2:db815d6d32e6
674 x y 2:db815d6d32e6
671 x y 2:db815d6d32e6
675
672
676 create bundle with two heads
673 create bundle with two heads
677
674
678 $ hg clone . tobundle
675 $ hg clone . tobundle
679 updating to branch default
676 updating to branch default
680 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
677 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
681 $ echo x > tobundle/x
678 $ echo x > tobundle/x
682 $ hg -R tobundle add tobundle/x
679 $ hg -R tobundle add tobundle/x
683 $ hg -R tobundle commit -m'x'
680 $ hg -R tobundle commit -m'x'
684 $ hg -R tobundle update -r -2
681 $ hg -R tobundle update -r -2
685 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
682 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
686 $ echo y > tobundle/y
683 $ echo y > tobundle/y
687 $ hg -R tobundle branch test
684 $ hg -R tobundle branch test
688 marked working directory as branch test
685 marked working directory as branch test
689 (branches are permanent and global, did you want a bookmark?)
686 (branches are permanent and global, did you want a bookmark?)
690 $ hg -R tobundle add tobundle/y
687 $ hg -R tobundle add tobundle/y
691 $ hg -R tobundle commit -m'y'
688 $ hg -R tobundle commit -m'y'
692 $ hg -R tobundle bundle tobundle.hg
689 $ hg -R tobundle bundle tobundle.hg
693 searching for changes
690 searching for changes
694 2 changesets found
691 2 changesets found
695 $ hg unbundle tobundle.hg
692 $ hg unbundle tobundle.hg
696 adding changesets
693 adding changesets
697 adding manifests
694 adding manifests
698 adding file changes
695 adding file changes
699 added 2 changesets with 2 changes to 2 files (+1 heads)
696 added 2 changesets with 2 changes to 2 files (+1 heads)
700 new changesets 125c9a1d6df6:9ba5f110a0b3
697 new changesets 125c9a1d6df6:9ba5f110a0b3
701 (run 'hg heads' to see heads, 'hg merge' to merge)
698 (run 'hg heads' to see heads, 'hg merge' to merge)
702
699
703 update to active bookmark if it's not the parent
700 update to active bookmark if it's not the parent
704
701
705 (it is known issue that fsmonitor can't handle nested repositories. In
702 (it is known issue that fsmonitor can't handle nested repositories. In
706 this test scenario, cloned-bookmark-default and tobundle exist in the
703 this test scenario, cloned-bookmark-default and tobundle exist in the
707 working directory of current repository)
704 working directory of current repository)
708
705
709 $ hg summary
706 $ hg summary
710 parent: 2:db815d6d32e6
707 parent: 2:db815d6d32e6
711 2
708 2
712 branch: default
709 branch: default
713 bookmarks: *Z Y x y
710 bookmarks: *Z Y x y
714 commit: 1 added, 1 unknown (new branch head) (no-fsmonitor !)
711 commit: 1 added, 1 unknown (new branch head) (no-fsmonitor !)
715 commit: 1 added, * unknown (new branch head) (glob) (fsmonitor !)
712 commit: 1 added, * unknown (new branch head) (glob) (fsmonitor !)
716 update: 2 new changesets (update)
713 update: 2 new changesets (update)
717 phases: 5 draft
714 phases: 5 draft
718 $ hg update
715 $ hg update
719 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
716 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
720 updating bookmark Z
717 updating bookmark Z
721 $ hg bookmarks
718 $ hg bookmarks
722 X2 1:925d80f479bb
719 X2 1:925d80f479bb
723 Y 2:db815d6d32e6
720 Y 2:db815d6d32e6
724 * Z 3:125c9a1d6df6
721 * Z 3:125c9a1d6df6
725 x y 2:db815d6d32e6
722 x y 2:db815d6d32e6
726
723
727 pull --update works the same as pull && update
724 pull --update works the same as pull && update
728
725
729 $ hg bookmark -r3 Y
726 $ hg bookmark -r3 Y
730 moving bookmark 'Y' forward from db815d6d32e6
727 moving bookmark 'Y' forward from db815d6d32e6
731 $ cp -R ../cloned-bookmarks-update ../cloned-bookmarks-manual-update
728 $ cp -R ../cloned-bookmarks-update ../cloned-bookmarks-manual-update
732 $ cp -R ../cloned-bookmarks-update ../cloned-bookmarks-manual-update-with-divergence
729 $ cp -R ../cloned-bookmarks-update ../cloned-bookmarks-manual-update-with-divergence
733
730
734 (manual version)
731 (manual version)
735
732
736 $ hg -R ../cloned-bookmarks-manual-update update Y
733 $ hg -R ../cloned-bookmarks-manual-update update Y
737 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
734 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
738 (activating bookmark Y)
735 (activating bookmark Y)
739 $ hg -R ../cloned-bookmarks-manual-update pull .
736 $ hg -R ../cloned-bookmarks-manual-update pull .
740 pulling from .
737 pulling from .
741 searching for changes
738 searching for changes
742 adding changesets
739 adding changesets
743 adding manifests
740 adding manifests
744 adding file changes
741 adding file changes
745 added 2 changesets with 2 changes to 2 files (+1 heads)
742 added 2 changesets with 2 changes to 2 files (+1 heads)
746 updating bookmark Y
743 updating bookmark Y
747 updating bookmark Z
744 updating bookmark Z
748 new changesets 125c9a1d6df6:9ba5f110a0b3
745 new changesets 125c9a1d6df6:9ba5f110a0b3
749 (run 'hg heads' to see heads, 'hg merge' to merge)
746 (run 'hg heads' to see heads, 'hg merge' to merge)
750
747
751 (# tests strange but with --date crashing when bookmark have to move)
748 (# tests strange but with --date crashing when bookmark have to move)
752
749
753 $ hg -R ../cloned-bookmarks-manual-update update -d 1986
750 $ hg -R ../cloned-bookmarks-manual-update update -d 1986
754 abort: revision matching date not found
751 abort: revision matching date not found
755 [255]
752 [255]
756 $ hg -R ../cloned-bookmarks-manual-update update
753 $ hg -R ../cloned-bookmarks-manual-update update
757 updating to active bookmark Y
754 updating to active bookmark Y
758 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
755 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
759
756
760 (all in one version)
757 (all in one version)
761
758
762 $ hg -R ../cloned-bookmarks-update update Y
759 $ hg -R ../cloned-bookmarks-update update Y
763 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
760 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
764 (activating bookmark Y)
761 (activating bookmark Y)
765 $ hg -R ../cloned-bookmarks-update pull --update .
762 $ hg -R ../cloned-bookmarks-update pull --update .
766 pulling from .
763 pulling from .
767 searching for changes
764 searching for changes
768 adding changesets
765 adding changesets
769 adding manifests
766 adding manifests
770 adding file changes
767 adding file changes
771 added 2 changesets with 2 changes to 2 files (+1 heads)
768 added 2 changesets with 2 changes to 2 files (+1 heads)
772 updating bookmark Y
769 updating bookmark Y
773 updating bookmark Z
770 updating bookmark Z
774 new changesets 125c9a1d6df6:9ba5f110a0b3
771 new changesets 125c9a1d6df6:9ba5f110a0b3
775 updating to active bookmark Y
772 updating to active bookmark Y
776 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
773 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
777
774
778 We warn about divergent during bare update to the active bookmark
775 We warn about divergent during bare update to the active bookmark
779
776
780 $ hg -R ../cloned-bookmarks-manual-update-with-divergence update Y
777 $ hg -R ../cloned-bookmarks-manual-update-with-divergence update Y
781 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
778 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
782 (activating bookmark Y)
779 (activating bookmark Y)
783 $ hg -R ../cloned-bookmarks-manual-update-with-divergence bookmarks -r X2 Y@1
780 $ hg -R ../cloned-bookmarks-manual-update-with-divergence bookmarks -r X2 Y@1
784 $ hg -R ../cloned-bookmarks-manual-update-with-divergence bookmarks
781 $ hg -R ../cloned-bookmarks-manual-update-with-divergence bookmarks
785 X2 1:925d80f479bb
782 X2 1:925d80f479bb
786 * Y 2:db815d6d32e6
783 * Y 2:db815d6d32e6
787 Y@1 1:925d80f479bb
784 Y@1 1:925d80f479bb
788 Z 2:db815d6d32e6
785 Z 2:db815d6d32e6
789 x y 2:db815d6d32e6
786 x y 2:db815d6d32e6
790 $ hg -R ../cloned-bookmarks-manual-update-with-divergence pull
787 $ hg -R ../cloned-bookmarks-manual-update-with-divergence pull
791 pulling from $TESTTMP/repo
788 pulling from $TESTTMP/repo
792 searching for changes
789 searching for changes
793 adding changesets
790 adding changesets
794 adding manifests
791 adding manifests
795 adding file changes
792 adding file changes
796 added 2 changesets with 2 changes to 2 files (+1 heads)
793 added 2 changesets with 2 changes to 2 files (+1 heads)
797 updating bookmark Y
794 updating bookmark Y
798 updating bookmark Z
795 updating bookmark Z
799 new changesets 125c9a1d6df6:9ba5f110a0b3
796 new changesets 125c9a1d6df6:9ba5f110a0b3
800 (run 'hg heads' to see heads, 'hg merge' to merge)
797 (run 'hg heads' to see heads, 'hg merge' to merge)
801 $ hg -R ../cloned-bookmarks-manual-update-with-divergence update
798 $ hg -R ../cloned-bookmarks-manual-update-with-divergence update
802 updating to active bookmark Y
799 updating to active bookmark Y
803 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
800 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
804 1 other divergent bookmarks for "Y"
801 1 other divergent bookmarks for "Y"
805
802
806 test wrongly formated bookmark
803 test wrongly formated bookmark
807
804
808 $ echo '' >> .hg/bookmarks
805 $ echo '' >> .hg/bookmarks
809 $ hg bookmarks
806 $ hg bookmarks
810 X2 1:925d80f479bb
807 X2 1:925d80f479bb
811 Y 3:125c9a1d6df6
808 Y 3:125c9a1d6df6
812 * Z 3:125c9a1d6df6
809 * Z 3:125c9a1d6df6
813 x y 2:db815d6d32e6
810 x y 2:db815d6d32e6
814 $ echo "Ican'thasformatedlines" >> .hg/bookmarks
811 $ echo "Ican'thasformatedlines" >> .hg/bookmarks
815 $ hg bookmarks
812 $ hg bookmarks
816 malformed line in .hg/bookmarks: "Ican'thasformatedlines"
813 malformed line in .hg/bookmarks: "Ican'thasformatedlines"
817 X2 1:925d80f479bb
814 X2 1:925d80f479bb
818 Y 3:125c9a1d6df6
815 Y 3:125c9a1d6df6
819 * Z 3:125c9a1d6df6
816 * Z 3:125c9a1d6df6
820 x y 2:db815d6d32e6
817 x y 2:db815d6d32e6
821
818
822 test missing revisions
819 test missing revisions
823
820
824 $ echo "925d80f479b925d80f479bc925d80f479bccabab z" > .hg/bookmarks
821 $ echo "925d80f479b925d80f479bc925d80f479bccabab z" > .hg/bookmarks
825 $ hg book
822 $ hg book
826 no bookmarks set
823 no bookmarks set
827
824
828 test stripping a non-checked-out but bookmarked revision
825 test stripping a non-checked-out but bookmarked revision
829
826
830 $ hg log --graph
827 $ hg log --graph
831 o changeset: 4:9ba5f110a0b3
828 o changeset: 4:9ba5f110a0b3
832 | branch: test
829 | branch: test
833 | tag: tip
830 | tag: tip
834 | parent: 2:db815d6d32e6
831 | parent: 2:db815d6d32e6
835 | user: test
832 | user: test
836 | date: Thu Jan 01 00:00:00 1970 +0000
833 | date: Thu Jan 01 00:00:00 1970 +0000
837 | summary: y
834 | summary: y
838 |
835 |
839 | @ changeset: 3:125c9a1d6df6
836 | @ changeset: 3:125c9a1d6df6
840 |/ user: test
837 |/ user: test
841 | date: Thu Jan 01 00:00:00 1970 +0000
838 | date: Thu Jan 01 00:00:00 1970 +0000
842 | summary: x
839 | summary: x
843 |
840 |
844 o changeset: 2:db815d6d32e6
841 o changeset: 2:db815d6d32e6
845 | parent: 0:f7b1eb17ad24
842 | parent: 0:f7b1eb17ad24
846 | user: test
843 | user: test
847 | date: Thu Jan 01 00:00:00 1970 +0000
844 | date: Thu Jan 01 00:00:00 1970 +0000
848 | summary: 2
845 | summary: 2
849 |
846 |
850 | o changeset: 1:925d80f479bb
847 | o changeset: 1:925d80f479bb
851 |/ user: test
848 |/ user: test
852 | date: Thu Jan 01 00:00:00 1970 +0000
849 | date: Thu Jan 01 00:00:00 1970 +0000
853 | summary: 1
850 | summary: 1
854 |
851 |
855 o changeset: 0:f7b1eb17ad24
852 o changeset: 0:f7b1eb17ad24
856 user: test
853 user: test
857 date: Thu Jan 01 00:00:00 1970 +0000
854 date: Thu Jan 01 00:00:00 1970 +0000
858 summary: 0
855 summary: 0
859
856
860 $ hg book should-end-on-two
857 $ hg book should-end-on-two
861 $ hg co --clean 4
858 $ hg co --clean 4
862 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
859 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
863 (leaving bookmark should-end-on-two)
860 (leaving bookmark should-end-on-two)
864 $ hg book four
861 $ hg book four
865 $ hg --config extensions.mq= strip 3
862 $ hg --config extensions.mq= strip 3
866 saved backup bundle to * (glob)
863 saved backup bundle to * (glob)
867 should-end-on-two should end up pointing to revision 2, as that's the
864 should-end-on-two should end up pointing to revision 2, as that's the
868 tipmost surviving ancestor of the stripped revision.
865 tipmost surviving ancestor of the stripped revision.
869 $ hg log --graph
866 $ hg log --graph
870 @ changeset: 3:9ba5f110a0b3
867 @ changeset: 3:9ba5f110a0b3
871 | branch: test
868 | branch: test
872 | bookmark: four
869 | bookmark: four
873 | tag: tip
870 | tag: tip
874 | user: test
871 | user: test
875 | date: Thu Jan 01 00:00:00 1970 +0000
872 | date: Thu Jan 01 00:00:00 1970 +0000
876 | summary: y
873 | summary: y
877 |
874 |
878 o changeset: 2:db815d6d32e6
875 o changeset: 2:db815d6d32e6
879 | bookmark: should-end-on-two
876 | bookmark: should-end-on-two
880 | parent: 0:f7b1eb17ad24
877 | parent: 0:f7b1eb17ad24
881 | user: test
878 | user: test
882 | date: Thu Jan 01 00:00:00 1970 +0000
879 | date: Thu Jan 01 00:00:00 1970 +0000
883 | summary: 2
880 | summary: 2
884 |
881 |
885 | o changeset: 1:925d80f479bb
882 | o changeset: 1:925d80f479bb
886 |/ user: test
883 |/ user: test
887 | date: Thu Jan 01 00:00:00 1970 +0000
884 | date: Thu Jan 01 00:00:00 1970 +0000
888 | summary: 1
885 | summary: 1
889 |
886 |
890 o changeset: 0:f7b1eb17ad24
887 o changeset: 0:f7b1eb17ad24
891 user: test
888 user: test
892 date: Thu Jan 01 00:00:00 1970 +0000
889 date: Thu Jan 01 00:00:00 1970 +0000
893 summary: 0
890 summary: 0
894
891
895
892
896 no-op update doesn't deactivate bookmarks
893 no-op update doesn't deactivate bookmarks
897
894
898 (it is known issue that fsmonitor can't handle nested repositories. In
895 (it is known issue that fsmonitor can't handle nested repositories. In
899 this test scenario, cloned-bookmark-default and tobundle exist in the
896 this test scenario, cloned-bookmark-default and tobundle exist in the
900 working directory of current repository)
897 working directory of current repository)
901
898
902 $ hg bookmarks
899 $ hg bookmarks
903 * four 3:9ba5f110a0b3
900 * four 3:9ba5f110a0b3
904 should-end-on-two 2:db815d6d32e6
901 should-end-on-two 2:db815d6d32e6
905 $ hg up four
902 $ hg up four
906 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
903 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
907 $ hg up
904 $ hg up
908 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
905 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
909 $ hg sum
906 $ hg sum
910 parent: 3:9ba5f110a0b3 tip
907 parent: 3:9ba5f110a0b3 tip
911 y
908 y
912 branch: test
909 branch: test
913 bookmarks: *four
910 bookmarks: *four
914 commit: 2 unknown (clean) (no-fsmonitor !)
911 commit: 2 unknown (clean) (no-fsmonitor !)
915 commit: * unknown (clean) (glob) (fsmonitor !)
912 commit: * unknown (clean) (glob) (fsmonitor !)
916 update: (current)
913 update: (current)
917 phases: 4 draft
914 phases: 4 draft
918
915
919 test clearing divergent bookmarks of linear ancestors
916 test clearing divergent bookmarks of linear ancestors
920
917
921 $ hg bookmark Z -r 0
918 $ hg bookmark Z -r 0
922 $ hg bookmark Z@1 -r 1
919 $ hg bookmark Z@1 -r 1
923 $ hg bookmark Z@2 -r 2
920 $ hg bookmark Z@2 -r 2
924 $ hg bookmark Z@3 -r 3
921 $ hg bookmark Z@3 -r 3
925 $ hg book
922 $ hg book
926 Z 0:f7b1eb17ad24
923 Z 0:f7b1eb17ad24
927 Z@1 1:925d80f479bb
924 Z@1 1:925d80f479bb
928 Z@2 2:db815d6d32e6
925 Z@2 2:db815d6d32e6
929 Z@3 3:9ba5f110a0b3
926 Z@3 3:9ba5f110a0b3
930 * four 3:9ba5f110a0b3
927 * four 3:9ba5f110a0b3
931 should-end-on-two 2:db815d6d32e6
928 should-end-on-two 2:db815d6d32e6
932 $ hg bookmark Z
929 $ hg bookmark Z
933 moving bookmark 'Z' forward from f7b1eb17ad24
930 moving bookmark 'Z' forward from f7b1eb17ad24
934 $ hg book
931 $ hg book
935 * Z 3:9ba5f110a0b3
932 * Z 3:9ba5f110a0b3
936 Z@1 1:925d80f479bb
933 Z@1 1:925d80f479bb
937 four 3:9ba5f110a0b3
934 four 3:9ba5f110a0b3
938 should-end-on-two 2:db815d6d32e6
935 should-end-on-two 2:db815d6d32e6
939
936
940 test clearing only a single divergent bookmark across branches
937 test clearing only a single divergent bookmark across branches
941
938
942 $ hg book foo -r 1
939 $ hg book foo -r 1
943 $ hg book foo@1 -r 0
940 $ hg book foo@1 -r 0
944 $ hg book foo@2 -r 2
941 $ hg book foo@2 -r 2
945 $ hg book foo@3 -r 3
942 $ hg book foo@3 -r 3
946 $ hg book foo -r foo@3
943 $ hg book foo -r foo@3
947 $ hg book
944 $ hg book
948 * Z 3:9ba5f110a0b3
945 * Z 3:9ba5f110a0b3
949 Z@1 1:925d80f479bb
946 Z@1 1:925d80f479bb
950 foo 3:9ba5f110a0b3
947 foo 3:9ba5f110a0b3
951 foo@1 0:f7b1eb17ad24
948 foo@1 0:f7b1eb17ad24
952 foo@2 2:db815d6d32e6
949 foo@2 2:db815d6d32e6
953 four 3:9ba5f110a0b3
950 four 3:9ba5f110a0b3
954 should-end-on-two 2:db815d6d32e6
951 should-end-on-two 2:db815d6d32e6
955
952
956 pull --update works the same as pull && update (case #2)
953 pull --update works the same as pull && update (case #2)
957
954
958 It is assumed that "hg pull" itself doesn't update current active
955 It is assumed that "hg pull" itself doesn't update current active
959 bookmark ('Y' in tests below).
956 bookmark ('Y' in tests below).
960
957
961 $ hg pull -q ../cloned-bookmarks-update
958 $ hg pull -q ../cloned-bookmarks-update
962 divergent bookmark Z stored as Z@2
959 divergent bookmark Z stored as Z@2
963
960
964 (pulling revision on another named branch with --update updates
961 (pulling revision on another named branch with --update updates
965 neither the working directory nor current active bookmark: "no-op"
962 neither the working directory nor current active bookmark: "no-op"
966 case)
963 case)
967
964
968 $ echo yy >> y
965 $ echo yy >> y
969 $ hg commit -m yy
966 $ hg commit -m yy
970
967
971 $ hg -R ../cloned-bookmarks-update bookmarks | grep ' Y '
968 $ hg -R ../cloned-bookmarks-update bookmarks | grep ' Y '
972 * Y 3:125c9a1d6df6
969 * Y 3:125c9a1d6df6
973 $ hg -R ../cloned-bookmarks-update pull . --update
970 $ hg -R ../cloned-bookmarks-update pull . --update
974 pulling from .
971 pulling from .
975 searching for changes
972 searching for changes
976 adding changesets
973 adding changesets
977 adding manifests
974 adding manifests
978 adding file changes
975 adding file changes
979 added 1 changesets with 1 changes to 1 files
976 added 1 changesets with 1 changes to 1 files
980 divergent bookmark Z stored as Z@default
977 divergent bookmark Z stored as Z@default
981 adding remote bookmark foo
978 adding remote bookmark foo
982 adding remote bookmark four
979 adding remote bookmark four
983 adding remote bookmark should-end-on-two
980 adding remote bookmark should-end-on-two
984 new changesets 5fb12f0f2d51
981 new changesets 5fb12f0f2d51
985 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
982 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
986 $ hg -R ../cloned-bookmarks-update parents -T "{rev}:{node|short}\n"
983 $ hg -R ../cloned-bookmarks-update parents -T "{rev}:{node|short}\n"
987 3:125c9a1d6df6
984 3:125c9a1d6df6
988 $ hg -R ../cloned-bookmarks-update bookmarks | grep ' Y '
985 $ hg -R ../cloned-bookmarks-update bookmarks | grep ' Y '
989 * Y 3:125c9a1d6df6
986 * Y 3:125c9a1d6df6
990
987
991 (pulling revision on current named/topological branch with --update
988 (pulling revision on current named/topological branch with --update
992 updates the working directory and current active bookmark)
989 updates the working directory and current active bookmark)
993
990
994 $ hg update -C -q 125c9a1d6df6
991 $ hg update -C -q 125c9a1d6df6
995 $ echo xx >> x
992 $ echo xx >> x
996 $ hg commit -m xx
993 $ hg commit -m xx
997
994
998 $ hg -R ../cloned-bookmarks-update bookmarks | grep ' Y '
995 $ hg -R ../cloned-bookmarks-update bookmarks | grep ' Y '
999 * Y 3:125c9a1d6df6
996 * Y 3:125c9a1d6df6
1000 $ hg -R ../cloned-bookmarks-update pull . --update
997 $ hg -R ../cloned-bookmarks-update pull . --update
1001 pulling from .
998 pulling from .
1002 searching for changes
999 searching for changes
1003 adding changesets
1000 adding changesets
1004 adding manifests
1001 adding manifests
1005 adding file changes
1002 adding file changes
1006 added 1 changesets with 1 changes to 1 files
1003 added 1 changesets with 1 changes to 1 files
1007 divergent bookmark Z stored as Z@default
1004 divergent bookmark Z stored as Z@default
1008 new changesets 81dcce76aa0b
1005 new changesets 81dcce76aa0b
1009 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1006 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1010 updating bookmark Y
1007 updating bookmark Y
1011 $ hg -R ../cloned-bookmarks-update parents -T "{rev}:{node|short}\n"
1008 $ hg -R ../cloned-bookmarks-update parents -T "{rev}:{node|short}\n"
1012 6:81dcce76aa0b
1009 6:81dcce76aa0b
1013 $ hg -R ../cloned-bookmarks-update bookmarks | grep ' Y '
1010 $ hg -R ../cloned-bookmarks-update bookmarks | grep ' Y '
1014 * Y 6:81dcce76aa0b
1011 * Y 6:81dcce76aa0b
1015
1012
1016 $ cd ..
1013 $ cd ..
1017
1014
1018 ensure changelog is written before bookmarks
1015 ensure changelog is written before bookmarks
1019 $ hg init orderrepo
1016 $ hg init orderrepo
1020 $ cd orderrepo
1017 $ cd orderrepo
1021 $ touch a
1018 $ touch a
1022 $ hg commit -Aqm one
1019 $ hg commit -Aqm one
1023 $ hg book mybook
1020 $ hg book mybook
1024 $ echo a > a
1021 $ echo a > a
1025
1022
1026 $ cat > $TESTTMP/pausefinalize.py <<EOF
1023 $ cat > $TESTTMP/pausefinalize.py <<EOF
1027 > from __future__ import absolute_import
1024 > from __future__ import absolute_import
1028 > import os
1025 > import os
1029 > import time
1026 > import time
1030 > from mercurial import extensions, localrepo
1027 > from mercurial import extensions, localrepo
1031 > def transaction(orig, self, desc, report=None):
1028 > def transaction(orig, self, desc, report=None):
1032 > tr = orig(self, desc, report)
1029 > tr = orig(self, desc, report)
1033 > def sleep(*args, **kwargs):
1030 > def sleep(*args, **kwargs):
1034 > retry = 20
1031 > retry = 20
1035 > while retry > 0 and not os.path.exists(b"$TESTTMP/unpause"):
1032 > while retry > 0 and not os.path.exists(b"$TESTTMP/unpause"):
1036 > retry -= 1
1033 > retry -= 1
1037 > time.sleep(0.5)
1034 > time.sleep(0.5)
1038 > if os.path.exists(b"$TESTTMP/unpause"):
1035 > if os.path.exists(b"$TESTTMP/unpause"):
1039 > os.remove(b"$TESTTMP/unpause")
1036 > os.remove(b"$TESTTMP/unpause")
1040 > # It is important that this finalizer start with 'a', so it runs before
1037 > # It is important that this finalizer start with 'a', so it runs before
1041 > # the changelog finalizer appends to the changelog.
1038 > # the changelog finalizer appends to the changelog.
1042 > tr.addfinalize(b'a-sleep', sleep)
1039 > tr.addfinalize(b'a-sleep', sleep)
1043 > return tr
1040 > return tr
1044 >
1041 >
1045 > def extsetup(ui):
1042 > def extsetup(ui):
1046 > # This extension inserts an artifical pause during the transaction
1043 > # This extension inserts an artifical pause during the transaction
1047 > # finalizer, so we can run commands mid-transaction-close.
1044 > # finalizer, so we can run commands mid-transaction-close.
1048 > extensions.wrapfunction(localrepo.localrepository, 'transaction',
1045 > extensions.wrapfunction(localrepo.localrepository, 'transaction',
1049 > transaction)
1046 > transaction)
1050 > EOF
1047 > EOF
1051 $ hg commit -qm two --config extensions.pausefinalize=$TESTTMP/pausefinalize.py &
1048 $ hg commit -qm two --config extensions.pausefinalize=$TESTTMP/pausefinalize.py &
1052 $ sleep 2
1049 $ sleep 2
1053 $ hg log -r .
1050 $ hg log -r .
1054 changeset: 0:867bc5792c8c
1051 changeset: 0:867bc5792c8c
1055 bookmark: mybook
1052 bookmark: mybook
1056 tag: tip
1053 tag: tip
1057 user: test
1054 user: test
1058 date: Thu Jan 01 00:00:00 1970 +0000
1055 date: Thu Jan 01 00:00:00 1970 +0000
1059 summary: one
1056 summary: one
1060
1057
1061 $ hg bookmarks
1058 $ hg bookmarks
1062 * mybook 0:867bc5792c8c
1059 * mybook 0:867bc5792c8c
1063 $ touch $TESTTMP/unpause
1060 $ touch $TESTTMP/unpause
1064
1061
1065 $ cd ..
1062 $ cd ..
1066
1063
1067 check whether HG_PENDING makes pending changes only in related
1064 check whether HG_PENDING makes pending changes only in related
1068 repositories visible to an external hook.
1065 repositories visible to an external hook.
1069
1066
1070 (emulate a transaction running concurrently by copied
1067 (emulate a transaction running concurrently by copied
1071 .hg/bookmarks.pending in subsequent test)
1068 .hg/bookmarks.pending in subsequent test)
1072
1069
1073 $ cat > $TESTTMP/savepending.sh <<EOF
1070 $ cat > $TESTTMP/savepending.sh <<EOF
1074 > cp .hg/bookmarks.pending .hg/bookmarks.pending.saved
1071 > cp .hg/bookmarks.pending .hg/bookmarks.pending.saved
1075 > exit 1 # to avoid adding new bookmark for subsequent tests
1072 > exit 1 # to avoid adding new bookmark for subsequent tests
1076 > EOF
1073 > EOF
1077
1074
1078 $ hg init unrelated
1075 $ hg init unrelated
1079 $ cd unrelated
1076 $ cd unrelated
1080 $ echo a > a
1077 $ echo a > a
1081 $ hg add a
1078 $ hg add a
1082 $ hg commit -m '#0'
1079 $ hg commit -m '#0'
1083 $ hg --config hooks.pretxnclose="sh $TESTTMP/savepending.sh" bookmarks INVISIBLE
1080 $ hg --config hooks.pretxnclose="sh $TESTTMP/savepending.sh" bookmarks INVISIBLE
1084 transaction abort!
1081 transaction abort!
1085 rollback completed
1082 rollback completed
1086 abort: pretxnclose hook exited with status 1
1083 abort: pretxnclose hook exited with status 1
1087 [255]
1084 [255]
1088 $ cp .hg/bookmarks.pending.saved .hg/bookmarks.pending
1085 $ cp .hg/bookmarks.pending.saved .hg/bookmarks.pending
1089
1086
1090 (check visible bookmarks while transaction running in repo)
1087 (check visible bookmarks while transaction running in repo)
1091
1088
1092 $ cat > $TESTTMP/checkpending.sh <<EOF
1089 $ cat > $TESTTMP/checkpending.sh <<EOF
1093 > echo "@repo"
1090 > echo "@repo"
1094 > hg -R "$TESTTMP/repo" bookmarks
1091 > hg -R "$TESTTMP/repo" bookmarks
1095 > echo "@unrelated"
1092 > echo "@unrelated"
1096 > hg -R "$TESTTMP/unrelated" bookmarks
1093 > hg -R "$TESTTMP/unrelated" bookmarks
1097 > exit 1 # to avoid adding new bookmark for subsequent tests
1094 > exit 1 # to avoid adding new bookmark for subsequent tests
1098 > EOF
1095 > EOF
1099
1096
1100 $ cd ../repo
1097 $ cd ../repo
1101 $ hg --config hooks.pretxnclose="sh $TESTTMP/checkpending.sh" bookmarks NEW
1098 $ hg --config hooks.pretxnclose="sh $TESTTMP/checkpending.sh" bookmarks NEW
1102 @repo
1099 @repo
1103 * NEW 6:81dcce76aa0b
1100 * NEW 6:81dcce76aa0b
1104 X2 1:925d80f479bb
1101 X2 1:925d80f479bb
1105 Y 4:125c9a1d6df6
1102 Y 4:125c9a1d6df6
1106 Z 5:5fb12f0f2d51
1103 Z 5:5fb12f0f2d51
1107 Z@1 1:925d80f479bb
1104 Z@1 1:925d80f479bb
1108 Z@2 4:125c9a1d6df6
1105 Z@2 4:125c9a1d6df6
1109 foo 3:9ba5f110a0b3
1106 foo 3:9ba5f110a0b3
1110 foo@1 0:f7b1eb17ad24
1107 foo@1 0:f7b1eb17ad24
1111 foo@2 2:db815d6d32e6
1108 foo@2 2:db815d6d32e6
1112 four 3:9ba5f110a0b3
1109 four 3:9ba5f110a0b3
1113 should-end-on-two 2:db815d6d32e6
1110 should-end-on-two 2:db815d6d32e6
1114 x y 2:db815d6d32e6
1111 x y 2:db815d6d32e6
1115 @unrelated
1112 @unrelated
1116 no bookmarks set
1113 no bookmarks set
1117 transaction abort!
1114 transaction abort!
1118 rollback completed
1115 rollback completed
1119 abort: pretxnclose hook exited with status 1
1116 abort: pretxnclose hook exited with status 1
1120 [255]
1117 [255]
1121
1118
1122 Check pretxnclose-bookmark can abort a transaction
1119 Check pretxnclose-bookmark can abort a transaction
1123 --------------------------------------------------
1120 --------------------------------------------------
1124
1121
1125 add hooks:
1122 add hooks:
1126
1123
1127 * to prevent NEW bookmark on a non-public changeset
1124 * to prevent NEW bookmark on a non-public changeset
1128 * to prevent non-forward move of NEW bookmark
1125 * to prevent non-forward move of NEW bookmark
1129
1126
1130 $ cat << EOF >> .hg/hgrc
1127 $ cat << EOF >> .hg/hgrc
1131 > [hooks]
1128 > [hooks]
1132 > pretxnclose-bookmark.force-public = sh -c "(echo \$HG_BOOKMARK| grep -v NEW > /dev/null) || [ -z \"\$HG_NODE\" ] || (hg log -r \"\$HG_NODE\" -T '{phase}' | grep public > /dev/null)"
1129 > pretxnclose-bookmark.force-public = sh -c "(echo \$HG_BOOKMARK| grep -v NEW > /dev/null) || [ -z \"\$HG_NODE\" ] || (hg log -r \"\$HG_NODE\" -T '{phase}' | grep public > /dev/null)"
1133 > pretxnclose-bookmark.force-forward = sh -c "(echo \$HG_BOOKMARK| grep -v NEW > /dev/null) || [ -z \"\$HG_NODE\" ] || (hg log -r \"max(\$HG_OLDNODE::\$HG_NODE)\" -T 'MATCH' | grep MATCH > /dev/null)"
1130 > pretxnclose-bookmark.force-forward = sh -c "(echo \$HG_BOOKMARK| grep -v NEW > /dev/null) || [ -z \"\$HG_NODE\" ] || (hg log -r \"max(\$HG_OLDNODE::\$HG_NODE)\" -T 'MATCH' | grep MATCH > /dev/null)"
1134 > EOF
1131 > EOF
1135
1132
1136 $ hg log -G -T phases
1133 $ hg log -G -T phases
1137 @ changeset: 6:81dcce76aa0b
1134 @ changeset: 6:81dcce76aa0b
1138 | tag: tip
1135 | tag: tip
1139 | phase: draft
1136 | phase: draft
1140 | parent: 4:125c9a1d6df6
1137 | parent: 4:125c9a1d6df6
1141 | user: test
1138 | user: test
1142 | date: Thu Jan 01 00:00:00 1970 +0000
1139 | date: Thu Jan 01 00:00:00 1970 +0000
1143 | summary: xx
1140 | summary: xx
1144 |
1141 |
1145 | o changeset: 5:5fb12f0f2d51
1142 | o changeset: 5:5fb12f0f2d51
1146 | | branch: test
1143 | | branch: test
1147 | | bookmark: Z
1144 | | bookmark: Z
1148 | | phase: draft
1145 | | phase: draft
1149 | | parent: 3:9ba5f110a0b3
1146 | | parent: 3:9ba5f110a0b3
1150 | | user: test
1147 | | user: test
1151 | | date: Thu Jan 01 00:00:00 1970 +0000
1148 | | date: Thu Jan 01 00:00:00 1970 +0000
1152 | | summary: yy
1149 | | summary: yy
1153 | |
1150 | |
1154 o | changeset: 4:125c9a1d6df6
1151 o | changeset: 4:125c9a1d6df6
1155 | | bookmark: Y
1152 | | bookmark: Y
1156 | | bookmark: Z@2
1153 | | bookmark: Z@2
1157 | | phase: public
1154 | | phase: public
1158 | | parent: 2:db815d6d32e6
1155 | | parent: 2:db815d6d32e6
1159 | | user: test
1156 | | user: test
1160 | | date: Thu Jan 01 00:00:00 1970 +0000
1157 | | date: Thu Jan 01 00:00:00 1970 +0000
1161 | | summary: x
1158 | | summary: x
1162 | |
1159 | |
1163 | o changeset: 3:9ba5f110a0b3
1160 | o changeset: 3:9ba5f110a0b3
1164 |/ branch: test
1161 |/ branch: test
1165 | bookmark: foo
1162 | bookmark: foo
1166 | bookmark: four
1163 | bookmark: four
1167 | phase: public
1164 | phase: public
1168 | user: test
1165 | user: test
1169 | date: Thu Jan 01 00:00:00 1970 +0000
1166 | date: Thu Jan 01 00:00:00 1970 +0000
1170 | summary: y
1167 | summary: y
1171 |
1168 |
1172 o changeset: 2:db815d6d32e6
1169 o changeset: 2:db815d6d32e6
1173 | bookmark: foo@2
1170 | bookmark: foo@2
1174 | bookmark: should-end-on-two
1171 | bookmark: should-end-on-two
1175 | bookmark: x y
1172 | bookmark: x y
1176 | phase: public
1173 | phase: public
1177 | parent: 0:f7b1eb17ad24
1174 | parent: 0:f7b1eb17ad24
1178 | user: test
1175 | user: test
1179 | date: Thu Jan 01 00:00:00 1970 +0000
1176 | date: Thu Jan 01 00:00:00 1970 +0000
1180 | summary: 2
1177 | summary: 2
1181 |
1178 |
1182 | o changeset: 1:925d80f479bb
1179 | o changeset: 1:925d80f479bb
1183 |/ bookmark: X2
1180 |/ bookmark: X2
1184 | bookmark: Z@1
1181 | bookmark: Z@1
1185 | phase: public
1182 | phase: public
1186 | user: test
1183 | user: test
1187 | date: Thu Jan 01 00:00:00 1970 +0000
1184 | date: Thu Jan 01 00:00:00 1970 +0000
1188 | summary: 1
1185 | summary: 1
1189 |
1186 |
1190 o changeset: 0:f7b1eb17ad24
1187 o changeset: 0:f7b1eb17ad24
1191 bookmark: foo@1
1188 bookmark: foo@1
1192 phase: public
1189 phase: public
1193 user: test
1190 user: test
1194 date: Thu Jan 01 00:00:00 1970 +0000
1191 date: Thu Jan 01 00:00:00 1970 +0000
1195 summary: 0
1192 summary: 0
1196
1193
1197
1194
1198 attempt to create on a default changeset
1195 attempt to create on a default changeset
1199
1196
1200 $ hg bookmark -r 81dcce76aa0b NEW
1197 $ hg bookmark -r 81dcce76aa0b NEW
1201 transaction abort!
1198 transaction abort!
1202 rollback completed
1199 rollback completed
1203 abort: pretxnclose-bookmark.force-public hook exited with status 1
1200 abort: pretxnclose-bookmark.force-public hook exited with status 1
1204 [255]
1201 [255]
1205
1202
1206 create on a public changeset
1203 create on a public changeset
1207
1204
1208 $ hg bookmark -r 9ba5f110a0b3 NEW
1205 $ hg bookmark -r 9ba5f110a0b3 NEW
1209
1206
1210 move to the other branch
1207 move to the other branch
1211
1208
1212 $ hg bookmark -f -r 125c9a1d6df6 NEW
1209 $ hg bookmark -f -r 125c9a1d6df6 NEW
1213 transaction abort!
1210 transaction abort!
1214 rollback completed
1211 rollback completed
1215 abort: pretxnclose-bookmark.force-forward hook exited with status 1
1212 abort: pretxnclose-bookmark.force-forward hook exited with status 1
1216 [255]
1213 [255]
General Comments 0
You need to be logged in to leave comments. Login now