##// END OF EJS Templates
bookmarks: inform transaction-related hooks that some bookmarks were moved...
Pierre-Yves David -
r22941:da2758c0 default
parent child Browse files
Show More
@@ -1,440 +1,441 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, lock as lockmod
10 from mercurial import encoding, error, util, obsolete, lock as lockmod
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 recordchange(self, tr):
50 def recordchange(self, tr):
51 """record that bookmarks have been changed in a transaction
51 """record that bookmarks have been changed in a transaction
52
52
53 The transaction is then responsible for updating the file content."""
53 The transaction is then responsible for updating the file content."""
54 tr.addfilegenerator('bookmarks', ('bookmarks',), self._write,
54 tr.addfilegenerator('bookmarks', ('bookmarks',), self._write,
55 vfs=self._repo.vfs)
55 vfs=self._repo.vfs)
56 tr.hookargs['bookmark_moved'] = '1'
56
57
57 def write(self):
58 def write(self):
58 '''Write bookmarks
59 '''Write bookmarks
59
60
60 Write the given bookmark => hash dictionary to the .hg/bookmarks file
61 Write the given bookmark => hash dictionary to the .hg/bookmarks file
61 in a format equal to those of localtags.
62 in a format equal to those of localtags.
62
63
63 We also store a backup of the previous state in undo.bookmarks that
64 We also store a backup of the previous state in undo.bookmarks that
64 can be copied back on rollback.
65 can be copied back on rollback.
65 '''
66 '''
66 repo = self._repo
67 repo = self._repo
67 if repo._bookmarkcurrent not in self:
68 if repo._bookmarkcurrent not in self:
68 unsetcurrent(repo)
69 unsetcurrent(repo)
69
70
70 wlock = repo.wlock()
71 wlock = repo.wlock()
71 try:
72 try:
72
73
73 file = repo.vfs('bookmarks', 'w', atomictemp=True)
74 file = repo.vfs('bookmarks', 'w', atomictemp=True)
74 self._write(file)
75 self._write(file)
75 file.close()
76 file.close()
76
77
77 # touch 00changelog.i so hgweb reloads bookmarks (no lock needed)
78 # touch 00changelog.i so hgweb reloads bookmarks (no lock needed)
78 try:
79 try:
79 repo.svfs.utime('00changelog.i', None)
80 repo.svfs.utime('00changelog.i', None)
80 except OSError:
81 except OSError:
81 pass
82 pass
82
83
83 finally:
84 finally:
84 wlock.release()
85 wlock.release()
85
86
86 def _write(self, fp):
87 def _write(self, fp):
87 for name, node in self.iteritems():
88 for name, node in self.iteritems():
88 fp.write("%s %s\n" % (hex(node), encoding.fromlocal(name)))
89 fp.write("%s %s\n" % (hex(node), encoding.fromlocal(name)))
89
90
90 def readcurrent(repo):
91 def readcurrent(repo):
91 '''Get the current bookmark
92 '''Get the current bookmark
92
93
93 If we use gittish branches we have a current bookmark that
94 If we use gittish branches we have a current bookmark that
94 we are on. This function returns the name of the bookmark. It
95 we are on. This function returns the name of the bookmark. It
95 is stored in .hg/bookmarks.current
96 is stored in .hg/bookmarks.current
96 '''
97 '''
97 mark = None
98 mark = None
98 try:
99 try:
99 file = repo.opener('bookmarks.current')
100 file = repo.opener('bookmarks.current')
100 except IOError, inst:
101 except IOError, inst:
101 if inst.errno != errno.ENOENT:
102 if inst.errno != errno.ENOENT:
102 raise
103 raise
103 return None
104 return None
104 try:
105 try:
105 # No readline() in osutil.posixfile, reading everything is cheap
106 # No readline() in osutil.posixfile, reading everything is cheap
106 mark = encoding.tolocal((file.readlines() or [''])[0])
107 mark = encoding.tolocal((file.readlines() or [''])[0])
107 if mark == '' or mark not in repo._bookmarks:
108 if mark == '' or mark not in repo._bookmarks:
108 mark = None
109 mark = None
109 finally:
110 finally:
110 file.close()
111 file.close()
111 return mark
112 return mark
112
113
113 def setcurrent(repo, mark):
114 def setcurrent(repo, mark):
114 '''Set the name of the bookmark that we are currently on
115 '''Set the name of the bookmark that we are currently on
115
116
116 Set the name of the bookmark that we are on (hg update <bookmark>).
117 Set the name of the bookmark that we are on (hg update <bookmark>).
117 The name is recorded in .hg/bookmarks.current
118 The name is recorded in .hg/bookmarks.current
118 '''
119 '''
119 if mark not in repo._bookmarks:
120 if mark not in repo._bookmarks:
120 raise AssertionError('bookmark %s does not exist!' % mark)
121 raise AssertionError('bookmark %s does not exist!' % mark)
121
122
122 current = repo._bookmarkcurrent
123 current = repo._bookmarkcurrent
123 if current == mark:
124 if current == mark:
124 return
125 return
125
126
126 wlock = repo.wlock()
127 wlock = repo.wlock()
127 try:
128 try:
128 file = repo.opener('bookmarks.current', 'w', atomictemp=True)
129 file = repo.opener('bookmarks.current', 'w', atomictemp=True)
129 file.write(encoding.fromlocal(mark))
130 file.write(encoding.fromlocal(mark))
130 file.close()
131 file.close()
131 finally:
132 finally:
132 wlock.release()
133 wlock.release()
133 repo._bookmarkcurrent = mark
134 repo._bookmarkcurrent = mark
134
135
135 def unsetcurrent(repo):
136 def unsetcurrent(repo):
136 wlock = repo.wlock()
137 wlock = repo.wlock()
137 try:
138 try:
138 try:
139 try:
139 repo.vfs.unlink('bookmarks.current')
140 repo.vfs.unlink('bookmarks.current')
140 repo._bookmarkcurrent = None
141 repo._bookmarkcurrent = None
141 except OSError, inst:
142 except OSError, inst:
142 if inst.errno != errno.ENOENT:
143 if inst.errno != errno.ENOENT:
143 raise
144 raise
144 finally:
145 finally:
145 wlock.release()
146 wlock.release()
146
147
147 def iscurrent(repo, mark=None, parents=None):
148 def iscurrent(repo, mark=None, parents=None):
148 '''Tell whether the current bookmark is also active
149 '''Tell whether the current bookmark is also active
149
150
150 I.e., the bookmark listed in .hg/bookmarks.current also points to a
151 I.e., the bookmark listed in .hg/bookmarks.current also points to a
151 parent of the working directory.
152 parent of the working directory.
152 '''
153 '''
153 if not mark:
154 if not mark:
154 mark = repo._bookmarkcurrent
155 mark = repo._bookmarkcurrent
155 if not parents:
156 if not parents:
156 parents = [p.node() for p in repo[None].parents()]
157 parents = [p.node() for p in repo[None].parents()]
157 marks = repo._bookmarks
158 marks = repo._bookmarks
158 return (mark in marks and marks[mark] in parents)
159 return (mark in marks and marks[mark] in parents)
159
160
160 def updatecurrentbookmark(repo, oldnode, curbranch):
161 def updatecurrentbookmark(repo, oldnode, curbranch):
161 try:
162 try:
162 return update(repo, oldnode, repo.branchtip(curbranch))
163 return update(repo, oldnode, repo.branchtip(curbranch))
163 except error.RepoLookupError:
164 except error.RepoLookupError:
164 if curbranch == "default": # no default branch!
165 if curbranch == "default": # no default branch!
165 return update(repo, oldnode, repo.lookup("tip"))
166 return update(repo, oldnode, repo.lookup("tip"))
166 else:
167 else:
167 raise util.Abort(_("branch %s not found") % curbranch)
168 raise util.Abort(_("branch %s not found") % curbranch)
168
169
169 def deletedivergent(repo, deletefrom, bm):
170 def deletedivergent(repo, deletefrom, bm):
170 '''Delete divergent versions of bm on nodes in deletefrom.
171 '''Delete divergent versions of bm on nodes in deletefrom.
171
172
172 Return True if at least one bookmark was deleted, False otherwise.'''
173 Return True if at least one bookmark was deleted, False otherwise.'''
173 deleted = False
174 deleted = False
174 marks = repo._bookmarks
175 marks = repo._bookmarks
175 divergent = [b for b in marks if b.split('@', 1)[0] == bm.split('@', 1)[0]]
176 divergent = [b for b in marks if b.split('@', 1)[0] == bm.split('@', 1)[0]]
176 for mark in divergent:
177 for mark in divergent:
177 if mark == '@' or '@' not in mark:
178 if mark == '@' or '@' not in mark:
178 # can't be divergent by definition
179 # can't be divergent by definition
179 continue
180 continue
180 if mark and marks[mark] in deletefrom:
181 if mark and marks[mark] in deletefrom:
181 if mark != bm:
182 if mark != bm:
182 del marks[mark]
183 del marks[mark]
183 deleted = True
184 deleted = True
184 return deleted
185 return deleted
185
186
186 def calculateupdate(ui, repo, checkout):
187 def calculateupdate(ui, repo, checkout):
187 '''Return a tuple (targetrev, movemarkfrom) indicating the rev to
188 '''Return a tuple (targetrev, movemarkfrom) indicating the rev to
188 check out and where to move the active bookmark from, if needed.'''
189 check out and where to move the active bookmark from, if needed.'''
189 movemarkfrom = None
190 movemarkfrom = None
190 if checkout is None:
191 if checkout is None:
191 curmark = repo._bookmarkcurrent
192 curmark = repo._bookmarkcurrent
192 if iscurrent(repo):
193 if iscurrent(repo):
193 movemarkfrom = repo['.'].node()
194 movemarkfrom = repo['.'].node()
194 elif curmark:
195 elif curmark:
195 ui.status(_("updating to active bookmark %s\n") % curmark)
196 ui.status(_("updating to active bookmark %s\n") % curmark)
196 checkout = curmark
197 checkout = curmark
197 return (checkout, movemarkfrom)
198 return (checkout, movemarkfrom)
198
199
199 def update(repo, parents, node):
200 def update(repo, parents, node):
200 deletefrom = parents
201 deletefrom = parents
201 marks = repo._bookmarks
202 marks = repo._bookmarks
202 update = False
203 update = False
203 cur = repo._bookmarkcurrent
204 cur = repo._bookmarkcurrent
204 if not cur:
205 if not cur:
205 return False
206 return False
206
207
207 if marks[cur] in parents:
208 if marks[cur] in parents:
208 new = repo[node]
209 new = repo[node]
209 divs = [repo[b] for b in marks
210 divs = [repo[b] for b in marks
210 if b.split('@', 1)[0] == cur.split('@', 1)[0]]
211 if b.split('@', 1)[0] == cur.split('@', 1)[0]]
211 anc = repo.changelog.ancestors([new.rev()])
212 anc = repo.changelog.ancestors([new.rev()])
212 deletefrom = [b.node() for b in divs if b.rev() in anc or b == new]
213 deletefrom = [b.node() for b in divs if b.rev() in anc or b == new]
213 if validdest(repo, repo[marks[cur]], new):
214 if validdest(repo, repo[marks[cur]], new):
214 marks[cur] = new.node()
215 marks[cur] = new.node()
215 update = True
216 update = True
216
217
217 if deletedivergent(repo, deletefrom, cur):
218 if deletedivergent(repo, deletefrom, cur):
218 update = True
219 update = True
219
220
220 if update:
221 if update:
221 marks.write()
222 marks.write()
222 return update
223 return update
223
224
224 def listbookmarks(repo):
225 def listbookmarks(repo):
225 # We may try to list bookmarks on a repo type that does not
226 # We may try to list bookmarks on a repo type that does not
226 # support it (e.g., statichttprepository).
227 # support it (e.g., statichttprepository).
227 marks = getattr(repo, '_bookmarks', {})
228 marks = getattr(repo, '_bookmarks', {})
228
229
229 d = {}
230 d = {}
230 hasnode = repo.changelog.hasnode
231 hasnode = repo.changelog.hasnode
231 for k, v in marks.iteritems():
232 for k, v in marks.iteritems():
232 # don't expose local divergent bookmarks
233 # don't expose local divergent bookmarks
233 if hasnode(v) and ('@' not in k or k.endswith('@')):
234 if hasnode(v) and ('@' not in k or k.endswith('@')):
234 d[k] = hex(v)
235 d[k] = hex(v)
235 return d
236 return d
236
237
237 def pushbookmark(repo, key, old, new):
238 def pushbookmark(repo, key, old, new):
238 w = l = tr = None
239 w = l = tr = None
239 try:
240 try:
240 w = repo.wlock()
241 w = repo.wlock()
241 l = repo.lock()
242 l = repo.lock()
242 tr = repo.transaction('bookmarks')
243 tr = repo.transaction('bookmarks')
243 marks = repo._bookmarks
244 marks = repo._bookmarks
244 existing = hex(marks.get(key, ''))
245 existing = hex(marks.get(key, ''))
245 if existing != old and existing != new:
246 if existing != old and existing != new:
246 return False
247 return False
247 if new == '':
248 if new == '':
248 del marks[key]
249 del marks[key]
249 else:
250 else:
250 if new not in repo:
251 if new not in repo:
251 return False
252 return False
252 marks[key] = repo[new].node()
253 marks[key] = repo[new].node()
253 marks.recordchange(tr)
254 marks.recordchange(tr)
254 tr.close()
255 tr.close()
255 return True
256 return True
256 finally:
257 finally:
257 lockmod.release(tr, l, w)
258 lockmod.release(tr, l, w)
258
259
259 def compare(repo, srcmarks, dstmarks,
260 def compare(repo, srcmarks, dstmarks,
260 srchex=None, dsthex=None, targets=None):
261 srchex=None, dsthex=None, targets=None):
261 '''Compare bookmarks between srcmarks and dstmarks
262 '''Compare bookmarks between srcmarks and dstmarks
262
263
263 This returns tuple "(addsrc, adddst, advsrc, advdst, diverge,
264 This returns tuple "(addsrc, adddst, advsrc, advdst, diverge,
264 differ, invalid)", each are list of bookmarks below:
265 differ, invalid)", each are list of bookmarks below:
265
266
266 :addsrc: added on src side (removed on dst side, perhaps)
267 :addsrc: added on src side (removed on dst side, perhaps)
267 :adddst: added on dst side (removed on src side, perhaps)
268 :adddst: added on dst side (removed on src side, perhaps)
268 :advsrc: advanced on src side
269 :advsrc: advanced on src side
269 :advdst: advanced on dst side
270 :advdst: advanced on dst side
270 :diverge: diverge
271 :diverge: diverge
271 :differ: changed, but changeset referred on src is unknown on dst
272 :differ: changed, but changeset referred on src is unknown on dst
272 :invalid: unknown on both side
273 :invalid: unknown on both side
273
274
274 Each elements of lists in result tuple is tuple "(bookmark name,
275 Each elements of lists in result tuple is tuple "(bookmark name,
275 changeset ID on source side, changeset ID on destination
276 changeset ID on source side, changeset ID on destination
276 side)". Each changeset IDs are 40 hexadecimal digit string or
277 side)". Each changeset IDs are 40 hexadecimal digit string or
277 None.
278 None.
278
279
279 Changeset IDs of tuples in "addsrc", "adddst", "differ" or
280 Changeset IDs of tuples in "addsrc", "adddst", "differ" or
280 "invalid" list may be unknown for repo.
281 "invalid" list may be unknown for repo.
281
282
282 This function expects that "srcmarks" and "dstmarks" return
283 This function expects that "srcmarks" and "dstmarks" return
283 changeset ID in 40 hexadecimal digit string for specified
284 changeset ID in 40 hexadecimal digit string for specified
284 bookmark. If not so (e.g. bmstore "repo._bookmarks" returning
285 bookmark. If not so (e.g. bmstore "repo._bookmarks" returning
285 binary value), "srchex" or "dsthex" should be specified to convert
286 binary value), "srchex" or "dsthex" should be specified to convert
286 into such form.
287 into such form.
287
288
288 If "targets" is specified, only bookmarks listed in it are
289 If "targets" is specified, only bookmarks listed in it are
289 examined.
290 examined.
290 '''
291 '''
291 if not srchex:
292 if not srchex:
292 srchex = lambda x: x
293 srchex = lambda x: x
293 if not dsthex:
294 if not dsthex:
294 dsthex = lambda x: x
295 dsthex = lambda x: x
295
296
296 if targets:
297 if targets:
297 bset = set(targets)
298 bset = set(targets)
298 else:
299 else:
299 srcmarkset = set(srcmarks)
300 srcmarkset = set(srcmarks)
300 dstmarkset = set(dstmarks)
301 dstmarkset = set(dstmarks)
301 bset = srcmarkset ^ dstmarkset
302 bset = srcmarkset ^ dstmarkset
302 for b in srcmarkset & dstmarkset:
303 for b in srcmarkset & dstmarkset:
303 if srchex(srcmarks[b]) != dsthex(dstmarks[b]):
304 if srchex(srcmarks[b]) != dsthex(dstmarks[b]):
304 bset.add(b)
305 bset.add(b)
305
306
306 results = ([], [], [], [], [], [], [])
307 results = ([], [], [], [], [], [], [])
307 addsrc = results[0].append
308 addsrc = results[0].append
308 adddst = results[1].append
309 adddst = results[1].append
309 advsrc = results[2].append
310 advsrc = results[2].append
310 advdst = results[3].append
311 advdst = results[3].append
311 diverge = results[4].append
312 diverge = results[4].append
312 differ = results[5].append
313 differ = results[5].append
313 invalid = results[6].append
314 invalid = results[6].append
314
315
315 for b in sorted(bset):
316 for b in sorted(bset):
316 if b not in srcmarks:
317 if b not in srcmarks:
317 if b in dstmarks:
318 if b in dstmarks:
318 adddst((b, None, dsthex(dstmarks[b])))
319 adddst((b, None, dsthex(dstmarks[b])))
319 else:
320 else:
320 invalid((b, None, None))
321 invalid((b, None, None))
321 elif b not in dstmarks:
322 elif b not in dstmarks:
322 addsrc((b, srchex(srcmarks[b]), None))
323 addsrc((b, srchex(srcmarks[b]), None))
323 else:
324 else:
324 scid = srchex(srcmarks[b])
325 scid = srchex(srcmarks[b])
325 dcid = dsthex(dstmarks[b])
326 dcid = dsthex(dstmarks[b])
326 if scid in repo and dcid in repo:
327 if scid in repo and dcid in repo:
327 sctx = repo[scid]
328 sctx = repo[scid]
328 dctx = repo[dcid]
329 dctx = repo[dcid]
329 if sctx.rev() < dctx.rev():
330 if sctx.rev() < dctx.rev():
330 if validdest(repo, sctx, dctx):
331 if validdest(repo, sctx, dctx):
331 advdst((b, scid, dcid))
332 advdst((b, scid, dcid))
332 else:
333 else:
333 diverge((b, scid, dcid))
334 diverge((b, scid, dcid))
334 else:
335 else:
335 if validdest(repo, dctx, sctx):
336 if validdest(repo, dctx, sctx):
336 advsrc((b, scid, dcid))
337 advsrc((b, scid, dcid))
337 else:
338 else:
338 diverge((b, scid, dcid))
339 diverge((b, scid, dcid))
339 else:
340 else:
340 # it is too expensive to examine in detail, in this case
341 # it is too expensive to examine in detail, in this case
341 differ((b, scid, dcid))
342 differ((b, scid, dcid))
342
343
343 return results
344 return results
344
345
345 def _diverge(ui, b, path, localmarks):
346 def _diverge(ui, b, path, localmarks):
346 if b == '@':
347 if b == '@':
347 b = ''
348 b = ''
348 # find a unique @ suffix
349 # find a unique @ suffix
349 for x in range(1, 100):
350 for x in range(1, 100):
350 n = '%s@%d' % (b, x)
351 n = '%s@%d' % (b, x)
351 if n not in localmarks:
352 if n not in localmarks:
352 break
353 break
353 # try to use an @pathalias suffix
354 # try to use an @pathalias suffix
354 # if an @pathalias already exists, we overwrite (update) it
355 # if an @pathalias already exists, we overwrite (update) it
355 if path.startswith("file:"):
356 if path.startswith("file:"):
356 path = util.url(path).path
357 path = util.url(path).path
357 for p, u in ui.configitems("paths"):
358 for p, u in ui.configitems("paths"):
358 if u.startswith("file:"):
359 if u.startswith("file:"):
359 u = util.url(u).path
360 u = util.url(u).path
360 if path == u:
361 if path == u:
361 n = '%s@%s' % (b, p)
362 n = '%s@%s' % (b, p)
362 return n
363 return n
363
364
364 def updatefromremote(ui, repo, remotemarks, path, trfunc, explicit=()):
365 def updatefromremote(ui, repo, remotemarks, path, trfunc, explicit=()):
365 ui.debug("checking for updated bookmarks\n")
366 ui.debug("checking for updated bookmarks\n")
366 localmarks = repo._bookmarks
367 localmarks = repo._bookmarks
367 (addsrc, adddst, advsrc, advdst, diverge, differ, invalid
368 (addsrc, adddst, advsrc, advdst, diverge, differ, invalid
368 ) = compare(repo, remotemarks, localmarks, dsthex=hex)
369 ) = compare(repo, remotemarks, localmarks, dsthex=hex)
369
370
370 status = ui.status
371 status = ui.status
371 warn = ui.warn
372 warn = ui.warn
372 if ui.configbool('ui', 'quietbookmarkmove', False):
373 if ui.configbool('ui', 'quietbookmarkmove', False):
373 status = warn = ui.debug
374 status = warn = ui.debug
374
375
375 explicit = set(explicit)
376 explicit = set(explicit)
376 changed = []
377 changed = []
377 for b, scid, dcid in addsrc:
378 for b, scid, dcid in addsrc:
378 if scid in repo: # add remote bookmarks for changes we already have
379 if scid in repo: # add remote bookmarks for changes we already have
379 changed.append((b, bin(scid), status,
380 changed.append((b, bin(scid), status,
380 _("adding remote bookmark %s\n") % (b)))
381 _("adding remote bookmark %s\n") % (b)))
381 for b, scid, dcid in advsrc:
382 for b, scid, dcid in advsrc:
382 changed.append((b, bin(scid), status,
383 changed.append((b, bin(scid), status,
383 _("updating bookmark %s\n") % (b)))
384 _("updating bookmark %s\n") % (b)))
384 # remove normal movement from explicit set
385 # remove normal movement from explicit set
385 explicit.difference_update(d[0] for d in changed)
386 explicit.difference_update(d[0] for d in changed)
386
387
387 for b, scid, dcid in diverge:
388 for b, scid, dcid in diverge:
388 if b in explicit:
389 if b in explicit:
389 explicit.discard(b)
390 explicit.discard(b)
390 changed.append((b, bin(scid), status,
391 changed.append((b, bin(scid), status,
391 _("importing bookmark %s\n") % (b, b)))
392 _("importing bookmark %s\n") % (b, b)))
392 else:
393 else:
393 db = _diverge(ui, b, path, localmarks)
394 db = _diverge(ui, b, path, localmarks)
394 changed.append((db, bin(scid), warn,
395 changed.append((db, bin(scid), warn,
395 _("divergent bookmark %s stored as %s\n")
396 _("divergent bookmark %s stored as %s\n")
396 % (b, db)))
397 % (b, db)))
397 for b, scid, dcid in adddst + advdst:
398 for b, scid, dcid in adddst + advdst:
398 if b in explicit:
399 if b in explicit:
399 explicit.discard(b)
400 explicit.discard(b)
400 changed.append((b, bin(scid), status,
401 changed.append((b, bin(scid), status,
401 _("importing bookmark %s\n") % (b, b)))
402 _("importing bookmark %s\n") % (b, b)))
402
403
403 if changed:
404 if changed:
404 tr = trfunc()
405 tr = trfunc()
405 for b, node, writer, msg in sorted(changed):
406 for b, node, writer, msg in sorted(changed):
406 localmarks[b] = node
407 localmarks[b] = node
407 writer(msg)
408 writer(msg)
408 localmarks.recordchange(tr)
409 localmarks.recordchange(tr)
409
410
410 def diff(ui, dst, src):
411 def diff(ui, dst, src):
411 ui.status(_("searching for changed bookmarks\n"))
412 ui.status(_("searching for changed bookmarks\n"))
412
413
413 smarks = src.listkeys('bookmarks')
414 smarks = src.listkeys('bookmarks')
414 dmarks = dst.listkeys('bookmarks')
415 dmarks = dst.listkeys('bookmarks')
415
416
416 diff = sorted(set(smarks) - set(dmarks))
417 diff = sorted(set(smarks) - set(dmarks))
417 for k in diff:
418 for k in diff:
418 mark = ui.debugflag and smarks[k] or smarks[k][:12]
419 mark = ui.debugflag and smarks[k] or smarks[k][:12]
419 ui.write(" %-25s %s\n" % (k, mark))
420 ui.write(" %-25s %s\n" % (k, mark))
420
421
421 if len(diff) <= 0:
422 if len(diff) <= 0:
422 ui.status(_("no changed bookmarks found\n"))
423 ui.status(_("no changed bookmarks found\n"))
423 return 1
424 return 1
424 return 0
425 return 0
425
426
426 def validdest(repo, old, new):
427 def validdest(repo, old, new):
427 """Is the new bookmark destination a valid update from the old one"""
428 """Is the new bookmark destination a valid update from the old one"""
428 repo = repo.unfiltered()
429 repo = repo.unfiltered()
429 if old == new:
430 if old == new:
430 # Old == new -> nothing to update.
431 # Old == new -> nothing to update.
431 return False
432 return False
432 elif not old:
433 elif not old:
433 # old is nullrev, anything is valid.
434 # old is nullrev, anything is valid.
434 # (new != nullrev has been excluded by the previous check)
435 # (new != nullrev has been excluded by the previous check)
435 return True
436 return True
436 elif repo.obsstore:
437 elif repo.obsstore:
437 return new.node() in obsolete.foreground(repo, [old.node()])
438 return new.node() in obsolete.foreground(repo, [old.node()])
438 else:
439 else:
439 # still an independent clause as it is lazyer (and therefore faster)
440 # still an independent clause as it is lazyer (and therefore faster)
440 return old.descendant(new)
441 return old.descendant(new)
@@ -1,484 +1,484 b''
1 Test exchange of common information using bundle2
1 Test exchange of common information using bundle2
2
2
3
3
4 $ getmainid() {
4 $ getmainid() {
5 > hg -R main log --template '{node}\n' --rev "$1"
5 > hg -R main log --template '{node}\n' --rev "$1"
6 > }
6 > }
7
7
8 enable obsolescence
8 enable obsolescence
9
9
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
14
15 $ cat >> $HGRCPATH << EOF
15 $ cat >> $HGRCPATH << EOF
16 > [extensions]
16 > [extensions]
17 > obsolete=$TESTTMP/obs.py
17 > obsolete=$TESTTMP/obs.py
18 > [experimental]
18 > [experimental]
19 > bundle2-exp=True
19 > bundle2-exp=True
20 > [ui]
20 > [ui]
21 > ssh=python "$TESTDIR/dummyssh"
21 > ssh=python "$TESTDIR/dummyssh"
22 > logtemplate={rev}:{node|short} {phase} {author} {bookmarks} {desc|firstline}
22 > logtemplate={rev}:{node|short} {phase} {author} {bookmarks} {desc|firstline}
23 > [web]
23 > [web]
24 > push_ssl = false
24 > push_ssl = false
25 > allow_push = *
25 > allow_push = *
26 > [phases]
26 > [phases]
27 > publish=False
27 > publish=False
28 > [hooks]
28 > [hooks]
29 > changegroup = sh -c "HG_LOCAL= HG_NODE= HG_TAG= python \"$TESTDIR/printenv.py\" changegroup"
29 > changegroup = sh -c "HG_LOCAL= HG_NODE= HG_TAG= python \"$TESTDIR/printenv.py\" changegroup"
30 > b2x-transactionclose = sh -c "HG_LOCAL= HG_NODE= HG_TAG= python \"$TESTDIR/printenv.py\" b2x-transactionclose"
30 > b2x-transactionclose = sh -c "HG_LOCAL= HG_NODE= HG_TAG= python \"$TESTDIR/printenv.py\" b2x-transactionclose"
31 > EOF
31 > EOF
32
32
33 The extension requires a repo (currently unused)
33 The extension requires a repo (currently unused)
34
34
35 $ hg init main
35 $ hg init main
36 $ cd main
36 $ cd main
37 $ touch a
37 $ touch a
38 $ hg add a
38 $ hg add a
39 $ hg commit -m 'a'
39 $ hg commit -m 'a'
40
40
41 $ hg unbundle $TESTDIR/bundles/rebase.hg
41 $ hg unbundle $TESTDIR/bundles/rebase.hg
42 adding changesets
42 adding changesets
43 adding manifests
43 adding manifests
44 adding file changes
44 adding file changes
45 added 8 changesets with 7 changes to 7 files (+3 heads)
45 added 8 changesets with 7 changes to 7 files (+3 heads)
46 changegroup hook: HG_PHASES_MOVED=1 HG_SOURCE=unbundle HG_URL=bundle:*/tests/bundles/rebase.hg (glob)
46 changegroup hook: HG_PHASES_MOVED=1 HG_SOURCE=unbundle HG_URL=bundle:*/tests/bundles/rebase.hg (glob)
47 (run 'hg heads' to see heads, 'hg merge' to merge)
47 (run 'hg heads' to see heads, 'hg merge' to merge)
48
48
49 $ cd ..
49 $ cd ..
50
50
51 Real world exchange
51 Real world exchange
52 =====================
52 =====================
53
53
54 Add more obsolescence information
54 Add more obsolescence information
55
55
56 $ hg -R main debugobsolete -d '0 0' 1111111111111111111111111111111111111111 `getmainid 9520eea781bc`
56 $ hg -R main debugobsolete -d '0 0' 1111111111111111111111111111111111111111 `getmainid 9520eea781bc`
57 $ hg -R main debugobsolete -d '0 0' 2222222222222222222222222222222222222222 `getmainid 24b6387c8c8c`
57 $ hg -R main debugobsolete -d '0 0' 2222222222222222222222222222222222222222 `getmainid 24b6387c8c8c`
58
58
59 clone --pull
59 clone --pull
60
60
61 $ hg -R main phase --public cd010b8cd998
61 $ hg -R main phase --public cd010b8cd998
62 $ hg clone main other --pull --rev 9520eea781bc
62 $ hg clone main other --pull --rev 9520eea781bc
63 adding changesets
63 adding changesets
64 adding manifests
64 adding manifests
65 adding file changes
65 adding file changes
66 added 2 changesets with 2 changes to 2 files
66 added 2 changesets with 2 changes to 2 files
67 1 new obsolescence markers
67 1 new obsolescence markers
68 changegroup hook: HG_NEW_OBSMARKERS=1 HG_PHASES_MOVED=1 HG_SOURCE=bundle2 HG_URL=bundle2
68 changegroup hook: HG_NEW_OBSMARKERS=1 HG_PHASES_MOVED=1 HG_SOURCE=bundle2 HG_URL=bundle2
69 updating to branch default
69 updating to branch default
70 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
70 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
71 $ hg -R other log -G
71 $ hg -R other log -G
72 @ 1:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
72 @ 1:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
73 |
73 |
74 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
74 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
75
75
76 $ hg -R other debugobsolete
76 $ hg -R other debugobsolete
77 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
77 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
78
78
79 pull
79 pull
80
80
81 $ hg -R main phase --public 9520eea781bc
81 $ hg -R main phase --public 9520eea781bc
82 $ hg -R other pull -r 24b6387c8c8c
82 $ hg -R other pull -r 24b6387c8c8c
83 pulling from $TESTTMP/main (glob)
83 pulling from $TESTTMP/main (glob)
84 searching for changes
84 searching for changes
85 adding changesets
85 adding changesets
86 adding manifests
86 adding manifests
87 adding file changes
87 adding file changes
88 added 1 changesets with 1 changes to 1 files (+1 heads)
88 added 1 changesets with 1 changes to 1 files (+1 heads)
89 1 new obsolescence markers
89 1 new obsolescence markers
90 changegroup hook: HG_NEW_OBSMARKERS=1 HG_PHASES_MOVED=1 HG_SOURCE=bundle2 HG_URL=bundle2
90 changegroup hook: HG_NEW_OBSMARKERS=1 HG_PHASES_MOVED=1 HG_SOURCE=bundle2 HG_URL=bundle2
91 (run 'hg heads' to see heads, 'hg merge' to merge)
91 (run 'hg heads' to see heads, 'hg merge' to merge)
92 $ hg -R other log -G
92 $ hg -R other log -G
93 o 2:24b6387c8c8c draft Nicolas Dumazet <nicdumz.commits@gmail.com> F
93 o 2:24b6387c8c8c draft Nicolas Dumazet <nicdumz.commits@gmail.com> F
94 |
94 |
95 | @ 1:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
95 | @ 1:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
96 |/
96 |/
97 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
97 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
98
98
99 $ hg -R other debugobsolete
99 $ hg -R other debugobsolete
100 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
100 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
101 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
101 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
102
102
103 pull empty (with phase movement)
103 pull empty (with phase movement)
104
104
105 $ hg -R main phase --public 24b6387c8c8c
105 $ hg -R main phase --public 24b6387c8c8c
106 $ hg -R other pull -r 24b6387c8c8c
106 $ hg -R other pull -r 24b6387c8c8c
107 pulling from $TESTTMP/main (glob)
107 pulling from $TESTTMP/main (glob)
108 no changes found
108 no changes found
109 $ hg -R other log -G
109 $ hg -R other log -G
110 o 2:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
110 o 2:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
111 |
111 |
112 | @ 1:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
112 | @ 1:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
113 |/
113 |/
114 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
114 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
115
115
116 $ hg -R other debugobsolete
116 $ hg -R other debugobsolete
117 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
117 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
118 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
118 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
119
119
120 pull empty
120 pull empty
121
121
122 $ hg -R other pull -r 24b6387c8c8c
122 $ hg -R other pull -r 24b6387c8c8c
123 pulling from $TESTTMP/main (glob)
123 pulling from $TESTTMP/main (glob)
124 no changes found
124 no changes found
125 $ hg -R other log -G
125 $ hg -R other log -G
126 o 2:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
126 o 2:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
127 |
127 |
128 | @ 1:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
128 | @ 1:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
129 |/
129 |/
130 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
130 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
131
131
132 $ hg -R other debugobsolete
132 $ hg -R other debugobsolete
133 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
133 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
134 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
134 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
135
135
136 add extra data to test their exchange during push
136 add extra data to test their exchange during push
137
137
138 $ hg -R main bookmark --rev eea13746799a book_eea1
138 $ hg -R main bookmark --rev eea13746799a book_eea1
139 $ hg -R main debugobsolete -d '0 0' 3333333333333333333333333333333333333333 `getmainid eea13746799a`
139 $ hg -R main debugobsolete -d '0 0' 3333333333333333333333333333333333333333 `getmainid eea13746799a`
140 $ hg -R main bookmark --rev 02de42196ebe book_02de
140 $ hg -R main bookmark --rev 02de42196ebe book_02de
141 $ hg -R main debugobsolete -d '0 0' 4444444444444444444444444444444444444444 `getmainid 02de42196ebe`
141 $ hg -R main debugobsolete -d '0 0' 4444444444444444444444444444444444444444 `getmainid 02de42196ebe`
142 $ hg -R main bookmark --rev 42ccdea3bb16 book_42cc
142 $ hg -R main bookmark --rev 42ccdea3bb16 book_42cc
143 $ hg -R main debugobsolete -d '0 0' 5555555555555555555555555555555555555555 `getmainid 42ccdea3bb16`
143 $ hg -R main debugobsolete -d '0 0' 5555555555555555555555555555555555555555 `getmainid 42ccdea3bb16`
144 $ hg -R main bookmark --rev 5fddd98957c8 book_5fdd
144 $ hg -R main bookmark --rev 5fddd98957c8 book_5fdd
145 $ hg -R main debugobsolete -d '0 0' 6666666666666666666666666666666666666666 `getmainid 5fddd98957c8`
145 $ hg -R main debugobsolete -d '0 0' 6666666666666666666666666666666666666666 `getmainid 5fddd98957c8`
146 $ hg -R main bookmark --rev 32af7686d403 book_32af
146 $ hg -R main bookmark --rev 32af7686d403 book_32af
147 $ hg -R main debugobsolete -d '0 0' 7777777777777777777777777777777777777777 `getmainid 32af7686d403`
147 $ hg -R main debugobsolete -d '0 0' 7777777777777777777777777777777777777777 `getmainid 32af7686d403`
148
148
149 $ hg -R other bookmark --rev cd010b8cd998 book_eea1
149 $ hg -R other bookmark --rev cd010b8cd998 book_eea1
150 $ hg -R other bookmark --rev cd010b8cd998 book_02de
150 $ hg -R other bookmark --rev cd010b8cd998 book_02de
151 $ hg -R other bookmark --rev cd010b8cd998 book_42cc
151 $ hg -R other bookmark --rev cd010b8cd998 book_42cc
152 $ hg -R other bookmark --rev cd010b8cd998 book_5fdd
152 $ hg -R other bookmark --rev cd010b8cd998 book_5fdd
153 $ hg -R other bookmark --rev cd010b8cd998 book_32af
153 $ hg -R other bookmark --rev cd010b8cd998 book_32af
154
154
155 $ hg -R main phase --public eea13746799a
155 $ hg -R main phase --public eea13746799a
156
156
157 push
157 push
158 $ hg -R main push other --rev eea13746799a --bookmark book_eea1
158 $ hg -R main push other --rev eea13746799a --bookmark book_eea1
159 pushing to other
159 pushing to other
160 searching for changes
160 searching for changes
161 b2x-transactionclose hook: HG_BUNDLE2-EXP=1 HG_NEW_OBSMARKERS=1 HG_PHASES_MOVED=1 HG_SOURCE=push HG_URL=push
161 b2x-transactionclose hook: HG_BOOKMARK_MOVED=1 HG_BUNDLE2-EXP=1 HG_NEW_OBSMARKERS=1 HG_PHASES_MOVED=1 HG_SOURCE=push HG_URL=push
162 changegroup hook: HG_BUNDLE2-EXP=1 HG_NEW_OBSMARKERS=1 HG_PHASES_MOVED=1 HG_SOURCE=bundle2 HG_URL=bundle2
162 changegroup hook: HG_BOOKMARK_MOVED=1 HG_BUNDLE2-EXP=1 HG_NEW_OBSMARKERS=1 HG_PHASES_MOVED=1 HG_SOURCE=bundle2 HG_URL=bundle2
163 remote: adding changesets
163 remote: adding changesets
164 remote: adding manifests
164 remote: adding manifests
165 remote: adding file changes
165 remote: adding file changes
166 remote: added 1 changesets with 0 changes to 0 files (-1 heads)
166 remote: added 1 changesets with 0 changes to 0 files (-1 heads)
167 remote: 1 new obsolescence markers
167 remote: 1 new obsolescence markers
168 updating bookmark book_eea1
168 updating bookmark book_eea1
169 $ hg -R other log -G
169 $ hg -R other log -G
170 o 3:eea13746799a public Nicolas Dumazet <nicdumz.commits@gmail.com> book_eea1 G
170 o 3:eea13746799a public Nicolas Dumazet <nicdumz.commits@gmail.com> book_eea1 G
171 |\
171 |\
172 | o 2:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
172 | o 2:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
173 | |
173 | |
174 @ | 1:9520eea781bc public Nicolas Dumazet <nicdumz.commits@gmail.com> E
174 @ | 1:9520eea781bc public Nicolas Dumazet <nicdumz.commits@gmail.com> E
175 |/
175 |/
176 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> book_02de book_32af book_42cc book_5fdd A
176 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> book_02de book_32af book_42cc book_5fdd A
177
177
178 $ hg -R other debugobsolete
178 $ hg -R other debugobsolete
179 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
179 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
180 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
180 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
181 3333333333333333333333333333333333333333 eea13746799a9e0bfd88f29d3c2e9dc9389f524f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
181 3333333333333333333333333333333333333333 eea13746799a9e0bfd88f29d3c2e9dc9389f524f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
182
182
183 pull over ssh
183 pull over ssh
184
184
185 $ hg -R other pull ssh://user@dummy/main -r 02de42196ebe --bookmark book_02de
185 $ hg -R other pull ssh://user@dummy/main -r 02de42196ebe --bookmark book_02de
186 pulling from ssh://user@dummy/main
186 pulling from ssh://user@dummy/main
187 searching for changes
187 searching for changes
188 adding changesets
188 adding changesets
189 adding manifests
189 adding manifests
190 adding file changes
190 adding file changes
191 added 1 changesets with 1 changes to 1 files (+1 heads)
191 added 1 changesets with 1 changes to 1 files (+1 heads)
192 1 new obsolescence markers
192 1 new obsolescence markers
193 updating bookmark book_02de
193 updating bookmark book_02de
194 changegroup hook: HG_NEW_OBSMARKERS=1 HG_PHASES_MOVED=1 HG_SOURCE=bundle2 HG_URL=bundle2
194 changegroup hook: HG_BOOKMARK_MOVED=1 HG_NEW_OBSMARKERS=1 HG_PHASES_MOVED=1 HG_SOURCE=bundle2 HG_URL=bundle2
195 (run 'hg heads' to see heads, 'hg merge' to merge)
195 (run 'hg heads' to see heads, 'hg merge' to merge)
196 $ hg -R other debugobsolete
196 $ hg -R other debugobsolete
197 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
197 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
198 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
198 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
199 3333333333333333333333333333333333333333 eea13746799a9e0bfd88f29d3c2e9dc9389f524f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
199 3333333333333333333333333333333333333333 eea13746799a9e0bfd88f29d3c2e9dc9389f524f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
200 4444444444444444444444444444444444444444 02de42196ebee42ef284b6780a87cdc96e8eaab6 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
200 4444444444444444444444444444444444444444 02de42196ebee42ef284b6780a87cdc96e8eaab6 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
201
201
202 pull over http
202 pull over http
203
203
204 $ hg -R main serve -p $HGPORT -d --pid-file=main.pid -E main-error.log
204 $ hg -R main serve -p $HGPORT -d --pid-file=main.pid -E main-error.log
205 $ cat main.pid >> $DAEMON_PIDS
205 $ cat main.pid >> $DAEMON_PIDS
206
206
207 $ hg -R other pull http://localhost:$HGPORT/ -r 42ccdea3bb16 --bookmark book_42cc
207 $ hg -R other pull http://localhost:$HGPORT/ -r 42ccdea3bb16 --bookmark book_42cc
208 pulling from http://localhost:$HGPORT/
208 pulling from http://localhost:$HGPORT/
209 searching for changes
209 searching for changes
210 adding changesets
210 adding changesets
211 adding manifests
211 adding manifests
212 adding file changes
212 adding file changes
213 added 1 changesets with 1 changes to 1 files (+1 heads)
213 added 1 changesets with 1 changes to 1 files (+1 heads)
214 1 new obsolescence markers
214 1 new obsolescence markers
215 updating bookmark book_42cc
215 updating bookmark book_42cc
216 changegroup hook: HG_NEW_OBSMARKERS=1 HG_PHASES_MOVED=1 HG_SOURCE=bundle2 HG_URL=bundle2
216 changegroup hook: HG_BOOKMARK_MOVED=1 HG_NEW_OBSMARKERS=1 HG_PHASES_MOVED=1 HG_SOURCE=bundle2 HG_URL=bundle2
217 (run 'hg heads .' to see heads, 'hg merge' to merge)
217 (run 'hg heads .' to see heads, 'hg merge' to merge)
218 $ cat main-error.log
218 $ cat main-error.log
219 $ hg -R other debugobsolete
219 $ hg -R other debugobsolete
220 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
220 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
221 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
221 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
222 3333333333333333333333333333333333333333 eea13746799a9e0bfd88f29d3c2e9dc9389f524f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
222 3333333333333333333333333333333333333333 eea13746799a9e0bfd88f29d3c2e9dc9389f524f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
223 4444444444444444444444444444444444444444 02de42196ebee42ef284b6780a87cdc96e8eaab6 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
223 4444444444444444444444444444444444444444 02de42196ebee42ef284b6780a87cdc96e8eaab6 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
224 5555555555555555555555555555555555555555 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
224 5555555555555555555555555555555555555555 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
225
225
226 push over ssh
226 push over ssh
227
227
228 $ hg -R main push ssh://user@dummy/other -r 5fddd98957c8 --bookmark book_5fdd
228 $ hg -R main push ssh://user@dummy/other -r 5fddd98957c8 --bookmark book_5fdd
229 pushing to ssh://user@dummy/other
229 pushing to ssh://user@dummy/other
230 searching for changes
230 searching for changes
231 remote: adding changesets
231 remote: adding changesets
232 remote: adding manifests
232 remote: adding manifests
233 remote: adding file changes
233 remote: adding file changes
234 remote: added 1 changesets with 1 changes to 1 files
234 remote: added 1 changesets with 1 changes to 1 files
235 remote: 1 new obsolescence markers
235 remote: 1 new obsolescence markers
236 updating bookmark book_5fdd
236 updating bookmark book_5fdd
237 remote: b2x-transactionclose hook: HG_BUNDLE2-EXP=1 HG_NEW_OBSMARKERS=1 HG_SOURCE=serve HG_URL=remote:ssh:127.0.0.1
237 remote: b2x-transactionclose hook: HG_BOOKMARK_MOVED=1 HG_BUNDLE2-EXP=1 HG_NEW_OBSMARKERS=1 HG_SOURCE=serve HG_URL=remote:ssh:127.0.0.1
238 remote: changegroup hook: HG_BUNDLE2-EXP=1 HG_NEW_OBSMARKERS=1 HG_SOURCE=bundle2 HG_URL=bundle2
238 remote: changegroup hook: HG_BOOKMARK_MOVED=1 HG_BUNDLE2-EXP=1 HG_NEW_OBSMARKERS=1 HG_SOURCE=bundle2 HG_URL=bundle2
239 $ hg -R other log -G
239 $ hg -R other log -G
240 o 6:5fddd98957c8 draft Nicolas Dumazet <nicdumz.commits@gmail.com> book_5fdd C
240 o 6:5fddd98957c8 draft Nicolas Dumazet <nicdumz.commits@gmail.com> book_5fdd C
241 |
241 |
242 o 5:42ccdea3bb16 draft Nicolas Dumazet <nicdumz.commits@gmail.com> book_42cc B
242 o 5:42ccdea3bb16 draft Nicolas Dumazet <nicdumz.commits@gmail.com> book_42cc B
243 |
243 |
244 | o 4:02de42196ebe draft Nicolas Dumazet <nicdumz.commits@gmail.com> book_02de H
244 | o 4:02de42196ebe draft Nicolas Dumazet <nicdumz.commits@gmail.com> book_02de H
245 | |
245 | |
246 | | o 3:eea13746799a public Nicolas Dumazet <nicdumz.commits@gmail.com> book_eea1 G
246 | | o 3:eea13746799a public Nicolas Dumazet <nicdumz.commits@gmail.com> book_eea1 G
247 | |/|
247 | |/|
248 | o | 2:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
248 | o | 2:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
249 |/ /
249 |/ /
250 | @ 1:9520eea781bc public Nicolas Dumazet <nicdumz.commits@gmail.com> E
250 | @ 1:9520eea781bc public Nicolas Dumazet <nicdumz.commits@gmail.com> E
251 |/
251 |/
252 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> book_32af A
252 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> book_32af A
253
253
254 $ hg -R other debugobsolete
254 $ hg -R other debugobsolete
255 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
255 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
256 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
256 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
257 3333333333333333333333333333333333333333 eea13746799a9e0bfd88f29d3c2e9dc9389f524f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
257 3333333333333333333333333333333333333333 eea13746799a9e0bfd88f29d3c2e9dc9389f524f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
258 4444444444444444444444444444444444444444 02de42196ebee42ef284b6780a87cdc96e8eaab6 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
258 4444444444444444444444444444444444444444 02de42196ebee42ef284b6780a87cdc96e8eaab6 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
259 5555555555555555555555555555555555555555 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
259 5555555555555555555555555555555555555555 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
260 6666666666666666666666666666666666666666 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
260 6666666666666666666666666666666666666666 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
261
261
262 push over http
262 push over http
263
263
264 $ hg -R other serve -p $HGPORT2 -d --pid-file=other.pid -E other-error.log
264 $ hg -R other serve -p $HGPORT2 -d --pid-file=other.pid -E other-error.log
265 $ cat other.pid >> $DAEMON_PIDS
265 $ cat other.pid >> $DAEMON_PIDS
266
266
267 $ hg -R main phase --public 32af7686d403
267 $ hg -R main phase --public 32af7686d403
268 $ hg -R main push http://localhost:$HGPORT2/ -r 32af7686d403 --bookmark book_32af
268 $ hg -R main push http://localhost:$HGPORT2/ -r 32af7686d403 --bookmark book_32af
269 pushing to http://localhost:$HGPORT2/
269 pushing to http://localhost:$HGPORT2/
270 searching for changes
270 searching for changes
271 remote: adding changesets
271 remote: adding changesets
272 remote: adding manifests
272 remote: adding manifests
273 remote: adding file changes
273 remote: adding file changes
274 remote: added 1 changesets with 1 changes to 1 files
274 remote: added 1 changesets with 1 changes to 1 files
275 remote: 1 new obsolescence markers
275 remote: 1 new obsolescence markers
276 updating bookmark book_32af
276 updating bookmark book_32af
277 $ cat other-error.log
277 $ cat other-error.log
278
278
279 Check final content.
279 Check final content.
280
280
281 $ hg -R other log -G
281 $ hg -R other log -G
282 o 7:32af7686d403 public Nicolas Dumazet <nicdumz.commits@gmail.com> book_32af D
282 o 7:32af7686d403 public Nicolas Dumazet <nicdumz.commits@gmail.com> book_32af D
283 |
283 |
284 o 6:5fddd98957c8 public Nicolas Dumazet <nicdumz.commits@gmail.com> book_5fdd C
284 o 6:5fddd98957c8 public Nicolas Dumazet <nicdumz.commits@gmail.com> book_5fdd C
285 |
285 |
286 o 5:42ccdea3bb16 public Nicolas Dumazet <nicdumz.commits@gmail.com> book_42cc B
286 o 5:42ccdea3bb16 public Nicolas Dumazet <nicdumz.commits@gmail.com> book_42cc B
287 |
287 |
288 | o 4:02de42196ebe draft Nicolas Dumazet <nicdumz.commits@gmail.com> book_02de H
288 | o 4:02de42196ebe draft Nicolas Dumazet <nicdumz.commits@gmail.com> book_02de H
289 | |
289 | |
290 | | o 3:eea13746799a public Nicolas Dumazet <nicdumz.commits@gmail.com> book_eea1 G
290 | | o 3:eea13746799a public Nicolas Dumazet <nicdumz.commits@gmail.com> book_eea1 G
291 | |/|
291 | |/|
292 | o | 2:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
292 | o | 2:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
293 |/ /
293 |/ /
294 | @ 1:9520eea781bc public Nicolas Dumazet <nicdumz.commits@gmail.com> E
294 | @ 1:9520eea781bc public Nicolas Dumazet <nicdumz.commits@gmail.com> E
295 |/
295 |/
296 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
296 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
297
297
298 $ hg -R other debugobsolete
298 $ hg -R other debugobsolete
299 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
299 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
300 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
300 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
301 3333333333333333333333333333333333333333 eea13746799a9e0bfd88f29d3c2e9dc9389f524f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
301 3333333333333333333333333333333333333333 eea13746799a9e0bfd88f29d3c2e9dc9389f524f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
302 4444444444444444444444444444444444444444 02de42196ebee42ef284b6780a87cdc96e8eaab6 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
302 4444444444444444444444444444444444444444 02de42196ebee42ef284b6780a87cdc96e8eaab6 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
303 5555555555555555555555555555555555555555 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
303 5555555555555555555555555555555555555555 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
304 6666666666666666666666666666666666666666 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
304 6666666666666666666666666666666666666666 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
305 7777777777777777777777777777777777777777 32af7686d403cf45b5d95f2d70cebea587ac806a 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
305 7777777777777777777777777777777777777777 32af7686d403cf45b5d95f2d70cebea587ac806a 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
306
306
307 Error Handling
307 Error Handling
308 ==============
308 ==============
309
309
310 Check that errors are properly returned to the client during push.
310 Check that errors are properly returned to the client during push.
311
311
312 Setting up
312 Setting up
313
313
314 $ cat > failpush.py << EOF
314 $ cat > failpush.py << EOF
315 > """A small extension that makes push fails when using bundle2
315 > """A small extension that makes push fails when using bundle2
316 >
316 >
317 > used to test error handling in bundle2
317 > used to test error handling in bundle2
318 > """
318 > """
319 >
319 >
320 > from mercurial import util
320 > from mercurial import util
321 > from mercurial import bundle2
321 > from mercurial import bundle2
322 > from mercurial import exchange
322 > from mercurial import exchange
323 > from mercurial import extensions
323 > from mercurial import extensions
324 >
324 >
325 > def _pushbundle2failpart(pushop, bundler):
325 > def _pushbundle2failpart(pushop, bundler):
326 > reason = pushop.ui.config('failpush', 'reason', None)
326 > reason = pushop.ui.config('failpush', 'reason', None)
327 > part = None
327 > part = None
328 > if reason == 'abort':
328 > if reason == 'abort':
329 > bundler.newpart('test:abort')
329 > bundler.newpart('test:abort')
330 > if reason == 'unknown':
330 > if reason == 'unknown':
331 > bundler.newpart('TEST:UNKNOWN')
331 > bundler.newpart('TEST:UNKNOWN')
332 > if reason == 'race':
332 > if reason == 'race':
333 > # 20 Bytes of crap
333 > # 20 Bytes of crap
334 > bundler.newpart('b2x:check:heads', data='01234567890123456789')
334 > bundler.newpart('b2x:check:heads', data='01234567890123456789')
335 >
335 >
336 > @bundle2.parthandler("test:abort")
336 > @bundle2.parthandler("test:abort")
337 > def handleabort(op, part):
337 > def handleabort(op, part):
338 > raise util.Abort('Abandon ship!', hint="don't panic")
338 > raise util.Abort('Abandon ship!', hint="don't panic")
339 >
339 >
340 > def uisetup(ui):
340 > def uisetup(ui):
341 > exchange.b2partsgenmapping['failpart'] = _pushbundle2failpart
341 > exchange.b2partsgenmapping['failpart'] = _pushbundle2failpart
342 > exchange.b2partsgenorder.insert(0, 'failpart')
342 > exchange.b2partsgenorder.insert(0, 'failpart')
343 >
343 >
344 > EOF
344 > EOF
345
345
346 $ cd main
346 $ cd main
347 $ hg up tip
347 $ hg up tip
348 3 files updated, 0 files merged, 1 files removed, 0 files unresolved
348 3 files updated, 0 files merged, 1 files removed, 0 files unresolved
349 $ echo 'I' > I
349 $ echo 'I' > I
350 $ hg add I
350 $ hg add I
351 $ hg ci -m 'I'
351 $ hg ci -m 'I'
352 $ hg id
352 $ hg id
353 e7ec4e813ba6 tip
353 e7ec4e813ba6 tip
354 $ cd ..
354 $ cd ..
355
355
356 $ cat << EOF >> $HGRCPATH
356 $ cat << EOF >> $HGRCPATH
357 > [extensions]
357 > [extensions]
358 > failpush=$TESTTMP/failpush.py
358 > failpush=$TESTTMP/failpush.py
359 > EOF
359 > EOF
360
360
361 $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS
361 $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS
362 $ hg -R other serve -p $HGPORT2 -d --pid-file=other.pid -E other-error.log
362 $ hg -R other serve -p $HGPORT2 -d --pid-file=other.pid -E other-error.log
363 $ cat other.pid >> $DAEMON_PIDS
363 $ cat other.pid >> $DAEMON_PIDS
364
364
365 Doing the actual push: Abort error
365 Doing the actual push: Abort error
366
366
367 $ cat << EOF >> $HGRCPATH
367 $ cat << EOF >> $HGRCPATH
368 > [failpush]
368 > [failpush]
369 > reason = abort
369 > reason = abort
370 > EOF
370 > EOF
371
371
372 $ hg -R main push other -r e7ec4e813ba6
372 $ hg -R main push other -r e7ec4e813ba6
373 pushing to other
373 pushing to other
374 searching for changes
374 searching for changes
375 abort: Abandon ship!
375 abort: Abandon ship!
376 (don't panic)
376 (don't panic)
377 [255]
377 [255]
378
378
379 $ hg -R main push ssh://user@dummy/other -r e7ec4e813ba6
379 $ hg -R main push ssh://user@dummy/other -r e7ec4e813ba6
380 pushing to ssh://user@dummy/other
380 pushing to ssh://user@dummy/other
381 searching for changes
381 searching for changes
382 abort: Abandon ship!
382 abort: Abandon ship!
383 (don't panic)
383 (don't panic)
384 [255]
384 [255]
385
385
386 $ hg -R main push http://localhost:$HGPORT2/ -r e7ec4e813ba6
386 $ hg -R main push http://localhost:$HGPORT2/ -r e7ec4e813ba6
387 pushing to http://localhost:$HGPORT2/
387 pushing to http://localhost:$HGPORT2/
388 searching for changes
388 searching for changes
389 abort: Abandon ship!
389 abort: Abandon ship!
390 (don't panic)
390 (don't panic)
391 [255]
391 [255]
392
392
393
393
394 Doing the actual push: unknown mandatory parts
394 Doing the actual push: unknown mandatory parts
395
395
396 $ cat << EOF >> $HGRCPATH
396 $ cat << EOF >> $HGRCPATH
397 > [failpush]
397 > [failpush]
398 > reason = unknown
398 > reason = unknown
399 > EOF
399 > EOF
400
400
401 $ hg -R main push other -r e7ec4e813ba6
401 $ hg -R main push other -r e7ec4e813ba6
402 pushing to other
402 pushing to other
403 searching for changes
403 searching for changes
404 abort: missing support for test:unknown
404 abort: missing support for test:unknown
405 [255]
405 [255]
406
406
407 $ hg -R main push ssh://user@dummy/other -r e7ec4e813ba6
407 $ hg -R main push ssh://user@dummy/other -r e7ec4e813ba6
408 pushing to ssh://user@dummy/other
408 pushing to ssh://user@dummy/other
409 searching for changes
409 searching for changes
410 abort: missing support for test:unknown
410 abort: missing support for test:unknown
411 [255]
411 [255]
412
412
413 $ hg -R main push http://localhost:$HGPORT2/ -r e7ec4e813ba6
413 $ hg -R main push http://localhost:$HGPORT2/ -r e7ec4e813ba6
414 pushing to http://localhost:$HGPORT2/
414 pushing to http://localhost:$HGPORT2/
415 searching for changes
415 searching for changes
416 abort: missing support for test:unknown
416 abort: missing support for test:unknown
417 [255]
417 [255]
418
418
419 Doing the actual push: race
419 Doing the actual push: race
420
420
421 $ cat << EOF >> $HGRCPATH
421 $ cat << EOF >> $HGRCPATH
422 > [failpush]
422 > [failpush]
423 > reason = race
423 > reason = race
424 > EOF
424 > EOF
425
425
426 $ hg -R main push other -r e7ec4e813ba6
426 $ hg -R main push other -r e7ec4e813ba6
427 pushing to other
427 pushing to other
428 searching for changes
428 searching for changes
429 abort: push failed:
429 abort: push failed:
430 'repository changed while pushing - please try again'
430 'repository changed while pushing - please try again'
431 [255]
431 [255]
432
432
433 $ hg -R main push ssh://user@dummy/other -r e7ec4e813ba6
433 $ hg -R main push ssh://user@dummy/other -r e7ec4e813ba6
434 pushing to ssh://user@dummy/other
434 pushing to ssh://user@dummy/other
435 searching for changes
435 searching for changes
436 abort: push failed:
436 abort: push failed:
437 'repository changed while pushing - please try again'
437 'repository changed while pushing - please try again'
438 [255]
438 [255]
439
439
440 $ hg -R main push http://localhost:$HGPORT2/ -r e7ec4e813ba6
440 $ hg -R main push http://localhost:$HGPORT2/ -r e7ec4e813ba6
441 pushing to http://localhost:$HGPORT2/
441 pushing to http://localhost:$HGPORT2/
442 searching for changes
442 searching for changes
443 abort: push failed:
443 abort: push failed:
444 'repository changed while pushing - please try again'
444 'repository changed while pushing - please try again'
445 [255]
445 [255]
446
446
447 Doing the actual push: hook abort
447 Doing the actual push: hook abort
448
448
449 $ cat << EOF >> $HGRCPATH
449 $ cat << EOF >> $HGRCPATH
450 > [failpush]
450 > [failpush]
451 > reason =
451 > reason =
452 > [hooks]
452 > [hooks]
453 > b2x-pretransactionclose.failpush = false
453 > b2x-pretransactionclose.failpush = false
454 > EOF
454 > EOF
455
455
456 $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS
456 $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS
457 $ hg -R other serve -p $HGPORT2 -d --pid-file=other.pid -E other-error.log
457 $ hg -R other serve -p $HGPORT2 -d --pid-file=other.pid -E other-error.log
458 $ cat other.pid >> $DAEMON_PIDS
458 $ cat other.pid >> $DAEMON_PIDS
459
459
460 $ hg -R main push other -r e7ec4e813ba6
460 $ hg -R main push other -r e7ec4e813ba6
461 pushing to other
461 pushing to other
462 searching for changes
462 searching for changes
463 transaction abort!
463 transaction abort!
464 rollback completed
464 rollback completed
465 changegroup hook: HG_BUNDLE2-EXP=1 HG_NEW_OBSMARKERS=0 HG_SOURCE=bundle2 HG_URL=bundle2
465 changegroup hook: HG_BUNDLE2-EXP=1 HG_NEW_OBSMARKERS=0 HG_SOURCE=bundle2 HG_URL=bundle2
466 abort: b2x-pretransactionclose.failpush hook exited with status 1
466 abort: b2x-pretransactionclose.failpush hook exited with status 1
467 [255]
467 [255]
468
468
469 $ hg -R main push ssh://user@dummy/other -r e7ec4e813ba6
469 $ hg -R main push ssh://user@dummy/other -r e7ec4e813ba6
470 pushing to ssh://user@dummy/other
470 pushing to ssh://user@dummy/other
471 searching for changes
471 searching for changes
472 abort: b2x-pretransactionclose.failpush hook exited with status 1
472 abort: b2x-pretransactionclose.failpush hook exited with status 1
473 remote: transaction abort!
473 remote: transaction abort!
474 remote: rollback completed
474 remote: rollback completed
475 remote: changegroup hook: HG_BUNDLE2-EXP=1 HG_NEW_OBSMARKERS=0 HG_SOURCE=bundle2 HG_URL=bundle2
475 remote: changegroup hook: HG_BUNDLE2-EXP=1 HG_NEW_OBSMARKERS=0 HG_SOURCE=bundle2 HG_URL=bundle2
476 [255]
476 [255]
477
477
478 $ hg -R main push http://localhost:$HGPORT2/ -r e7ec4e813ba6
478 $ hg -R main push http://localhost:$HGPORT2/ -r e7ec4e813ba6
479 pushing to http://localhost:$HGPORT2/
479 pushing to http://localhost:$HGPORT2/
480 searching for changes
480 searching for changes
481 abort: b2x-pretransactionclose.failpush hook exited with status 1
481 abort: b2x-pretransactionclose.failpush hook exited with status 1
482 [255]
482 [255]
483
483
484
484
General Comments 0
You need to be logged in to leave comments. Login now