##// END OF EJS Templates
pull: merge bookmark updates and imports...
Pierre-Yves David -
r22659:79818570 default
parent child Browse files
Show More
@@ -1,417 +1,425 b''
1 # Mercurial bookmark support code
1 # Mercurial bookmark support code
2 #
2 #
3 # Copyright 2008 David Soria Parra <dsp@php.net>
3 # Copyright 2008 David Soria Parra <dsp@php.net>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from mercurial.i18n import _
8 from mercurial.i18n import _
9 from mercurial.node import hex, bin
9 from mercurial.node import hex, bin
10 from mercurial import encoding, error, util, obsolete
10 from mercurial import encoding, error, util, obsolete
11 import errno
11 import errno
12
12
13 class bmstore(dict):
13 class bmstore(dict):
14 """Storage for bookmarks.
14 """Storage for bookmarks.
15
15
16 This object should do all bookmark reads and writes, so that it's
16 This object should do all bookmark reads and writes, so that it's
17 fairly simple to replace the storage underlying bookmarks without
17 fairly simple to replace the storage underlying bookmarks without
18 having to clone the logic surrounding bookmarks.
18 having to clone the logic surrounding bookmarks.
19
19
20 This particular bmstore implementation stores bookmarks as
20 This particular bmstore implementation stores bookmarks as
21 {hash}\s{name}\n (the same format as localtags) in
21 {hash}\s{name}\n (the same format as localtags) in
22 .hg/bookmarks. The mapping is stored as {name: nodeid}.
22 .hg/bookmarks. The mapping is stored as {name: nodeid}.
23
23
24 This class does NOT handle the "current" bookmark state at this
24 This class does NOT handle the "current" bookmark state at this
25 time.
25 time.
26 """
26 """
27
27
28 def __init__(self, repo):
28 def __init__(self, repo):
29 dict.__init__(self)
29 dict.__init__(self)
30 self._repo = repo
30 self._repo = repo
31 try:
31 try:
32 for line in repo.vfs('bookmarks'):
32 for line in repo.vfs('bookmarks'):
33 line = line.strip()
33 line = line.strip()
34 if not line:
34 if not line:
35 continue
35 continue
36 if ' ' not in line:
36 if ' ' not in line:
37 repo.ui.warn(_('malformed line in .hg/bookmarks: %r\n')
37 repo.ui.warn(_('malformed line in .hg/bookmarks: %r\n')
38 % line)
38 % line)
39 continue
39 continue
40 sha, refspec = line.split(' ', 1)
40 sha, refspec = line.split(' ', 1)
41 refspec = encoding.tolocal(refspec)
41 refspec = encoding.tolocal(refspec)
42 try:
42 try:
43 self[refspec] = repo.changelog.lookup(sha)
43 self[refspec] = repo.changelog.lookup(sha)
44 except LookupError:
44 except LookupError:
45 pass
45 pass
46 except IOError, inst:
46 except IOError, inst:
47 if inst.errno != errno.ENOENT:
47 if inst.errno != errno.ENOENT:
48 raise
48 raise
49
49
50 def write(self):
50 def write(self):
51 '''Write bookmarks
51 '''Write bookmarks
52
52
53 Write the given bookmark => hash dictionary to the .hg/bookmarks file
53 Write the given bookmark => hash dictionary to the .hg/bookmarks file
54 in a format equal to those of localtags.
54 in a format equal to those of localtags.
55
55
56 We also store a backup of the previous state in undo.bookmarks that
56 We also store a backup of the previous state in undo.bookmarks that
57 can be copied back on rollback.
57 can be copied back on rollback.
58 '''
58 '''
59 repo = self._repo
59 repo = self._repo
60 if repo._bookmarkcurrent not in self:
60 if repo._bookmarkcurrent not in self:
61 unsetcurrent(repo)
61 unsetcurrent(repo)
62
62
63 wlock = repo.wlock()
63 wlock = repo.wlock()
64 try:
64 try:
65
65
66 file = repo.vfs('bookmarks', 'w', atomictemp=True)
66 file = repo.vfs('bookmarks', 'w', atomictemp=True)
67 for name, node in self.iteritems():
67 for name, node in self.iteritems():
68 file.write("%s %s\n" % (hex(node), encoding.fromlocal(name)))
68 file.write("%s %s\n" % (hex(node), encoding.fromlocal(name)))
69 file.close()
69 file.close()
70
70
71 # touch 00changelog.i so hgweb reloads bookmarks (no lock needed)
71 # touch 00changelog.i so hgweb reloads bookmarks (no lock needed)
72 try:
72 try:
73 repo.svfs.utime('00changelog.i', None)
73 repo.svfs.utime('00changelog.i', None)
74 except OSError:
74 except OSError:
75 pass
75 pass
76
76
77 finally:
77 finally:
78 wlock.release()
78 wlock.release()
79
79
80 def readcurrent(repo):
80 def readcurrent(repo):
81 '''Get the current bookmark
81 '''Get the current bookmark
82
82
83 If we use gittish branches we have a current bookmark that
83 If we use gittish branches we have a current bookmark that
84 we are on. This function returns the name of the bookmark. It
84 we are on. This function returns the name of the bookmark. It
85 is stored in .hg/bookmarks.current
85 is stored in .hg/bookmarks.current
86 '''
86 '''
87 mark = None
87 mark = None
88 try:
88 try:
89 file = repo.opener('bookmarks.current')
89 file = repo.opener('bookmarks.current')
90 except IOError, inst:
90 except IOError, inst:
91 if inst.errno != errno.ENOENT:
91 if inst.errno != errno.ENOENT:
92 raise
92 raise
93 return None
93 return None
94 try:
94 try:
95 # No readline() in osutil.posixfile, reading everything is cheap
95 # No readline() in osutil.posixfile, reading everything is cheap
96 mark = encoding.tolocal((file.readlines() or [''])[0])
96 mark = encoding.tolocal((file.readlines() or [''])[0])
97 if mark == '' or mark not in repo._bookmarks:
97 if mark == '' or mark not in repo._bookmarks:
98 mark = None
98 mark = None
99 finally:
99 finally:
100 file.close()
100 file.close()
101 return mark
101 return mark
102
102
103 def setcurrent(repo, mark):
103 def setcurrent(repo, mark):
104 '''Set the name of the bookmark that we are currently on
104 '''Set the name of the bookmark that we are currently on
105
105
106 Set the name of the bookmark that we are on (hg update <bookmark>).
106 Set the name of the bookmark that we are on (hg update <bookmark>).
107 The name is recorded in .hg/bookmarks.current
107 The name is recorded in .hg/bookmarks.current
108 '''
108 '''
109 if mark not in repo._bookmarks:
109 if mark not in repo._bookmarks:
110 raise AssertionError('bookmark %s does not exist!' % mark)
110 raise AssertionError('bookmark %s does not exist!' % mark)
111
111
112 current = repo._bookmarkcurrent
112 current = repo._bookmarkcurrent
113 if current == mark:
113 if current == mark:
114 return
114 return
115
115
116 wlock = repo.wlock()
116 wlock = repo.wlock()
117 try:
117 try:
118 file = repo.opener('bookmarks.current', 'w', atomictemp=True)
118 file = repo.opener('bookmarks.current', 'w', atomictemp=True)
119 file.write(encoding.fromlocal(mark))
119 file.write(encoding.fromlocal(mark))
120 file.close()
120 file.close()
121 finally:
121 finally:
122 wlock.release()
122 wlock.release()
123 repo._bookmarkcurrent = mark
123 repo._bookmarkcurrent = mark
124
124
125 def unsetcurrent(repo):
125 def unsetcurrent(repo):
126 wlock = repo.wlock()
126 wlock = repo.wlock()
127 try:
127 try:
128 try:
128 try:
129 repo.vfs.unlink('bookmarks.current')
129 repo.vfs.unlink('bookmarks.current')
130 repo._bookmarkcurrent = None
130 repo._bookmarkcurrent = None
131 except OSError, inst:
131 except OSError, inst:
132 if inst.errno != errno.ENOENT:
132 if inst.errno != errno.ENOENT:
133 raise
133 raise
134 finally:
134 finally:
135 wlock.release()
135 wlock.release()
136
136
137 def iscurrent(repo, mark=None, parents=None):
137 def iscurrent(repo, mark=None, parents=None):
138 '''Tell whether the current bookmark is also active
138 '''Tell whether the current bookmark is also active
139
139
140 I.e., the bookmark listed in .hg/bookmarks.current also points to a
140 I.e., the bookmark listed in .hg/bookmarks.current also points to a
141 parent of the working directory.
141 parent of the working directory.
142 '''
142 '''
143 if not mark:
143 if not mark:
144 mark = repo._bookmarkcurrent
144 mark = repo._bookmarkcurrent
145 if not parents:
145 if not parents:
146 parents = [p.node() for p in repo[None].parents()]
146 parents = [p.node() for p in repo[None].parents()]
147 marks = repo._bookmarks
147 marks = repo._bookmarks
148 return (mark in marks and marks[mark] in parents)
148 return (mark in marks and marks[mark] in parents)
149
149
150 def updatecurrentbookmark(repo, oldnode, curbranch):
150 def updatecurrentbookmark(repo, oldnode, curbranch):
151 try:
151 try:
152 return update(repo, oldnode, repo.branchtip(curbranch))
152 return update(repo, oldnode, repo.branchtip(curbranch))
153 except error.RepoLookupError:
153 except error.RepoLookupError:
154 if curbranch == "default": # no default branch!
154 if curbranch == "default": # no default branch!
155 return update(repo, oldnode, repo.lookup("tip"))
155 return update(repo, oldnode, repo.lookup("tip"))
156 else:
156 else:
157 raise util.Abort(_("branch %s not found") % curbranch)
157 raise util.Abort(_("branch %s not found") % curbranch)
158
158
159 def deletedivergent(repo, deletefrom, bm):
159 def deletedivergent(repo, deletefrom, bm):
160 '''Delete divergent versions of bm on nodes in deletefrom.
160 '''Delete divergent versions of bm on nodes in deletefrom.
161
161
162 Return True if at least one bookmark was deleted, False otherwise.'''
162 Return True if at least one bookmark was deleted, False otherwise.'''
163 deleted = False
163 deleted = False
164 marks = repo._bookmarks
164 marks = repo._bookmarks
165 divergent = [b for b in marks if b.split('@', 1)[0] == bm.split('@', 1)[0]]
165 divergent = [b for b in marks if b.split('@', 1)[0] == bm.split('@', 1)[0]]
166 for mark in divergent:
166 for mark in divergent:
167 if mark == '@' or '@' not in mark:
167 if mark == '@' or '@' not in mark:
168 # can't be divergent by definition
168 # can't be divergent by definition
169 continue
169 continue
170 if mark and marks[mark] in deletefrom:
170 if mark and marks[mark] in deletefrom:
171 if mark != bm:
171 if mark != bm:
172 del marks[mark]
172 del marks[mark]
173 deleted = True
173 deleted = True
174 return deleted
174 return deleted
175
175
176 def calculateupdate(ui, repo, checkout):
176 def calculateupdate(ui, repo, checkout):
177 '''Return a tuple (targetrev, movemarkfrom) indicating the rev to
177 '''Return a tuple (targetrev, movemarkfrom) indicating the rev to
178 check out and where to move the active bookmark from, if needed.'''
178 check out and where to move the active bookmark from, if needed.'''
179 movemarkfrom = None
179 movemarkfrom = None
180 if checkout is None:
180 if checkout is None:
181 curmark = repo._bookmarkcurrent
181 curmark = repo._bookmarkcurrent
182 if iscurrent(repo):
182 if iscurrent(repo):
183 movemarkfrom = repo['.'].node()
183 movemarkfrom = repo['.'].node()
184 elif curmark:
184 elif curmark:
185 ui.status(_("updating to active bookmark %s\n") % curmark)
185 ui.status(_("updating to active bookmark %s\n") % curmark)
186 checkout = curmark
186 checkout = curmark
187 return (checkout, movemarkfrom)
187 return (checkout, movemarkfrom)
188
188
189 def update(repo, parents, node):
189 def update(repo, parents, node):
190 deletefrom = parents
190 deletefrom = parents
191 marks = repo._bookmarks
191 marks = repo._bookmarks
192 update = False
192 update = False
193 cur = repo._bookmarkcurrent
193 cur = repo._bookmarkcurrent
194 if not cur:
194 if not cur:
195 return False
195 return False
196
196
197 if marks[cur] in parents:
197 if marks[cur] in parents:
198 new = repo[node]
198 new = repo[node]
199 divs = [repo[b] for b in marks
199 divs = [repo[b] for b in marks
200 if b.split('@', 1)[0] == cur.split('@', 1)[0]]
200 if b.split('@', 1)[0] == cur.split('@', 1)[0]]
201 anc = repo.changelog.ancestors([new.rev()])
201 anc = repo.changelog.ancestors([new.rev()])
202 deletefrom = [b.node() for b in divs if b.rev() in anc or b == new]
202 deletefrom = [b.node() for b in divs if b.rev() in anc or b == new]
203 if validdest(repo, repo[marks[cur]], new):
203 if validdest(repo, repo[marks[cur]], new):
204 marks[cur] = new.node()
204 marks[cur] = new.node()
205 update = True
205 update = True
206
206
207 if deletedivergent(repo, deletefrom, cur):
207 if deletedivergent(repo, deletefrom, cur):
208 update = True
208 update = True
209
209
210 if update:
210 if update:
211 marks.write()
211 marks.write()
212 return update
212 return update
213
213
214 def listbookmarks(repo):
214 def listbookmarks(repo):
215 # We may try to list bookmarks on a repo type that does not
215 # We may try to list bookmarks on a repo type that does not
216 # support it (e.g., statichttprepository).
216 # support it (e.g., statichttprepository).
217 marks = getattr(repo, '_bookmarks', {})
217 marks = getattr(repo, '_bookmarks', {})
218
218
219 d = {}
219 d = {}
220 hasnode = repo.changelog.hasnode
220 hasnode = repo.changelog.hasnode
221 for k, v in marks.iteritems():
221 for k, v in marks.iteritems():
222 # don't expose local divergent bookmarks
222 # don't expose local divergent bookmarks
223 if hasnode(v) and ('@' not in k or k.endswith('@')):
223 if hasnode(v) and ('@' not in k or k.endswith('@')):
224 d[k] = hex(v)
224 d[k] = hex(v)
225 return d
225 return d
226
226
227 def pushbookmark(repo, key, old, new):
227 def pushbookmark(repo, key, old, new):
228 w = repo.wlock()
228 w = repo.wlock()
229 try:
229 try:
230 marks = repo._bookmarks
230 marks = repo._bookmarks
231 existing = hex(marks.get(key, ''))
231 existing = hex(marks.get(key, ''))
232 if existing != old and existing != new:
232 if existing != old and existing != new:
233 return False
233 return False
234 if new == '':
234 if new == '':
235 del marks[key]
235 del marks[key]
236 else:
236 else:
237 if new not in repo:
237 if new not in repo:
238 return False
238 return False
239 marks[key] = repo[new].node()
239 marks[key] = repo[new].node()
240 marks.write()
240 marks.write()
241 return True
241 return True
242 finally:
242 finally:
243 w.release()
243 w.release()
244
244
245 def compare(repo, srcmarks, dstmarks,
245 def compare(repo, srcmarks, dstmarks,
246 srchex=None, dsthex=None, targets=None):
246 srchex=None, dsthex=None, targets=None):
247 '''Compare bookmarks between srcmarks and dstmarks
247 '''Compare bookmarks between srcmarks and dstmarks
248
248
249 This returns tuple "(addsrc, adddst, advsrc, advdst, diverge,
249 This returns tuple "(addsrc, adddst, advsrc, advdst, diverge,
250 differ, invalid)", each are list of bookmarks below:
250 differ, invalid)", each are list of bookmarks below:
251
251
252 :addsrc: added on src side (removed on dst side, perhaps)
252 :addsrc: added on src side (removed on dst side, perhaps)
253 :adddst: added on dst side (removed on src side, perhaps)
253 :adddst: added on dst side (removed on src side, perhaps)
254 :advsrc: advanced on src side
254 :advsrc: advanced on src side
255 :advdst: advanced on dst side
255 :advdst: advanced on dst side
256 :diverge: diverge
256 :diverge: diverge
257 :differ: changed, but changeset referred on src is unknown on dst
257 :differ: changed, but changeset referred on src is unknown on dst
258 :invalid: unknown on both side
258 :invalid: unknown on both side
259
259
260 Each elements of lists in result tuple is tuple "(bookmark name,
260 Each elements of lists in result tuple is tuple "(bookmark name,
261 changeset ID on source side, changeset ID on destination
261 changeset ID on source side, changeset ID on destination
262 side)". Each changeset IDs are 40 hexadecimal digit string or
262 side)". Each changeset IDs are 40 hexadecimal digit string or
263 None.
263 None.
264
264
265 Changeset IDs of tuples in "addsrc", "adddst", "differ" or
265 Changeset IDs of tuples in "addsrc", "adddst", "differ" or
266 "invalid" list may be unknown for repo.
266 "invalid" list may be unknown for repo.
267
267
268 This function expects that "srcmarks" and "dstmarks" return
268 This function expects that "srcmarks" and "dstmarks" return
269 changeset ID in 40 hexadecimal digit string for specified
269 changeset ID in 40 hexadecimal digit string for specified
270 bookmark. If not so (e.g. bmstore "repo._bookmarks" returning
270 bookmark. If not so (e.g. bmstore "repo._bookmarks" returning
271 binary value), "srchex" or "dsthex" should be specified to convert
271 binary value), "srchex" or "dsthex" should be specified to convert
272 into such form.
272 into such form.
273
273
274 If "targets" is specified, only bookmarks listed in it are
274 If "targets" is specified, only bookmarks listed in it are
275 examined.
275 examined.
276 '''
276 '''
277 if not srchex:
277 if not srchex:
278 srchex = lambda x: x
278 srchex = lambda x: x
279 if not dsthex:
279 if not dsthex:
280 dsthex = lambda x: x
280 dsthex = lambda x: x
281
281
282 if targets:
282 if targets:
283 bset = set(targets)
283 bset = set(targets)
284 else:
284 else:
285 srcmarkset = set(srcmarks)
285 srcmarkset = set(srcmarks)
286 dstmarkset = set(dstmarks)
286 dstmarkset = set(dstmarks)
287 bset = srcmarkset ^ dstmarkset
287 bset = srcmarkset ^ dstmarkset
288 for b in srcmarkset & dstmarkset:
288 for b in srcmarkset & dstmarkset:
289 if srchex(srcmarks[b]) != dsthex(dstmarks[b]):
289 if srchex(srcmarks[b]) != dsthex(dstmarks[b]):
290 bset.add(b)
290 bset.add(b)
291
291
292 results = ([], [], [], [], [], [], [])
292 results = ([], [], [], [], [], [], [])
293 addsrc = results[0].append
293 addsrc = results[0].append
294 adddst = results[1].append
294 adddst = results[1].append
295 advsrc = results[2].append
295 advsrc = results[2].append
296 advdst = results[3].append
296 advdst = results[3].append
297 diverge = results[4].append
297 diverge = results[4].append
298 differ = results[5].append
298 differ = results[5].append
299 invalid = results[6].append
299 invalid = results[6].append
300
300
301 for b in sorted(bset):
301 for b in sorted(bset):
302 if b not in srcmarks:
302 if b not in srcmarks:
303 if b in dstmarks:
303 if b in dstmarks:
304 adddst((b, None, dsthex(dstmarks[b])))
304 adddst((b, None, dsthex(dstmarks[b])))
305 else:
305 else:
306 invalid((b, None, None))
306 invalid((b, None, None))
307 elif b not in dstmarks:
307 elif b not in dstmarks:
308 addsrc((b, srchex(srcmarks[b]), None))
308 addsrc((b, srchex(srcmarks[b]), None))
309 else:
309 else:
310 scid = srchex(srcmarks[b])
310 scid = srchex(srcmarks[b])
311 dcid = dsthex(dstmarks[b])
311 dcid = dsthex(dstmarks[b])
312 if scid in repo and dcid in repo:
312 if scid in repo and dcid in repo:
313 sctx = repo[scid]
313 sctx = repo[scid]
314 dctx = repo[dcid]
314 dctx = repo[dcid]
315 if sctx.rev() < dctx.rev():
315 if sctx.rev() < dctx.rev():
316 if validdest(repo, sctx, dctx):
316 if validdest(repo, sctx, dctx):
317 advdst((b, scid, dcid))
317 advdst((b, scid, dcid))
318 else:
318 else:
319 diverge((b, scid, dcid))
319 diverge((b, scid, dcid))
320 else:
320 else:
321 if validdest(repo, dctx, sctx):
321 if validdest(repo, dctx, sctx):
322 advsrc((b, scid, dcid))
322 advsrc((b, scid, dcid))
323 else:
323 else:
324 diverge((b, scid, dcid))
324 diverge((b, scid, dcid))
325 else:
325 else:
326 # it is too expensive to examine in detail, in this case
326 # it is too expensive to examine in detail, in this case
327 differ((b, scid, dcid))
327 differ((b, scid, dcid))
328
328
329 return results
329 return results
330
330
331 def _diverge(ui, b, path, localmarks):
331 def _diverge(ui, b, path, localmarks):
332 if b == '@':
332 if b == '@':
333 b = ''
333 b = ''
334 # find a unique @ suffix
334 # find a unique @ suffix
335 for x in range(1, 100):
335 for x in range(1, 100):
336 n = '%s@%d' % (b, x)
336 n = '%s@%d' % (b, x)
337 if n not in localmarks:
337 if n not in localmarks:
338 break
338 break
339 # try to use an @pathalias suffix
339 # try to use an @pathalias suffix
340 # if an @pathalias already exists, we overwrite (update) it
340 # if an @pathalias already exists, we overwrite (update) it
341 if path.startswith("file:"):
341 if path.startswith("file:"):
342 path = util.url(path).path
342 path = util.url(path).path
343 for p, u in ui.configitems("paths"):
343 for p, u in ui.configitems("paths"):
344 if u.startswith("file:"):
344 if u.startswith("file:"):
345 u = util.url(u).path
345 u = util.url(u).path
346 if path == u:
346 if path == u:
347 n = '%s@%s' % (b, p)
347 n = '%s@%s' % (b, p)
348 return n
348 return n
349
349
350 def updatefromremote(ui, repo, remotemarks, path, explicit=()):
350 def updatefromremote(ui, repo, remotemarks, path, explicit=()):
351 ui.debug("checking for updated bookmarks\n")
351 ui.debug("checking for updated bookmarks\n")
352 localmarks = repo._bookmarks
352 localmarks = repo._bookmarks
353 (addsrc, adddst, advsrc, advdst, diverge, differ, invalid
353 (addsrc, adddst, advsrc, advdst, diverge, differ, invalid
354 ) = compare(repo, remotemarks, localmarks, dsthex=hex)
354 ) = compare(repo, remotemarks, localmarks, dsthex=hex)
355
355
356 status = ui.status
356 status = ui.status
357 warn = ui.warn
357 warn = ui.warn
358 if ui.configbool('ui', 'quietbookmarkmove', False):
358 if ui.configbool('ui', 'quietbookmarkmove', False):
359 status = warn = ui.debug
359 status = warn = ui.debug
360
360
361 explicit = set(explicit)
361 changed = []
362 changed = []
362 for b, scid, dcid in addsrc:
363 for b, scid, dcid in addsrc:
363 if scid in repo: # add remote bookmarks for changes we already have
364 if scid in repo: # add remote bookmarks for changes we already have
364 changed.append((b, bin(scid), status,
365 changed.append((b, bin(scid), status,
365 _("adding remote bookmark %s\n") % (b)))
366 _("adding remote bookmark %s\n") % (b)))
366 for b, scid, dcid in advsrc:
367 for b, scid, dcid in advsrc:
367 changed.append((b, bin(scid), status,
368 changed.append((b, bin(scid), status,
368 _("updating bookmark %s\n") % (b)))
369 _("updating bookmark %s\n") % (b)))
370 # remove normal movement from explicit set
371 explicit.difference_update(d[0] for d in changed)
372
369 for b, scid, dcid in diverge:
373 for b, scid, dcid in diverge:
370 db = _diverge(ui, b, path, localmarks)
374 if b in explicit:
371 changed.append((db, bin(scid), warn,
375 explicit.discard(b)
372 _("divergent bookmark %s stored as %s\n") % (b, db)))
376 changed.append((b, bin(scid), status,
377 _("importing bookmark %s\n") % (b, b)))
378 else:
379 db = _diverge(ui, b, path, localmarks)
380 changed.append((db, bin(scid), warn,
381 _("divergent bookmark %s stored as %s\n")
382 % (b, db)))
383 for b, scid, dcid in adddst + advdst:
384 if b in explicit:
385 explicit.discard(b)
386 changed.append((b, bin(scid), status,
387 _("importing bookmark %s\n") % (b, b)))
388
373 if changed:
389 if changed:
374 for b, node, writer, msg in sorted(changed):
390 for b, node, writer, msg in sorted(changed):
375 localmarks[b] = node
391 localmarks[b] = node
376 writer(msg)
392 writer(msg)
377 localmarks.write()
393 localmarks.write()
378 # update specified bookmarks
379 if explicit:
380 marks = repo._bookmarks
381 for b in explicit:
382 # explicit pull overrides local bookmark if any
383 repo.ui.status(_("importing bookmark %s\n") % b)
384 marks[b] = repo[remotemarks[b]].node()
385 marks.write()
386
394
387 def diff(ui, dst, src):
395 def diff(ui, dst, src):
388 ui.status(_("searching for changed bookmarks\n"))
396 ui.status(_("searching for changed bookmarks\n"))
389
397
390 smarks = src.listkeys('bookmarks')
398 smarks = src.listkeys('bookmarks')
391 dmarks = dst.listkeys('bookmarks')
399 dmarks = dst.listkeys('bookmarks')
392
400
393 diff = sorted(set(smarks) - set(dmarks))
401 diff = sorted(set(smarks) - set(dmarks))
394 for k in diff:
402 for k in diff:
395 mark = ui.debugflag and smarks[k] or smarks[k][:12]
403 mark = ui.debugflag and smarks[k] or smarks[k][:12]
396 ui.write(" %-25s %s\n" % (k, mark))
404 ui.write(" %-25s %s\n" % (k, mark))
397
405
398 if len(diff) <= 0:
406 if len(diff) <= 0:
399 ui.status(_("no changed bookmarks found\n"))
407 ui.status(_("no changed bookmarks found\n"))
400 return 1
408 return 1
401 return 0
409 return 0
402
410
403 def validdest(repo, old, new):
411 def validdest(repo, old, new):
404 """Is the new bookmark destination a valid update from the old one"""
412 """Is the new bookmark destination a valid update from the old one"""
405 repo = repo.unfiltered()
413 repo = repo.unfiltered()
406 if old == new:
414 if old == new:
407 # Old == new -> nothing to update.
415 # Old == new -> nothing to update.
408 return False
416 return False
409 elif not old:
417 elif not old:
410 # old is nullrev, anything is valid.
418 # old is nullrev, anything is valid.
411 # (new != nullrev has been excluded by the previous check)
419 # (new != nullrev has been excluded by the previous check)
412 return True
420 return True
413 elif repo.obsstore:
421 elif repo.obsstore:
414 return new.node() in obsolete.foreground(repo, [old.node()])
422 return new.node() in obsolete.foreground(repo, [old.node()])
415 else:
423 else:
416 # still an independent clause as it is lazyer (and therefore faster)
424 # still an independent clause as it is lazyer (and therefore faster)
417 return old.descendant(new)
425 return old.descendant(new)
@@ -1,446 +1,444 b''
1 #require serve
1 #require serve
2
2
3 $ cat << EOF >> $HGRCPATH
3 $ cat << EOF >> $HGRCPATH
4 > [ui]
4 > [ui]
5 > logtemplate={rev}:{node|short} {desc|firstline}
5 > logtemplate={rev}:{node|short} {desc|firstline}
6 > [phases]
6 > [phases]
7 > publish=False
7 > publish=False
8 > [extensions]
8 > [extensions]
9 > EOF
9 > EOF
10 $ cat > obs.py << EOF
10 $ cat > obs.py << EOF
11 > import mercurial.obsolete
11 > import mercurial.obsolete
12 > mercurial.obsolete._enabled = True
12 > mercurial.obsolete._enabled = True
13 > EOF
13 > EOF
14 $ echo "obs=${TESTTMP}/obs.py" >> $HGRCPATH
14 $ echo "obs=${TESTTMP}/obs.py" >> $HGRCPATH
15
15
16 initialize
16 initialize
17
17
18 $ hg init a
18 $ hg init a
19 $ cd a
19 $ cd a
20 $ echo 'test' > test
20 $ echo 'test' > test
21 $ hg commit -Am'test'
21 $ hg commit -Am'test'
22 adding test
22 adding test
23
23
24 set bookmarks
24 set bookmarks
25
25
26 $ hg bookmark X
26 $ hg bookmark X
27 $ hg bookmark Y
27 $ hg bookmark Y
28 $ hg bookmark Z
28 $ hg bookmark Z
29
29
30 import bookmark by name
30 import bookmark by name
31
31
32 $ hg init ../b
32 $ hg init ../b
33 $ cd ../b
33 $ cd ../b
34 $ hg book Y
34 $ hg book Y
35 $ hg book
35 $ hg book
36 * Y -1:000000000000
36 * Y -1:000000000000
37 $ hg pull ../a
37 $ hg pull ../a
38 pulling from ../a
38 pulling from ../a
39 requesting all changes
39 requesting all changes
40 adding changesets
40 adding changesets
41 adding manifests
41 adding manifests
42 adding file changes
42 adding file changes
43 added 1 changesets with 1 changes to 1 files
43 added 1 changesets with 1 changes to 1 files
44 adding remote bookmark X
44 adding remote bookmark X
45 updating bookmark Y
45 updating bookmark Y
46 adding remote bookmark Z
46 adding remote bookmark Z
47 (run 'hg update' to get a working copy)
47 (run 'hg update' to get a working copy)
48 $ hg bookmarks
48 $ hg bookmarks
49 X 0:4e3505fd9583
49 X 0:4e3505fd9583
50 * Y 0:4e3505fd9583
50 * Y 0:4e3505fd9583
51 Z 0:4e3505fd9583
51 Z 0:4e3505fd9583
52 $ hg debugpushkey ../a namespaces
52 $ hg debugpushkey ../a namespaces
53 bookmarks
53 bookmarks
54 namespaces
54 namespaces
55 obsolete
55 obsolete
56 phases
56 phases
57 $ hg debugpushkey ../a bookmarks
57 $ hg debugpushkey ../a bookmarks
58 X 4e3505fd95835d721066b76e75dbb8cc554d7f77
58 X 4e3505fd95835d721066b76e75dbb8cc554d7f77
59 Y 4e3505fd95835d721066b76e75dbb8cc554d7f77
59 Y 4e3505fd95835d721066b76e75dbb8cc554d7f77
60 Z 4e3505fd95835d721066b76e75dbb8cc554d7f77
60 Z 4e3505fd95835d721066b76e75dbb8cc554d7f77
61 $ hg pull -B X ../a
61 $ hg pull -B X ../a
62 pulling from ../a
62 pulling from ../a
63 no changes found
63 no changes found
64 importing bookmark X
65 $ hg bookmark
64 $ hg bookmark
66 X 0:4e3505fd9583
65 X 0:4e3505fd9583
67 * Y 0:4e3505fd9583
66 * Y 0:4e3505fd9583
68 Z 0:4e3505fd9583
67 Z 0:4e3505fd9583
69
68
70 export bookmark by name
69 export bookmark by name
71
70
72 $ hg bookmark W
71 $ hg bookmark W
73 $ hg bookmark foo
72 $ hg bookmark foo
74 $ hg bookmark foobar
73 $ hg bookmark foobar
75 $ hg push -B W ../a
74 $ hg push -B W ../a
76 pushing to ../a
75 pushing to ../a
77 searching for changes
76 searching for changes
78 no changes found
77 no changes found
79 exporting bookmark W
78 exporting bookmark W
80 [1]
79 [1]
81 $ hg -R ../a bookmarks
80 $ hg -R ../a bookmarks
82 W -1:000000000000
81 W -1:000000000000
83 X 0:4e3505fd9583
82 X 0:4e3505fd9583
84 Y 0:4e3505fd9583
83 Y 0:4e3505fd9583
85 * Z 0:4e3505fd9583
84 * Z 0:4e3505fd9583
86
85
87 delete a remote bookmark
86 delete a remote bookmark
88
87
89 $ hg book -d W
88 $ hg book -d W
90 $ hg push -B W ../a
89 $ hg push -B W ../a
91 pushing to ../a
90 pushing to ../a
92 searching for changes
91 searching for changes
93 no changes found
92 no changes found
94 deleting remote bookmark W
93 deleting remote bookmark W
95 [1]
94 [1]
96
95
97 push/pull name that doesn't exist
96 push/pull name that doesn't exist
98
97
99 $ hg push -B badname ../a
98 $ hg push -B badname ../a
100 pushing to ../a
99 pushing to ../a
101 searching for changes
100 searching for changes
102 bookmark badname does not exist on the local or remote repository!
101 bookmark badname does not exist on the local or remote repository!
103 no changes found
102 no changes found
104 [2]
103 [2]
105 $ hg pull -B anotherbadname ../a
104 $ hg pull -B anotherbadname ../a
106 pulling from ../a
105 pulling from ../a
107 abort: remote bookmark anotherbadname not found!
106 abort: remote bookmark anotherbadname not found!
108 [255]
107 [255]
109
108
110 divergent bookmarks
109 divergent bookmarks
111
110
112 $ cd ../a
111 $ cd ../a
113 $ echo c1 > f1
112 $ echo c1 > f1
114 $ hg ci -Am1
113 $ hg ci -Am1
115 adding f1
114 adding f1
116 $ hg book -f @
115 $ hg book -f @
117 $ hg book -f X
116 $ hg book -f X
118 $ hg book
117 $ hg book
119 @ 1:0d2164f0ce0d
118 @ 1:0d2164f0ce0d
120 * X 1:0d2164f0ce0d
119 * X 1:0d2164f0ce0d
121 Y 0:4e3505fd9583
120 Y 0:4e3505fd9583
122 Z 1:0d2164f0ce0d
121 Z 1:0d2164f0ce0d
123
122
124 $ cd ../b
123 $ cd ../b
125 $ hg up
124 $ hg up
126 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
125 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
127 updating bookmark foobar
126 updating bookmark foobar
128 $ echo c2 > f2
127 $ echo c2 > f2
129 $ hg ci -Am2
128 $ hg ci -Am2
130 adding f2
129 adding f2
131 $ hg book -if @
130 $ hg book -if @
132 $ hg book -if X
131 $ hg book -if X
133 $ hg book
132 $ hg book
134 @ 1:9b140be10808
133 @ 1:9b140be10808
135 X 1:9b140be10808
134 X 1:9b140be10808
136 Y 0:4e3505fd9583
135 Y 0:4e3505fd9583
137 Z 0:4e3505fd9583
136 Z 0:4e3505fd9583
138 foo -1:000000000000
137 foo -1:000000000000
139 * foobar 1:9b140be10808
138 * foobar 1:9b140be10808
140
139
141 $ hg pull --config paths.foo=../a foo
140 $ hg pull --config paths.foo=../a foo
142 pulling from $TESTTMP/a (glob)
141 pulling from $TESTTMP/a (glob)
143 searching for changes
142 searching for changes
144 adding changesets
143 adding changesets
145 adding manifests
144 adding manifests
146 adding file changes
145 adding file changes
147 added 1 changesets with 1 changes to 1 files (+1 heads)
146 added 1 changesets with 1 changes to 1 files (+1 heads)
148 divergent bookmark @ stored as @foo
147 divergent bookmark @ stored as @foo
149 divergent bookmark X stored as X@foo
148 divergent bookmark X stored as X@foo
150 updating bookmark Z
149 updating bookmark Z
151 (run 'hg heads' to see heads, 'hg merge' to merge)
150 (run 'hg heads' to see heads, 'hg merge' to merge)
152 $ hg book
151 $ hg book
153 @ 1:9b140be10808
152 @ 1:9b140be10808
154 @foo 2:0d2164f0ce0d
153 @foo 2:0d2164f0ce0d
155 X 1:9b140be10808
154 X 1:9b140be10808
156 X@foo 2:0d2164f0ce0d
155 X@foo 2:0d2164f0ce0d
157 Y 0:4e3505fd9583
156 Y 0:4e3505fd9583
158 Z 2:0d2164f0ce0d
157 Z 2:0d2164f0ce0d
159 foo -1:000000000000
158 foo -1:000000000000
160 * foobar 1:9b140be10808
159 * foobar 1:9b140be10808
161 $ hg push -f ../a
160 $ hg push -f ../a
162 pushing to ../a
161 pushing to ../a
163 searching for changes
162 searching for changes
164 adding changesets
163 adding changesets
165 adding manifests
164 adding manifests
166 adding file changes
165 adding file changes
167 added 1 changesets with 1 changes to 1 files (+1 heads)
166 added 1 changesets with 1 changes to 1 files (+1 heads)
168 $ hg -R ../a book
167 $ hg -R ../a book
169 @ 1:0d2164f0ce0d
168 @ 1:0d2164f0ce0d
170 * X 1:0d2164f0ce0d
169 * X 1:0d2164f0ce0d
171 Y 0:4e3505fd9583
170 Y 0:4e3505fd9583
172 Z 1:0d2164f0ce0d
171 Z 1:0d2164f0ce0d
173
172
174 revsets should not ignore divergent bookmarks
173 revsets should not ignore divergent bookmarks
175
174
176 $ hg bookmark -fr 1 Z
175 $ hg bookmark -fr 1 Z
177 $ hg log -r 'bookmark()' --template '{rev}:{node|short} {bookmarks}\n'
176 $ hg log -r 'bookmark()' --template '{rev}:{node|short} {bookmarks}\n'
178 0:4e3505fd9583 Y
177 0:4e3505fd9583 Y
179 1:9b140be10808 @ X Z foobar
178 1:9b140be10808 @ X Z foobar
180 2:0d2164f0ce0d @foo X@foo
179 2:0d2164f0ce0d @foo X@foo
181 $ hg log -r 'bookmark("X@foo")' --template '{rev}:{node|short} {bookmarks}\n'
180 $ hg log -r 'bookmark("X@foo")' --template '{rev}:{node|short} {bookmarks}\n'
182 2:0d2164f0ce0d @foo X@foo
181 2:0d2164f0ce0d @foo X@foo
183 $ hg log -r 'bookmark("re:X@foo")' --template '{rev}:{node|short} {bookmarks}\n'
182 $ hg log -r 'bookmark("re:X@foo")' --template '{rev}:{node|short} {bookmarks}\n'
184 2:0d2164f0ce0d @foo X@foo
183 2:0d2164f0ce0d @foo X@foo
185
184
186 update a remote bookmark from a non-head to a head
185 update a remote bookmark from a non-head to a head
187
186
188 $ hg up -q Y
187 $ hg up -q Y
189 $ echo c3 > f2
188 $ echo c3 > f2
190 $ hg ci -Am3
189 $ hg ci -Am3
191 adding f2
190 adding f2
192 created new head
191 created new head
193 $ hg push ../a
192 $ hg push ../a
194 pushing to ../a
193 pushing to ../a
195 searching for changes
194 searching for changes
196 adding changesets
195 adding changesets
197 adding manifests
196 adding manifests
198 adding file changes
197 adding file changes
199 added 1 changesets with 1 changes to 1 files (+1 heads)
198 added 1 changesets with 1 changes to 1 files (+1 heads)
200 updating bookmark Y
199 updating bookmark Y
201 $ hg -R ../a book
200 $ hg -R ../a book
202 @ 1:0d2164f0ce0d
201 @ 1:0d2164f0ce0d
203 * X 1:0d2164f0ce0d
202 * X 1:0d2164f0ce0d
204 Y 3:f6fc62dde3c0
203 Y 3:f6fc62dde3c0
205 Z 1:0d2164f0ce0d
204 Z 1:0d2164f0ce0d
206
205
207 update a bookmark in the middle of a client pulling changes
206 update a bookmark in the middle of a client pulling changes
208
207
209 $ cd ..
208 $ cd ..
210 $ hg clone -q a pull-race
209 $ hg clone -q a pull-race
211 $ hg clone -q pull-race pull-race2
210 $ hg clone -q pull-race pull-race2
212 $ cd pull-race
211 $ cd pull-race
213 $ hg up -q Y
212 $ hg up -q Y
214 $ echo c4 > f2
213 $ echo c4 > f2
215 $ hg ci -Am4
214 $ hg ci -Am4
216 $ echo c5 > f3
215 $ echo c5 > f3
217 $ cat <<EOF > .hg/hgrc
216 $ cat <<EOF > .hg/hgrc
218 > [hooks]
217 > [hooks]
219 > outgoing.makecommit = hg ci -Am5; echo committed in pull-race
218 > outgoing.makecommit = hg ci -Am5; echo committed in pull-race
220 > EOF
219 > EOF
221 $ cd ../pull-race2
220 $ cd ../pull-race2
222 $ hg pull
221 $ hg pull
223 pulling from $TESTTMP/pull-race (glob)
222 pulling from $TESTTMP/pull-race (glob)
224 searching for changes
223 searching for changes
225 adding changesets
224 adding changesets
226 adding f3
225 adding f3
227 committed in pull-race
226 committed in pull-race
228 adding manifests
227 adding manifests
229 adding file changes
228 adding file changes
230 added 1 changesets with 1 changes to 1 files
229 added 1 changesets with 1 changes to 1 files
231 updating bookmark Y
230 updating bookmark Y
232 (run 'hg update' to get a working copy)
231 (run 'hg update' to get a working copy)
233 $ hg book
232 $ hg book
234 * @ 1:0d2164f0ce0d
233 * @ 1:0d2164f0ce0d
235 X 1:0d2164f0ce0d
234 X 1:0d2164f0ce0d
236 Y 4:b0a5eff05604
235 Y 4:b0a5eff05604
237 Z 1:0d2164f0ce0d
236 Z 1:0d2164f0ce0d
238 $ cd ../b
237 $ cd ../b
239
238
240 diverging a remote bookmark fails
239 diverging a remote bookmark fails
241
240
242 $ hg up -q 4e3505fd9583
241 $ hg up -q 4e3505fd9583
243 $ echo c4 > f2
242 $ echo c4 > f2
244 $ hg ci -Am4
243 $ hg ci -Am4
245 adding f2
244 adding f2
246 created new head
245 created new head
247 $ echo c5 > f2
246 $ echo c5 > f2
248 $ hg ci -Am5
247 $ hg ci -Am5
249 $ hg log -G
248 $ hg log -G
250 @ 5:c922c0139ca0 5
249 @ 5:c922c0139ca0 5
251 |
250 |
252 o 4:4efff6d98829 4
251 o 4:4efff6d98829 4
253 |
252 |
254 | o 3:f6fc62dde3c0 3
253 | o 3:f6fc62dde3c0 3
255 |/
254 |/
256 | o 2:0d2164f0ce0d 1
255 | o 2:0d2164f0ce0d 1
257 |/
256 |/
258 | o 1:9b140be10808 2
257 | o 1:9b140be10808 2
259 |/
258 |/
260 o 0:4e3505fd9583 test
259 o 0:4e3505fd9583 test
261
260
262
261
263 $ hg book -f Y
262 $ hg book -f Y
264
263
265 $ cat <<EOF > ../a/.hg/hgrc
264 $ cat <<EOF > ../a/.hg/hgrc
266 > [web]
265 > [web]
267 > push_ssl = false
266 > push_ssl = false
268 > allow_push = *
267 > allow_push = *
269 > EOF
268 > EOF
270
269
271 $ hg -R ../a serve -p $HGPORT2 -d --pid-file=../hg2.pid
270 $ hg -R ../a serve -p $HGPORT2 -d --pid-file=../hg2.pid
272 $ cat ../hg2.pid >> $DAEMON_PIDS
271 $ cat ../hg2.pid >> $DAEMON_PIDS
273
272
274 $ hg push http://localhost:$HGPORT2/
273 $ hg push http://localhost:$HGPORT2/
275 pushing to http://localhost:$HGPORT2/
274 pushing to http://localhost:$HGPORT2/
276 searching for changes
275 searching for changes
277 abort: push creates new remote head c922c0139ca0 with bookmark 'Y'!
276 abort: push creates new remote head c922c0139ca0 with bookmark 'Y'!
278 (merge or see "hg help push" for details about pushing new heads)
277 (merge or see "hg help push" for details about pushing new heads)
279 [255]
278 [255]
280 $ hg -R ../a book
279 $ hg -R ../a book
281 @ 1:0d2164f0ce0d
280 @ 1:0d2164f0ce0d
282 * X 1:0d2164f0ce0d
281 * X 1:0d2164f0ce0d
283 Y 3:f6fc62dde3c0
282 Y 3:f6fc62dde3c0
284 Z 1:0d2164f0ce0d
283 Z 1:0d2164f0ce0d
285
284
286
285
287 Unrelated marker does not alter the decision
286 Unrelated marker does not alter the decision
288
287
289 $ hg debugobsolete aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
288 $ hg debugobsolete aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
290 $ hg push http://localhost:$HGPORT2/
289 $ hg push http://localhost:$HGPORT2/
291 pushing to http://localhost:$HGPORT2/
290 pushing to http://localhost:$HGPORT2/
292 searching for changes
291 searching for changes
293 abort: push creates new remote head c922c0139ca0 with bookmark 'Y'!
292 abort: push creates new remote head c922c0139ca0 with bookmark 'Y'!
294 (merge or see "hg help push" for details about pushing new heads)
293 (merge or see "hg help push" for details about pushing new heads)
295 [255]
294 [255]
296 $ hg -R ../a book
295 $ hg -R ../a book
297 @ 1:0d2164f0ce0d
296 @ 1:0d2164f0ce0d
298 * X 1:0d2164f0ce0d
297 * X 1:0d2164f0ce0d
299 Y 3:f6fc62dde3c0
298 Y 3:f6fc62dde3c0
300 Z 1:0d2164f0ce0d
299 Z 1:0d2164f0ce0d
301
300
302 Update to a successor works
301 Update to a successor works
303
302
304 $ hg id --debug -r 3
303 $ hg id --debug -r 3
305 f6fc62dde3c0771e29704af56ba4d8af77abcc2f
304 f6fc62dde3c0771e29704af56ba4d8af77abcc2f
306 $ hg id --debug -r 4
305 $ hg id --debug -r 4
307 4efff6d98829d9c824c621afd6e3f01865f5439f
306 4efff6d98829d9c824c621afd6e3f01865f5439f
308 $ hg id --debug -r 5
307 $ hg id --debug -r 5
309 c922c0139ca03858f655e4a2af4dd02796a63969 tip Y
308 c922c0139ca03858f655e4a2af4dd02796a63969 tip Y
310 $ hg debugobsolete f6fc62dde3c0771e29704af56ba4d8af77abcc2f cccccccccccccccccccccccccccccccccccccccc
309 $ hg debugobsolete f6fc62dde3c0771e29704af56ba4d8af77abcc2f cccccccccccccccccccccccccccccccccccccccc
311 $ hg debugobsolete cccccccccccccccccccccccccccccccccccccccc 4efff6d98829d9c824c621afd6e3f01865f5439f
310 $ hg debugobsolete cccccccccccccccccccccccccccccccccccccccc 4efff6d98829d9c824c621afd6e3f01865f5439f
312 $ hg push http://localhost:$HGPORT2/
311 $ hg push http://localhost:$HGPORT2/
313 pushing to http://localhost:$HGPORT2/
312 pushing to http://localhost:$HGPORT2/
314 searching for changes
313 searching for changes
315 remote: adding changesets
314 remote: adding changesets
316 remote: adding manifests
315 remote: adding manifests
317 remote: adding file changes
316 remote: adding file changes
318 remote: added 2 changesets with 2 changes to 1 files (+1 heads)
317 remote: added 2 changesets with 2 changes to 1 files (+1 heads)
319 updating bookmark Y
318 updating bookmark Y
320 $ hg -R ../a book
319 $ hg -R ../a book
321 @ 1:0d2164f0ce0d
320 @ 1:0d2164f0ce0d
322 * X 1:0d2164f0ce0d
321 * X 1:0d2164f0ce0d
323 Y 5:c922c0139ca0
322 Y 5:c922c0139ca0
324 Z 1:0d2164f0ce0d
323 Z 1:0d2164f0ce0d
325
324
326 hgweb
325 hgweb
327
326
328 $ cat <<EOF > .hg/hgrc
327 $ cat <<EOF > .hg/hgrc
329 > [web]
328 > [web]
330 > push_ssl = false
329 > push_ssl = false
331 > allow_push = *
330 > allow_push = *
332 > EOF
331 > EOF
333
332
334 $ hg serve -p $HGPORT -d --pid-file=../hg.pid -E errors.log
333 $ hg serve -p $HGPORT -d --pid-file=../hg.pid -E errors.log
335 $ cat ../hg.pid >> $DAEMON_PIDS
334 $ cat ../hg.pid >> $DAEMON_PIDS
336 $ cd ../a
335 $ cd ../a
337
336
338 $ hg debugpushkey http://localhost:$HGPORT/ namespaces
337 $ hg debugpushkey http://localhost:$HGPORT/ namespaces
339 bookmarks
338 bookmarks
340 namespaces
339 namespaces
341 obsolete
340 obsolete
342 phases
341 phases
343 $ hg debugpushkey http://localhost:$HGPORT/ bookmarks
342 $ hg debugpushkey http://localhost:$HGPORT/ bookmarks
344 @ 9b140be1080824d768c5a4691a564088eede71f9
343 @ 9b140be1080824d768c5a4691a564088eede71f9
345 X 9b140be1080824d768c5a4691a564088eede71f9
344 X 9b140be1080824d768c5a4691a564088eede71f9
346 Y c922c0139ca03858f655e4a2af4dd02796a63969
345 Y c922c0139ca03858f655e4a2af4dd02796a63969
347 Z 9b140be1080824d768c5a4691a564088eede71f9
346 Z 9b140be1080824d768c5a4691a564088eede71f9
348 foo 0000000000000000000000000000000000000000
347 foo 0000000000000000000000000000000000000000
349 foobar 9b140be1080824d768c5a4691a564088eede71f9
348 foobar 9b140be1080824d768c5a4691a564088eede71f9
350 $ hg out -B http://localhost:$HGPORT/
349 $ hg out -B http://localhost:$HGPORT/
351 comparing with http://localhost:$HGPORT/
350 comparing with http://localhost:$HGPORT/
352 searching for changed bookmarks
351 searching for changed bookmarks
353 no changed bookmarks found
352 no changed bookmarks found
354 [1]
353 [1]
355 $ hg push -B Z http://localhost:$HGPORT/
354 $ hg push -B Z http://localhost:$HGPORT/
356 pushing to http://localhost:$HGPORT/
355 pushing to http://localhost:$HGPORT/
357 searching for changes
356 searching for changes
358 no changes found
357 no changes found
359 updating bookmark Z
358 updating bookmark Z
360 [1]
359 [1]
361 $ hg book -d Z
360 $ hg book -d Z
362 $ hg in -B http://localhost:$HGPORT/
361 $ hg in -B http://localhost:$HGPORT/
363 comparing with http://localhost:$HGPORT/
362 comparing with http://localhost:$HGPORT/
364 searching for changed bookmarks
363 searching for changed bookmarks
365 Z 0d2164f0ce0d
364 Z 0d2164f0ce0d
366 foo 000000000000
365 foo 000000000000
367 foobar 9b140be10808
366 foobar 9b140be10808
368 $ hg pull -B Z http://localhost:$HGPORT/
367 $ hg pull -B Z http://localhost:$HGPORT/
369 pulling from http://localhost:$HGPORT/
368 pulling from http://localhost:$HGPORT/
370 no changes found
369 no changes found
371 divergent bookmark @ stored as @1
370 divergent bookmark @ stored as @1
372 divergent bookmark X stored as X@1
371 divergent bookmark X stored as X@1
373 adding remote bookmark Z
372 adding remote bookmark Z
374 adding remote bookmark foo
373 adding remote bookmark foo
375 adding remote bookmark foobar
374 adding remote bookmark foobar
376 importing bookmark Z
377 $ hg clone http://localhost:$HGPORT/ cloned-bookmarks
375 $ hg clone http://localhost:$HGPORT/ cloned-bookmarks
378 requesting all changes
376 requesting all changes
379 adding changesets
377 adding changesets
380 adding manifests
378 adding manifests
381 adding file changes
379 adding file changes
382 added 5 changesets with 5 changes to 3 files (+2 heads)
380 added 5 changesets with 5 changes to 3 files (+2 heads)
383 updating to bookmark @
381 updating to bookmark @
384 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
382 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
385 $ hg -R cloned-bookmarks bookmarks
383 $ hg -R cloned-bookmarks bookmarks
386 * @ 1:9b140be10808
384 * @ 1:9b140be10808
387 X 1:9b140be10808
385 X 1:9b140be10808
388 Y 4:c922c0139ca0
386 Y 4:c922c0139ca0
389 Z 2:0d2164f0ce0d
387 Z 2:0d2164f0ce0d
390 foo -1:000000000000
388 foo -1:000000000000
391 foobar 1:9b140be10808
389 foobar 1:9b140be10808
392
390
393 $ cd ..
391 $ cd ..
394
392
395 Pushing a bookmark should only push the changes required by that
393 Pushing a bookmark should only push the changes required by that
396 bookmark, not all outgoing changes:
394 bookmark, not all outgoing changes:
397 $ hg clone http://localhost:$HGPORT/ addmarks
395 $ hg clone http://localhost:$HGPORT/ addmarks
398 requesting all changes
396 requesting all changes
399 adding changesets
397 adding changesets
400 adding manifests
398 adding manifests
401 adding file changes
399 adding file changes
402 added 5 changesets with 5 changes to 3 files (+2 heads)
400 added 5 changesets with 5 changes to 3 files (+2 heads)
403 updating to bookmark @
401 updating to bookmark @
404 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
402 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
405 $ cd addmarks
403 $ cd addmarks
406 $ echo foo > foo
404 $ echo foo > foo
407 $ hg add foo
405 $ hg add foo
408 $ hg commit -m 'add foo'
406 $ hg commit -m 'add foo'
409 $ echo bar > bar
407 $ echo bar > bar
410 $ hg add bar
408 $ hg add bar
411 $ hg commit -m 'add bar'
409 $ hg commit -m 'add bar'
412 $ hg co "tip^"
410 $ hg co "tip^"
413 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
411 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
414 (leaving bookmark @)
412 (leaving bookmark @)
415 $ hg book add-foo
413 $ hg book add-foo
416 $ hg book -r tip add-bar
414 $ hg book -r tip add-bar
417 Note: this push *must* push only a single changeset, as that's the point
415 Note: this push *must* push only a single changeset, as that's the point
418 of this test.
416 of this test.
419 $ hg push -B add-foo --traceback
417 $ hg push -B add-foo --traceback
420 pushing to http://localhost:$HGPORT/
418 pushing to http://localhost:$HGPORT/
421 searching for changes
419 searching for changes
422 remote: adding changesets
420 remote: adding changesets
423 remote: adding manifests
421 remote: adding manifests
424 remote: adding file changes
422 remote: adding file changes
425 remote: added 1 changesets with 1 changes to 1 files
423 remote: added 1 changesets with 1 changes to 1 files
426 exporting bookmark add-foo
424 exporting bookmark add-foo
427
425
428 pushing a new bookmark on a new head does not require -f if -B is specified
426 pushing a new bookmark on a new head does not require -f if -B is specified
429
427
430 $ hg up -q X
428 $ hg up -q X
431 $ hg book W
429 $ hg book W
432 $ echo c5 > f2
430 $ echo c5 > f2
433 $ hg ci -Am5
431 $ hg ci -Am5
434 created new head
432 created new head
435 $ hg push -B W
433 $ hg push -B W
436 pushing to http://localhost:$HGPORT/
434 pushing to http://localhost:$HGPORT/
437 searching for changes
435 searching for changes
438 remote: adding changesets
436 remote: adding changesets
439 remote: adding manifests
437 remote: adding manifests
440 remote: adding file changes
438 remote: adding file changes
441 remote: added 1 changesets with 1 changes to 1 files (+1 heads)
439 remote: added 1 changesets with 1 changes to 1 files (+1 heads)
442 exporting bookmark W
440 exporting bookmark W
443 $ hg -R ../b id -r W
441 $ hg -R ../b id -r W
444 cc978a373a53 tip W
442 cc978a373a53 tip W
445
443
446 $ cd ..
444 $ cd ..
@@ -1,1195 +1,1193 b''
1
1
2 $ getmainid() {
2 $ getmainid() {
3 > hg -R main log --template '{node}\n' --rev "$1"
3 > hg -R main log --template '{node}\n' --rev "$1"
4 > }
4 > }
5
5
6 Create an extension to test bundle2 API
6 Create an extension to test bundle2 API
7
7
8 $ cat > bundle2.py << EOF
8 $ cat > bundle2.py << EOF
9 > """A small extension to test bundle2 implementation
9 > """A small extension to test bundle2 implementation
10 >
10 >
11 > Current bundle2 implementation is far too limited to be used in any core
11 > Current bundle2 implementation is far too limited to be used in any core
12 > code. We still need to be able to test it while it grow up.
12 > code. We still need to be able to test it while it grow up.
13 > """
13 > """
14 >
14 >
15 > import sys, os
15 > import sys, os
16 > from mercurial import cmdutil
16 > from mercurial import cmdutil
17 > from mercurial import util
17 > from mercurial import util
18 > from mercurial import bundle2
18 > from mercurial import bundle2
19 > from mercurial import scmutil
19 > from mercurial import scmutil
20 > from mercurial import discovery
20 > from mercurial import discovery
21 > from mercurial import changegroup
21 > from mercurial import changegroup
22 > from mercurial import error
22 > from mercurial import error
23 > from mercurial import obsolete
23 > from mercurial import obsolete
24 >
24 >
25 > obsolete._enabled = True
25 > obsolete._enabled = True
26 >
26 >
27 > try:
27 > try:
28 > import msvcrt
28 > import msvcrt
29 > msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
29 > msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
30 > msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
30 > msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
31 > msvcrt.setmode(sys.stderr.fileno(), os.O_BINARY)
31 > msvcrt.setmode(sys.stderr.fileno(), os.O_BINARY)
32 > except ImportError:
32 > except ImportError:
33 > pass
33 > pass
34 >
34 >
35 > cmdtable = {}
35 > cmdtable = {}
36 > command = cmdutil.command(cmdtable)
36 > command = cmdutil.command(cmdtable)
37 >
37 >
38 > ELEPHANTSSONG = """Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko
38 > ELEPHANTSSONG = """Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko
39 > Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
39 > Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
40 > Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko."""
40 > Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko."""
41 > assert len(ELEPHANTSSONG) == 178 # future test say 178 bytes, trust it.
41 > assert len(ELEPHANTSSONG) == 178 # future test say 178 bytes, trust it.
42 >
42 >
43 > @bundle2.parthandler('test:song')
43 > @bundle2.parthandler('test:song')
44 > def songhandler(op, part):
44 > def songhandler(op, part):
45 > """handle a "test:song" bundle2 part, printing the lyrics on stdin"""
45 > """handle a "test:song" bundle2 part, printing the lyrics on stdin"""
46 > op.ui.write('The choir starts singing:\n')
46 > op.ui.write('The choir starts singing:\n')
47 > verses = 0
47 > verses = 0
48 > for line in part.read().split('\n'):
48 > for line in part.read().split('\n'):
49 > op.ui.write(' %s\n' % line)
49 > op.ui.write(' %s\n' % line)
50 > verses += 1
50 > verses += 1
51 > op.records.add('song', {'verses': verses})
51 > op.records.add('song', {'verses': verses})
52 >
52 >
53 > @bundle2.parthandler('test:ping')
53 > @bundle2.parthandler('test:ping')
54 > def pinghandler(op, part):
54 > def pinghandler(op, part):
55 > op.ui.write('received ping request (id %i)\n' % part.id)
55 > op.ui.write('received ping request (id %i)\n' % part.id)
56 > if op.reply is not None and 'ping-pong' in op.reply.capabilities:
56 > if op.reply is not None and 'ping-pong' in op.reply.capabilities:
57 > op.ui.write_err('replying to ping request (id %i)\n' % part.id)
57 > op.ui.write_err('replying to ping request (id %i)\n' % part.id)
58 > op.reply.newpart('test:pong', [('in-reply-to', str(part.id))])
58 > op.reply.newpart('test:pong', [('in-reply-to', str(part.id))])
59 >
59 >
60 > @bundle2.parthandler('test:debugreply')
60 > @bundle2.parthandler('test:debugreply')
61 > def debugreply(op, part):
61 > def debugreply(op, part):
62 > """print data about the capacity of the bundle reply"""
62 > """print data about the capacity of the bundle reply"""
63 > if op.reply is None:
63 > if op.reply is None:
64 > op.ui.write('debugreply: no reply\n')
64 > op.ui.write('debugreply: no reply\n')
65 > else:
65 > else:
66 > op.ui.write('debugreply: capabilities:\n')
66 > op.ui.write('debugreply: capabilities:\n')
67 > for cap in sorted(op.reply.capabilities):
67 > for cap in sorted(op.reply.capabilities):
68 > op.ui.write('debugreply: %r\n' % cap)
68 > op.ui.write('debugreply: %r\n' % cap)
69 > for val in op.reply.capabilities[cap]:
69 > for val in op.reply.capabilities[cap]:
70 > op.ui.write('debugreply: %r\n' % val)
70 > op.ui.write('debugreply: %r\n' % val)
71 >
71 >
72 > @command('bundle2',
72 > @command('bundle2',
73 > [('', 'param', [], 'stream level parameter'),
73 > [('', 'param', [], 'stream level parameter'),
74 > ('', 'unknown', False, 'include an unknown mandatory part in the bundle'),
74 > ('', 'unknown', False, 'include an unknown mandatory part in the bundle'),
75 > ('', 'unknownparams', False, 'include an unknown part parameters in the bundle'),
75 > ('', 'unknownparams', False, 'include an unknown part parameters in the bundle'),
76 > ('', 'parts', False, 'include some arbitrary parts to the bundle'),
76 > ('', 'parts', False, 'include some arbitrary parts to the bundle'),
77 > ('', 'reply', False, 'produce a reply bundle'),
77 > ('', 'reply', False, 'produce a reply bundle'),
78 > ('', 'pushrace', False, 'includes a check:head part with unknown nodes'),
78 > ('', 'pushrace', False, 'includes a check:head part with unknown nodes'),
79 > ('r', 'rev', [], 'includes those changeset in the bundle'),],
79 > ('r', 'rev', [], 'includes those changeset in the bundle'),],
80 > '[OUTPUTFILE]')
80 > '[OUTPUTFILE]')
81 > def cmdbundle2(ui, repo, path=None, **opts):
81 > def cmdbundle2(ui, repo, path=None, **opts):
82 > """write a bundle2 container on standard ouput"""
82 > """write a bundle2 container on standard ouput"""
83 > bundler = bundle2.bundle20(ui)
83 > bundler = bundle2.bundle20(ui)
84 > for p in opts['param']:
84 > for p in opts['param']:
85 > p = p.split('=', 1)
85 > p = p.split('=', 1)
86 > try:
86 > try:
87 > bundler.addparam(*p)
87 > bundler.addparam(*p)
88 > except ValueError, exc:
88 > except ValueError, exc:
89 > raise util.Abort('%s' % exc)
89 > raise util.Abort('%s' % exc)
90 >
90 >
91 > if opts['reply']:
91 > if opts['reply']:
92 > capsstring = 'ping-pong\nelephants=babar,celeste\ncity%3D%21=celeste%2Cville'
92 > capsstring = 'ping-pong\nelephants=babar,celeste\ncity%3D%21=celeste%2Cville'
93 > bundler.newpart('b2x:replycaps', data=capsstring)
93 > bundler.newpart('b2x:replycaps', data=capsstring)
94 >
94 >
95 > if opts['pushrace']:
95 > if opts['pushrace']:
96 > # also serve to test the assignement of data outside of init
96 > # also serve to test the assignement of data outside of init
97 > part = bundler.newpart('b2x:check:heads')
97 > part = bundler.newpart('b2x:check:heads')
98 > part.data = '01234567890123456789'
98 > part.data = '01234567890123456789'
99 >
99 >
100 > revs = opts['rev']
100 > revs = opts['rev']
101 > if 'rev' in opts:
101 > if 'rev' in opts:
102 > revs = scmutil.revrange(repo, opts['rev'])
102 > revs = scmutil.revrange(repo, opts['rev'])
103 > if revs:
103 > if revs:
104 > # very crude version of a changegroup part creation
104 > # very crude version of a changegroup part creation
105 > bundled = repo.revs('%ld::%ld', revs, revs)
105 > bundled = repo.revs('%ld::%ld', revs, revs)
106 > headmissing = [c.node() for c in repo.set('heads(%ld)', revs)]
106 > headmissing = [c.node() for c in repo.set('heads(%ld)', revs)]
107 > headcommon = [c.node() for c in repo.set('parents(%ld) - %ld', revs, revs)]
107 > headcommon = [c.node() for c in repo.set('parents(%ld) - %ld', revs, revs)]
108 > outgoing = discovery.outgoing(repo.changelog, headcommon, headmissing)
108 > outgoing = discovery.outgoing(repo.changelog, headcommon, headmissing)
109 > cg = changegroup.getlocalchangegroup(repo, 'test:bundle2', outgoing, None)
109 > cg = changegroup.getlocalchangegroup(repo, 'test:bundle2', outgoing, None)
110 > bundler.newpart('b2x:changegroup', data=cg.getchunks())
110 > bundler.newpart('b2x:changegroup', data=cg.getchunks())
111 >
111 >
112 > if opts['parts']:
112 > if opts['parts']:
113 > bundler.newpart('test:empty')
113 > bundler.newpart('test:empty')
114 > # add a second one to make sure we handle multiple parts
114 > # add a second one to make sure we handle multiple parts
115 > bundler.newpart('test:empty')
115 > bundler.newpart('test:empty')
116 > bundler.newpart('test:song', data=ELEPHANTSSONG)
116 > bundler.newpart('test:song', data=ELEPHANTSSONG)
117 > bundler.newpart('test:debugreply')
117 > bundler.newpart('test:debugreply')
118 > mathpart = bundler.newpart('test:math')
118 > mathpart = bundler.newpart('test:math')
119 > mathpart.addparam('pi', '3.14')
119 > mathpart.addparam('pi', '3.14')
120 > mathpart.addparam('e', '2.72')
120 > mathpart.addparam('e', '2.72')
121 > mathpart.addparam('cooking', 'raw', mandatory=False)
121 > mathpart.addparam('cooking', 'raw', mandatory=False)
122 > mathpart.data = '42'
122 > mathpart.data = '42'
123 > # advisory known part with unknown mandatory param
123 > # advisory known part with unknown mandatory param
124 > bundler.newpart('test:song', [('randomparam','')])
124 > bundler.newpart('test:song', [('randomparam','')])
125 > if opts['unknown']:
125 > if opts['unknown']:
126 > bundler.newpart('test:UNKNOWN', data='some random content')
126 > bundler.newpart('test:UNKNOWN', data='some random content')
127 > if opts['unknownparams']:
127 > if opts['unknownparams']:
128 > bundler.newpart('test:SONG', [('randomparams', '')])
128 > bundler.newpart('test:SONG', [('randomparams', '')])
129 > if opts['parts']:
129 > if opts['parts']:
130 > bundler.newpart('test:ping')
130 > bundler.newpart('test:ping')
131 >
131 >
132 > if path is None:
132 > if path is None:
133 > file = sys.stdout
133 > file = sys.stdout
134 > else:
134 > else:
135 > file = open(path, 'wb')
135 > file = open(path, 'wb')
136 >
136 >
137 > for chunk in bundler.getchunks():
137 > for chunk in bundler.getchunks():
138 > file.write(chunk)
138 > file.write(chunk)
139 >
139 >
140 > @command('unbundle2', [], '')
140 > @command('unbundle2', [], '')
141 > def cmdunbundle2(ui, repo, replypath=None):
141 > def cmdunbundle2(ui, repo, replypath=None):
142 > """process a bundle2 stream from stdin on the current repo"""
142 > """process a bundle2 stream from stdin on the current repo"""
143 > try:
143 > try:
144 > tr = None
144 > tr = None
145 > lock = repo.lock()
145 > lock = repo.lock()
146 > tr = repo.transaction('processbundle')
146 > tr = repo.transaction('processbundle')
147 > try:
147 > try:
148 > unbundler = bundle2.unbundle20(ui, sys.stdin)
148 > unbundler = bundle2.unbundle20(ui, sys.stdin)
149 > op = bundle2.processbundle(repo, unbundler, lambda: tr)
149 > op = bundle2.processbundle(repo, unbundler, lambda: tr)
150 > tr.close()
150 > tr.close()
151 > except error.BundleValueError, exc:
151 > except error.BundleValueError, exc:
152 > raise util.Abort('missing support for %s' % exc)
152 > raise util.Abort('missing support for %s' % exc)
153 > except error.PushRaced, exc:
153 > except error.PushRaced, exc:
154 > raise util.Abort('push race: %s' % exc)
154 > raise util.Abort('push race: %s' % exc)
155 > finally:
155 > finally:
156 > if tr is not None:
156 > if tr is not None:
157 > tr.release()
157 > tr.release()
158 > lock.release()
158 > lock.release()
159 > remains = sys.stdin.read()
159 > remains = sys.stdin.read()
160 > ui.write('%i unread bytes\n' % len(remains))
160 > ui.write('%i unread bytes\n' % len(remains))
161 > if op.records['song']:
161 > if op.records['song']:
162 > totalverses = sum(r['verses'] for r in op.records['song'])
162 > totalverses = sum(r['verses'] for r in op.records['song'])
163 > ui.write('%i total verses sung\n' % totalverses)
163 > ui.write('%i total verses sung\n' % totalverses)
164 > for rec in op.records['changegroup']:
164 > for rec in op.records['changegroup']:
165 > ui.write('addchangegroup return: %i\n' % rec['return'])
165 > ui.write('addchangegroup return: %i\n' % rec['return'])
166 > if op.reply is not None and replypath is not None:
166 > if op.reply is not None and replypath is not None:
167 > file = open(replypath, 'wb')
167 > file = open(replypath, 'wb')
168 > for chunk in op.reply.getchunks():
168 > for chunk in op.reply.getchunks():
169 > file.write(chunk)
169 > file.write(chunk)
170 >
170 >
171 > @command('statbundle2', [], '')
171 > @command('statbundle2', [], '')
172 > def cmdstatbundle2(ui, repo):
172 > def cmdstatbundle2(ui, repo):
173 > """print statistic on the bundle2 container read from stdin"""
173 > """print statistic on the bundle2 container read from stdin"""
174 > unbundler = bundle2.unbundle20(ui, sys.stdin)
174 > unbundler = bundle2.unbundle20(ui, sys.stdin)
175 > try:
175 > try:
176 > params = unbundler.params
176 > params = unbundler.params
177 > except error.BundleValueError, exc:
177 > except error.BundleValueError, exc:
178 > raise util.Abort('unknown parameters: %s' % exc)
178 > raise util.Abort('unknown parameters: %s' % exc)
179 > ui.write('options count: %i\n' % len(params))
179 > ui.write('options count: %i\n' % len(params))
180 > for key in sorted(params):
180 > for key in sorted(params):
181 > ui.write('- %s\n' % key)
181 > ui.write('- %s\n' % key)
182 > value = params[key]
182 > value = params[key]
183 > if value is not None:
183 > if value is not None:
184 > ui.write(' %s\n' % value)
184 > ui.write(' %s\n' % value)
185 > count = 0
185 > count = 0
186 > for p in unbundler.iterparts():
186 > for p in unbundler.iterparts():
187 > count += 1
187 > count += 1
188 > ui.write(' :%s:\n' % p.type)
188 > ui.write(' :%s:\n' % p.type)
189 > ui.write(' mandatory: %i\n' % len(p.mandatoryparams))
189 > ui.write(' mandatory: %i\n' % len(p.mandatoryparams))
190 > ui.write(' advisory: %i\n' % len(p.advisoryparams))
190 > ui.write(' advisory: %i\n' % len(p.advisoryparams))
191 > ui.write(' payload: %i bytes\n' % len(p.read()))
191 > ui.write(' payload: %i bytes\n' % len(p.read()))
192 > ui.write('parts count: %i\n' % count)
192 > ui.write('parts count: %i\n' % count)
193 > EOF
193 > EOF
194 $ cat >> $HGRCPATH << EOF
194 $ cat >> $HGRCPATH << EOF
195 > [extensions]
195 > [extensions]
196 > bundle2=$TESTTMP/bundle2.py
196 > bundle2=$TESTTMP/bundle2.py
197 > [experimental]
197 > [experimental]
198 > bundle2-exp=True
198 > bundle2-exp=True
199 > [ui]
199 > [ui]
200 > ssh=python "$TESTDIR/dummyssh"
200 > ssh=python "$TESTDIR/dummyssh"
201 > logtemplate={rev}:{node|short} {phase} {author} {bookmarks} {desc|firstline}
201 > logtemplate={rev}:{node|short} {phase} {author} {bookmarks} {desc|firstline}
202 > [web]
202 > [web]
203 > push_ssl = false
203 > push_ssl = false
204 > allow_push = *
204 > allow_push = *
205 > [phases]
205 > [phases]
206 > publish=False
206 > publish=False
207 > EOF
207 > EOF
208
208
209 The extension requires a repo (currently unused)
209 The extension requires a repo (currently unused)
210
210
211 $ hg init main
211 $ hg init main
212 $ cd main
212 $ cd main
213 $ touch a
213 $ touch a
214 $ hg add a
214 $ hg add a
215 $ hg commit -m 'a'
215 $ hg commit -m 'a'
216
216
217
217
218 Empty bundle
218 Empty bundle
219 =================
219 =================
220
220
221 - no option
221 - no option
222 - no parts
222 - no parts
223
223
224 Test bundling
224 Test bundling
225
225
226 $ hg bundle2
226 $ hg bundle2
227 HG2X\x00\x00\x00\x00 (no-eol) (esc)
227 HG2X\x00\x00\x00\x00 (no-eol) (esc)
228
228
229 Test unbundling
229 Test unbundling
230
230
231 $ hg bundle2 | hg statbundle2
231 $ hg bundle2 | hg statbundle2
232 options count: 0
232 options count: 0
233 parts count: 0
233 parts count: 0
234
234
235 Test old style bundle are detected and refused
235 Test old style bundle are detected and refused
236
236
237 $ hg bundle --all ../bundle.hg
237 $ hg bundle --all ../bundle.hg
238 1 changesets found
238 1 changesets found
239 $ hg statbundle2 < ../bundle.hg
239 $ hg statbundle2 < ../bundle.hg
240 abort: unknown bundle version 10
240 abort: unknown bundle version 10
241 [255]
241 [255]
242
242
243 Test parameters
243 Test parameters
244 =================
244 =================
245
245
246 - some options
246 - some options
247 - no parts
247 - no parts
248
248
249 advisory parameters, no value
249 advisory parameters, no value
250 -------------------------------
250 -------------------------------
251
251
252 Simplest possible parameters form
252 Simplest possible parameters form
253
253
254 Test generation simple option
254 Test generation simple option
255
255
256 $ hg bundle2 --param 'caution'
256 $ hg bundle2 --param 'caution'
257 HG2X\x00\x07caution\x00\x00 (no-eol) (esc)
257 HG2X\x00\x07caution\x00\x00 (no-eol) (esc)
258
258
259 Test unbundling
259 Test unbundling
260
260
261 $ hg bundle2 --param 'caution' | hg statbundle2
261 $ hg bundle2 --param 'caution' | hg statbundle2
262 options count: 1
262 options count: 1
263 - caution
263 - caution
264 parts count: 0
264 parts count: 0
265
265
266 Test generation multiple option
266 Test generation multiple option
267
267
268 $ hg bundle2 --param 'caution' --param 'meal'
268 $ hg bundle2 --param 'caution' --param 'meal'
269 HG2X\x00\x0ccaution meal\x00\x00 (no-eol) (esc)
269 HG2X\x00\x0ccaution meal\x00\x00 (no-eol) (esc)
270
270
271 Test unbundling
271 Test unbundling
272
272
273 $ hg bundle2 --param 'caution' --param 'meal' | hg statbundle2
273 $ hg bundle2 --param 'caution' --param 'meal' | hg statbundle2
274 options count: 2
274 options count: 2
275 - caution
275 - caution
276 - meal
276 - meal
277 parts count: 0
277 parts count: 0
278
278
279 advisory parameters, with value
279 advisory parameters, with value
280 -------------------------------
280 -------------------------------
281
281
282 Test generation
282 Test generation
283
283
284 $ hg bundle2 --param 'caution' --param 'meal=vegan' --param 'elephants'
284 $ hg bundle2 --param 'caution' --param 'meal=vegan' --param 'elephants'
285 HG2X\x00\x1ccaution meal=vegan elephants\x00\x00 (no-eol) (esc)
285 HG2X\x00\x1ccaution meal=vegan elephants\x00\x00 (no-eol) (esc)
286
286
287 Test unbundling
287 Test unbundling
288
288
289 $ hg bundle2 --param 'caution' --param 'meal=vegan' --param 'elephants' | hg statbundle2
289 $ hg bundle2 --param 'caution' --param 'meal=vegan' --param 'elephants' | hg statbundle2
290 options count: 3
290 options count: 3
291 - caution
291 - caution
292 - elephants
292 - elephants
293 - meal
293 - meal
294 vegan
294 vegan
295 parts count: 0
295 parts count: 0
296
296
297 parameter with special char in value
297 parameter with special char in value
298 ---------------------------------------------------
298 ---------------------------------------------------
299
299
300 Test generation
300 Test generation
301
301
302 $ hg bundle2 --param 'e|! 7/=babar%#==tutu' --param simple
302 $ hg bundle2 --param 'e|! 7/=babar%#==tutu' --param simple
303 HG2X\x00)e%7C%21%207/=babar%25%23%3D%3Dtutu simple\x00\x00 (no-eol) (esc)
303 HG2X\x00)e%7C%21%207/=babar%25%23%3D%3Dtutu simple\x00\x00 (no-eol) (esc)
304
304
305 Test unbundling
305 Test unbundling
306
306
307 $ hg bundle2 --param 'e|! 7/=babar%#==tutu' --param simple | hg statbundle2
307 $ hg bundle2 --param 'e|! 7/=babar%#==tutu' --param simple | hg statbundle2
308 options count: 2
308 options count: 2
309 - e|! 7/
309 - e|! 7/
310 babar%#==tutu
310 babar%#==tutu
311 - simple
311 - simple
312 parts count: 0
312 parts count: 0
313
313
314 Test unknown mandatory option
314 Test unknown mandatory option
315 ---------------------------------------------------
315 ---------------------------------------------------
316
316
317 $ hg bundle2 --param 'Gravity' | hg statbundle2
317 $ hg bundle2 --param 'Gravity' | hg statbundle2
318 abort: unknown parameters: Stream Parameter - Gravity
318 abort: unknown parameters: Stream Parameter - Gravity
319 [255]
319 [255]
320
320
321 Test debug output
321 Test debug output
322 ---------------------------------------------------
322 ---------------------------------------------------
323
323
324 bundling debug
324 bundling debug
325
325
326 $ hg bundle2 --debug --param 'e|! 7/=babar%#==tutu' --param simple ../out.hg2
326 $ hg bundle2 --debug --param 'e|! 7/=babar%#==tutu' --param simple ../out.hg2
327 start emission of HG2X stream
327 start emission of HG2X stream
328 bundle parameter: e%7C%21%207/=babar%25%23%3D%3Dtutu simple
328 bundle parameter: e%7C%21%207/=babar%25%23%3D%3Dtutu simple
329 start of parts
329 start of parts
330 end of bundle
330 end of bundle
331
331
332 file content is ok
332 file content is ok
333
333
334 $ cat ../out.hg2
334 $ cat ../out.hg2
335 HG2X\x00)e%7C%21%207/=babar%25%23%3D%3Dtutu simple\x00\x00 (no-eol) (esc)
335 HG2X\x00)e%7C%21%207/=babar%25%23%3D%3Dtutu simple\x00\x00 (no-eol) (esc)
336
336
337 unbundling debug
337 unbundling debug
338
338
339 $ hg statbundle2 --debug < ../out.hg2
339 $ hg statbundle2 --debug < ../out.hg2
340 start processing of HG2X stream
340 start processing of HG2X stream
341 reading bundle2 stream parameters
341 reading bundle2 stream parameters
342 ignoring unknown parameter 'e|! 7/'
342 ignoring unknown parameter 'e|! 7/'
343 ignoring unknown parameter 'simple'
343 ignoring unknown parameter 'simple'
344 options count: 2
344 options count: 2
345 - e|! 7/
345 - e|! 7/
346 babar%#==tutu
346 babar%#==tutu
347 - simple
347 - simple
348 start extraction of bundle2 parts
348 start extraction of bundle2 parts
349 part header size: 0
349 part header size: 0
350 end of bundle2 stream
350 end of bundle2 stream
351 parts count: 0
351 parts count: 0
352
352
353
353
354 Test buggy input
354 Test buggy input
355 ---------------------------------------------------
355 ---------------------------------------------------
356
356
357 empty parameter name
357 empty parameter name
358
358
359 $ hg bundle2 --param '' --quiet
359 $ hg bundle2 --param '' --quiet
360 abort: empty parameter name
360 abort: empty parameter name
361 [255]
361 [255]
362
362
363 bad parameter name
363 bad parameter name
364
364
365 $ hg bundle2 --param 42babar
365 $ hg bundle2 --param 42babar
366 abort: non letter first character: '42babar'
366 abort: non letter first character: '42babar'
367 [255]
367 [255]
368
368
369
369
370 Test part
370 Test part
371 =================
371 =================
372
372
373 $ hg bundle2 --parts ../parts.hg2 --debug
373 $ hg bundle2 --parts ../parts.hg2 --debug
374 start emission of HG2X stream
374 start emission of HG2X stream
375 bundle parameter:
375 bundle parameter:
376 start of parts
376 start of parts
377 bundle part: "test:empty"
377 bundle part: "test:empty"
378 bundle part: "test:empty"
378 bundle part: "test:empty"
379 bundle part: "test:song"
379 bundle part: "test:song"
380 bundle part: "test:debugreply"
380 bundle part: "test:debugreply"
381 bundle part: "test:math"
381 bundle part: "test:math"
382 bundle part: "test:song"
382 bundle part: "test:song"
383 bundle part: "test:ping"
383 bundle part: "test:ping"
384 end of bundle
384 end of bundle
385
385
386 $ cat ../parts.hg2
386 $ cat ../parts.hg2
387 HG2X\x00\x00\x00\x11 (esc)
387 HG2X\x00\x00\x00\x11 (esc)
388 test:empty\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11 (esc)
388 test:empty\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11 (esc)
389 test:empty\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x10 test:song\x00\x00\x00\x02\x00\x00\x00\x00\x00\xb2Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko (esc)
389 test:empty\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x10 test:song\x00\x00\x00\x02\x00\x00\x00\x00\x00\xb2Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko (esc)
390 Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
390 Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
391 Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko.\x00\x00\x00\x00\x00\x16\x0ftest:debugreply\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00+ test:math\x00\x00\x00\x04\x02\x01\x02\x04\x01\x04\x07\x03pi3.14e2.72cookingraw\x00\x00\x00\x0242\x00\x00\x00\x00\x00\x1d test:song\x00\x00\x00\x05\x01\x00\x0b\x00randomparam\x00\x00\x00\x00\x00\x10 test:ping\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00 (no-eol) (esc)
391 Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko.\x00\x00\x00\x00\x00\x16\x0ftest:debugreply\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00+ test:math\x00\x00\x00\x04\x02\x01\x02\x04\x01\x04\x07\x03pi3.14e2.72cookingraw\x00\x00\x00\x0242\x00\x00\x00\x00\x00\x1d test:song\x00\x00\x00\x05\x01\x00\x0b\x00randomparam\x00\x00\x00\x00\x00\x10 test:ping\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00 (no-eol) (esc)
392
392
393
393
394 $ hg statbundle2 < ../parts.hg2
394 $ hg statbundle2 < ../parts.hg2
395 options count: 0
395 options count: 0
396 :test:empty:
396 :test:empty:
397 mandatory: 0
397 mandatory: 0
398 advisory: 0
398 advisory: 0
399 payload: 0 bytes
399 payload: 0 bytes
400 :test:empty:
400 :test:empty:
401 mandatory: 0
401 mandatory: 0
402 advisory: 0
402 advisory: 0
403 payload: 0 bytes
403 payload: 0 bytes
404 :test:song:
404 :test:song:
405 mandatory: 0
405 mandatory: 0
406 advisory: 0
406 advisory: 0
407 payload: 178 bytes
407 payload: 178 bytes
408 :test:debugreply:
408 :test:debugreply:
409 mandatory: 0
409 mandatory: 0
410 advisory: 0
410 advisory: 0
411 payload: 0 bytes
411 payload: 0 bytes
412 :test:math:
412 :test:math:
413 mandatory: 2
413 mandatory: 2
414 advisory: 1
414 advisory: 1
415 payload: 2 bytes
415 payload: 2 bytes
416 :test:song:
416 :test:song:
417 mandatory: 1
417 mandatory: 1
418 advisory: 0
418 advisory: 0
419 payload: 0 bytes
419 payload: 0 bytes
420 :test:ping:
420 :test:ping:
421 mandatory: 0
421 mandatory: 0
422 advisory: 0
422 advisory: 0
423 payload: 0 bytes
423 payload: 0 bytes
424 parts count: 7
424 parts count: 7
425
425
426 $ hg statbundle2 --debug < ../parts.hg2
426 $ hg statbundle2 --debug < ../parts.hg2
427 start processing of HG2X stream
427 start processing of HG2X stream
428 reading bundle2 stream parameters
428 reading bundle2 stream parameters
429 options count: 0
429 options count: 0
430 start extraction of bundle2 parts
430 start extraction of bundle2 parts
431 part header size: 17
431 part header size: 17
432 part type: "test:empty"
432 part type: "test:empty"
433 part id: "0"
433 part id: "0"
434 part parameters: 0
434 part parameters: 0
435 :test:empty:
435 :test:empty:
436 mandatory: 0
436 mandatory: 0
437 advisory: 0
437 advisory: 0
438 payload chunk size: 0
438 payload chunk size: 0
439 payload: 0 bytes
439 payload: 0 bytes
440 part header size: 17
440 part header size: 17
441 part type: "test:empty"
441 part type: "test:empty"
442 part id: "1"
442 part id: "1"
443 part parameters: 0
443 part parameters: 0
444 :test:empty:
444 :test:empty:
445 mandatory: 0
445 mandatory: 0
446 advisory: 0
446 advisory: 0
447 payload chunk size: 0
447 payload chunk size: 0
448 payload: 0 bytes
448 payload: 0 bytes
449 part header size: 16
449 part header size: 16
450 part type: "test:song"
450 part type: "test:song"
451 part id: "2"
451 part id: "2"
452 part parameters: 0
452 part parameters: 0
453 :test:song:
453 :test:song:
454 mandatory: 0
454 mandatory: 0
455 advisory: 0
455 advisory: 0
456 payload chunk size: 178
456 payload chunk size: 178
457 payload chunk size: 0
457 payload chunk size: 0
458 payload: 178 bytes
458 payload: 178 bytes
459 part header size: 22
459 part header size: 22
460 part type: "test:debugreply"
460 part type: "test:debugreply"
461 part id: "3"
461 part id: "3"
462 part parameters: 0
462 part parameters: 0
463 :test:debugreply:
463 :test:debugreply:
464 mandatory: 0
464 mandatory: 0
465 advisory: 0
465 advisory: 0
466 payload chunk size: 0
466 payload chunk size: 0
467 payload: 0 bytes
467 payload: 0 bytes
468 part header size: 43
468 part header size: 43
469 part type: "test:math"
469 part type: "test:math"
470 part id: "4"
470 part id: "4"
471 part parameters: 3
471 part parameters: 3
472 :test:math:
472 :test:math:
473 mandatory: 2
473 mandatory: 2
474 advisory: 1
474 advisory: 1
475 payload chunk size: 2
475 payload chunk size: 2
476 payload chunk size: 0
476 payload chunk size: 0
477 payload: 2 bytes
477 payload: 2 bytes
478 part header size: 29
478 part header size: 29
479 part type: "test:song"
479 part type: "test:song"
480 part id: "5"
480 part id: "5"
481 part parameters: 1
481 part parameters: 1
482 :test:song:
482 :test:song:
483 mandatory: 1
483 mandatory: 1
484 advisory: 0
484 advisory: 0
485 payload chunk size: 0
485 payload chunk size: 0
486 payload: 0 bytes
486 payload: 0 bytes
487 part header size: 16
487 part header size: 16
488 part type: "test:ping"
488 part type: "test:ping"
489 part id: "6"
489 part id: "6"
490 part parameters: 0
490 part parameters: 0
491 :test:ping:
491 :test:ping:
492 mandatory: 0
492 mandatory: 0
493 advisory: 0
493 advisory: 0
494 payload chunk size: 0
494 payload chunk size: 0
495 payload: 0 bytes
495 payload: 0 bytes
496 part header size: 0
496 part header size: 0
497 end of bundle2 stream
497 end of bundle2 stream
498 parts count: 7
498 parts count: 7
499
499
500 Test actual unbundling of test part
500 Test actual unbundling of test part
501 =======================================
501 =======================================
502
502
503 Process the bundle
503 Process the bundle
504
504
505 $ hg unbundle2 --debug < ../parts.hg2
505 $ hg unbundle2 --debug < ../parts.hg2
506 start processing of HG2X stream
506 start processing of HG2X stream
507 reading bundle2 stream parameters
507 reading bundle2 stream parameters
508 start extraction of bundle2 parts
508 start extraction of bundle2 parts
509 part header size: 17
509 part header size: 17
510 part type: "test:empty"
510 part type: "test:empty"
511 part id: "0"
511 part id: "0"
512 part parameters: 0
512 part parameters: 0
513 ignoring unsupported advisory part test:empty
513 ignoring unsupported advisory part test:empty
514 payload chunk size: 0
514 payload chunk size: 0
515 part header size: 17
515 part header size: 17
516 part type: "test:empty"
516 part type: "test:empty"
517 part id: "1"
517 part id: "1"
518 part parameters: 0
518 part parameters: 0
519 ignoring unsupported advisory part test:empty
519 ignoring unsupported advisory part test:empty
520 payload chunk size: 0
520 payload chunk size: 0
521 part header size: 16
521 part header size: 16
522 part type: "test:song"
522 part type: "test:song"
523 part id: "2"
523 part id: "2"
524 part parameters: 0
524 part parameters: 0
525 found a handler for part 'test:song'
525 found a handler for part 'test:song'
526 The choir starts singing:
526 The choir starts singing:
527 payload chunk size: 178
527 payload chunk size: 178
528 payload chunk size: 0
528 payload chunk size: 0
529 Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko
529 Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko
530 Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
530 Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
531 Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko.
531 Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko.
532 part header size: 22
532 part header size: 22
533 part type: "test:debugreply"
533 part type: "test:debugreply"
534 part id: "3"
534 part id: "3"
535 part parameters: 0
535 part parameters: 0
536 found a handler for part 'test:debugreply'
536 found a handler for part 'test:debugreply'
537 debugreply: no reply
537 debugreply: no reply
538 payload chunk size: 0
538 payload chunk size: 0
539 part header size: 43
539 part header size: 43
540 part type: "test:math"
540 part type: "test:math"
541 part id: "4"
541 part id: "4"
542 part parameters: 3
542 part parameters: 3
543 ignoring unsupported advisory part test:math
543 ignoring unsupported advisory part test:math
544 payload chunk size: 2
544 payload chunk size: 2
545 payload chunk size: 0
545 payload chunk size: 0
546 part header size: 29
546 part header size: 29
547 part type: "test:song"
547 part type: "test:song"
548 part id: "5"
548 part id: "5"
549 part parameters: 1
549 part parameters: 1
550 found a handler for part 'test:song'
550 found a handler for part 'test:song'
551 ignoring unsupported advisory part test:song - randomparam
551 ignoring unsupported advisory part test:song - randomparam
552 payload chunk size: 0
552 payload chunk size: 0
553 part header size: 16
553 part header size: 16
554 part type: "test:ping"
554 part type: "test:ping"
555 part id: "6"
555 part id: "6"
556 part parameters: 0
556 part parameters: 0
557 found a handler for part 'test:ping'
557 found a handler for part 'test:ping'
558 received ping request (id 6)
558 received ping request (id 6)
559 payload chunk size: 0
559 payload chunk size: 0
560 part header size: 0
560 part header size: 0
561 end of bundle2 stream
561 end of bundle2 stream
562 0 unread bytes
562 0 unread bytes
563 3 total verses sung
563 3 total verses sung
564
564
565 Unbundle with an unknown mandatory part
565 Unbundle with an unknown mandatory part
566 (should abort)
566 (should abort)
567
567
568 $ hg bundle2 --parts --unknown ../unknown.hg2
568 $ hg bundle2 --parts --unknown ../unknown.hg2
569
569
570 $ hg unbundle2 < ../unknown.hg2
570 $ hg unbundle2 < ../unknown.hg2
571 The choir starts singing:
571 The choir starts singing:
572 Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko
572 Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko
573 Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
573 Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
574 Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko.
574 Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko.
575 debugreply: no reply
575 debugreply: no reply
576 0 unread bytes
576 0 unread bytes
577 abort: missing support for test:unknown
577 abort: missing support for test:unknown
578 [255]
578 [255]
579
579
580 Unbundle with an unknown mandatory part parameters
580 Unbundle with an unknown mandatory part parameters
581 (should abort)
581 (should abort)
582
582
583 $ hg bundle2 --unknownparams ../unknown.hg2
583 $ hg bundle2 --unknownparams ../unknown.hg2
584
584
585 $ hg unbundle2 < ../unknown.hg2
585 $ hg unbundle2 < ../unknown.hg2
586 0 unread bytes
586 0 unread bytes
587 abort: missing support for test:song - randomparams
587 abort: missing support for test:song - randomparams
588 [255]
588 [255]
589
589
590 unbundle with a reply
590 unbundle with a reply
591
591
592 $ hg bundle2 --parts --reply ../parts-reply.hg2
592 $ hg bundle2 --parts --reply ../parts-reply.hg2
593 $ hg unbundle2 ../reply.hg2 < ../parts-reply.hg2
593 $ hg unbundle2 ../reply.hg2 < ../parts-reply.hg2
594 0 unread bytes
594 0 unread bytes
595 3 total verses sung
595 3 total verses sung
596
596
597 The reply is a bundle
597 The reply is a bundle
598
598
599 $ cat ../reply.hg2
599 $ cat ../reply.hg2
600 HG2X\x00\x00\x00\x1f (esc)
600 HG2X\x00\x00\x00\x1f (esc)
601 b2x:output\x00\x00\x00\x00\x00\x01\x0b\x01in-reply-to3\x00\x00\x00\xd9The choir starts singing: (esc)
601 b2x:output\x00\x00\x00\x00\x00\x01\x0b\x01in-reply-to3\x00\x00\x00\xd9The choir starts singing: (esc)
602 Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko
602 Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko
603 Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
603 Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
604 Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko.
604 Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko.
605 \x00\x00\x00\x00\x00\x1f (esc)
605 \x00\x00\x00\x00\x00\x1f (esc)
606 b2x:output\x00\x00\x00\x01\x00\x01\x0b\x01in-reply-to4\x00\x00\x00\xc9debugreply: capabilities: (esc)
606 b2x:output\x00\x00\x00\x01\x00\x01\x0b\x01in-reply-to4\x00\x00\x00\xc9debugreply: capabilities: (esc)
607 debugreply: 'city=!'
607 debugreply: 'city=!'
608 debugreply: 'celeste,ville'
608 debugreply: 'celeste,ville'
609 debugreply: 'elephants'
609 debugreply: 'elephants'
610 debugreply: 'babar'
610 debugreply: 'babar'
611 debugreply: 'celeste'
611 debugreply: 'celeste'
612 debugreply: 'ping-pong'
612 debugreply: 'ping-pong'
613 \x00\x00\x00\x00\x00\x1e test:pong\x00\x00\x00\x02\x01\x00\x0b\x01in-reply-to7\x00\x00\x00\x00\x00\x1f (esc)
613 \x00\x00\x00\x00\x00\x1e test:pong\x00\x00\x00\x02\x01\x00\x0b\x01in-reply-to7\x00\x00\x00\x00\x00\x1f (esc)
614 b2x:output\x00\x00\x00\x03\x00\x01\x0b\x01in-reply-to7\x00\x00\x00=received ping request (id 7) (esc)
614 b2x:output\x00\x00\x00\x03\x00\x01\x0b\x01in-reply-to7\x00\x00\x00=received ping request (id 7) (esc)
615 replying to ping request (id 7)
615 replying to ping request (id 7)
616 \x00\x00\x00\x00\x00\x00 (no-eol) (esc)
616 \x00\x00\x00\x00\x00\x00 (no-eol) (esc)
617
617
618 The reply is valid
618 The reply is valid
619
619
620 $ hg statbundle2 < ../reply.hg2
620 $ hg statbundle2 < ../reply.hg2
621 options count: 0
621 options count: 0
622 :b2x:output:
622 :b2x:output:
623 mandatory: 0
623 mandatory: 0
624 advisory: 1
624 advisory: 1
625 payload: 217 bytes
625 payload: 217 bytes
626 :b2x:output:
626 :b2x:output:
627 mandatory: 0
627 mandatory: 0
628 advisory: 1
628 advisory: 1
629 payload: 201 bytes
629 payload: 201 bytes
630 :test:pong:
630 :test:pong:
631 mandatory: 1
631 mandatory: 1
632 advisory: 0
632 advisory: 0
633 payload: 0 bytes
633 payload: 0 bytes
634 :b2x:output:
634 :b2x:output:
635 mandatory: 0
635 mandatory: 0
636 advisory: 1
636 advisory: 1
637 payload: 61 bytes
637 payload: 61 bytes
638 parts count: 4
638 parts count: 4
639
639
640 Unbundle the reply to get the output:
640 Unbundle the reply to get the output:
641
641
642 $ hg unbundle2 < ../reply.hg2
642 $ hg unbundle2 < ../reply.hg2
643 remote: The choir starts singing:
643 remote: The choir starts singing:
644 remote: Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko
644 remote: Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko
645 remote: Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
645 remote: Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
646 remote: Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko.
646 remote: Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko.
647 remote: debugreply: capabilities:
647 remote: debugreply: capabilities:
648 remote: debugreply: 'city=!'
648 remote: debugreply: 'city=!'
649 remote: debugreply: 'celeste,ville'
649 remote: debugreply: 'celeste,ville'
650 remote: debugreply: 'elephants'
650 remote: debugreply: 'elephants'
651 remote: debugreply: 'babar'
651 remote: debugreply: 'babar'
652 remote: debugreply: 'celeste'
652 remote: debugreply: 'celeste'
653 remote: debugreply: 'ping-pong'
653 remote: debugreply: 'ping-pong'
654 remote: received ping request (id 7)
654 remote: received ping request (id 7)
655 remote: replying to ping request (id 7)
655 remote: replying to ping request (id 7)
656 0 unread bytes
656 0 unread bytes
657
657
658 Test push race detection
658 Test push race detection
659
659
660 $ hg bundle2 --pushrace ../part-race.hg2
660 $ hg bundle2 --pushrace ../part-race.hg2
661
661
662 $ hg unbundle2 < ../part-race.hg2
662 $ hg unbundle2 < ../part-race.hg2
663 0 unread bytes
663 0 unread bytes
664 abort: push race: repository changed while pushing - please try again
664 abort: push race: repository changed while pushing - please try again
665 [255]
665 [255]
666
666
667 Support for changegroup
667 Support for changegroup
668 ===================================
668 ===================================
669
669
670 $ hg unbundle $TESTDIR/bundles/rebase.hg
670 $ hg unbundle $TESTDIR/bundles/rebase.hg
671 adding changesets
671 adding changesets
672 adding manifests
672 adding manifests
673 adding file changes
673 adding file changes
674 added 8 changesets with 7 changes to 7 files (+3 heads)
674 added 8 changesets with 7 changes to 7 files (+3 heads)
675 (run 'hg heads' to see heads, 'hg merge' to merge)
675 (run 'hg heads' to see heads, 'hg merge' to merge)
676
676
677 $ hg log -G
677 $ hg log -G
678 o 8:02de42196ebe draft Nicolas Dumazet <nicdumz.commits@gmail.com> H
678 o 8:02de42196ebe draft Nicolas Dumazet <nicdumz.commits@gmail.com> H
679 |
679 |
680 | o 7:eea13746799a draft Nicolas Dumazet <nicdumz.commits@gmail.com> G
680 | o 7:eea13746799a draft Nicolas Dumazet <nicdumz.commits@gmail.com> G
681 |/|
681 |/|
682 o | 6:24b6387c8c8c draft Nicolas Dumazet <nicdumz.commits@gmail.com> F
682 o | 6:24b6387c8c8c draft Nicolas Dumazet <nicdumz.commits@gmail.com> F
683 | |
683 | |
684 | o 5:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
684 | o 5:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
685 |/
685 |/
686 | o 4:32af7686d403 draft Nicolas Dumazet <nicdumz.commits@gmail.com> D
686 | o 4:32af7686d403 draft Nicolas Dumazet <nicdumz.commits@gmail.com> D
687 | |
687 | |
688 | o 3:5fddd98957c8 draft Nicolas Dumazet <nicdumz.commits@gmail.com> C
688 | o 3:5fddd98957c8 draft Nicolas Dumazet <nicdumz.commits@gmail.com> C
689 | |
689 | |
690 | o 2:42ccdea3bb16 draft Nicolas Dumazet <nicdumz.commits@gmail.com> B
690 | o 2:42ccdea3bb16 draft Nicolas Dumazet <nicdumz.commits@gmail.com> B
691 |/
691 |/
692 o 1:cd010b8cd998 draft Nicolas Dumazet <nicdumz.commits@gmail.com> A
692 o 1:cd010b8cd998 draft Nicolas Dumazet <nicdumz.commits@gmail.com> A
693
693
694 @ 0:3903775176ed draft test a
694 @ 0:3903775176ed draft test a
695
695
696
696
697 $ hg bundle2 --debug --rev '8+7+5+4' ../rev.hg2
697 $ hg bundle2 --debug --rev '8+7+5+4' ../rev.hg2
698 4 changesets found
698 4 changesets found
699 list of changesets:
699 list of changesets:
700 32af7686d403cf45b5d95f2d70cebea587ac806a
700 32af7686d403cf45b5d95f2d70cebea587ac806a
701 9520eea781bcca16c1e15acc0ba14335a0e8e5ba
701 9520eea781bcca16c1e15acc0ba14335a0e8e5ba
702 eea13746799a9e0bfd88f29d3c2e9dc9389f524f
702 eea13746799a9e0bfd88f29d3c2e9dc9389f524f
703 02de42196ebee42ef284b6780a87cdc96e8eaab6
703 02de42196ebee42ef284b6780a87cdc96e8eaab6
704 start emission of HG2X stream
704 start emission of HG2X stream
705 bundle parameter:
705 bundle parameter:
706 start of parts
706 start of parts
707 bundle part: "b2x:changegroup"
707 bundle part: "b2x:changegroup"
708 bundling: 1/4 changesets (25.00%)
708 bundling: 1/4 changesets (25.00%)
709 bundling: 2/4 changesets (50.00%)
709 bundling: 2/4 changesets (50.00%)
710 bundling: 3/4 changesets (75.00%)
710 bundling: 3/4 changesets (75.00%)
711 bundling: 4/4 changesets (100.00%)
711 bundling: 4/4 changesets (100.00%)
712 bundling: 1/4 manifests (25.00%)
712 bundling: 1/4 manifests (25.00%)
713 bundling: 2/4 manifests (50.00%)
713 bundling: 2/4 manifests (50.00%)
714 bundling: 3/4 manifests (75.00%)
714 bundling: 3/4 manifests (75.00%)
715 bundling: 4/4 manifests (100.00%)
715 bundling: 4/4 manifests (100.00%)
716 bundling: D 1/3 files (33.33%)
716 bundling: D 1/3 files (33.33%)
717 bundling: E 2/3 files (66.67%)
717 bundling: E 2/3 files (66.67%)
718 bundling: H 3/3 files (100.00%)
718 bundling: H 3/3 files (100.00%)
719 end of bundle
719 end of bundle
720
720
721 $ cat ../rev.hg2
721 $ cat ../rev.hg2
722 HG2X\x00\x00\x00\x16\x0fb2x:changegroup\x00\x00\x00\x00\x00\x00\x00\x00\x06\x13\x00\x00\x00\xa42\xafv\x86\xd4\x03\xcfE\xb5\xd9_-p\xce\xbe\xa5\x87\xac\x80j_\xdd\xd9\x89W\xc8\xa5JMCm\xfe\x1d\xa9\xd8\x7f!\xa1\xb9{\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x002\xafv\x86\xd4\x03\xcfE\xb5\xd9_-p\xce\xbe\xa5\x87\xac\x80j\x00\x00\x00\x00\x00\x00\x00)\x00\x00\x00)6e1f4c47ecb533ffd0c8e52cdc88afb6cd39e20c (esc)
722 HG2X\x00\x00\x00\x16\x0fb2x:changegroup\x00\x00\x00\x00\x00\x00\x00\x00\x06\x13\x00\x00\x00\xa42\xafv\x86\xd4\x03\xcfE\xb5\xd9_-p\xce\xbe\xa5\x87\xac\x80j_\xdd\xd9\x89W\xc8\xa5JMCm\xfe\x1d\xa9\xd8\x7f!\xa1\xb9{\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x002\xafv\x86\xd4\x03\xcfE\xb5\xd9_-p\xce\xbe\xa5\x87\xac\x80j\x00\x00\x00\x00\x00\x00\x00)\x00\x00\x00)6e1f4c47ecb533ffd0c8e52cdc88afb6cd39e20c (esc)
723 \x00\x00\x00f\x00\x00\x00h\x00\x00\x00\x02D (esc)
723 \x00\x00\x00f\x00\x00\x00h\x00\x00\x00\x02D (esc)
724 \x00\x00\x00i\x00\x00\x00j\x00\x00\x00\x01D\x00\x00\x00\xa4\x95 \xee\xa7\x81\xbc\xca\x16\xc1\xe1Z\xcc\x0b\xa1C5\xa0\xe8\xe5\xba\xcd\x01\x0b\x8c\xd9\x98\xf3\x98\x1aZ\x81\x15\xf9O\x8d\xa4\xabP`\x89\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95 \xee\xa7\x81\xbc\xca\x16\xc1\xe1Z\xcc\x0b\xa1C5\xa0\xe8\xe5\xba\x00\x00\x00\x00\x00\x00\x00)\x00\x00\x00)4dece9c826f69490507b98c6383a3009b295837d (esc)
724 \x00\x00\x00i\x00\x00\x00j\x00\x00\x00\x01D\x00\x00\x00\xa4\x95 \xee\xa7\x81\xbc\xca\x16\xc1\xe1Z\xcc\x0b\xa1C5\xa0\xe8\xe5\xba\xcd\x01\x0b\x8c\xd9\x98\xf3\x98\x1aZ\x81\x15\xf9O\x8d\xa4\xabP`\x89\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95 \xee\xa7\x81\xbc\xca\x16\xc1\xe1Z\xcc\x0b\xa1C5\xa0\xe8\xe5\xba\x00\x00\x00\x00\x00\x00\x00)\x00\x00\x00)4dece9c826f69490507b98c6383a3009b295837d (esc)
725 \x00\x00\x00f\x00\x00\x00h\x00\x00\x00\x02E (esc)
725 \x00\x00\x00f\x00\x00\x00h\x00\x00\x00\x02E (esc)
726 \x00\x00\x00i\x00\x00\x00j\x00\x00\x00\x01E\x00\x00\x00\xa2\xee\xa17Fy\x9a\x9e\x0b\xfd\x88\xf2\x9d<.\x9d\xc98\x9fRO$\xb68|\x8c\x8c\xae7\x17\x88\x80\xf3\xfa\x95\xde\xd3\xcb\x1c\xf7\x85\x95 \xee\xa7\x81\xbc\xca\x16\xc1\xe1Z\xcc\x0b\xa1C5\xa0\xe8\xe5\xba\xee\xa17Fy\x9a\x9e\x0b\xfd\x88\xf2\x9d<.\x9d\xc98\x9fRO\x00\x00\x00\x00\x00\x00\x00)\x00\x00\x00)365b93d57fdf4814e2b5911d6bacff2b12014441 (esc)
726 \x00\x00\x00i\x00\x00\x00j\x00\x00\x00\x01E\x00\x00\x00\xa2\xee\xa17Fy\x9a\x9e\x0b\xfd\x88\xf2\x9d<.\x9d\xc98\x9fRO$\xb68|\x8c\x8c\xae7\x17\x88\x80\xf3\xfa\x95\xde\xd3\xcb\x1c\xf7\x85\x95 \xee\xa7\x81\xbc\xca\x16\xc1\xe1Z\xcc\x0b\xa1C5\xa0\xe8\xe5\xba\xee\xa17Fy\x9a\x9e\x0b\xfd\x88\xf2\x9d<.\x9d\xc98\x9fRO\x00\x00\x00\x00\x00\x00\x00)\x00\x00\x00)365b93d57fdf4814e2b5911d6bacff2b12014441 (esc)
727 \x00\x00\x00f\x00\x00\x00h\x00\x00\x00\x00\x00\x00\x00i\x00\x00\x00j\x00\x00\x00\x01G\x00\x00\x00\xa4\x02\xdeB\x19n\xbe\xe4.\xf2\x84\xb6x (esc)
727 \x00\x00\x00f\x00\x00\x00h\x00\x00\x00\x00\x00\x00\x00i\x00\x00\x00j\x00\x00\x00\x01G\x00\x00\x00\xa4\x02\xdeB\x19n\xbe\xe4.\xf2\x84\xb6x (esc)
728 \x87\xcd\xc9n\x8e\xaa\xb6$\xb68|\x8c\x8c\xae7\x17\x88\x80\xf3\xfa\x95\xde\xd3\xcb\x1c\xf7\x85\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\xdeB\x19n\xbe\xe4.\xf2\x84\xb6x (esc)
728 \x87\xcd\xc9n\x8e\xaa\xb6$\xb68|\x8c\x8c\xae7\x17\x88\x80\xf3\xfa\x95\xde\xd3\xcb\x1c\xf7\x85\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\xdeB\x19n\xbe\xe4.\xf2\x84\xb6x (esc)
729 \x87\xcd\xc9n\x8e\xaa\xb6\x00\x00\x00\x00\x00\x00\x00)\x00\x00\x00)8bee48edc7318541fc0013ee41b089276a8c24bf (esc)
729 \x87\xcd\xc9n\x8e\xaa\xb6\x00\x00\x00\x00\x00\x00\x00)\x00\x00\x00)8bee48edc7318541fc0013ee41b089276a8c24bf (esc)
730 \x00\x00\x00f\x00\x00\x00f\x00\x00\x00\x02H (esc)
730 \x00\x00\x00f\x00\x00\x00f\x00\x00\x00\x02H (esc)
731 \x00\x00\x00g\x00\x00\x00h\x00\x00\x00\x01H\x00\x00\x00\x00\x00\x00\x00\x8bn\x1fLG\xec\xb53\xff\xd0\xc8\xe5,\xdc\x88\xaf\xb6\xcd9\xe2\x0cf\xa5\xa0\x18\x17\xfd\xf5#\x9c'8\x02\xb5\xb7a\x8d\x05\x1c\x89\xe4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x002\xafv\x86\xd4\x03\xcfE\xb5\xd9_-p\xce\xbe\xa5\x87\xac\x80j\x00\x00\x00\x81\x00\x00\x00\x81\x00\x00\x00+D\x00c3f1ca2924c16a19b0656a84900e504e5b0aec2d (esc)
731 \x00\x00\x00g\x00\x00\x00h\x00\x00\x00\x01H\x00\x00\x00\x00\x00\x00\x00\x8bn\x1fLG\xec\xb53\xff\xd0\xc8\xe5,\xdc\x88\xaf\xb6\xcd9\xe2\x0cf\xa5\xa0\x18\x17\xfd\xf5#\x9c'8\x02\xb5\xb7a\x8d\x05\x1c\x89\xe4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x002\xafv\x86\xd4\x03\xcfE\xb5\xd9_-p\xce\xbe\xa5\x87\xac\x80j\x00\x00\x00\x81\x00\x00\x00\x81\x00\x00\x00+D\x00c3f1ca2924c16a19b0656a84900e504e5b0aec2d (esc)
732 \x00\x00\x00\x8bM\xec\xe9\xc8&\xf6\x94\x90P{\x98\xc68:0 \xb2\x95\x83}\x00}\x8c\x9d\x88\x84\x13%\xf5\xc6\xb0cq\xb3[N\x8a+\x1a\x83\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95 \xee\xa7\x81\xbc\xca\x16\xc1\xe1Z\xcc\x0b\xa1C5\xa0\xe8\xe5\xba\x00\x00\x00+\x00\x00\x00\xac\x00\x00\x00+E\x009c6fd0350a6c0d0c49d4a9c5017cf07043f54e58 (esc)
732 \x00\x00\x00\x8bM\xec\xe9\xc8&\xf6\x94\x90P{\x98\xc68:0 \xb2\x95\x83}\x00}\x8c\x9d\x88\x84\x13%\xf5\xc6\xb0cq\xb3[N\x8a+\x1a\x83\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95 \xee\xa7\x81\xbc\xca\x16\xc1\xe1Z\xcc\x0b\xa1C5\xa0\xe8\xe5\xba\x00\x00\x00+\x00\x00\x00\xac\x00\x00\x00+E\x009c6fd0350a6c0d0c49d4a9c5017cf07043f54e58 (esc)
733 \x00\x00\x00\x8b6[\x93\xd5\x7f\xdfH\x14\xe2\xb5\x91\x1dk\xac\xff+\x12\x01DA(\xa5\x84\xc6^\xf1!\xf8\x9e\xb6j\xb7\xd0\xbc\x15=\x80\x99\xe7\xceM\xec\xe9\xc8&\xf6\x94\x90P{\x98\xc68:0 \xb2\x95\x83}\xee\xa17Fy\x9a\x9e\x0b\xfd\x88\xf2\x9d<.\x9d\xc98\x9fRO\x00\x00\x00V\x00\x00\x00V\x00\x00\x00+F\x0022bfcfd62a21a3287edbd4d656218d0f525ed76a (esc)
733 \x00\x00\x00\x8b6[\x93\xd5\x7f\xdfH\x14\xe2\xb5\x91\x1dk\xac\xff+\x12\x01DA(\xa5\x84\xc6^\xf1!\xf8\x9e\xb6j\xb7\xd0\xbc\x15=\x80\x99\xe7\xceM\xec\xe9\xc8&\xf6\x94\x90P{\x98\xc68:0 \xb2\x95\x83}\xee\xa17Fy\x9a\x9e\x0b\xfd\x88\xf2\x9d<.\x9d\xc98\x9fRO\x00\x00\x00V\x00\x00\x00V\x00\x00\x00+F\x0022bfcfd62a21a3287edbd4d656218d0f525ed76a (esc)
734 \x00\x00\x00\x97\x8b\xeeH\xed\xc71\x85A\xfc\x00\x13\xeeA\xb0\x89'j\x8c$\xbf(\xa5\x84\xc6^\xf1!\xf8\x9e\xb6j\xb7\xd0\xbc\x15=\x80\x99\xe7\xce\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\xdeB\x19n\xbe\xe4.\xf2\x84\xb6x (esc)
734 \x00\x00\x00\x97\x8b\xeeH\xed\xc71\x85A\xfc\x00\x13\xeeA\xb0\x89'j\x8c$\xbf(\xa5\x84\xc6^\xf1!\xf8\x9e\xb6j\xb7\xd0\xbc\x15=\x80\x99\xe7\xce\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\xdeB\x19n\xbe\xe4.\xf2\x84\xb6x (esc)
735 \x87\xcd\xc9n\x8e\xaa\xb6\x00\x00\x00+\x00\x00\x00V\x00\x00\x00\x00\x00\x00\x00\x81\x00\x00\x00\x81\x00\x00\x00+H\x008500189e74a9e0475e822093bc7db0d631aeb0b4 (esc)
735 \x87\xcd\xc9n\x8e\xaa\xb6\x00\x00\x00+\x00\x00\x00V\x00\x00\x00\x00\x00\x00\x00\x81\x00\x00\x00\x81\x00\x00\x00+H\x008500189e74a9e0475e822093bc7db0d631aeb0b4 (esc)
736 \x00\x00\x00\x00\x00\x00\x00\x05D\x00\x00\x00b\xc3\xf1\xca)$\xc1j\x19\xb0ej\x84\x90\x0ePN[ (esc)
736 \x00\x00\x00\x00\x00\x00\x00\x05D\x00\x00\x00b\xc3\xf1\xca)$\xc1j\x19\xb0ej\x84\x90\x0ePN[ (esc)
737 \xec-\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x002\xafv\x86\xd4\x03\xcfE\xb5\xd9_-p\xce\xbe\xa5\x87\xac\x80j\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02D (esc)
737 \xec-\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x002\xafv\x86\xd4\x03\xcfE\xb5\xd9_-p\xce\xbe\xa5\x87\xac\x80j\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02D (esc)
738 \x00\x00\x00\x00\x00\x00\x00\x05E\x00\x00\x00b\x9co\xd05 (esc)
738 \x00\x00\x00\x00\x00\x00\x00\x05E\x00\x00\x00b\x9co\xd05 (esc)
739 l\r (no-eol) (esc)
739 l\r (no-eol) (esc)
740 \x0cI\xd4\xa9\xc5\x01|\xf0pC\xf5NX\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95 \xee\xa7\x81\xbc\xca\x16\xc1\xe1Z\xcc\x0b\xa1C5\xa0\xe8\xe5\xba\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02E (esc)
740 \x0cI\xd4\xa9\xc5\x01|\xf0pC\xf5NX\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95 \xee\xa7\x81\xbc\xca\x16\xc1\xe1Z\xcc\x0b\xa1C5\xa0\xe8\xe5\xba\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02E (esc)
741 \x00\x00\x00\x00\x00\x00\x00\x05H\x00\x00\x00b\x85\x00\x18\x9et\xa9\xe0G^\x82 \x93\xbc}\xb0\xd61\xae\xb0\xb4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\xdeB\x19n\xbe\xe4.\xf2\x84\xb6x (esc)
741 \x00\x00\x00\x00\x00\x00\x00\x05H\x00\x00\x00b\x85\x00\x18\x9et\xa9\xe0G^\x82 \x93\xbc}\xb0\xd61\xae\xb0\xb4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\xdeB\x19n\xbe\xe4.\xf2\x84\xb6x (esc)
742 \x87\xcd\xc9n\x8e\xaa\xb6\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02H (esc)
742 \x87\xcd\xc9n\x8e\xaa\xb6\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02H (esc)
743 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 (no-eol) (esc)
743 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 (no-eol) (esc)
744
744
745 $ hg unbundle2 < ../rev.hg2
745 $ hg unbundle2 < ../rev.hg2
746 adding changesets
746 adding changesets
747 adding manifests
747 adding manifests
748 adding file changes
748 adding file changes
749 added 0 changesets with 0 changes to 3 files
749 added 0 changesets with 0 changes to 3 files
750 0 unread bytes
750 0 unread bytes
751 addchangegroup return: 1
751 addchangegroup return: 1
752
752
753 with reply
753 with reply
754
754
755 $ hg bundle2 --rev '8+7+5+4' --reply ../rev-rr.hg2
755 $ hg bundle2 --rev '8+7+5+4' --reply ../rev-rr.hg2
756 $ hg unbundle2 ../rev-reply.hg2 < ../rev-rr.hg2
756 $ hg unbundle2 ../rev-reply.hg2 < ../rev-rr.hg2
757 0 unread bytes
757 0 unread bytes
758 addchangegroup return: 1
758 addchangegroup return: 1
759
759
760 $ cat ../rev-reply.hg2
760 $ cat ../rev-reply.hg2
761 HG2X\x00\x00\x003\x15b2x:reply:changegroup\x00\x00\x00\x00\x00\x02\x0b\x01\x06\x01in-reply-to1return1\x00\x00\x00\x00\x00\x1f (esc)
761 HG2X\x00\x00\x003\x15b2x:reply:changegroup\x00\x00\x00\x00\x00\x02\x0b\x01\x06\x01in-reply-to1return1\x00\x00\x00\x00\x00\x1f (esc)
762 b2x:output\x00\x00\x00\x01\x00\x01\x0b\x01in-reply-to1\x00\x00\x00dadding changesets (esc)
762 b2x:output\x00\x00\x00\x01\x00\x01\x0b\x01in-reply-to1\x00\x00\x00dadding changesets (esc)
763 adding manifests
763 adding manifests
764 adding file changes
764 adding file changes
765 added 0 changesets with 0 changes to 3 files
765 added 0 changesets with 0 changes to 3 files
766 \x00\x00\x00\x00\x00\x00 (no-eol) (esc)
766 \x00\x00\x00\x00\x00\x00 (no-eol) (esc)
767
767
768 $ cd ..
768 $ cd ..
769
769
770 Real world exchange
770 Real world exchange
771 =====================
771 =====================
772
772
773 Add more obsolescence information
773 Add more obsolescence information
774
774
775 $ hg -R main debugobsolete -d '0 0' 1111111111111111111111111111111111111111 `getmainid 9520eea781bc`
775 $ hg -R main debugobsolete -d '0 0' 1111111111111111111111111111111111111111 `getmainid 9520eea781bc`
776 $ hg -R main debugobsolete -d '0 0' 2222222222222222222222222222222222222222 `getmainid 24b6387c8c8c`
776 $ hg -R main debugobsolete -d '0 0' 2222222222222222222222222222222222222222 `getmainid 24b6387c8c8c`
777
777
778 clone --pull
778 clone --pull
779
779
780 $ hg -R main phase --public cd010b8cd998
780 $ hg -R main phase --public cd010b8cd998
781 $ hg clone main other --pull --rev 9520eea781bc
781 $ hg clone main other --pull --rev 9520eea781bc
782 adding changesets
782 adding changesets
783 adding manifests
783 adding manifests
784 adding file changes
784 adding file changes
785 added 2 changesets with 2 changes to 2 files
785 added 2 changesets with 2 changes to 2 files
786 1 new obsolescence markers
786 1 new obsolescence markers
787 updating to branch default
787 updating to branch default
788 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
788 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
789 $ hg -R other log -G
789 $ hg -R other log -G
790 @ 1:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
790 @ 1:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
791 |
791 |
792 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
792 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
793
793
794 $ hg -R other debugobsolete
794 $ hg -R other debugobsolete
795 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
795 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
796
796
797 pull
797 pull
798
798
799 $ hg -R main phase --public 9520eea781bc
799 $ hg -R main phase --public 9520eea781bc
800 $ hg -R other pull -r 24b6387c8c8c
800 $ hg -R other pull -r 24b6387c8c8c
801 pulling from $TESTTMP/main (glob)
801 pulling from $TESTTMP/main (glob)
802 searching for changes
802 searching for changes
803 adding changesets
803 adding changesets
804 adding manifests
804 adding manifests
805 adding file changes
805 adding file changes
806 added 1 changesets with 1 changes to 1 files (+1 heads)
806 added 1 changesets with 1 changes to 1 files (+1 heads)
807 1 new obsolescence markers
807 1 new obsolescence markers
808 (run 'hg heads' to see heads, 'hg merge' to merge)
808 (run 'hg heads' to see heads, 'hg merge' to merge)
809 $ hg -R other log -G
809 $ hg -R other log -G
810 o 2:24b6387c8c8c draft Nicolas Dumazet <nicdumz.commits@gmail.com> F
810 o 2:24b6387c8c8c draft Nicolas Dumazet <nicdumz.commits@gmail.com> F
811 |
811 |
812 | @ 1:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
812 | @ 1:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
813 |/
813 |/
814 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
814 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
815
815
816 $ hg -R other debugobsolete
816 $ hg -R other debugobsolete
817 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
817 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
818 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
818 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
819
819
820 pull empty (with phase movement)
820 pull empty (with phase movement)
821
821
822 $ hg -R main phase --public 24b6387c8c8c
822 $ hg -R main phase --public 24b6387c8c8c
823 $ hg -R other pull -r 24b6387c8c8c
823 $ hg -R other pull -r 24b6387c8c8c
824 pulling from $TESTTMP/main (glob)
824 pulling from $TESTTMP/main (glob)
825 no changes found
825 no changes found
826 $ hg -R other log -G
826 $ hg -R other log -G
827 o 2:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
827 o 2:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
828 |
828 |
829 | @ 1:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
829 | @ 1:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
830 |/
830 |/
831 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
831 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
832
832
833 $ hg -R other debugobsolete
833 $ hg -R other debugobsolete
834 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
834 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
835 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
835 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
836
836
837 pull empty
837 pull empty
838
838
839 $ hg -R other pull -r 24b6387c8c8c
839 $ hg -R other pull -r 24b6387c8c8c
840 pulling from $TESTTMP/main (glob)
840 pulling from $TESTTMP/main (glob)
841 no changes found
841 no changes found
842 $ hg -R other log -G
842 $ hg -R other log -G
843 o 2:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
843 o 2:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
844 |
844 |
845 | @ 1:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
845 | @ 1:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
846 |/
846 |/
847 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
847 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
848
848
849 $ hg -R other debugobsolete
849 $ hg -R other debugobsolete
850 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
850 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
851 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
851 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
852
852
853 add extra data to test their exchange during push
853 add extra data to test their exchange during push
854
854
855 $ hg -R main bookmark --rev eea13746799a book_eea1
855 $ hg -R main bookmark --rev eea13746799a book_eea1
856 $ hg -R main debugobsolete -d '0 0' 3333333333333333333333333333333333333333 `getmainid eea13746799a`
856 $ hg -R main debugobsolete -d '0 0' 3333333333333333333333333333333333333333 `getmainid eea13746799a`
857 $ hg -R main bookmark --rev 02de42196ebe book_02de
857 $ hg -R main bookmark --rev 02de42196ebe book_02de
858 $ hg -R main debugobsolete -d '0 0' 4444444444444444444444444444444444444444 `getmainid 02de42196ebe`
858 $ hg -R main debugobsolete -d '0 0' 4444444444444444444444444444444444444444 `getmainid 02de42196ebe`
859 $ hg -R main bookmark --rev 42ccdea3bb16 book_42cc
859 $ hg -R main bookmark --rev 42ccdea3bb16 book_42cc
860 $ hg -R main debugobsolete -d '0 0' 5555555555555555555555555555555555555555 `getmainid 42ccdea3bb16`
860 $ hg -R main debugobsolete -d '0 0' 5555555555555555555555555555555555555555 `getmainid 42ccdea3bb16`
861 $ hg -R main bookmark --rev 5fddd98957c8 book_5fdd
861 $ hg -R main bookmark --rev 5fddd98957c8 book_5fdd
862 $ hg -R main debugobsolete -d '0 0' 6666666666666666666666666666666666666666 `getmainid 5fddd98957c8`
862 $ hg -R main debugobsolete -d '0 0' 6666666666666666666666666666666666666666 `getmainid 5fddd98957c8`
863 $ hg -R main bookmark --rev 32af7686d403 book_32af
863 $ hg -R main bookmark --rev 32af7686d403 book_32af
864 $ hg -R main debugobsolete -d '0 0' 7777777777777777777777777777777777777777 `getmainid 32af7686d403`
864 $ hg -R main debugobsolete -d '0 0' 7777777777777777777777777777777777777777 `getmainid 32af7686d403`
865
865
866 $ hg -R other bookmark --rev cd010b8cd998 book_eea1
866 $ hg -R other bookmark --rev cd010b8cd998 book_eea1
867 $ hg -R other bookmark --rev cd010b8cd998 book_02de
867 $ hg -R other bookmark --rev cd010b8cd998 book_02de
868 $ hg -R other bookmark --rev cd010b8cd998 book_42cc
868 $ hg -R other bookmark --rev cd010b8cd998 book_42cc
869 $ hg -R other bookmark --rev cd010b8cd998 book_5fdd
869 $ hg -R other bookmark --rev cd010b8cd998 book_5fdd
870 $ hg -R other bookmark --rev cd010b8cd998 book_32af
870 $ hg -R other bookmark --rev cd010b8cd998 book_32af
871
871
872 $ hg -R main phase --public eea13746799a
872 $ hg -R main phase --public eea13746799a
873
873
874 push
874 push
875 $ hg -R main push other --rev eea13746799a --bookmark book_eea1
875 $ hg -R main push other --rev eea13746799a --bookmark book_eea1
876 pushing to other
876 pushing to other
877 searching for changes
877 searching for changes
878 remote: adding changesets
878 remote: adding changesets
879 remote: adding manifests
879 remote: adding manifests
880 remote: adding file changes
880 remote: adding file changes
881 remote: added 1 changesets with 0 changes to 0 files (-1 heads)
881 remote: added 1 changesets with 0 changes to 0 files (-1 heads)
882 remote: 1 new obsolescence markers
882 remote: 1 new obsolescence markers
883 updating bookmark book_eea1
883 updating bookmark book_eea1
884 $ hg -R other log -G
884 $ hg -R other log -G
885 o 3:eea13746799a public Nicolas Dumazet <nicdumz.commits@gmail.com> book_eea1 G
885 o 3:eea13746799a public Nicolas Dumazet <nicdumz.commits@gmail.com> book_eea1 G
886 |\
886 |\
887 | o 2:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
887 | o 2:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
888 | |
888 | |
889 @ | 1:9520eea781bc public Nicolas Dumazet <nicdumz.commits@gmail.com> E
889 @ | 1:9520eea781bc public Nicolas Dumazet <nicdumz.commits@gmail.com> E
890 |/
890 |/
891 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> book_02de book_32af book_42cc book_5fdd A
891 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> book_02de book_32af book_42cc book_5fdd A
892
892
893 $ hg -R other debugobsolete
893 $ hg -R other debugobsolete
894 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
894 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
895 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
895 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
896 3333333333333333333333333333333333333333 eea13746799a9e0bfd88f29d3c2e9dc9389f524f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
896 3333333333333333333333333333333333333333 eea13746799a9e0bfd88f29d3c2e9dc9389f524f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
897
897
898 pull over ssh
898 pull over ssh
899
899
900 $ hg -R other pull ssh://user@dummy/main -r 02de42196ebe --bookmark book_02de
900 $ hg -R other pull ssh://user@dummy/main -r 02de42196ebe --bookmark book_02de
901 pulling from ssh://user@dummy/main
901 pulling from ssh://user@dummy/main
902 searching for changes
902 searching for changes
903 adding changesets
903 adding changesets
904 adding manifests
904 adding manifests
905 adding file changes
905 adding file changes
906 added 1 changesets with 1 changes to 1 files (+1 heads)
906 added 1 changesets with 1 changes to 1 files (+1 heads)
907 1 new obsolescence markers
907 1 new obsolescence markers
908 updating bookmark book_02de
908 updating bookmark book_02de
909 importing bookmark book_02de
910 (run 'hg heads' to see heads, 'hg merge' to merge)
909 (run 'hg heads' to see heads, 'hg merge' to merge)
911 $ hg -R other debugobsolete
910 $ hg -R other debugobsolete
912 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
911 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
913 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
912 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
914 3333333333333333333333333333333333333333 eea13746799a9e0bfd88f29d3c2e9dc9389f524f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
913 3333333333333333333333333333333333333333 eea13746799a9e0bfd88f29d3c2e9dc9389f524f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
915 4444444444444444444444444444444444444444 02de42196ebee42ef284b6780a87cdc96e8eaab6 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
914 4444444444444444444444444444444444444444 02de42196ebee42ef284b6780a87cdc96e8eaab6 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
916
915
917 pull over http
916 pull over http
918
917
919 $ hg -R main serve -p $HGPORT -d --pid-file=main.pid -E main-error.log
918 $ hg -R main serve -p $HGPORT -d --pid-file=main.pid -E main-error.log
920 $ cat main.pid >> $DAEMON_PIDS
919 $ cat main.pid >> $DAEMON_PIDS
921
920
922 $ hg -R other pull http://localhost:$HGPORT/ -r 42ccdea3bb16 --bookmark book_42cc
921 $ hg -R other pull http://localhost:$HGPORT/ -r 42ccdea3bb16 --bookmark book_42cc
923 pulling from http://localhost:$HGPORT/
922 pulling from http://localhost:$HGPORT/
924 searching for changes
923 searching for changes
925 adding changesets
924 adding changesets
926 adding manifests
925 adding manifests
927 adding file changes
926 adding file changes
928 added 1 changesets with 1 changes to 1 files (+1 heads)
927 added 1 changesets with 1 changes to 1 files (+1 heads)
929 1 new obsolescence markers
928 1 new obsolescence markers
930 updating bookmark book_42cc
929 updating bookmark book_42cc
931 importing bookmark book_42cc
932 (run 'hg heads .' to see heads, 'hg merge' to merge)
930 (run 'hg heads .' to see heads, 'hg merge' to merge)
933 $ cat main-error.log
931 $ cat main-error.log
934 $ hg -R other debugobsolete
932 $ hg -R other debugobsolete
935 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
933 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
936 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
934 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
937 3333333333333333333333333333333333333333 eea13746799a9e0bfd88f29d3c2e9dc9389f524f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
935 3333333333333333333333333333333333333333 eea13746799a9e0bfd88f29d3c2e9dc9389f524f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
938 4444444444444444444444444444444444444444 02de42196ebee42ef284b6780a87cdc96e8eaab6 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
936 4444444444444444444444444444444444444444 02de42196ebee42ef284b6780a87cdc96e8eaab6 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
939 5555555555555555555555555555555555555555 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
937 5555555555555555555555555555555555555555 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
940
938
941 push over ssh
939 push over ssh
942
940
943 $ hg -R main push ssh://user@dummy/other -r 5fddd98957c8 --bookmark book_5fdd
941 $ hg -R main push ssh://user@dummy/other -r 5fddd98957c8 --bookmark book_5fdd
944 pushing to ssh://user@dummy/other
942 pushing to ssh://user@dummy/other
945 searching for changes
943 searching for changes
946 remote: adding changesets
944 remote: adding changesets
947 remote: adding manifests
945 remote: adding manifests
948 remote: adding file changes
946 remote: adding file changes
949 remote: added 1 changesets with 1 changes to 1 files
947 remote: added 1 changesets with 1 changes to 1 files
950 remote: 1 new obsolescence markers
948 remote: 1 new obsolescence markers
951 updating bookmark book_5fdd
949 updating bookmark book_5fdd
952 $ hg -R other log -G
950 $ hg -R other log -G
953 o 6:5fddd98957c8 draft Nicolas Dumazet <nicdumz.commits@gmail.com> book_5fdd C
951 o 6:5fddd98957c8 draft Nicolas Dumazet <nicdumz.commits@gmail.com> book_5fdd C
954 |
952 |
955 o 5:42ccdea3bb16 draft Nicolas Dumazet <nicdumz.commits@gmail.com> book_42cc B
953 o 5:42ccdea3bb16 draft Nicolas Dumazet <nicdumz.commits@gmail.com> book_42cc B
956 |
954 |
957 | o 4:02de42196ebe draft Nicolas Dumazet <nicdumz.commits@gmail.com> book_02de H
955 | o 4:02de42196ebe draft Nicolas Dumazet <nicdumz.commits@gmail.com> book_02de H
958 | |
956 | |
959 | | o 3:eea13746799a public Nicolas Dumazet <nicdumz.commits@gmail.com> book_eea1 G
957 | | o 3:eea13746799a public Nicolas Dumazet <nicdumz.commits@gmail.com> book_eea1 G
960 | |/|
958 | |/|
961 | o | 2:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
959 | o | 2:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
962 |/ /
960 |/ /
963 | @ 1:9520eea781bc public Nicolas Dumazet <nicdumz.commits@gmail.com> E
961 | @ 1:9520eea781bc public Nicolas Dumazet <nicdumz.commits@gmail.com> E
964 |/
962 |/
965 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> book_32af A
963 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> book_32af A
966
964
967 $ hg -R other debugobsolete
965 $ hg -R other debugobsolete
968 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
966 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
969 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
967 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
970 3333333333333333333333333333333333333333 eea13746799a9e0bfd88f29d3c2e9dc9389f524f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
968 3333333333333333333333333333333333333333 eea13746799a9e0bfd88f29d3c2e9dc9389f524f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
971 4444444444444444444444444444444444444444 02de42196ebee42ef284b6780a87cdc96e8eaab6 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
969 4444444444444444444444444444444444444444 02de42196ebee42ef284b6780a87cdc96e8eaab6 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
972 5555555555555555555555555555555555555555 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
970 5555555555555555555555555555555555555555 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
973 6666666666666666666666666666666666666666 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
971 6666666666666666666666666666666666666666 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
974
972
975 push over http
973 push over http
976
974
977 $ hg -R other serve -p $HGPORT2 -d --pid-file=other.pid -E other-error.log
975 $ hg -R other serve -p $HGPORT2 -d --pid-file=other.pid -E other-error.log
978 $ cat other.pid >> $DAEMON_PIDS
976 $ cat other.pid >> $DAEMON_PIDS
979
977
980 $ hg -R main phase --public 32af7686d403
978 $ hg -R main phase --public 32af7686d403
981 $ hg -R main push http://localhost:$HGPORT2/ -r 32af7686d403 --bookmark book_32af
979 $ hg -R main push http://localhost:$HGPORT2/ -r 32af7686d403 --bookmark book_32af
982 pushing to http://localhost:$HGPORT2/
980 pushing to http://localhost:$HGPORT2/
983 searching for changes
981 searching for changes
984 remote: adding changesets
982 remote: adding changesets
985 remote: adding manifests
983 remote: adding manifests
986 remote: adding file changes
984 remote: adding file changes
987 remote: added 1 changesets with 1 changes to 1 files
985 remote: added 1 changesets with 1 changes to 1 files
988 remote: 1 new obsolescence markers
986 remote: 1 new obsolescence markers
989 updating bookmark book_32af
987 updating bookmark book_32af
990 $ cat other-error.log
988 $ cat other-error.log
991
989
992 Check final content.
990 Check final content.
993
991
994 $ hg -R other log -G
992 $ hg -R other log -G
995 o 7:32af7686d403 public Nicolas Dumazet <nicdumz.commits@gmail.com> book_32af D
993 o 7:32af7686d403 public Nicolas Dumazet <nicdumz.commits@gmail.com> book_32af D
996 |
994 |
997 o 6:5fddd98957c8 public Nicolas Dumazet <nicdumz.commits@gmail.com> book_5fdd C
995 o 6:5fddd98957c8 public Nicolas Dumazet <nicdumz.commits@gmail.com> book_5fdd C
998 |
996 |
999 o 5:42ccdea3bb16 public Nicolas Dumazet <nicdumz.commits@gmail.com> book_42cc B
997 o 5:42ccdea3bb16 public Nicolas Dumazet <nicdumz.commits@gmail.com> book_42cc B
1000 |
998 |
1001 | o 4:02de42196ebe draft Nicolas Dumazet <nicdumz.commits@gmail.com> book_02de H
999 | o 4:02de42196ebe draft Nicolas Dumazet <nicdumz.commits@gmail.com> book_02de H
1002 | |
1000 | |
1003 | | o 3:eea13746799a public Nicolas Dumazet <nicdumz.commits@gmail.com> book_eea1 G
1001 | | o 3:eea13746799a public Nicolas Dumazet <nicdumz.commits@gmail.com> book_eea1 G
1004 | |/|
1002 | |/|
1005 | o | 2:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
1003 | o | 2:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
1006 |/ /
1004 |/ /
1007 | @ 1:9520eea781bc public Nicolas Dumazet <nicdumz.commits@gmail.com> E
1005 | @ 1:9520eea781bc public Nicolas Dumazet <nicdumz.commits@gmail.com> E
1008 |/
1006 |/
1009 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
1007 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
1010
1008
1011 $ hg -R other debugobsolete
1009 $ hg -R other debugobsolete
1012 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
1010 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
1013 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
1011 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
1014 3333333333333333333333333333333333333333 eea13746799a9e0bfd88f29d3c2e9dc9389f524f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
1012 3333333333333333333333333333333333333333 eea13746799a9e0bfd88f29d3c2e9dc9389f524f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
1015 4444444444444444444444444444444444444444 02de42196ebee42ef284b6780a87cdc96e8eaab6 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
1013 4444444444444444444444444444444444444444 02de42196ebee42ef284b6780a87cdc96e8eaab6 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
1016 5555555555555555555555555555555555555555 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
1014 5555555555555555555555555555555555555555 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
1017 6666666666666666666666666666666666666666 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
1015 6666666666666666666666666666666666666666 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
1018 7777777777777777777777777777777777777777 32af7686d403cf45b5d95f2d70cebea587ac806a 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
1016 7777777777777777777777777777777777777777 32af7686d403cf45b5d95f2d70cebea587ac806a 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
1019
1017
1020 Error Handling
1018 Error Handling
1021 ==============
1019 ==============
1022
1020
1023 Check that errors are properly returned to the client during push.
1021 Check that errors are properly returned to the client during push.
1024
1022
1025 Setting up
1023 Setting up
1026
1024
1027 $ cat > failpush.py << EOF
1025 $ cat > failpush.py << EOF
1028 > """A small extension that makes push fails when using bundle2
1026 > """A small extension that makes push fails when using bundle2
1029 >
1027 >
1030 > used to test error handling in bundle2
1028 > used to test error handling in bundle2
1031 > """
1029 > """
1032 >
1030 >
1033 > from mercurial import util
1031 > from mercurial import util
1034 > from mercurial import bundle2
1032 > from mercurial import bundle2
1035 > from mercurial import exchange
1033 > from mercurial import exchange
1036 > from mercurial import extensions
1034 > from mercurial import extensions
1037 >
1035 >
1038 > def _pushbundle2failpart(pushop, bundler):
1036 > def _pushbundle2failpart(pushop, bundler):
1039 > reason = pushop.ui.config('failpush', 'reason', None)
1037 > reason = pushop.ui.config('failpush', 'reason', None)
1040 > part = None
1038 > part = None
1041 > if reason == 'abort':
1039 > if reason == 'abort':
1042 > bundler.newpart('test:abort')
1040 > bundler.newpart('test:abort')
1043 > if reason == 'unknown':
1041 > if reason == 'unknown':
1044 > bundler.newpart('TEST:UNKNOWN')
1042 > bundler.newpart('TEST:UNKNOWN')
1045 > if reason == 'race':
1043 > if reason == 'race':
1046 > # 20 Bytes of crap
1044 > # 20 Bytes of crap
1047 > bundler.newpart('b2x:check:heads', data='01234567890123456789')
1045 > bundler.newpart('b2x:check:heads', data='01234567890123456789')
1048 >
1046 >
1049 > @bundle2.parthandler("test:abort")
1047 > @bundle2.parthandler("test:abort")
1050 > def handleabort(op, part):
1048 > def handleabort(op, part):
1051 > raise util.Abort('Abandon ship!', hint="don't panic")
1049 > raise util.Abort('Abandon ship!', hint="don't panic")
1052 >
1050 >
1053 > def uisetup(ui):
1051 > def uisetup(ui):
1054 > exchange.b2partsgenmapping['failpart'] = _pushbundle2failpart
1052 > exchange.b2partsgenmapping['failpart'] = _pushbundle2failpart
1055 > exchange.b2partsgenorder.insert(0, 'failpart')
1053 > exchange.b2partsgenorder.insert(0, 'failpart')
1056 >
1054 >
1057 > EOF
1055 > EOF
1058
1056
1059 $ cd main
1057 $ cd main
1060 $ hg up tip
1058 $ hg up tip
1061 3 files updated, 0 files merged, 1 files removed, 0 files unresolved
1059 3 files updated, 0 files merged, 1 files removed, 0 files unresolved
1062 $ echo 'I' > I
1060 $ echo 'I' > I
1063 $ hg add I
1061 $ hg add I
1064 $ hg ci -m 'I'
1062 $ hg ci -m 'I'
1065 $ hg id
1063 $ hg id
1066 e7ec4e813ba6 tip
1064 e7ec4e813ba6 tip
1067 $ cd ..
1065 $ cd ..
1068
1066
1069 $ cat << EOF >> $HGRCPATH
1067 $ cat << EOF >> $HGRCPATH
1070 > [extensions]
1068 > [extensions]
1071 > failpush=$TESTTMP/failpush.py
1069 > failpush=$TESTTMP/failpush.py
1072 > EOF
1070 > EOF
1073
1071
1074 $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS
1072 $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS
1075 $ hg -R other serve -p $HGPORT2 -d --pid-file=other.pid -E other-error.log
1073 $ hg -R other serve -p $HGPORT2 -d --pid-file=other.pid -E other-error.log
1076 $ cat other.pid >> $DAEMON_PIDS
1074 $ cat other.pid >> $DAEMON_PIDS
1077
1075
1078 Doing the actual push: Abort error
1076 Doing the actual push: Abort error
1079
1077
1080 $ cat << EOF >> $HGRCPATH
1078 $ cat << EOF >> $HGRCPATH
1081 > [failpush]
1079 > [failpush]
1082 > reason = abort
1080 > reason = abort
1083 > EOF
1081 > EOF
1084
1082
1085 $ hg -R main push other -r e7ec4e813ba6
1083 $ hg -R main push other -r e7ec4e813ba6
1086 pushing to other
1084 pushing to other
1087 searching for changes
1085 searching for changes
1088 abort: Abandon ship!
1086 abort: Abandon ship!
1089 (don't panic)
1087 (don't panic)
1090 [255]
1088 [255]
1091
1089
1092 $ hg -R main push ssh://user@dummy/other -r e7ec4e813ba6
1090 $ hg -R main push ssh://user@dummy/other -r e7ec4e813ba6
1093 pushing to ssh://user@dummy/other
1091 pushing to ssh://user@dummy/other
1094 searching for changes
1092 searching for changes
1095 abort: Abandon ship!
1093 abort: Abandon ship!
1096 (don't panic)
1094 (don't panic)
1097 [255]
1095 [255]
1098
1096
1099 $ hg -R main push http://localhost:$HGPORT2/ -r e7ec4e813ba6
1097 $ hg -R main push http://localhost:$HGPORT2/ -r e7ec4e813ba6
1100 pushing to http://localhost:$HGPORT2/
1098 pushing to http://localhost:$HGPORT2/
1101 searching for changes
1099 searching for changes
1102 abort: Abandon ship!
1100 abort: Abandon ship!
1103 (don't panic)
1101 (don't panic)
1104 [255]
1102 [255]
1105
1103
1106
1104
1107 Doing the actual push: unknown mandatory parts
1105 Doing the actual push: unknown mandatory parts
1108
1106
1109 $ cat << EOF >> $HGRCPATH
1107 $ cat << EOF >> $HGRCPATH
1110 > [failpush]
1108 > [failpush]
1111 > reason = unknown
1109 > reason = unknown
1112 > EOF
1110 > EOF
1113
1111
1114 $ hg -R main push other -r e7ec4e813ba6
1112 $ hg -R main push other -r e7ec4e813ba6
1115 pushing to other
1113 pushing to other
1116 searching for changes
1114 searching for changes
1117 abort: missing support for test:unknown
1115 abort: missing support for test:unknown
1118 [255]
1116 [255]
1119
1117
1120 $ hg -R main push ssh://user@dummy/other -r e7ec4e813ba6
1118 $ hg -R main push ssh://user@dummy/other -r e7ec4e813ba6
1121 pushing to ssh://user@dummy/other
1119 pushing to ssh://user@dummy/other
1122 searching for changes
1120 searching for changes
1123 abort: missing support for test:unknown
1121 abort: missing support for test:unknown
1124 [255]
1122 [255]
1125
1123
1126 $ hg -R main push http://localhost:$HGPORT2/ -r e7ec4e813ba6
1124 $ hg -R main push http://localhost:$HGPORT2/ -r e7ec4e813ba6
1127 pushing to http://localhost:$HGPORT2/
1125 pushing to http://localhost:$HGPORT2/
1128 searching for changes
1126 searching for changes
1129 abort: missing support for test:unknown
1127 abort: missing support for test:unknown
1130 [255]
1128 [255]
1131
1129
1132 Doing the actual push: race
1130 Doing the actual push: race
1133
1131
1134 $ cat << EOF >> $HGRCPATH
1132 $ cat << EOF >> $HGRCPATH
1135 > [failpush]
1133 > [failpush]
1136 > reason = race
1134 > reason = race
1137 > EOF
1135 > EOF
1138
1136
1139 $ hg -R main push other -r e7ec4e813ba6
1137 $ hg -R main push other -r e7ec4e813ba6
1140 pushing to other
1138 pushing to other
1141 searching for changes
1139 searching for changes
1142 abort: push failed:
1140 abort: push failed:
1143 'repository changed while pushing - please try again'
1141 'repository changed while pushing - please try again'
1144 [255]
1142 [255]
1145
1143
1146 $ hg -R main push ssh://user@dummy/other -r e7ec4e813ba6
1144 $ hg -R main push ssh://user@dummy/other -r e7ec4e813ba6
1147 pushing to ssh://user@dummy/other
1145 pushing to ssh://user@dummy/other
1148 searching for changes
1146 searching for changes
1149 abort: push failed:
1147 abort: push failed:
1150 'repository changed while pushing - please try again'
1148 'repository changed while pushing - please try again'
1151 [255]
1149 [255]
1152
1150
1153 $ hg -R main push http://localhost:$HGPORT2/ -r e7ec4e813ba6
1151 $ hg -R main push http://localhost:$HGPORT2/ -r e7ec4e813ba6
1154 pushing to http://localhost:$HGPORT2/
1152 pushing to http://localhost:$HGPORT2/
1155 searching for changes
1153 searching for changes
1156 abort: push failed:
1154 abort: push failed:
1157 'repository changed while pushing - please try again'
1155 'repository changed while pushing - please try again'
1158 [255]
1156 [255]
1159
1157
1160 Doing the actual push: hook abort
1158 Doing the actual push: hook abort
1161
1159
1162 $ cat << EOF >> $HGRCPATH
1160 $ cat << EOF >> $HGRCPATH
1163 > [failpush]
1161 > [failpush]
1164 > reason =
1162 > reason =
1165 > [hooks]
1163 > [hooks]
1166 > b2x-pretransactionclose.failpush = false
1164 > b2x-pretransactionclose.failpush = false
1167 > EOF
1165 > EOF
1168
1166
1169 $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS
1167 $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS
1170 $ hg -R other serve -p $HGPORT2 -d --pid-file=other.pid -E other-error.log
1168 $ hg -R other serve -p $HGPORT2 -d --pid-file=other.pid -E other-error.log
1171 $ cat other.pid >> $DAEMON_PIDS
1169 $ cat other.pid >> $DAEMON_PIDS
1172
1170
1173 $ hg -R main push other -r e7ec4e813ba6
1171 $ hg -R main push other -r e7ec4e813ba6
1174 pushing to other
1172 pushing to other
1175 searching for changes
1173 searching for changes
1176 transaction abort!
1174 transaction abort!
1177 rollback completed
1175 rollback completed
1178 abort: b2x-pretransactionclose.failpush hook exited with status 1
1176 abort: b2x-pretransactionclose.failpush hook exited with status 1
1179 [255]
1177 [255]
1180
1178
1181 $ hg -R main push ssh://user@dummy/other -r e7ec4e813ba6
1179 $ hg -R main push ssh://user@dummy/other -r e7ec4e813ba6
1182 pushing to ssh://user@dummy/other
1180 pushing to ssh://user@dummy/other
1183 searching for changes
1181 searching for changes
1184 abort: b2x-pretransactionclose.failpush hook exited with status 1
1182 abort: b2x-pretransactionclose.failpush hook exited with status 1
1185 remote: transaction abort!
1183 remote: transaction abort!
1186 remote: rollback completed
1184 remote: rollback completed
1187 [255]
1185 [255]
1188
1186
1189 $ hg -R main push http://localhost:$HGPORT2/ -r e7ec4e813ba6
1187 $ hg -R main push http://localhost:$HGPORT2/ -r e7ec4e813ba6
1190 pushing to http://localhost:$HGPORT2/
1188 pushing to http://localhost:$HGPORT2/
1191 searching for changes
1189 searching for changes
1192 abort: b2x-pretransactionclose.failpush hook exited with status 1
1190 abort: b2x-pretransactionclose.failpush hook exited with status 1
1193 [255]
1191 [255]
1194
1192
1195
1193
@@ -1,644 +1,643 b''
1 commit hooks can see env vars
1 commit hooks can see env vars
2
2
3 $ hg init a
3 $ hg init a
4 $ cd a
4 $ cd a
5 $ cat > .hg/hgrc <<EOF
5 $ cat > .hg/hgrc <<EOF
6 > [hooks]
6 > [hooks]
7 > commit = sh -c "HG_LOCAL= HG_TAG= python \"$TESTDIR/printenv.py\" commit"
7 > commit = sh -c "HG_LOCAL= HG_TAG= python \"$TESTDIR/printenv.py\" commit"
8 > commit.b = sh -c "HG_LOCAL= HG_TAG= python \"$TESTDIR/printenv.py\" commit.b"
8 > commit.b = sh -c "HG_LOCAL= HG_TAG= python \"$TESTDIR/printenv.py\" commit.b"
9 > precommit = sh -c "HG_LOCAL= HG_NODE= HG_TAG= python \"$TESTDIR/printenv.py\" precommit"
9 > precommit = sh -c "HG_LOCAL= HG_NODE= HG_TAG= python \"$TESTDIR/printenv.py\" precommit"
10 > pretxncommit = sh -c "HG_LOCAL= HG_TAG= python \"$TESTDIR/printenv.py\" pretxncommit"
10 > pretxncommit = sh -c "HG_LOCAL= HG_TAG= python \"$TESTDIR/printenv.py\" pretxncommit"
11 > pretxncommit.tip = hg -q tip
11 > pretxncommit.tip = hg -q tip
12 > pre-identify = python "$TESTDIR/printenv.py" pre-identify 1
12 > pre-identify = python "$TESTDIR/printenv.py" pre-identify 1
13 > pre-cat = python "$TESTDIR/printenv.py" pre-cat
13 > pre-cat = python "$TESTDIR/printenv.py" pre-cat
14 > post-cat = python "$TESTDIR/printenv.py" post-cat
14 > post-cat = python "$TESTDIR/printenv.py" post-cat
15 > EOF
15 > EOF
16 $ echo a > a
16 $ echo a > a
17 $ hg add a
17 $ hg add a
18 $ hg commit -m a
18 $ hg commit -m a
19 precommit hook: HG_PARENT1=0000000000000000000000000000000000000000
19 precommit hook: HG_PARENT1=0000000000000000000000000000000000000000
20 pretxncommit hook: HG_NODE=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PARENT1=0000000000000000000000000000000000000000 HG_PENDING=$TESTTMP/a
20 pretxncommit hook: HG_NODE=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PARENT1=0000000000000000000000000000000000000000 HG_PENDING=$TESTTMP/a
21 0:cb9a9f314b8b
21 0:cb9a9f314b8b
22 commit hook: HG_NODE=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PARENT1=0000000000000000000000000000000000000000
22 commit hook: HG_NODE=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PARENT1=0000000000000000000000000000000000000000
23 commit.b hook: HG_NODE=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PARENT1=0000000000000000000000000000000000000000
23 commit.b hook: HG_NODE=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PARENT1=0000000000000000000000000000000000000000
24
24
25 $ hg clone . ../b
25 $ hg clone . ../b
26 updating to branch default
26 updating to branch default
27 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
27 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
28 $ cd ../b
28 $ cd ../b
29
29
30 changegroup hooks can see env vars
30 changegroup hooks can see env vars
31
31
32 $ cat > .hg/hgrc <<EOF
32 $ cat > .hg/hgrc <<EOF
33 > [hooks]
33 > [hooks]
34 > prechangegroup = python "$TESTDIR/printenv.py" prechangegroup
34 > prechangegroup = python "$TESTDIR/printenv.py" prechangegroup
35 > changegroup = python "$TESTDIR/printenv.py" changegroup
35 > changegroup = python "$TESTDIR/printenv.py" changegroup
36 > incoming = python "$TESTDIR/printenv.py" incoming
36 > incoming = python "$TESTDIR/printenv.py" incoming
37 > EOF
37 > EOF
38
38
39 pretxncommit and commit hooks can see both parents of merge
39 pretxncommit and commit hooks can see both parents of merge
40
40
41 $ cd ../a
41 $ cd ../a
42 $ echo b >> a
42 $ echo b >> a
43 $ hg commit -m a1 -d "1 0"
43 $ hg commit -m a1 -d "1 0"
44 precommit hook: HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
44 precommit hook: HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
45 pretxncommit hook: HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PENDING=$TESTTMP/a
45 pretxncommit hook: HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PENDING=$TESTTMP/a
46 1:ab228980c14d
46 1:ab228980c14d
47 commit hook: HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
47 commit hook: HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
48 commit.b hook: HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
48 commit.b hook: HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
49 $ hg update -C 0
49 $ hg update -C 0
50 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
50 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
51 $ echo b > b
51 $ echo b > b
52 $ hg add b
52 $ hg add b
53 $ hg commit -m b -d '1 0'
53 $ hg commit -m b -d '1 0'
54 precommit hook: HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
54 precommit hook: HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
55 pretxncommit hook: HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PENDING=$TESTTMP/a
55 pretxncommit hook: HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PENDING=$TESTTMP/a
56 2:ee9deb46ab31
56 2:ee9deb46ab31
57 commit hook: HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
57 commit hook: HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
58 commit.b hook: HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
58 commit.b hook: HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
59 created new head
59 created new head
60 $ hg merge 1
60 $ hg merge 1
61 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
61 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
62 (branch merge, don't forget to commit)
62 (branch merge, don't forget to commit)
63 $ hg commit -m merge -d '2 0'
63 $ hg commit -m merge -d '2 0'
64 precommit hook: HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd
64 precommit hook: HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd
65 pretxncommit hook: HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd HG_PENDING=$TESTTMP/a
65 pretxncommit hook: HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd HG_PENDING=$TESTTMP/a
66 3:07f3376c1e65
66 3:07f3376c1e65
67 commit hook: HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd
67 commit hook: HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd
68 commit.b hook: HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd
68 commit.b hook: HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd
69
69
70 test generic hooks
70 test generic hooks
71
71
72 $ hg id
72 $ hg id
73 pre-identify hook: HG_ARGS=id HG_OPTS={'bookmarks': None, 'branch': None, 'id': None, 'insecure': None, 'num': None, 'remotecmd': '', 'rev': '', 'ssh': '', 'tags': None} HG_PATS=[]
73 pre-identify hook: HG_ARGS=id HG_OPTS={'bookmarks': None, 'branch': None, 'id': None, 'insecure': None, 'num': None, 'remotecmd': '', 'rev': '', 'ssh': '', 'tags': None} HG_PATS=[]
74 abort: pre-identify hook exited with status 1
74 abort: pre-identify hook exited with status 1
75 [255]
75 [255]
76 $ hg cat b
76 $ hg cat b
77 pre-cat hook: HG_ARGS=cat b HG_OPTS={'decode': None, 'exclude': [], 'include': [], 'output': '', 'rev': ''} HG_PATS=['b']
77 pre-cat hook: HG_ARGS=cat b HG_OPTS={'decode': None, 'exclude': [], 'include': [], 'output': '', 'rev': ''} HG_PATS=['b']
78 b
78 b
79 post-cat hook: HG_ARGS=cat b HG_OPTS={'decode': None, 'exclude': [], 'include': [], 'output': '', 'rev': ''} HG_PATS=['b'] HG_RESULT=0
79 post-cat hook: HG_ARGS=cat b HG_OPTS={'decode': None, 'exclude': [], 'include': [], 'output': '', 'rev': ''} HG_PATS=['b'] HG_RESULT=0
80
80
81 $ cd ../b
81 $ cd ../b
82 $ hg pull ../a
82 $ hg pull ../a
83 pulling from ../a
83 pulling from ../a
84 searching for changes
84 searching for changes
85 prechangegroup hook: HG_SOURCE=pull HG_URL=file:$TESTTMP/a
85 prechangegroup hook: HG_SOURCE=pull HG_URL=file:$TESTTMP/a
86 adding changesets
86 adding changesets
87 adding manifests
87 adding manifests
88 adding file changes
88 adding file changes
89 added 3 changesets with 2 changes to 2 files
89 added 3 changesets with 2 changes to 2 files
90 changegroup hook: HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_SOURCE=pull HG_URL=file:$TESTTMP/a
90 changegroup hook: HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_SOURCE=pull HG_URL=file:$TESTTMP/a
91 incoming hook: HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_SOURCE=pull HG_URL=file:$TESTTMP/a
91 incoming hook: HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_SOURCE=pull HG_URL=file:$TESTTMP/a
92 incoming hook: HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_SOURCE=pull HG_URL=file:$TESTTMP/a
92 incoming hook: HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_SOURCE=pull HG_URL=file:$TESTTMP/a
93 incoming hook: HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_SOURCE=pull HG_URL=file:$TESTTMP/a
93 incoming hook: HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_SOURCE=pull HG_URL=file:$TESTTMP/a
94 (run 'hg update' to get a working copy)
94 (run 'hg update' to get a working copy)
95
95
96 tag hooks can see env vars
96 tag hooks can see env vars
97
97
98 $ cd ../a
98 $ cd ../a
99 $ cat >> .hg/hgrc <<EOF
99 $ cat >> .hg/hgrc <<EOF
100 > pretag = python "$TESTDIR/printenv.py" pretag
100 > pretag = python "$TESTDIR/printenv.py" pretag
101 > tag = sh -c "HG_PARENT1= HG_PARENT2= python \"$TESTDIR/printenv.py\" tag"
101 > tag = sh -c "HG_PARENT1= HG_PARENT2= python \"$TESTDIR/printenv.py\" tag"
102 > EOF
102 > EOF
103 $ hg tag -d '3 0' a
103 $ hg tag -d '3 0' a
104 pretag hook: HG_LOCAL=0 HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_TAG=a
104 pretag hook: HG_LOCAL=0 HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_TAG=a
105 precommit hook: HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2
105 precommit hook: HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2
106 pretxncommit hook: HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2 HG_PENDING=$TESTTMP/a
106 pretxncommit hook: HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2 HG_PENDING=$TESTTMP/a
107 4:539e4b31b6dc
107 4:539e4b31b6dc
108 tag hook: HG_LOCAL=0 HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_TAG=a
108 tag hook: HG_LOCAL=0 HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_TAG=a
109 commit hook: HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2
109 commit hook: HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2
110 commit.b hook: HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2
110 commit.b hook: HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2
111 $ hg tag -l la
111 $ hg tag -l la
112 pretag hook: HG_LOCAL=1 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=la
112 pretag hook: HG_LOCAL=1 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=la
113 tag hook: HG_LOCAL=1 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=la
113 tag hook: HG_LOCAL=1 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=la
114
114
115 pretag hook can forbid tagging
115 pretag hook can forbid tagging
116
116
117 $ echo "pretag.forbid = python \"$TESTDIR/printenv.py\" pretag.forbid 1" >> .hg/hgrc
117 $ echo "pretag.forbid = python \"$TESTDIR/printenv.py\" pretag.forbid 1" >> .hg/hgrc
118 $ hg tag -d '4 0' fa
118 $ hg tag -d '4 0' fa
119 pretag hook: HG_LOCAL=0 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=fa
119 pretag hook: HG_LOCAL=0 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=fa
120 pretag.forbid hook: HG_LOCAL=0 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=fa
120 pretag.forbid hook: HG_LOCAL=0 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=fa
121 abort: pretag.forbid hook exited with status 1
121 abort: pretag.forbid hook exited with status 1
122 [255]
122 [255]
123 $ hg tag -l fla
123 $ hg tag -l fla
124 pretag hook: HG_LOCAL=1 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=fla
124 pretag hook: HG_LOCAL=1 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=fla
125 pretag.forbid hook: HG_LOCAL=1 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=fla
125 pretag.forbid hook: HG_LOCAL=1 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=fla
126 abort: pretag.forbid hook exited with status 1
126 abort: pretag.forbid hook exited with status 1
127 [255]
127 [255]
128
128
129 pretxncommit hook can see changeset, can roll back txn, changeset no
129 pretxncommit hook can see changeset, can roll back txn, changeset no
130 more there after
130 more there after
131
131
132 $ echo "pretxncommit.forbid0 = hg tip -q" >> .hg/hgrc
132 $ echo "pretxncommit.forbid0 = hg tip -q" >> .hg/hgrc
133 $ echo "pretxncommit.forbid1 = python \"$TESTDIR/printenv.py\" pretxncommit.forbid 1" >> .hg/hgrc
133 $ echo "pretxncommit.forbid1 = python \"$TESTDIR/printenv.py\" pretxncommit.forbid 1" >> .hg/hgrc
134 $ echo z > z
134 $ echo z > z
135 $ hg add z
135 $ hg add z
136 $ hg -q tip
136 $ hg -q tip
137 4:539e4b31b6dc
137 4:539e4b31b6dc
138 $ hg commit -m 'fail' -d '4 0'
138 $ hg commit -m 'fail' -d '4 0'
139 precommit hook: HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
139 precommit hook: HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
140 pretxncommit hook: HG_NODE=6f611f8018c10e827fee6bd2bc807f937e761567 HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PENDING=$TESTTMP/a
140 pretxncommit hook: HG_NODE=6f611f8018c10e827fee6bd2bc807f937e761567 HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PENDING=$TESTTMP/a
141 5:6f611f8018c1
141 5:6f611f8018c1
142 5:6f611f8018c1
142 5:6f611f8018c1
143 pretxncommit.forbid hook: HG_NODE=6f611f8018c10e827fee6bd2bc807f937e761567 HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PENDING=$TESTTMP/a
143 pretxncommit.forbid hook: HG_NODE=6f611f8018c10e827fee6bd2bc807f937e761567 HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PENDING=$TESTTMP/a
144 transaction abort!
144 transaction abort!
145 rollback completed
145 rollback completed
146 abort: pretxncommit.forbid1 hook exited with status 1
146 abort: pretxncommit.forbid1 hook exited with status 1
147 [255]
147 [255]
148 $ hg -q tip
148 $ hg -q tip
149 4:539e4b31b6dc
149 4:539e4b31b6dc
150
150
151 precommit hook can prevent commit
151 precommit hook can prevent commit
152
152
153 $ echo "precommit.forbid = python \"$TESTDIR/printenv.py\" precommit.forbid 1" >> .hg/hgrc
153 $ echo "precommit.forbid = python \"$TESTDIR/printenv.py\" precommit.forbid 1" >> .hg/hgrc
154 $ hg commit -m 'fail' -d '4 0'
154 $ hg commit -m 'fail' -d '4 0'
155 precommit hook: HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
155 precommit hook: HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
156 precommit.forbid hook: HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
156 precommit.forbid hook: HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
157 abort: precommit.forbid hook exited with status 1
157 abort: precommit.forbid hook exited with status 1
158 [255]
158 [255]
159 $ hg -q tip
159 $ hg -q tip
160 4:539e4b31b6dc
160 4:539e4b31b6dc
161
161
162 preupdate hook can prevent update
162 preupdate hook can prevent update
163
163
164 $ echo "preupdate = python \"$TESTDIR/printenv.py\" preupdate" >> .hg/hgrc
164 $ echo "preupdate = python \"$TESTDIR/printenv.py\" preupdate" >> .hg/hgrc
165 $ hg update 1
165 $ hg update 1
166 preupdate hook: HG_PARENT1=ab228980c14d
166 preupdate hook: HG_PARENT1=ab228980c14d
167 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
167 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
168
168
169 update hook
169 update hook
170
170
171 $ echo "update = python \"$TESTDIR/printenv.py\" update" >> .hg/hgrc
171 $ echo "update = python \"$TESTDIR/printenv.py\" update" >> .hg/hgrc
172 $ hg update
172 $ hg update
173 preupdate hook: HG_PARENT1=539e4b31b6dc
173 preupdate hook: HG_PARENT1=539e4b31b6dc
174 update hook: HG_ERROR=0 HG_PARENT1=539e4b31b6dc
174 update hook: HG_ERROR=0 HG_PARENT1=539e4b31b6dc
175 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
175 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
176
176
177 pushkey hook
177 pushkey hook
178
178
179 $ echo "pushkey = python \"$TESTDIR/printenv.py\" pushkey" >> .hg/hgrc
179 $ echo "pushkey = python \"$TESTDIR/printenv.py\" pushkey" >> .hg/hgrc
180 $ cd ../b
180 $ cd ../b
181 $ hg bookmark -r null foo
181 $ hg bookmark -r null foo
182 $ hg push -B foo ../a
182 $ hg push -B foo ../a
183 pushing to ../a
183 pushing to ../a
184 searching for changes
184 searching for changes
185 no changes found
185 no changes found
186 pushkey hook: HG_KEY=foo HG_NAMESPACE=bookmarks HG_NEW=0000000000000000000000000000000000000000 HG_RET=1
186 pushkey hook: HG_KEY=foo HG_NAMESPACE=bookmarks HG_NEW=0000000000000000000000000000000000000000 HG_RET=1
187 exporting bookmark foo
187 exporting bookmark foo
188 [1]
188 [1]
189 $ cd ../a
189 $ cd ../a
190
190
191 listkeys hook
191 listkeys hook
192
192
193 $ echo "listkeys = python \"$TESTDIR/printenv.py\" listkeys" >> .hg/hgrc
193 $ echo "listkeys = python \"$TESTDIR/printenv.py\" listkeys" >> .hg/hgrc
194 $ hg bookmark -r null bar
194 $ hg bookmark -r null bar
195 $ cd ../b
195 $ cd ../b
196 $ hg pull -B bar ../a
196 $ hg pull -B bar ../a
197 pulling from ../a
197 pulling from ../a
198 listkeys hook: HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'}
198 listkeys hook: HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'}
199 listkeys hook: HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'}
199 listkeys hook: HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'}
200 no changes found
200 no changes found
201 listkeys hook: HG_NAMESPACE=phases HG_VALUES={'cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b': '1', 'publishing': 'True'}
201 listkeys hook: HG_NAMESPACE=phases HG_VALUES={'cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b': '1', 'publishing': 'True'}
202 adding remote bookmark bar
202 adding remote bookmark bar
203 importing bookmark bar
204 $ cd ../a
203 $ cd ../a
205
204
206 test that prepushkey can prevent incoming keys
205 test that prepushkey can prevent incoming keys
207
206
208 $ echo "prepushkey = python \"$TESTDIR/printenv.py\" prepushkey.forbid 1" >> .hg/hgrc
207 $ echo "prepushkey = python \"$TESTDIR/printenv.py\" prepushkey.forbid 1" >> .hg/hgrc
209 $ cd ../b
208 $ cd ../b
210 $ hg bookmark -r null baz
209 $ hg bookmark -r null baz
211 $ hg push -B baz ../a
210 $ hg push -B baz ../a
212 pushing to ../a
211 pushing to ../a
213 searching for changes
212 searching for changes
214 listkeys hook: HG_NAMESPACE=phases HG_VALUES={'cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b': '1', 'publishing': 'True'}
213 listkeys hook: HG_NAMESPACE=phases HG_VALUES={'cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b': '1', 'publishing': 'True'}
215 listkeys hook: HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'}
214 listkeys hook: HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'}
216 no changes found
215 no changes found
217 listkeys hook: HG_NAMESPACE=phases HG_VALUES={'cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b': '1', 'publishing': 'True'}
216 listkeys hook: HG_NAMESPACE=phases HG_VALUES={'cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b': '1', 'publishing': 'True'}
218 prepushkey.forbid hook: HG_KEY=baz HG_NAMESPACE=bookmarks HG_NEW=0000000000000000000000000000000000000000
217 prepushkey.forbid hook: HG_KEY=baz HG_NAMESPACE=bookmarks HG_NEW=0000000000000000000000000000000000000000
219 abort: prepushkey hook exited with status 1
218 abort: prepushkey hook exited with status 1
220 [255]
219 [255]
221 $ cd ../a
220 $ cd ../a
222
221
223 test that prelistkeys can prevent listing keys
222 test that prelistkeys can prevent listing keys
224
223
225 $ echo "prelistkeys = python \"$TESTDIR/printenv.py\" prelistkeys.forbid 1" >> .hg/hgrc
224 $ echo "prelistkeys = python \"$TESTDIR/printenv.py\" prelistkeys.forbid 1" >> .hg/hgrc
226 $ hg bookmark -r null quux
225 $ hg bookmark -r null quux
227 $ cd ../b
226 $ cd ../b
228 $ hg pull -B quux ../a
227 $ hg pull -B quux ../a
229 pulling from ../a
228 pulling from ../a
230 prelistkeys.forbid hook: HG_NAMESPACE=bookmarks
229 prelistkeys.forbid hook: HG_NAMESPACE=bookmarks
231 abort: prelistkeys hook exited with status 1
230 abort: prelistkeys hook exited with status 1
232 [255]
231 [255]
233 $ cd ../a
232 $ cd ../a
234 $ rm .hg/hgrc
233 $ rm .hg/hgrc
235
234
236 prechangegroup hook can prevent incoming changes
235 prechangegroup hook can prevent incoming changes
237
236
238 $ cd ../b
237 $ cd ../b
239 $ hg -q tip
238 $ hg -q tip
240 3:07f3376c1e65
239 3:07f3376c1e65
241 $ cat > .hg/hgrc <<EOF
240 $ cat > .hg/hgrc <<EOF
242 > [hooks]
241 > [hooks]
243 > prechangegroup.forbid = python "$TESTDIR/printenv.py" prechangegroup.forbid 1
242 > prechangegroup.forbid = python "$TESTDIR/printenv.py" prechangegroup.forbid 1
244 > EOF
243 > EOF
245 $ hg pull ../a
244 $ hg pull ../a
246 pulling from ../a
245 pulling from ../a
247 searching for changes
246 searching for changes
248 prechangegroup.forbid hook: HG_SOURCE=pull HG_URL=file:$TESTTMP/a
247 prechangegroup.forbid hook: HG_SOURCE=pull HG_URL=file:$TESTTMP/a
249 abort: prechangegroup.forbid hook exited with status 1
248 abort: prechangegroup.forbid hook exited with status 1
250 [255]
249 [255]
251
250
252 pretxnchangegroup hook can see incoming changes, can roll back txn,
251 pretxnchangegroup hook can see incoming changes, can roll back txn,
253 incoming changes no longer there after
252 incoming changes no longer there after
254
253
255 $ cat > .hg/hgrc <<EOF
254 $ cat > .hg/hgrc <<EOF
256 > [hooks]
255 > [hooks]
257 > pretxnchangegroup.forbid0 = hg tip -q
256 > pretxnchangegroup.forbid0 = hg tip -q
258 > pretxnchangegroup.forbid1 = python "$TESTDIR/printenv.py" pretxnchangegroup.forbid 1
257 > pretxnchangegroup.forbid1 = python "$TESTDIR/printenv.py" pretxnchangegroup.forbid 1
259 > EOF
258 > EOF
260 $ hg pull ../a
259 $ hg pull ../a
261 pulling from ../a
260 pulling from ../a
262 searching for changes
261 searching for changes
263 adding changesets
262 adding changesets
264 adding manifests
263 adding manifests
265 adding file changes
264 adding file changes
266 added 1 changesets with 1 changes to 1 files
265 added 1 changesets with 1 changes to 1 files
267 4:539e4b31b6dc
266 4:539e4b31b6dc
268 pretxnchangegroup.forbid hook: HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PENDING=$TESTTMP/b HG_SOURCE=pull HG_URL=file:$TESTTMP/a
267 pretxnchangegroup.forbid hook: HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PENDING=$TESTTMP/b HG_SOURCE=pull HG_URL=file:$TESTTMP/a
269 transaction abort!
268 transaction abort!
270 rollback completed
269 rollback completed
271 abort: pretxnchangegroup.forbid1 hook exited with status 1
270 abort: pretxnchangegroup.forbid1 hook exited with status 1
272 [255]
271 [255]
273 $ hg -q tip
272 $ hg -q tip
274 3:07f3376c1e65
273 3:07f3376c1e65
275
274
276 outgoing hooks can see env vars
275 outgoing hooks can see env vars
277
276
278 $ rm .hg/hgrc
277 $ rm .hg/hgrc
279 $ cat > ../a/.hg/hgrc <<EOF
278 $ cat > ../a/.hg/hgrc <<EOF
280 > [hooks]
279 > [hooks]
281 > preoutgoing = python "$TESTDIR/printenv.py" preoutgoing
280 > preoutgoing = python "$TESTDIR/printenv.py" preoutgoing
282 > outgoing = python "$TESTDIR/printenv.py" outgoing
281 > outgoing = python "$TESTDIR/printenv.py" outgoing
283 > EOF
282 > EOF
284 $ hg pull ../a
283 $ hg pull ../a
285 pulling from ../a
284 pulling from ../a
286 searching for changes
285 searching for changes
287 preoutgoing hook: HG_SOURCE=pull
286 preoutgoing hook: HG_SOURCE=pull
288 adding changesets
287 adding changesets
289 outgoing hook: HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_SOURCE=pull
288 outgoing hook: HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_SOURCE=pull
290 adding manifests
289 adding manifests
291 adding file changes
290 adding file changes
292 added 1 changesets with 1 changes to 1 files
291 added 1 changesets with 1 changes to 1 files
293 adding remote bookmark quux
292 adding remote bookmark quux
294 (run 'hg update' to get a working copy)
293 (run 'hg update' to get a working copy)
295 $ hg rollback
294 $ hg rollback
296 repository tip rolled back to revision 3 (undo pull)
295 repository tip rolled back to revision 3 (undo pull)
297
296
298 preoutgoing hook can prevent outgoing changes
297 preoutgoing hook can prevent outgoing changes
299
298
300 $ echo "preoutgoing.forbid = python \"$TESTDIR/printenv.py\" preoutgoing.forbid 1" >> ../a/.hg/hgrc
299 $ echo "preoutgoing.forbid = python \"$TESTDIR/printenv.py\" preoutgoing.forbid 1" >> ../a/.hg/hgrc
301 $ hg pull ../a
300 $ hg pull ../a
302 pulling from ../a
301 pulling from ../a
303 searching for changes
302 searching for changes
304 preoutgoing hook: HG_SOURCE=pull
303 preoutgoing hook: HG_SOURCE=pull
305 preoutgoing.forbid hook: HG_SOURCE=pull
304 preoutgoing.forbid hook: HG_SOURCE=pull
306 abort: preoutgoing.forbid hook exited with status 1
305 abort: preoutgoing.forbid hook exited with status 1
307 [255]
306 [255]
308
307
309 outgoing hooks work for local clones
308 outgoing hooks work for local clones
310
309
311 $ cd ..
310 $ cd ..
312 $ cat > a/.hg/hgrc <<EOF
311 $ cat > a/.hg/hgrc <<EOF
313 > [hooks]
312 > [hooks]
314 > preoutgoing = python "$TESTDIR/printenv.py" preoutgoing
313 > preoutgoing = python "$TESTDIR/printenv.py" preoutgoing
315 > outgoing = python "$TESTDIR/printenv.py" outgoing
314 > outgoing = python "$TESTDIR/printenv.py" outgoing
316 > EOF
315 > EOF
317 $ hg clone a c
316 $ hg clone a c
318 preoutgoing hook: HG_SOURCE=clone
317 preoutgoing hook: HG_SOURCE=clone
319 outgoing hook: HG_NODE=0000000000000000000000000000000000000000 HG_SOURCE=clone
318 outgoing hook: HG_NODE=0000000000000000000000000000000000000000 HG_SOURCE=clone
320 updating to branch default
319 updating to branch default
321 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
320 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
322 $ rm -rf c
321 $ rm -rf c
323
322
324 preoutgoing hook can prevent outgoing changes for local clones
323 preoutgoing hook can prevent outgoing changes for local clones
325
324
326 $ echo "preoutgoing.forbid = python \"$TESTDIR/printenv.py\" preoutgoing.forbid 1" >> a/.hg/hgrc
325 $ echo "preoutgoing.forbid = python \"$TESTDIR/printenv.py\" preoutgoing.forbid 1" >> a/.hg/hgrc
327 $ hg clone a zzz
326 $ hg clone a zzz
328 preoutgoing hook: HG_SOURCE=clone
327 preoutgoing hook: HG_SOURCE=clone
329 preoutgoing.forbid hook: HG_SOURCE=clone
328 preoutgoing.forbid hook: HG_SOURCE=clone
330 abort: preoutgoing.forbid hook exited with status 1
329 abort: preoutgoing.forbid hook exited with status 1
331 [255]
330 [255]
332
331
333 $ cd "$TESTTMP/b"
332 $ cd "$TESTTMP/b"
334
333
335 $ cat > hooktests.py <<EOF
334 $ cat > hooktests.py <<EOF
336 > from mercurial import util
335 > from mercurial import util
337 >
336 >
338 > uncallable = 0
337 > uncallable = 0
339 >
338 >
340 > def printargs(args):
339 > def printargs(args):
341 > args.pop('ui', None)
340 > args.pop('ui', None)
342 > args.pop('repo', None)
341 > args.pop('repo', None)
343 > a = list(args.items())
342 > a = list(args.items())
344 > a.sort()
343 > a.sort()
345 > print 'hook args:'
344 > print 'hook args:'
346 > for k, v in a:
345 > for k, v in a:
347 > print ' ', k, v
346 > print ' ', k, v
348 >
347 >
349 > def passhook(**args):
348 > def passhook(**args):
350 > printargs(args)
349 > printargs(args)
351 >
350 >
352 > def failhook(**args):
351 > def failhook(**args):
353 > printargs(args)
352 > printargs(args)
354 > return True
353 > return True
355 >
354 >
356 > class LocalException(Exception):
355 > class LocalException(Exception):
357 > pass
356 > pass
358 >
357 >
359 > def raisehook(**args):
358 > def raisehook(**args):
360 > raise LocalException('exception from hook')
359 > raise LocalException('exception from hook')
361 >
360 >
362 > def aborthook(**args):
361 > def aborthook(**args):
363 > raise util.Abort('raise abort from hook')
362 > raise util.Abort('raise abort from hook')
364 >
363 >
365 > def brokenhook(**args):
364 > def brokenhook(**args):
366 > return 1 + {}
365 > return 1 + {}
367 >
366 >
368 > def verbosehook(ui, **args):
367 > def verbosehook(ui, **args):
369 > ui.note('verbose output from hook\n')
368 > ui.note('verbose output from hook\n')
370 >
369 >
371 > def printtags(ui, repo, **args):
370 > def printtags(ui, repo, **args):
372 > print sorted(repo.tags())
371 > print sorted(repo.tags())
373 >
372 >
374 > class container:
373 > class container:
375 > unreachable = 1
374 > unreachable = 1
376 > EOF
375 > EOF
377
376
378 test python hooks
377 test python hooks
379
378
380 #if windows
379 #if windows
381 $ PYTHONPATH="$TESTTMP/b;$PYTHONPATH"
380 $ PYTHONPATH="$TESTTMP/b;$PYTHONPATH"
382 #else
381 #else
383 $ PYTHONPATH="$TESTTMP/b:$PYTHONPATH"
382 $ PYTHONPATH="$TESTTMP/b:$PYTHONPATH"
384 #endif
383 #endif
385 $ export PYTHONPATH
384 $ export PYTHONPATH
386
385
387 $ echo '[hooks]' > ../a/.hg/hgrc
386 $ echo '[hooks]' > ../a/.hg/hgrc
388 $ echo 'preoutgoing.broken = python:hooktests.brokenhook' >> ../a/.hg/hgrc
387 $ echo 'preoutgoing.broken = python:hooktests.brokenhook' >> ../a/.hg/hgrc
389 $ hg pull ../a 2>&1 | grep 'raised an exception'
388 $ hg pull ../a 2>&1 | grep 'raised an exception'
390 error: preoutgoing.broken hook raised an exception: unsupported operand type(s) for +: 'int' and 'dict'
389 error: preoutgoing.broken hook raised an exception: unsupported operand type(s) for +: 'int' and 'dict'
391
390
392 $ echo '[hooks]' > ../a/.hg/hgrc
391 $ echo '[hooks]' > ../a/.hg/hgrc
393 $ echo 'preoutgoing.raise = python:hooktests.raisehook' >> ../a/.hg/hgrc
392 $ echo 'preoutgoing.raise = python:hooktests.raisehook' >> ../a/.hg/hgrc
394 $ hg pull ../a 2>&1 | grep 'raised an exception'
393 $ hg pull ../a 2>&1 | grep 'raised an exception'
395 error: preoutgoing.raise hook raised an exception: exception from hook
394 error: preoutgoing.raise hook raised an exception: exception from hook
396
395
397 $ echo '[hooks]' > ../a/.hg/hgrc
396 $ echo '[hooks]' > ../a/.hg/hgrc
398 $ echo 'preoutgoing.abort = python:hooktests.aborthook' >> ../a/.hg/hgrc
397 $ echo 'preoutgoing.abort = python:hooktests.aborthook' >> ../a/.hg/hgrc
399 $ hg pull ../a
398 $ hg pull ../a
400 pulling from ../a
399 pulling from ../a
401 searching for changes
400 searching for changes
402 error: preoutgoing.abort hook failed: raise abort from hook
401 error: preoutgoing.abort hook failed: raise abort from hook
403 abort: raise abort from hook
402 abort: raise abort from hook
404 [255]
403 [255]
405
404
406 $ echo '[hooks]' > ../a/.hg/hgrc
405 $ echo '[hooks]' > ../a/.hg/hgrc
407 $ echo 'preoutgoing.fail = python:hooktests.failhook' >> ../a/.hg/hgrc
406 $ echo 'preoutgoing.fail = python:hooktests.failhook' >> ../a/.hg/hgrc
408 $ hg pull ../a
407 $ hg pull ../a
409 pulling from ../a
408 pulling from ../a
410 searching for changes
409 searching for changes
411 hook args:
410 hook args:
412 hooktype preoutgoing
411 hooktype preoutgoing
413 source pull
412 source pull
414 abort: preoutgoing.fail hook failed
413 abort: preoutgoing.fail hook failed
415 [255]
414 [255]
416
415
417 $ echo '[hooks]' > ../a/.hg/hgrc
416 $ echo '[hooks]' > ../a/.hg/hgrc
418 $ echo 'preoutgoing.uncallable = python:hooktests.uncallable' >> ../a/.hg/hgrc
417 $ echo 'preoutgoing.uncallable = python:hooktests.uncallable' >> ../a/.hg/hgrc
419 $ hg pull ../a
418 $ hg pull ../a
420 pulling from ../a
419 pulling from ../a
421 searching for changes
420 searching for changes
422 abort: preoutgoing.uncallable hook is invalid ("hooktests.uncallable" is not callable)
421 abort: preoutgoing.uncallable hook is invalid ("hooktests.uncallable" is not callable)
423 [255]
422 [255]
424
423
425 $ echo '[hooks]' > ../a/.hg/hgrc
424 $ echo '[hooks]' > ../a/.hg/hgrc
426 $ echo 'preoutgoing.nohook = python:hooktests.nohook' >> ../a/.hg/hgrc
425 $ echo 'preoutgoing.nohook = python:hooktests.nohook' >> ../a/.hg/hgrc
427 $ hg pull ../a
426 $ hg pull ../a
428 pulling from ../a
427 pulling from ../a
429 searching for changes
428 searching for changes
430 abort: preoutgoing.nohook hook is invalid ("hooktests.nohook" is not defined)
429 abort: preoutgoing.nohook hook is invalid ("hooktests.nohook" is not defined)
431 [255]
430 [255]
432
431
433 $ echo '[hooks]' > ../a/.hg/hgrc
432 $ echo '[hooks]' > ../a/.hg/hgrc
434 $ echo 'preoutgoing.nomodule = python:nomodule' >> ../a/.hg/hgrc
433 $ echo 'preoutgoing.nomodule = python:nomodule' >> ../a/.hg/hgrc
435 $ hg pull ../a
434 $ hg pull ../a
436 pulling from ../a
435 pulling from ../a
437 searching for changes
436 searching for changes
438 abort: preoutgoing.nomodule hook is invalid ("nomodule" not in a module)
437 abort: preoutgoing.nomodule hook is invalid ("nomodule" not in a module)
439 [255]
438 [255]
440
439
441 $ echo '[hooks]' > ../a/.hg/hgrc
440 $ echo '[hooks]' > ../a/.hg/hgrc
442 $ echo 'preoutgoing.badmodule = python:nomodule.nowhere' >> ../a/.hg/hgrc
441 $ echo 'preoutgoing.badmodule = python:nomodule.nowhere' >> ../a/.hg/hgrc
443 $ hg pull ../a
442 $ hg pull ../a
444 pulling from ../a
443 pulling from ../a
445 searching for changes
444 searching for changes
446 abort: preoutgoing.badmodule hook is invalid (import of "nomodule" failed)
445 abort: preoutgoing.badmodule hook is invalid (import of "nomodule" failed)
447 [255]
446 [255]
448
447
449 $ echo '[hooks]' > ../a/.hg/hgrc
448 $ echo '[hooks]' > ../a/.hg/hgrc
450 $ echo 'preoutgoing.unreachable = python:hooktests.container.unreachable' >> ../a/.hg/hgrc
449 $ echo 'preoutgoing.unreachable = python:hooktests.container.unreachable' >> ../a/.hg/hgrc
451 $ hg pull ../a
450 $ hg pull ../a
452 pulling from ../a
451 pulling from ../a
453 searching for changes
452 searching for changes
454 abort: preoutgoing.unreachable hook is invalid (import of "hooktests.container" failed)
453 abort: preoutgoing.unreachable hook is invalid (import of "hooktests.container" failed)
455 [255]
454 [255]
456
455
457 $ echo '[hooks]' > ../a/.hg/hgrc
456 $ echo '[hooks]' > ../a/.hg/hgrc
458 $ echo 'preoutgoing.pass = python:hooktests.passhook' >> ../a/.hg/hgrc
457 $ echo 'preoutgoing.pass = python:hooktests.passhook' >> ../a/.hg/hgrc
459 $ hg pull ../a
458 $ hg pull ../a
460 pulling from ../a
459 pulling from ../a
461 searching for changes
460 searching for changes
462 hook args:
461 hook args:
463 hooktype preoutgoing
462 hooktype preoutgoing
464 source pull
463 source pull
465 adding changesets
464 adding changesets
466 adding manifests
465 adding manifests
467 adding file changes
466 adding file changes
468 added 1 changesets with 1 changes to 1 files
467 added 1 changesets with 1 changes to 1 files
469 adding remote bookmark quux
468 adding remote bookmark quux
470 (run 'hg update' to get a working copy)
469 (run 'hg update' to get a working copy)
471
470
472 make sure --traceback works
471 make sure --traceback works
473
472
474 $ echo '[hooks]' > .hg/hgrc
473 $ echo '[hooks]' > .hg/hgrc
475 $ echo 'commit.abort = python:hooktests.aborthook' >> .hg/hgrc
474 $ echo 'commit.abort = python:hooktests.aborthook' >> .hg/hgrc
476
475
477 $ echo aa > a
476 $ echo aa > a
478 $ hg --traceback commit -d '0 0' -ma 2>&1 | grep '^Traceback'
477 $ hg --traceback commit -d '0 0' -ma 2>&1 | grep '^Traceback'
479 Traceback (most recent call last):
478 Traceback (most recent call last):
480
479
481 $ cd ..
480 $ cd ..
482 $ hg init c
481 $ hg init c
483 $ cd c
482 $ cd c
484
483
485 $ cat > hookext.py <<EOF
484 $ cat > hookext.py <<EOF
486 > def autohook(**args):
485 > def autohook(**args):
487 > print "Automatically installed hook"
486 > print "Automatically installed hook"
488 >
487 >
489 > def reposetup(ui, repo):
488 > def reposetup(ui, repo):
490 > repo.ui.setconfig("hooks", "commit.auto", autohook)
489 > repo.ui.setconfig("hooks", "commit.auto", autohook)
491 > EOF
490 > EOF
492 $ echo '[extensions]' >> .hg/hgrc
491 $ echo '[extensions]' >> .hg/hgrc
493 $ echo 'hookext = hookext.py' >> .hg/hgrc
492 $ echo 'hookext = hookext.py' >> .hg/hgrc
494
493
495 $ touch foo
494 $ touch foo
496 $ hg add foo
495 $ hg add foo
497 $ hg ci -d '0 0' -m 'add foo'
496 $ hg ci -d '0 0' -m 'add foo'
498 Automatically installed hook
497 Automatically installed hook
499 $ echo >> foo
498 $ echo >> foo
500 $ hg ci --debug -d '0 0' -m 'change foo'
499 $ hg ci --debug -d '0 0' -m 'change foo'
501 foo
500 foo
502 calling hook commit.auto: hgext_hookext.autohook
501 calling hook commit.auto: hgext_hookext.autohook
503 Automatically installed hook
502 Automatically installed hook
504 committed changeset 1:52998019f6252a2b893452765fcb0a47351a5708
503 committed changeset 1:52998019f6252a2b893452765fcb0a47351a5708
505
504
506 $ hg showconfig hooks
505 $ hg showconfig hooks
507 hooks.commit.auto=<function autohook at *> (glob)
506 hooks.commit.auto=<function autohook at *> (glob)
508
507
509 test python hook configured with python:[file]:[hook] syntax
508 test python hook configured with python:[file]:[hook] syntax
510
509
511 $ cd ..
510 $ cd ..
512 $ mkdir d
511 $ mkdir d
513 $ cd d
512 $ cd d
514 $ hg init repo
513 $ hg init repo
515 $ mkdir hooks
514 $ mkdir hooks
516
515
517 $ cd hooks
516 $ cd hooks
518 $ cat > testhooks.py <<EOF
517 $ cat > testhooks.py <<EOF
519 > def testhook(**args):
518 > def testhook(**args):
520 > print 'hook works'
519 > print 'hook works'
521 > EOF
520 > EOF
522 $ echo '[hooks]' > ../repo/.hg/hgrc
521 $ echo '[hooks]' > ../repo/.hg/hgrc
523 $ echo "pre-commit.test = python:`pwd`/testhooks.py:testhook" >> ../repo/.hg/hgrc
522 $ echo "pre-commit.test = python:`pwd`/testhooks.py:testhook" >> ../repo/.hg/hgrc
524
523
525 $ cd ../repo
524 $ cd ../repo
526 $ hg commit -d '0 0'
525 $ hg commit -d '0 0'
527 hook works
526 hook works
528 nothing changed
527 nothing changed
529 [1]
528 [1]
530
529
531 $ echo '[hooks]' > .hg/hgrc
530 $ echo '[hooks]' > .hg/hgrc
532 $ echo "update.ne = python:`pwd`/nonexistent.py:testhook" >> .hg/hgrc
531 $ echo "update.ne = python:`pwd`/nonexistent.py:testhook" >> .hg/hgrc
533 $ echo "pre-identify.npmd = python:`pwd`/:no_python_module_dir" >> .hg/hgrc
532 $ echo "pre-identify.npmd = python:`pwd`/:no_python_module_dir" >> .hg/hgrc
534
533
535 $ hg up null
534 $ hg up null
536 loading update.ne hook failed:
535 loading update.ne hook failed:
537 abort: No such file or directory: $TESTTMP/d/repo/nonexistent.py
536 abort: No such file or directory: $TESTTMP/d/repo/nonexistent.py
538 [255]
537 [255]
539
538
540 $ hg id
539 $ hg id
541 loading pre-identify.npmd hook failed:
540 loading pre-identify.npmd hook failed:
542 abort: No module named repo!
541 abort: No module named repo!
543 [255]
542 [255]
544
543
545 $ cd ../../b
544 $ cd ../../b
546
545
547 make sure --traceback works on hook import failure
546 make sure --traceback works on hook import failure
548
547
549 $ cat > importfail.py <<EOF
548 $ cat > importfail.py <<EOF
550 > import somebogusmodule
549 > import somebogusmodule
551 > # dereference something in the module to force demandimport to load it
550 > # dereference something in the module to force demandimport to load it
552 > somebogusmodule.whatever
551 > somebogusmodule.whatever
553 > EOF
552 > EOF
554
553
555 $ echo '[hooks]' > .hg/hgrc
554 $ echo '[hooks]' > .hg/hgrc
556 $ echo 'precommit.importfail = python:importfail.whatever' >> .hg/hgrc
555 $ echo 'precommit.importfail = python:importfail.whatever' >> .hg/hgrc
557
556
558 $ echo a >> a
557 $ echo a >> a
559 $ hg --traceback commit -ma 2>&1 | egrep -v '^( +File| [a-zA-Z(])'
558 $ hg --traceback commit -ma 2>&1 | egrep -v '^( +File| [a-zA-Z(])'
560 exception from first failed import attempt:
559 exception from first failed import attempt:
561 Traceback (most recent call last):
560 Traceback (most recent call last):
562 ImportError: No module named somebogusmodule
561 ImportError: No module named somebogusmodule
563 exception from second failed import attempt:
562 exception from second failed import attempt:
564 Traceback (most recent call last):
563 Traceback (most recent call last):
565 ImportError: No module named hgext_importfail
564 ImportError: No module named hgext_importfail
566 Traceback (most recent call last):
565 Traceback (most recent call last):
567 Abort: precommit.importfail hook is invalid (import of "importfail" failed)
566 Abort: precommit.importfail hook is invalid (import of "importfail" failed)
568 abort: precommit.importfail hook is invalid (import of "importfail" failed)
567 abort: precommit.importfail hook is invalid (import of "importfail" failed)
569
568
570 Issue1827: Hooks Update & Commit not completely post operation
569 Issue1827: Hooks Update & Commit not completely post operation
571
570
572 commit and update hooks should run after command completion
571 commit and update hooks should run after command completion
573
572
574 $ echo '[hooks]' > .hg/hgrc
573 $ echo '[hooks]' > .hg/hgrc
575 $ echo 'commit = hg id' >> .hg/hgrc
574 $ echo 'commit = hg id' >> .hg/hgrc
576 $ echo 'update = hg id' >> .hg/hgrc
575 $ echo 'update = hg id' >> .hg/hgrc
577 $ echo bb > a
576 $ echo bb > a
578 $ hg ci -ma
577 $ hg ci -ma
579 223eafe2750c tip
578 223eafe2750c tip
580 $ hg up 0
579 $ hg up 0
581 cb9a9f314b8b
580 cb9a9f314b8b
582 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
581 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
583
582
584 make sure --verbose (and --quiet/--debug etc.) are propagated to the local ui
583 make sure --verbose (and --quiet/--debug etc.) are propagated to the local ui
585 that is passed to pre/post hooks
584 that is passed to pre/post hooks
586
585
587 $ echo '[hooks]' > .hg/hgrc
586 $ echo '[hooks]' > .hg/hgrc
588 $ echo 'pre-identify = python:hooktests.verbosehook' >> .hg/hgrc
587 $ echo 'pre-identify = python:hooktests.verbosehook' >> .hg/hgrc
589 $ hg id
588 $ hg id
590 cb9a9f314b8b
589 cb9a9f314b8b
591 $ hg id --verbose
590 $ hg id --verbose
592 calling hook pre-identify: hooktests.verbosehook
591 calling hook pre-identify: hooktests.verbosehook
593 verbose output from hook
592 verbose output from hook
594 cb9a9f314b8b
593 cb9a9f314b8b
595
594
596 Ensure hooks can be prioritized
595 Ensure hooks can be prioritized
597
596
598 $ echo '[hooks]' > .hg/hgrc
597 $ echo '[hooks]' > .hg/hgrc
599 $ echo 'pre-identify.a = python:hooktests.verbosehook' >> .hg/hgrc
598 $ echo 'pre-identify.a = python:hooktests.verbosehook' >> .hg/hgrc
600 $ echo 'pre-identify.b = python:hooktests.verbosehook' >> .hg/hgrc
599 $ echo 'pre-identify.b = python:hooktests.verbosehook' >> .hg/hgrc
601 $ echo 'priority.pre-identify.b = 1' >> .hg/hgrc
600 $ echo 'priority.pre-identify.b = 1' >> .hg/hgrc
602 $ echo 'pre-identify.c = python:hooktests.verbosehook' >> .hg/hgrc
601 $ echo 'pre-identify.c = python:hooktests.verbosehook' >> .hg/hgrc
603 $ hg id --verbose
602 $ hg id --verbose
604 calling hook pre-identify.b: hooktests.verbosehook
603 calling hook pre-identify.b: hooktests.verbosehook
605 verbose output from hook
604 verbose output from hook
606 calling hook pre-identify.a: hooktests.verbosehook
605 calling hook pre-identify.a: hooktests.verbosehook
607 verbose output from hook
606 verbose output from hook
608 calling hook pre-identify.c: hooktests.verbosehook
607 calling hook pre-identify.c: hooktests.verbosehook
609 verbose output from hook
608 verbose output from hook
610 cb9a9f314b8b
609 cb9a9f314b8b
611
610
612 new tags must be visible in pretxncommit (issue3210)
611 new tags must be visible in pretxncommit (issue3210)
613
612
614 $ echo 'pretxncommit.printtags = python:hooktests.printtags' >> .hg/hgrc
613 $ echo 'pretxncommit.printtags = python:hooktests.printtags' >> .hg/hgrc
615 $ hg tag -f foo
614 $ hg tag -f foo
616 ['a', 'foo', 'tip']
615 ['a', 'foo', 'tip']
617
616
618 new commits must be visible in pretxnchangegroup (issue3428)
617 new commits must be visible in pretxnchangegroup (issue3428)
619
618
620 $ cd ..
619 $ cd ..
621 $ hg init to
620 $ hg init to
622 $ echo '[hooks]' >> to/.hg/hgrc
621 $ echo '[hooks]' >> to/.hg/hgrc
623 $ echo 'pretxnchangegroup = hg --traceback tip' >> to/.hg/hgrc
622 $ echo 'pretxnchangegroup = hg --traceback tip' >> to/.hg/hgrc
624 $ echo a >> to/a
623 $ echo a >> to/a
625 $ hg --cwd to ci -Ama
624 $ hg --cwd to ci -Ama
626 adding a
625 adding a
627 $ hg clone to from
626 $ hg clone to from
628 updating to branch default
627 updating to branch default
629 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
628 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
630 $ echo aa >> from/a
629 $ echo aa >> from/a
631 $ hg --cwd from ci -mb
630 $ hg --cwd from ci -mb
632 $ hg --cwd from push
631 $ hg --cwd from push
633 pushing to $TESTTMP/to (glob)
632 pushing to $TESTTMP/to (glob)
634 searching for changes
633 searching for changes
635 adding changesets
634 adding changesets
636 adding manifests
635 adding manifests
637 adding file changes
636 adding file changes
638 added 1 changesets with 1 changes to 1 files
637 added 1 changesets with 1 changes to 1 files
639 changeset: 1:9836a07b9b9d
638 changeset: 1:9836a07b9b9d
640 tag: tip
639 tag: tip
641 user: test
640 user: test
642 date: Thu Jan 01 00:00:00 1970 +0000
641 date: Thu Jan 01 00:00:00 1970 +0000
643 summary: b
642 summary: b
644
643
@@ -1,432 +1,431 b''
1
1
2
2
3 This test tries to exercise the ssh functionality with a dummy script
3 This test tries to exercise the ssh functionality with a dummy script
4
4
5 creating 'remote' repo
5 creating 'remote' repo
6
6
7 $ hg init remote
7 $ hg init remote
8 $ cd remote
8 $ cd remote
9 $ echo this > foo
9 $ echo this > foo
10 $ echo this > fooO
10 $ echo this > fooO
11 $ hg ci -A -m "init" foo fooO
11 $ hg ci -A -m "init" foo fooO
12 $ cat <<EOF > .hg/hgrc
12 $ cat <<EOF > .hg/hgrc
13 > [server]
13 > [server]
14 > uncompressed = True
14 > uncompressed = True
15 >
15 >
16 > [hooks]
16 > [hooks]
17 > changegroup = python "$TESTDIR/printenv.py" changegroup-in-remote 0 ../dummylog
17 > changegroup = python "$TESTDIR/printenv.py" changegroup-in-remote 0 ../dummylog
18 > EOF
18 > EOF
19 $ cd ..
19 $ cd ..
20
20
21 repo not found error
21 repo not found error
22
22
23 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/nonexistent local
23 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/nonexistent local
24 remote: abort: there is no Mercurial repository here (.hg not found)!
24 remote: abort: there is no Mercurial repository here (.hg not found)!
25 abort: no suitable response from remote hg!
25 abort: no suitable response from remote hg!
26 [255]
26 [255]
27
27
28 non-existent absolute path
28 non-existent absolute path
29
29
30 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy//`pwd`/nonexistent local
30 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy//`pwd`/nonexistent local
31 remote: abort: there is no Mercurial repository here (.hg not found)!
31 remote: abort: there is no Mercurial repository here (.hg not found)!
32 abort: no suitable response from remote hg!
32 abort: no suitable response from remote hg!
33 [255]
33 [255]
34
34
35 clone remote via stream
35 clone remote via stream
36
36
37 $ hg clone -e "python \"$TESTDIR/dummyssh\"" --uncompressed ssh://user@dummy/remote local-stream
37 $ hg clone -e "python \"$TESTDIR/dummyssh\"" --uncompressed ssh://user@dummy/remote local-stream
38 streaming all changes
38 streaming all changes
39 4 files to transfer, 392 bytes of data
39 4 files to transfer, 392 bytes of data
40 transferred 392 bytes in * seconds (*/sec) (glob)
40 transferred 392 bytes in * seconds (*/sec) (glob)
41 updating to branch default
41 updating to branch default
42 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
42 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
43 $ cd local-stream
43 $ cd local-stream
44 $ hg verify
44 $ hg verify
45 checking changesets
45 checking changesets
46 checking manifests
46 checking manifests
47 crosschecking files in changesets and manifests
47 crosschecking files in changesets and manifests
48 checking files
48 checking files
49 2 files, 1 changesets, 2 total revisions
49 2 files, 1 changesets, 2 total revisions
50 $ cd ..
50 $ cd ..
51
51
52 clone remote via pull
52 clone remote via pull
53
53
54 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote local
54 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote local
55 requesting all changes
55 requesting all changes
56 adding changesets
56 adding changesets
57 adding manifests
57 adding manifests
58 adding file changes
58 adding file changes
59 added 1 changesets with 2 changes to 2 files
59 added 1 changesets with 2 changes to 2 files
60 updating to branch default
60 updating to branch default
61 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
61 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
62
62
63 verify
63 verify
64
64
65 $ cd local
65 $ cd local
66 $ hg verify
66 $ hg verify
67 checking changesets
67 checking changesets
68 checking manifests
68 checking manifests
69 crosschecking files in changesets and manifests
69 crosschecking files in changesets and manifests
70 checking files
70 checking files
71 2 files, 1 changesets, 2 total revisions
71 2 files, 1 changesets, 2 total revisions
72 $ echo '[hooks]' >> .hg/hgrc
72 $ echo '[hooks]' >> .hg/hgrc
73 $ echo "changegroup = python \"$TESTDIR/printenv.py\" changegroup-in-local 0 ../dummylog" >> .hg/hgrc
73 $ echo "changegroup = python \"$TESTDIR/printenv.py\" changegroup-in-local 0 ../dummylog" >> .hg/hgrc
74
74
75 empty default pull
75 empty default pull
76
76
77 $ hg paths
77 $ hg paths
78 default = ssh://user@dummy/remote
78 default = ssh://user@dummy/remote
79 $ hg pull -e "python \"$TESTDIR/dummyssh\""
79 $ hg pull -e "python \"$TESTDIR/dummyssh\""
80 pulling from ssh://user@dummy/remote
80 pulling from ssh://user@dummy/remote
81 searching for changes
81 searching for changes
82 no changes found
82 no changes found
83
83
84 local change
84 local change
85
85
86 $ echo bleah > foo
86 $ echo bleah > foo
87 $ hg ci -m "add"
87 $ hg ci -m "add"
88
88
89 updating rc
89 updating rc
90
90
91 $ echo "default-push = ssh://user@dummy/remote" >> .hg/hgrc
91 $ echo "default-push = ssh://user@dummy/remote" >> .hg/hgrc
92 $ echo "[ui]" >> .hg/hgrc
92 $ echo "[ui]" >> .hg/hgrc
93 $ echo "ssh = python \"$TESTDIR/dummyssh\"" >> .hg/hgrc
93 $ echo "ssh = python \"$TESTDIR/dummyssh\"" >> .hg/hgrc
94
94
95 find outgoing
95 find outgoing
96
96
97 $ hg out ssh://user@dummy/remote
97 $ hg out ssh://user@dummy/remote
98 comparing with ssh://user@dummy/remote
98 comparing with ssh://user@dummy/remote
99 searching for changes
99 searching for changes
100 changeset: 1:a28a9d1a809c
100 changeset: 1:a28a9d1a809c
101 tag: tip
101 tag: tip
102 user: test
102 user: test
103 date: Thu Jan 01 00:00:00 1970 +0000
103 date: Thu Jan 01 00:00:00 1970 +0000
104 summary: add
104 summary: add
105
105
106
106
107 find incoming on the remote side
107 find incoming on the remote side
108
108
109 $ hg incoming -R ../remote -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/local
109 $ hg incoming -R ../remote -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/local
110 comparing with ssh://user@dummy/local
110 comparing with ssh://user@dummy/local
111 searching for changes
111 searching for changes
112 changeset: 1:a28a9d1a809c
112 changeset: 1:a28a9d1a809c
113 tag: tip
113 tag: tip
114 user: test
114 user: test
115 date: Thu Jan 01 00:00:00 1970 +0000
115 date: Thu Jan 01 00:00:00 1970 +0000
116 summary: add
116 summary: add
117
117
118
118
119 find incoming on the remote side (using absolute path)
119 find incoming on the remote side (using absolute path)
120
120
121 $ hg incoming -R ../remote -e "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/`pwd`"
121 $ hg incoming -R ../remote -e "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/`pwd`"
122 comparing with ssh://user@dummy/$TESTTMP/local
122 comparing with ssh://user@dummy/$TESTTMP/local
123 searching for changes
123 searching for changes
124 changeset: 1:a28a9d1a809c
124 changeset: 1:a28a9d1a809c
125 tag: tip
125 tag: tip
126 user: test
126 user: test
127 date: Thu Jan 01 00:00:00 1970 +0000
127 date: Thu Jan 01 00:00:00 1970 +0000
128 summary: add
128 summary: add
129
129
130
130
131 push
131 push
132
132
133 $ hg push
133 $ hg push
134 pushing to ssh://user@dummy/remote
134 pushing to ssh://user@dummy/remote
135 searching for changes
135 searching for changes
136 remote: adding changesets
136 remote: adding changesets
137 remote: adding manifests
137 remote: adding manifests
138 remote: adding file changes
138 remote: adding file changes
139 remote: added 1 changesets with 1 changes to 1 files
139 remote: added 1 changesets with 1 changes to 1 files
140 $ cd ../remote
140 $ cd ../remote
141
141
142 check remote tip
142 check remote tip
143
143
144 $ hg tip
144 $ hg tip
145 changeset: 1:a28a9d1a809c
145 changeset: 1:a28a9d1a809c
146 tag: tip
146 tag: tip
147 user: test
147 user: test
148 date: Thu Jan 01 00:00:00 1970 +0000
148 date: Thu Jan 01 00:00:00 1970 +0000
149 summary: add
149 summary: add
150
150
151 $ hg verify
151 $ hg verify
152 checking changesets
152 checking changesets
153 checking manifests
153 checking manifests
154 crosschecking files in changesets and manifests
154 crosschecking files in changesets and manifests
155 checking files
155 checking files
156 2 files, 2 changesets, 3 total revisions
156 2 files, 2 changesets, 3 total revisions
157 $ hg cat -r tip foo
157 $ hg cat -r tip foo
158 bleah
158 bleah
159 $ echo z > z
159 $ echo z > z
160 $ hg ci -A -m z z
160 $ hg ci -A -m z z
161 created new head
161 created new head
162
162
163 test pushkeys and bookmarks
163 test pushkeys and bookmarks
164
164
165 $ cd ../local
165 $ cd ../local
166 $ hg debugpushkey --config ui.ssh="python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote namespaces
166 $ hg debugpushkey --config ui.ssh="python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote namespaces
167 bookmarks
167 bookmarks
168 namespaces
168 namespaces
169 phases
169 phases
170 $ hg book foo -r 0
170 $ hg book foo -r 0
171 $ hg out -B
171 $ hg out -B
172 comparing with ssh://user@dummy/remote
172 comparing with ssh://user@dummy/remote
173 searching for changed bookmarks
173 searching for changed bookmarks
174 foo 1160648e36ce
174 foo 1160648e36ce
175 $ hg push -B foo
175 $ hg push -B foo
176 pushing to ssh://user@dummy/remote
176 pushing to ssh://user@dummy/remote
177 searching for changes
177 searching for changes
178 no changes found
178 no changes found
179 exporting bookmark foo
179 exporting bookmark foo
180 [1]
180 [1]
181 $ hg debugpushkey --config ui.ssh="python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote bookmarks
181 $ hg debugpushkey --config ui.ssh="python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote bookmarks
182 foo 1160648e36cec0054048a7edc4110c6f84fde594
182 foo 1160648e36cec0054048a7edc4110c6f84fde594
183 $ hg book -f foo
183 $ hg book -f foo
184 $ hg push --traceback
184 $ hg push --traceback
185 pushing to ssh://user@dummy/remote
185 pushing to ssh://user@dummy/remote
186 searching for changes
186 searching for changes
187 no changes found
187 no changes found
188 updating bookmark foo
188 updating bookmark foo
189 [1]
189 [1]
190 $ hg book -d foo
190 $ hg book -d foo
191 $ hg in -B
191 $ hg in -B
192 comparing with ssh://user@dummy/remote
192 comparing with ssh://user@dummy/remote
193 searching for changed bookmarks
193 searching for changed bookmarks
194 foo a28a9d1a809c
194 foo a28a9d1a809c
195 $ hg book -f -r 0 foo
195 $ hg book -f -r 0 foo
196 $ hg pull -B foo
196 $ hg pull -B foo
197 pulling from ssh://user@dummy/remote
197 pulling from ssh://user@dummy/remote
198 no changes found
198 no changes found
199 updating bookmark foo
199 updating bookmark foo
200 importing bookmark foo
201 $ hg book -d foo
200 $ hg book -d foo
202 $ hg push -B foo
201 $ hg push -B foo
203 pushing to ssh://user@dummy/remote
202 pushing to ssh://user@dummy/remote
204 searching for changes
203 searching for changes
205 no changes found
204 no changes found
206 deleting remote bookmark foo
205 deleting remote bookmark foo
207 [1]
206 [1]
208
207
209 a bad, evil hook that prints to stdout
208 a bad, evil hook that prints to stdout
210
209
211 $ cat <<EOF > $TESTTMP/badhook
210 $ cat <<EOF > $TESTTMP/badhook
212 > import sys
211 > import sys
213 > sys.stdout.write("KABOOM\n")
212 > sys.stdout.write("KABOOM\n")
214 > EOF
213 > EOF
215
214
216 $ echo '[hooks]' >> ../remote/.hg/hgrc
215 $ echo '[hooks]' >> ../remote/.hg/hgrc
217 $ echo "changegroup.stdout = python $TESTTMP/badhook" >> ../remote/.hg/hgrc
216 $ echo "changegroup.stdout = python $TESTTMP/badhook" >> ../remote/.hg/hgrc
218 $ echo r > r
217 $ echo r > r
219 $ hg ci -A -m z r
218 $ hg ci -A -m z r
220
219
221 push should succeed even though it has an unexpected response
220 push should succeed even though it has an unexpected response
222
221
223 $ hg push
222 $ hg push
224 pushing to ssh://user@dummy/remote
223 pushing to ssh://user@dummy/remote
225 searching for changes
224 searching for changes
226 remote has heads on branch 'default' that are not known locally: 6c0482d977a3
225 remote has heads on branch 'default' that are not known locally: 6c0482d977a3
227 remote: adding changesets
226 remote: adding changesets
228 remote: adding manifests
227 remote: adding manifests
229 remote: adding file changes
228 remote: adding file changes
230 remote: added 1 changesets with 1 changes to 1 files
229 remote: added 1 changesets with 1 changes to 1 files
231 remote: KABOOM
230 remote: KABOOM
232 $ hg -R ../remote heads
231 $ hg -R ../remote heads
233 changeset: 3:1383141674ec
232 changeset: 3:1383141674ec
234 tag: tip
233 tag: tip
235 parent: 1:a28a9d1a809c
234 parent: 1:a28a9d1a809c
236 user: test
235 user: test
237 date: Thu Jan 01 00:00:00 1970 +0000
236 date: Thu Jan 01 00:00:00 1970 +0000
238 summary: z
237 summary: z
239
238
240 changeset: 2:6c0482d977a3
239 changeset: 2:6c0482d977a3
241 parent: 0:1160648e36ce
240 parent: 0:1160648e36ce
242 user: test
241 user: test
243 date: Thu Jan 01 00:00:00 1970 +0000
242 date: Thu Jan 01 00:00:00 1970 +0000
244 summary: z
243 summary: z
245
244
246
245
247 clone bookmarks
246 clone bookmarks
248
247
249 $ hg -R ../remote bookmark test
248 $ hg -R ../remote bookmark test
250 $ hg -R ../remote bookmarks
249 $ hg -R ../remote bookmarks
251 * test 2:6c0482d977a3
250 * test 2:6c0482d977a3
252 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote local-bookmarks
251 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote local-bookmarks
253 requesting all changes
252 requesting all changes
254 adding changesets
253 adding changesets
255 adding manifests
254 adding manifests
256 adding file changes
255 adding file changes
257 added 4 changesets with 5 changes to 4 files (+1 heads)
256 added 4 changesets with 5 changes to 4 files (+1 heads)
258 updating to branch default
257 updating to branch default
259 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
258 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
260 $ hg -R local-bookmarks bookmarks
259 $ hg -R local-bookmarks bookmarks
261 test 2:6c0482d977a3
260 test 2:6c0482d977a3
262
261
263 passwords in ssh urls are not supported
262 passwords in ssh urls are not supported
264 (we use a glob here because different Python versions give different
263 (we use a glob here because different Python versions give different
265 results here)
264 results here)
266
265
267 $ hg push ssh://user:erroneouspwd@dummy/remote
266 $ hg push ssh://user:erroneouspwd@dummy/remote
268 pushing to ssh://user:*@dummy/remote (glob)
267 pushing to ssh://user:*@dummy/remote (glob)
269 abort: password in URL not supported!
268 abort: password in URL not supported!
270 [255]
269 [255]
271
270
272 $ cd ..
271 $ cd ..
273
272
274 hide outer repo
273 hide outer repo
275 $ hg init
274 $ hg init
276
275
277 Test remote paths with spaces (issue2983):
276 Test remote paths with spaces (issue2983):
278
277
279 $ hg init --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
278 $ hg init --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
280 $ touch "$TESTTMP/a repo/test"
279 $ touch "$TESTTMP/a repo/test"
281 $ hg -R 'a repo' commit -A -m "test"
280 $ hg -R 'a repo' commit -A -m "test"
282 adding test
281 adding test
283 $ hg -R 'a repo' tag tag
282 $ hg -R 'a repo' tag tag
284 $ hg id --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
283 $ hg id --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
285 73649e48688a
284 73649e48688a
286
285
287 $ hg id --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo#noNoNO"
286 $ hg id --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo#noNoNO"
288 abort: unknown revision 'noNoNO'!
287 abort: unknown revision 'noNoNO'!
289 [255]
288 [255]
290
289
291 Test (non-)escaping of remote paths with spaces when cloning (issue3145):
290 Test (non-)escaping of remote paths with spaces when cloning (issue3145):
292
291
293 $ hg clone --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
292 $ hg clone --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
294 destination directory: a repo
293 destination directory: a repo
295 abort: destination 'a repo' is not empty
294 abort: destination 'a repo' is not empty
296 [255]
295 [255]
297
296
298 Test hg-ssh using a helper script that will restore PYTHONPATH (which might
297 Test hg-ssh using a helper script that will restore PYTHONPATH (which might
299 have been cleared by a hg.exe wrapper) and invoke hg-ssh with the right
298 have been cleared by a hg.exe wrapper) and invoke hg-ssh with the right
300 parameters:
299 parameters:
301
300
302 $ cat > ssh.sh << EOF
301 $ cat > ssh.sh << EOF
303 > userhost="\$1"
302 > userhost="\$1"
304 > SSH_ORIGINAL_COMMAND="\$2"
303 > SSH_ORIGINAL_COMMAND="\$2"
305 > export SSH_ORIGINAL_COMMAND
304 > export SSH_ORIGINAL_COMMAND
306 > PYTHONPATH="$PYTHONPATH"
305 > PYTHONPATH="$PYTHONPATH"
307 > export PYTHONPATH
306 > export PYTHONPATH
308 > python "$TESTDIR/../contrib/hg-ssh" "$TESTTMP/a repo"
307 > python "$TESTDIR/../contrib/hg-ssh" "$TESTTMP/a repo"
309 > EOF
308 > EOF
310
309
311 $ hg id --ssh "sh ssh.sh" "ssh://user@dummy/a repo"
310 $ hg id --ssh "sh ssh.sh" "ssh://user@dummy/a repo"
312 73649e48688a
311 73649e48688a
313
312
314 $ hg id --ssh "sh ssh.sh" "ssh://user@dummy/a'repo"
313 $ hg id --ssh "sh ssh.sh" "ssh://user@dummy/a'repo"
315 remote: Illegal repository "$TESTTMP/a'repo" (glob)
314 remote: Illegal repository "$TESTTMP/a'repo" (glob)
316 abort: no suitable response from remote hg!
315 abort: no suitable response from remote hg!
317 [255]
316 [255]
318
317
319 $ hg id --ssh "sh ssh.sh" --remotecmd hacking "ssh://user@dummy/a'repo"
318 $ hg id --ssh "sh ssh.sh" --remotecmd hacking "ssh://user@dummy/a'repo"
320 remote: Illegal command "hacking -R 'a'\''repo' serve --stdio"
319 remote: Illegal command "hacking -R 'a'\''repo' serve --stdio"
321 abort: no suitable response from remote hg!
320 abort: no suitable response from remote hg!
322 [255]
321 [255]
323
322
324 $ SSH_ORIGINAL_COMMAND="'hg' -R 'a'repo' serve --stdio" python "$TESTDIR/../contrib/hg-ssh"
323 $ SSH_ORIGINAL_COMMAND="'hg' -R 'a'repo' serve --stdio" python "$TESTDIR/../contrib/hg-ssh"
325 Illegal command "'hg' -R 'a'repo' serve --stdio": No closing quotation
324 Illegal command "'hg' -R 'a'repo' serve --stdio": No closing quotation
326 [255]
325 [255]
327
326
328 Test hg-ssh in read-only mode:
327 Test hg-ssh in read-only mode:
329
328
330 $ cat > ssh.sh << EOF
329 $ cat > ssh.sh << EOF
331 > userhost="\$1"
330 > userhost="\$1"
332 > SSH_ORIGINAL_COMMAND="\$2"
331 > SSH_ORIGINAL_COMMAND="\$2"
333 > export SSH_ORIGINAL_COMMAND
332 > export SSH_ORIGINAL_COMMAND
334 > PYTHONPATH="$PYTHONPATH"
333 > PYTHONPATH="$PYTHONPATH"
335 > export PYTHONPATH
334 > export PYTHONPATH
336 > python "$TESTDIR/../contrib/hg-ssh" --read-only "$TESTTMP/remote"
335 > python "$TESTDIR/../contrib/hg-ssh" --read-only "$TESTTMP/remote"
337 > EOF
336 > EOF
338
337
339 $ hg clone --ssh "sh ssh.sh" "ssh://user@dummy/$TESTTMP/remote" read-only-local
338 $ hg clone --ssh "sh ssh.sh" "ssh://user@dummy/$TESTTMP/remote" read-only-local
340 requesting all changes
339 requesting all changes
341 adding changesets
340 adding changesets
342 adding manifests
341 adding manifests
343 adding file changes
342 adding file changes
344 added 4 changesets with 5 changes to 4 files (+1 heads)
343 added 4 changesets with 5 changes to 4 files (+1 heads)
345 updating to branch default
344 updating to branch default
346 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
345 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
347
346
348 $ cd read-only-local
347 $ cd read-only-local
349 $ echo "baz" > bar
348 $ echo "baz" > bar
350 $ hg ci -A -m "unpushable commit" bar
349 $ hg ci -A -m "unpushable commit" bar
351 $ hg push --ssh "sh ../ssh.sh"
350 $ hg push --ssh "sh ../ssh.sh"
352 pushing to ssh://user@dummy/*/remote (glob)
351 pushing to ssh://user@dummy/*/remote (glob)
353 searching for changes
352 searching for changes
354 remote: Permission denied
353 remote: Permission denied
355 remote: abort: prechangegroup.hg-ssh hook failed
354 remote: abort: prechangegroup.hg-ssh hook failed
356 remote: Permission denied
355 remote: Permission denied
357 remote: abort: prepushkey.hg-ssh hook failed
356 remote: abort: prepushkey.hg-ssh hook failed
358 abort: unexpected response: empty string
357 abort: unexpected response: empty string
359 [255]
358 [255]
360
359
361 $ cd ..
360 $ cd ..
362
361
363 stderr from remote commands should be printed before stdout from local code (issue4336)
362 stderr from remote commands should be printed before stdout from local code (issue4336)
364
363
365 $ hg clone remote stderr-ordering
364 $ hg clone remote stderr-ordering
366 updating to branch default
365 updating to branch default
367 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
366 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
368 $ cd stderr-ordering
367 $ cd stderr-ordering
369 $ cat >> localwrite.py << EOF
368 $ cat >> localwrite.py << EOF
370 > from mercurial import exchange, extensions
369 > from mercurial import exchange, extensions
371 >
370 >
372 > def wrappedpush(orig, repo, *args, **kwargs):
371 > def wrappedpush(orig, repo, *args, **kwargs):
373 > res = orig(repo, *args, **kwargs)
372 > res = orig(repo, *args, **kwargs)
374 > repo.ui.write('local stdout\n')
373 > repo.ui.write('local stdout\n')
375 > return res
374 > return res
376 >
375 >
377 > def extsetup(ui):
376 > def extsetup(ui):
378 > extensions.wrapfunction(exchange, 'push', wrappedpush)
377 > extensions.wrapfunction(exchange, 'push', wrappedpush)
379 > EOF
378 > EOF
380
379
381 $ cat >> .hg/hgrc << EOF
380 $ cat >> .hg/hgrc << EOF
382 > [paths]
381 > [paths]
383 > default-push = ssh://user@dummy/remote
382 > default-push = ssh://user@dummy/remote
384 > [ui]
383 > [ui]
385 > ssh = python "$TESTDIR/dummyssh"
384 > ssh = python "$TESTDIR/dummyssh"
386 > [extensions]
385 > [extensions]
387 > localwrite = localwrite.py
386 > localwrite = localwrite.py
388 > EOF
387 > EOF
389
388
390 $ echo localwrite > foo
389 $ echo localwrite > foo
391 $ hg commit -m 'testing localwrite'
390 $ hg commit -m 'testing localwrite'
392 $ hg push
391 $ hg push
393 pushing to ssh://user@dummy/remote
392 pushing to ssh://user@dummy/remote
394 searching for changes
393 searching for changes
395 remote: adding changesets
394 remote: adding changesets
396 remote: adding manifests
395 remote: adding manifests
397 remote: adding file changes
396 remote: adding file changes
398 remote: added 1 changesets with 1 changes to 1 files
397 remote: added 1 changesets with 1 changes to 1 files
399 remote: KABOOM
398 remote: KABOOM
400 local stdout
399 local stdout
401
400
402 $ cd ..
401 $ cd ..
403
402
404 $ cat dummylog
403 $ cat dummylog
405 Got arguments 1:user@dummy 2:hg -R nonexistent serve --stdio
404 Got arguments 1:user@dummy 2:hg -R nonexistent serve --stdio
406 Got arguments 1:user@dummy 2:hg -R /$TESTTMP/nonexistent serve --stdio
405 Got arguments 1:user@dummy 2:hg -R /$TESTTMP/nonexistent serve --stdio
407 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
406 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
408 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
407 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
409 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
408 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
410 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
409 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
411 Got arguments 1:user@dummy 2:hg -R local serve --stdio
410 Got arguments 1:user@dummy 2:hg -R local serve --stdio
412 Got arguments 1:user@dummy 2:hg -R $TESTTMP/local serve --stdio
411 Got arguments 1:user@dummy 2:hg -R $TESTTMP/local serve --stdio
413 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
412 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
414 changegroup-in-remote hook: HG_NODE=a28a9d1a809cab7d4e2fde4bee738a9ede948b60 HG_SOURCE=serve HG_URL=remote:ssh:127.0.0.1
413 changegroup-in-remote hook: HG_NODE=a28a9d1a809cab7d4e2fde4bee738a9ede948b60 HG_SOURCE=serve HG_URL=remote:ssh:127.0.0.1
415 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
414 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
416 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
415 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
417 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
416 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
418 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
417 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
419 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
418 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
420 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
419 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
421 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
420 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
422 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
421 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
423 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
422 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
424 changegroup-in-remote hook: HG_NODE=1383141674ec756a6056f6a9097618482fe0f4a6 HG_SOURCE=serve HG_URL=remote:ssh:127.0.0.1
423 changegroup-in-remote hook: HG_NODE=1383141674ec756a6056f6a9097618482fe0f4a6 HG_SOURCE=serve HG_URL=remote:ssh:127.0.0.1
425 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
424 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
426 Got arguments 1:user@dummy 2:hg init 'a repo'
425 Got arguments 1:user@dummy 2:hg init 'a repo'
427 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
426 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
428 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
427 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
429 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
428 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
430 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
429 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
431 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
430 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
432 changegroup-in-remote hook: HG_NODE=65c38f4125f9602c8db4af56530cc221d93b8ef8 HG_SOURCE=serve HG_URL=remote:ssh:127.0.0.1
431 changegroup-in-remote hook: HG_NODE=65c38f4125f9602c8db4af56530cc221d93b8ef8 HG_SOURCE=serve HG_URL=remote:ssh:127.0.0.1
General Comments 0
You need to be logged in to leave comments. Login now