##// END OF EJS Templates
changegroup: move message about added changes to transaction summary...
marmoute -
r43167:d7304434 default
parent child Browse files
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -1,1426 +1,1441 b''
1 # changegroup.py - Mercurial changegroup manipulation functions
1 # changegroup.py - Mercurial changegroup manipulation functions
2 #
2 #
3 # Copyright 2006 Matt Mackall <mpm@selenic.com>
3 # Copyright 2006 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import os
10 import os
11 import struct
11 import struct
12 import weakref
12 import weakref
13
13
14 from .i18n import _
14 from .i18n import _
15 from .node import (
15 from .node import (
16 hex,
16 hex,
17 nullid,
17 nullid,
18 nullrev,
18 nullrev,
19 short,
19 short,
20 )
20 )
21
21
22 from . import (
22 from . import (
23 error,
23 error,
24 match as matchmod,
24 match as matchmod,
25 mdiff,
25 mdiff,
26 phases,
26 phases,
27 pycompat,
27 pycompat,
28 util,
28 util,
29 )
29 )
30
30
31 from .interfaces import (
31 from .interfaces import (
32 repository,
32 repository,
33 )
33 )
34
34
35 _CHANGEGROUPV1_DELTA_HEADER = struct.Struct("20s20s20s20s")
35 _CHANGEGROUPV1_DELTA_HEADER = struct.Struct("20s20s20s20s")
36 _CHANGEGROUPV2_DELTA_HEADER = struct.Struct("20s20s20s20s20s")
36 _CHANGEGROUPV2_DELTA_HEADER = struct.Struct("20s20s20s20s20s")
37 _CHANGEGROUPV3_DELTA_HEADER = struct.Struct(">20s20s20s20s20sH")
37 _CHANGEGROUPV3_DELTA_HEADER = struct.Struct(">20s20s20s20s20sH")
38
38
39 LFS_REQUIREMENT = 'lfs'
39 LFS_REQUIREMENT = 'lfs'
40
40
41 readexactly = util.readexactly
41 readexactly = util.readexactly
42
42
43 def getchunk(stream):
43 def getchunk(stream):
44 """return the next chunk from stream as a string"""
44 """return the next chunk from stream as a string"""
45 d = readexactly(stream, 4)
45 d = readexactly(stream, 4)
46 l = struct.unpack(">l", d)[0]
46 l = struct.unpack(">l", d)[0]
47 if l <= 4:
47 if l <= 4:
48 if l:
48 if l:
49 raise error.Abort(_("invalid chunk length %d") % l)
49 raise error.Abort(_("invalid chunk length %d") % l)
50 return ""
50 return ""
51 return readexactly(stream, l - 4)
51 return readexactly(stream, l - 4)
52
52
53 def chunkheader(length):
53 def chunkheader(length):
54 """return a changegroup chunk header (string)"""
54 """return a changegroup chunk header (string)"""
55 return struct.pack(">l", length + 4)
55 return struct.pack(">l", length + 4)
56
56
57 def closechunk():
57 def closechunk():
58 """return a changegroup chunk header (string) for a zero-length chunk"""
58 """return a changegroup chunk header (string) for a zero-length chunk"""
59 return struct.pack(">l", 0)
59 return struct.pack(">l", 0)
60
60
61 def _fileheader(path):
61 def _fileheader(path):
62 """Obtain a changegroup chunk header for a named path."""
62 """Obtain a changegroup chunk header for a named path."""
63 return chunkheader(len(path)) + path
63 return chunkheader(len(path)) + path
64
64
65 def writechunks(ui, chunks, filename, vfs=None):
65 def writechunks(ui, chunks, filename, vfs=None):
66 """Write chunks to a file and return its filename.
66 """Write chunks to a file and return its filename.
67
67
68 The stream is assumed to be a bundle file.
68 The stream is assumed to be a bundle file.
69 Existing files will not be overwritten.
69 Existing files will not be overwritten.
70 If no filename is specified, a temporary file is created.
70 If no filename is specified, a temporary file is created.
71 """
71 """
72 fh = None
72 fh = None
73 cleanup = None
73 cleanup = None
74 try:
74 try:
75 if filename:
75 if filename:
76 if vfs:
76 if vfs:
77 fh = vfs.open(filename, "wb")
77 fh = vfs.open(filename, "wb")
78 else:
78 else:
79 # Increase default buffer size because default is usually
79 # Increase default buffer size because default is usually
80 # small (4k is common on Linux).
80 # small (4k is common on Linux).
81 fh = open(filename, "wb", 131072)
81 fh = open(filename, "wb", 131072)
82 else:
82 else:
83 fd, filename = pycompat.mkstemp(prefix="hg-bundle-", suffix=".hg")
83 fd, filename = pycompat.mkstemp(prefix="hg-bundle-", suffix=".hg")
84 fh = os.fdopen(fd, r"wb")
84 fh = os.fdopen(fd, r"wb")
85 cleanup = filename
85 cleanup = filename
86 for c in chunks:
86 for c in chunks:
87 fh.write(c)
87 fh.write(c)
88 cleanup = None
88 cleanup = None
89 return filename
89 return filename
90 finally:
90 finally:
91 if fh is not None:
91 if fh is not None:
92 fh.close()
92 fh.close()
93 if cleanup is not None:
93 if cleanup is not None:
94 if filename and vfs:
94 if filename and vfs:
95 vfs.unlink(cleanup)
95 vfs.unlink(cleanup)
96 else:
96 else:
97 os.unlink(cleanup)
97 os.unlink(cleanup)
98
98
99 class cg1unpacker(object):
99 class cg1unpacker(object):
100 """Unpacker for cg1 changegroup streams.
100 """Unpacker for cg1 changegroup streams.
101
101
102 A changegroup unpacker handles the framing of the revision data in
102 A changegroup unpacker handles the framing of the revision data in
103 the wire format. Most consumers will want to use the apply()
103 the wire format. Most consumers will want to use the apply()
104 method to add the changes from the changegroup to a repository.
104 method to add the changes from the changegroup to a repository.
105
105
106 If you're forwarding a changegroup unmodified to another consumer,
106 If you're forwarding a changegroup unmodified to another consumer,
107 use getchunks(), which returns an iterator of changegroup
107 use getchunks(), which returns an iterator of changegroup
108 chunks. This is mostly useful for cases where you need to know the
108 chunks. This is mostly useful for cases where you need to know the
109 data stream has ended by observing the end of the changegroup.
109 data stream has ended by observing the end of the changegroup.
110
110
111 deltachunk() is useful only if you're applying delta data. Most
111 deltachunk() is useful only if you're applying delta data. Most
112 consumers should prefer apply() instead.
112 consumers should prefer apply() instead.
113
113
114 A few other public methods exist. Those are used only for
114 A few other public methods exist. Those are used only for
115 bundlerepo and some debug commands - their use is discouraged.
115 bundlerepo and some debug commands - their use is discouraged.
116 """
116 """
117 deltaheader = _CHANGEGROUPV1_DELTA_HEADER
117 deltaheader = _CHANGEGROUPV1_DELTA_HEADER
118 deltaheadersize = deltaheader.size
118 deltaheadersize = deltaheader.size
119 version = '01'
119 version = '01'
120 _grouplistcount = 1 # One list of files after the manifests
120 _grouplistcount = 1 # One list of files after the manifests
121
121
122 def __init__(self, fh, alg, extras=None):
122 def __init__(self, fh, alg, extras=None):
123 if alg is None:
123 if alg is None:
124 alg = 'UN'
124 alg = 'UN'
125 if alg not in util.compengines.supportedbundletypes:
125 if alg not in util.compengines.supportedbundletypes:
126 raise error.Abort(_('unknown stream compression type: %s')
126 raise error.Abort(_('unknown stream compression type: %s')
127 % alg)
127 % alg)
128 if alg == 'BZ':
128 if alg == 'BZ':
129 alg = '_truncatedBZ'
129 alg = '_truncatedBZ'
130
130
131 compengine = util.compengines.forbundletype(alg)
131 compengine = util.compengines.forbundletype(alg)
132 self._stream = compengine.decompressorreader(fh)
132 self._stream = compengine.decompressorreader(fh)
133 self._type = alg
133 self._type = alg
134 self.extras = extras or {}
134 self.extras = extras or {}
135 self.callback = None
135 self.callback = None
136
136
137 # These methods (compressed, read, seek, tell) all appear to only
137 # These methods (compressed, read, seek, tell) all appear to only
138 # be used by bundlerepo, but it's a little hard to tell.
138 # be used by bundlerepo, but it's a little hard to tell.
139 def compressed(self):
139 def compressed(self):
140 return self._type is not None and self._type != 'UN'
140 return self._type is not None and self._type != 'UN'
141 def read(self, l):
141 def read(self, l):
142 return self._stream.read(l)
142 return self._stream.read(l)
143 def seek(self, pos):
143 def seek(self, pos):
144 return self._stream.seek(pos)
144 return self._stream.seek(pos)
145 def tell(self):
145 def tell(self):
146 return self._stream.tell()
146 return self._stream.tell()
147 def close(self):
147 def close(self):
148 return self._stream.close()
148 return self._stream.close()
149
149
150 def _chunklength(self):
150 def _chunklength(self):
151 d = readexactly(self._stream, 4)
151 d = readexactly(self._stream, 4)
152 l = struct.unpack(">l", d)[0]
152 l = struct.unpack(">l", d)[0]
153 if l <= 4:
153 if l <= 4:
154 if l:
154 if l:
155 raise error.Abort(_("invalid chunk length %d") % l)
155 raise error.Abort(_("invalid chunk length %d") % l)
156 return 0
156 return 0
157 if self.callback:
157 if self.callback:
158 self.callback()
158 self.callback()
159 return l - 4
159 return l - 4
160
160
161 def changelogheader(self):
161 def changelogheader(self):
162 """v10 does not have a changelog header chunk"""
162 """v10 does not have a changelog header chunk"""
163 return {}
163 return {}
164
164
165 def manifestheader(self):
165 def manifestheader(self):
166 """v10 does not have a manifest header chunk"""
166 """v10 does not have a manifest header chunk"""
167 return {}
167 return {}
168
168
169 def filelogheader(self):
169 def filelogheader(self):
170 """return the header of the filelogs chunk, v10 only has the filename"""
170 """return the header of the filelogs chunk, v10 only has the filename"""
171 l = self._chunklength()
171 l = self._chunklength()
172 if not l:
172 if not l:
173 return {}
173 return {}
174 fname = readexactly(self._stream, l)
174 fname = readexactly(self._stream, l)
175 return {'filename': fname}
175 return {'filename': fname}
176
176
177 def _deltaheader(self, headertuple, prevnode):
177 def _deltaheader(self, headertuple, prevnode):
178 node, p1, p2, cs = headertuple
178 node, p1, p2, cs = headertuple
179 if prevnode is None:
179 if prevnode is None:
180 deltabase = p1
180 deltabase = p1
181 else:
181 else:
182 deltabase = prevnode
182 deltabase = prevnode
183 flags = 0
183 flags = 0
184 return node, p1, p2, deltabase, cs, flags
184 return node, p1, p2, deltabase, cs, flags
185
185
186 def deltachunk(self, prevnode):
186 def deltachunk(self, prevnode):
187 l = self._chunklength()
187 l = self._chunklength()
188 if not l:
188 if not l:
189 return {}
189 return {}
190 headerdata = readexactly(self._stream, self.deltaheadersize)
190 headerdata = readexactly(self._stream, self.deltaheadersize)
191 header = self.deltaheader.unpack(headerdata)
191 header = self.deltaheader.unpack(headerdata)
192 delta = readexactly(self._stream, l - self.deltaheadersize)
192 delta = readexactly(self._stream, l - self.deltaheadersize)
193 node, p1, p2, deltabase, cs, flags = self._deltaheader(header, prevnode)
193 node, p1, p2, deltabase, cs, flags = self._deltaheader(header, prevnode)
194 return (node, p1, p2, cs, deltabase, delta, flags)
194 return (node, p1, p2, cs, deltabase, delta, flags)
195
195
196 def getchunks(self):
196 def getchunks(self):
197 """returns all the chunks contains in the bundle
197 """returns all the chunks contains in the bundle
198
198
199 Used when you need to forward the binary stream to a file or another
199 Used when you need to forward the binary stream to a file or another
200 network API. To do so, it parse the changegroup data, otherwise it will
200 network API. To do so, it parse the changegroup data, otherwise it will
201 block in case of sshrepo because it don't know the end of the stream.
201 block in case of sshrepo because it don't know the end of the stream.
202 """
202 """
203 # For changegroup 1 and 2, we expect 3 parts: changelog, manifestlog,
203 # For changegroup 1 and 2, we expect 3 parts: changelog, manifestlog,
204 # and a list of filelogs. For changegroup 3, we expect 4 parts:
204 # and a list of filelogs. For changegroup 3, we expect 4 parts:
205 # changelog, manifestlog, a list of tree manifestlogs, and a list of
205 # changelog, manifestlog, a list of tree manifestlogs, and a list of
206 # filelogs.
206 # filelogs.
207 #
207 #
208 # Changelog and manifestlog parts are terminated with empty chunks. The
208 # Changelog and manifestlog parts are terminated with empty chunks. The
209 # tree and file parts are a list of entry sections. Each entry section
209 # tree and file parts are a list of entry sections. Each entry section
210 # is a series of chunks terminating in an empty chunk. The list of these
210 # is a series of chunks terminating in an empty chunk. The list of these
211 # entry sections is terminated in yet another empty chunk, so we know
211 # entry sections is terminated in yet another empty chunk, so we know
212 # we've reached the end of the tree/file list when we reach an empty
212 # we've reached the end of the tree/file list when we reach an empty
213 # chunk that was proceeded by no non-empty chunks.
213 # chunk that was proceeded by no non-empty chunks.
214
214
215 parts = 0
215 parts = 0
216 while parts < 2 + self._grouplistcount:
216 while parts < 2 + self._grouplistcount:
217 noentries = True
217 noentries = True
218 while True:
218 while True:
219 chunk = getchunk(self)
219 chunk = getchunk(self)
220 if not chunk:
220 if not chunk:
221 # The first two empty chunks represent the end of the
221 # The first two empty chunks represent the end of the
222 # changelog and the manifestlog portions. The remaining
222 # changelog and the manifestlog portions. The remaining
223 # empty chunks represent either A) the end of individual
223 # empty chunks represent either A) the end of individual
224 # tree or file entries in the file list, or B) the end of
224 # tree or file entries in the file list, or B) the end of
225 # the entire list. It's the end of the entire list if there
225 # the entire list. It's the end of the entire list if there
226 # were no entries (i.e. noentries is True).
226 # were no entries (i.e. noentries is True).
227 if parts < 2:
227 if parts < 2:
228 parts += 1
228 parts += 1
229 elif noentries:
229 elif noentries:
230 parts += 1
230 parts += 1
231 break
231 break
232 noentries = False
232 noentries = False
233 yield chunkheader(len(chunk))
233 yield chunkheader(len(chunk))
234 pos = 0
234 pos = 0
235 while pos < len(chunk):
235 while pos < len(chunk):
236 next = pos + 2**20
236 next = pos + 2**20
237 yield chunk[pos:next]
237 yield chunk[pos:next]
238 pos = next
238 pos = next
239 yield closechunk()
239 yield closechunk()
240
240
241 def _unpackmanifests(self, repo, revmap, trp, prog):
241 def _unpackmanifests(self, repo, revmap, trp, prog):
242 self.callback = prog.increment
242 self.callback = prog.increment
243 # no need to check for empty manifest group here:
243 # no need to check for empty manifest group here:
244 # if the result of the merge of 1 and 2 is the same in 3 and 4,
244 # if the result of the merge of 1 and 2 is the same in 3 and 4,
245 # no new manifest will be created and the manifest group will
245 # no new manifest will be created and the manifest group will
246 # be empty during the pull
246 # be empty during the pull
247 self.manifestheader()
247 self.manifestheader()
248 deltas = self.deltaiter()
248 deltas = self.deltaiter()
249 repo.manifestlog.getstorage(b'').addgroup(deltas, revmap, trp)
249 repo.manifestlog.getstorage(b'').addgroup(deltas, revmap, trp)
250 prog.complete()
250 prog.complete()
251 self.callback = None
251 self.callback = None
252
252
253 def apply(self, repo, tr, srctype, url, targetphase=phases.draft,
253 def apply(self, repo, tr, srctype, url, targetphase=phases.draft,
254 expectedtotal=None):
254 expectedtotal=None):
255 """Add the changegroup returned by source.read() to this repo.
255 """Add the changegroup returned by source.read() to this repo.
256 srctype is a string like 'push', 'pull', or 'unbundle'. url is
256 srctype is a string like 'push', 'pull', or 'unbundle'. url is
257 the URL of the repo where this changegroup is coming from.
257 the URL of the repo where this changegroup is coming from.
258
258
259 Return an integer summarizing the change to this repo:
259 Return an integer summarizing the change to this repo:
260 - nothing changed or no source: 0
260 - nothing changed or no source: 0
261 - more heads than before: 1+added heads (2..n)
261 - more heads than before: 1+added heads (2..n)
262 - fewer heads than before: -1-removed heads (-2..-n)
262 - fewer heads than before: -1-removed heads (-2..-n)
263 - number of heads stays the same: 1
263 - number of heads stays the same: 1
264 """
264 """
265 repo = repo.unfiltered()
265 repo = repo.unfiltered()
266 def csmap(x):
266 def csmap(x):
267 repo.ui.debug("add changeset %s\n" % short(x))
267 repo.ui.debug("add changeset %s\n" % short(x))
268 return len(cl)
268 return len(cl)
269
269
270 def revmap(x):
270 def revmap(x):
271 return cl.rev(x)
271 return cl.rev(x)
272
272
273 changesets = files = revisions = 0
273 changesets = 0
274
274
275 try:
275 try:
276 # The transaction may already carry source information. In this
276 # The transaction may already carry source information. In this
277 # case we use the top level data. We overwrite the argument
277 # case we use the top level data. We overwrite the argument
278 # because we need to use the top level value (if they exist)
278 # because we need to use the top level value (if they exist)
279 # in this function.
279 # in this function.
280 srctype = tr.hookargs.setdefault('source', srctype)
280 srctype = tr.hookargs.setdefault('source', srctype)
281 tr.hookargs.setdefault('url', url)
281 tr.hookargs.setdefault('url', url)
282 repo.hook('prechangegroup',
282 repo.hook('prechangegroup',
283 throw=True, **pycompat.strkwargs(tr.hookargs))
283 throw=True, **pycompat.strkwargs(tr.hookargs))
284
284
285 # write changelog data to temp files so concurrent readers
285 # write changelog data to temp files so concurrent readers
286 # will not see an inconsistent view
286 # will not see an inconsistent view
287 cl = repo.changelog
287 cl = repo.changelog
288 cl.delayupdate(tr)
288 cl.delayupdate(tr)
289 oldheads = set(cl.heads())
289 oldheads = set(cl.heads())
290
290
291 trp = weakref.proxy(tr)
291 trp = weakref.proxy(tr)
292 # pull off the changeset group
292 # pull off the changeset group
293 repo.ui.status(_("adding changesets\n"))
293 repo.ui.status(_("adding changesets\n"))
294 clstart = len(cl)
294 clstart = len(cl)
295 progress = repo.ui.makeprogress(_('changesets'), unit=_('chunks'),
295 progress = repo.ui.makeprogress(_('changesets'), unit=_('chunks'),
296 total=expectedtotal)
296 total=expectedtotal)
297 self.callback = progress.increment
297 self.callback = progress.increment
298
298
299 efiles = set()
299 efiles = set()
300 def onchangelog(cl, node):
300 def onchangelog(cl, node):
301 efiles.update(cl.readfiles(node))
301 efiles.update(cl.readfiles(node))
302
302
303 self.changelogheader()
303 self.changelogheader()
304 deltas = self.deltaiter()
304 deltas = self.deltaiter()
305 cgnodes = cl.addgroup(deltas, csmap, trp, addrevisioncb=onchangelog)
305 cgnodes = cl.addgroup(deltas, csmap, trp, addrevisioncb=onchangelog)
306 efiles = len(efiles)
306 efiles = len(efiles)
307
307
308 if not cgnodes:
308 if not cgnodes:
309 repo.ui.develwarn('applied empty changelog from changegroup',
309 repo.ui.develwarn('applied empty changelog from changegroup',
310 config='warn-empty-changegroup')
310 config='warn-empty-changegroup')
311 clend = len(cl)
311 clend = len(cl)
312 changesets = clend - clstart
312 changesets = clend - clstart
313 progress.complete()
313 progress.complete()
314 self.callback = None
314 self.callback = None
315
315
316 # pull off the manifest group
316 # pull off the manifest group
317 repo.ui.status(_("adding manifests\n"))
317 repo.ui.status(_("adding manifests\n"))
318 # We know that we'll never have more manifests than we had
318 # We know that we'll never have more manifests than we had
319 # changesets.
319 # changesets.
320 progress = repo.ui.makeprogress(_('manifests'), unit=_('chunks'),
320 progress = repo.ui.makeprogress(_('manifests'), unit=_('chunks'),
321 total=changesets)
321 total=changesets)
322 self._unpackmanifests(repo, revmap, trp, progress)
322 self._unpackmanifests(repo, revmap, trp, progress)
323
323
324 needfiles = {}
324 needfiles = {}
325 if repo.ui.configbool('server', 'validate'):
325 if repo.ui.configbool('server', 'validate'):
326 cl = repo.changelog
326 cl = repo.changelog
327 ml = repo.manifestlog
327 ml = repo.manifestlog
328 # validate incoming csets have their manifests
328 # validate incoming csets have their manifests
329 for cset in pycompat.xrange(clstart, clend):
329 for cset in pycompat.xrange(clstart, clend):
330 mfnode = cl.changelogrevision(cset).manifest
330 mfnode = cl.changelogrevision(cset).manifest
331 mfest = ml[mfnode].readdelta()
331 mfest = ml[mfnode].readdelta()
332 # store file cgnodes we must see
332 # store file cgnodes we must see
333 for f, n in mfest.iteritems():
333 for f, n in mfest.iteritems():
334 needfiles.setdefault(f, set()).add(n)
334 needfiles.setdefault(f, set()).add(n)
335
335
336 # process the files
336 # process the files
337 repo.ui.status(_("adding file changes\n"))
337 repo.ui.status(_("adding file changes\n"))
338 newrevs, newfiles = _addchangegroupfiles(
338 newrevs, newfiles = _addchangegroupfiles(
339 repo, self, revmap, trp, efiles, needfiles)
339 repo, self, revmap, trp, efiles, needfiles)
340 revisions += newrevs
340
341 files += newfiles
341 # making sure the value exists
342 tr.changes.setdefault('changegroup-count-changesets', 0)
343 tr.changes.setdefault('changegroup-count-revisions', 0)
344 tr.changes.setdefault('changegroup-count-files', 0)
345 tr.changes.setdefault('changegroup-count-heads', 0)
346
347 # some code use bundle operation for internal purpose. They usually
348 # set `ui.quiet` to do this outside of user sight. Size the report
349 # of such operation now happens at the end of the transaction, that
350 # ui.quiet has not direct effect on the output.
351 #
352 # To preserve this intend use an inelegant hack, we fail to report
353 # the change if `quiet` is set. We should probably move to
354 # something better, but this is a good first step to allow the "end
355 # of transaction report" to pass tests.
356 if not repo.ui.quiet:
357 tr.changes['changegroup-count-changesets'] += changesets
358 tr.changes['changegroup-count-revisions'] += newrevs
359 tr.changes['changegroup-count-files'] += newfiles
342
360
343 deltaheads = 0
361 deltaheads = 0
344 if oldheads:
362 if oldheads:
345 heads = cl.heads()
363 heads = cl.heads()
346 deltaheads = len(heads) - len(oldheads)
364 deltaheads += len(heads) - len(oldheads)
347 for h in heads:
365 for h in heads:
348 if h not in oldheads and repo[h].closesbranch():
366 if h not in oldheads and repo[h].closesbranch():
349 deltaheads -= 1
367 deltaheads -= 1
350 htext = ""
351 if deltaheads:
352 htext = _(" (%+d heads)") % deltaheads
353
368
354 repo.ui.status(_("added %d changesets"
369 # see previous comment about checking ui.quiet
355 " with %d changes to %d files%s\n")
370 if not repo.ui.quiet:
356 % (changesets, revisions, files, htext))
371 tr.changes['changegroup-count-heads'] += deltaheads
357 repo.invalidatevolatilesets()
372 repo.invalidatevolatilesets()
358
373
359 if changesets > 0:
374 if changesets > 0:
360 if 'node' not in tr.hookargs:
375 if 'node' not in tr.hookargs:
361 tr.hookargs['node'] = hex(cl.node(clstart))
376 tr.hookargs['node'] = hex(cl.node(clstart))
362 tr.hookargs['node_last'] = hex(cl.node(clend - 1))
377 tr.hookargs['node_last'] = hex(cl.node(clend - 1))
363 hookargs = dict(tr.hookargs)
378 hookargs = dict(tr.hookargs)
364 else:
379 else:
365 hookargs = dict(tr.hookargs)
380 hookargs = dict(tr.hookargs)
366 hookargs['node'] = hex(cl.node(clstart))
381 hookargs['node'] = hex(cl.node(clstart))
367 hookargs['node_last'] = hex(cl.node(clend - 1))
382 hookargs['node_last'] = hex(cl.node(clend - 1))
368 repo.hook('pretxnchangegroup',
383 repo.hook('pretxnchangegroup',
369 throw=True, **pycompat.strkwargs(hookargs))
384 throw=True, **pycompat.strkwargs(hookargs))
370
385
371 added = [cl.node(r) for r in pycompat.xrange(clstart, clend)]
386 added = [cl.node(r) for r in pycompat.xrange(clstart, clend)]
372 phaseall = None
387 phaseall = None
373 if srctype in ('push', 'serve'):
388 if srctype in ('push', 'serve'):
374 # Old servers can not push the boundary themselves.
389 # Old servers can not push the boundary themselves.
375 # New servers won't push the boundary if changeset already
390 # New servers won't push the boundary if changeset already
376 # exists locally as secret
391 # exists locally as secret
377 #
392 #
378 # We should not use added here but the list of all change in
393 # We should not use added here but the list of all change in
379 # the bundle
394 # the bundle
380 if repo.publishing():
395 if repo.publishing():
381 targetphase = phaseall = phases.public
396 targetphase = phaseall = phases.public
382 else:
397 else:
383 # closer target phase computation
398 # closer target phase computation
384
399
385 # Those changesets have been pushed from the
400 # Those changesets have been pushed from the
386 # outside, their phases are going to be pushed
401 # outside, their phases are going to be pushed
387 # alongside. Therefor `targetphase` is
402 # alongside. Therefor `targetphase` is
388 # ignored.
403 # ignored.
389 targetphase = phaseall = phases.draft
404 targetphase = phaseall = phases.draft
390 if added:
405 if added:
391 phases.registernew(repo, tr, targetphase, added)
406 phases.registernew(repo, tr, targetphase, added)
392 if phaseall is not None:
407 if phaseall is not None:
393 phases.advanceboundary(repo, tr, phaseall, cgnodes)
408 phases.advanceboundary(repo, tr, phaseall, cgnodes)
394
409
395 if changesets > 0:
410 if changesets > 0:
396
411
397 def runhooks():
412 def runhooks():
398 # These hooks run when the lock releases, not when the
413 # These hooks run when the lock releases, not when the
399 # transaction closes. So it's possible for the changelog
414 # transaction closes. So it's possible for the changelog
400 # to have changed since we last saw it.
415 # to have changed since we last saw it.
401 if clstart >= len(repo):
416 if clstart >= len(repo):
402 return
417 return
403
418
404 repo.hook("changegroup", **pycompat.strkwargs(hookargs))
419 repo.hook("changegroup", **pycompat.strkwargs(hookargs))
405
420
406 for n in added:
421 for n in added:
407 args = hookargs.copy()
422 args = hookargs.copy()
408 args['node'] = hex(n)
423 args['node'] = hex(n)
409 del args['node_last']
424 del args['node_last']
410 repo.hook("incoming", **pycompat.strkwargs(args))
425 repo.hook("incoming", **pycompat.strkwargs(args))
411
426
412 newheads = [h for h in repo.heads()
427 newheads = [h for h in repo.heads()
413 if h not in oldheads]
428 if h not in oldheads]
414 repo.ui.log("incoming",
429 repo.ui.log("incoming",
415 "%d incoming changes - new heads: %s\n",
430 "%d incoming changes - new heads: %s\n",
416 len(added),
431 len(added),
417 ', '.join([hex(c[:6]) for c in newheads]))
432 ', '.join([hex(c[:6]) for c in newheads]))
418
433
419 tr.addpostclose('changegroup-runhooks-%020i' % clstart,
434 tr.addpostclose('changegroup-runhooks-%020i' % clstart,
420 lambda tr: repo._afterlock(runhooks))
435 lambda tr: repo._afterlock(runhooks))
421 finally:
436 finally:
422 repo.ui.flush()
437 repo.ui.flush()
423 # never return 0 here:
438 # never return 0 here:
424 if deltaheads < 0:
439 if deltaheads < 0:
425 ret = deltaheads - 1
440 ret = deltaheads - 1
426 else:
441 else:
427 ret = deltaheads + 1
442 ret = deltaheads + 1
428 return ret
443 return ret
429
444
430 def deltaiter(self):
445 def deltaiter(self):
431 """
446 """
432 returns an iterator of the deltas in this changegroup
447 returns an iterator of the deltas in this changegroup
433
448
434 Useful for passing to the underlying storage system to be stored.
449 Useful for passing to the underlying storage system to be stored.
435 """
450 """
436 chain = None
451 chain = None
437 for chunkdata in iter(lambda: self.deltachunk(chain), {}):
452 for chunkdata in iter(lambda: self.deltachunk(chain), {}):
438 # Chunkdata: (node, p1, p2, cs, deltabase, delta, flags)
453 # Chunkdata: (node, p1, p2, cs, deltabase, delta, flags)
439 yield chunkdata
454 yield chunkdata
440 chain = chunkdata[0]
455 chain = chunkdata[0]
441
456
442 class cg2unpacker(cg1unpacker):
457 class cg2unpacker(cg1unpacker):
443 """Unpacker for cg2 streams.
458 """Unpacker for cg2 streams.
444
459
445 cg2 streams add support for generaldelta, so the delta header
460 cg2 streams add support for generaldelta, so the delta header
446 format is slightly different. All other features about the data
461 format is slightly different. All other features about the data
447 remain the same.
462 remain the same.
448 """
463 """
449 deltaheader = _CHANGEGROUPV2_DELTA_HEADER
464 deltaheader = _CHANGEGROUPV2_DELTA_HEADER
450 deltaheadersize = deltaheader.size
465 deltaheadersize = deltaheader.size
451 version = '02'
466 version = '02'
452
467
453 def _deltaheader(self, headertuple, prevnode):
468 def _deltaheader(self, headertuple, prevnode):
454 node, p1, p2, deltabase, cs = headertuple
469 node, p1, p2, deltabase, cs = headertuple
455 flags = 0
470 flags = 0
456 return node, p1, p2, deltabase, cs, flags
471 return node, p1, p2, deltabase, cs, flags
457
472
458 class cg3unpacker(cg2unpacker):
473 class cg3unpacker(cg2unpacker):
459 """Unpacker for cg3 streams.
474 """Unpacker for cg3 streams.
460
475
461 cg3 streams add support for exchanging treemanifests and revlog
476 cg3 streams add support for exchanging treemanifests and revlog
462 flags. It adds the revlog flags to the delta header and an empty chunk
477 flags. It adds the revlog flags to the delta header and an empty chunk
463 separating manifests and files.
478 separating manifests and files.
464 """
479 """
465 deltaheader = _CHANGEGROUPV3_DELTA_HEADER
480 deltaheader = _CHANGEGROUPV3_DELTA_HEADER
466 deltaheadersize = deltaheader.size
481 deltaheadersize = deltaheader.size
467 version = '03'
482 version = '03'
468 _grouplistcount = 2 # One list of manifests and one list of files
483 _grouplistcount = 2 # One list of manifests and one list of files
469
484
470 def _deltaheader(self, headertuple, prevnode):
485 def _deltaheader(self, headertuple, prevnode):
471 node, p1, p2, deltabase, cs, flags = headertuple
486 node, p1, p2, deltabase, cs, flags = headertuple
472 return node, p1, p2, deltabase, cs, flags
487 return node, p1, p2, deltabase, cs, flags
473
488
474 def _unpackmanifests(self, repo, revmap, trp, prog):
489 def _unpackmanifests(self, repo, revmap, trp, prog):
475 super(cg3unpacker, self)._unpackmanifests(repo, revmap, trp, prog)
490 super(cg3unpacker, self)._unpackmanifests(repo, revmap, trp, prog)
476 for chunkdata in iter(self.filelogheader, {}):
491 for chunkdata in iter(self.filelogheader, {}):
477 # If we get here, there are directory manifests in the changegroup
492 # If we get here, there are directory manifests in the changegroup
478 d = chunkdata["filename"]
493 d = chunkdata["filename"]
479 repo.ui.debug("adding %s revisions\n" % d)
494 repo.ui.debug("adding %s revisions\n" % d)
480 deltas = self.deltaiter()
495 deltas = self.deltaiter()
481 if not repo.manifestlog.getstorage(d).addgroup(deltas, revmap, trp):
496 if not repo.manifestlog.getstorage(d).addgroup(deltas, revmap, trp):
482 raise error.Abort(_("received dir revlog group is empty"))
497 raise error.Abort(_("received dir revlog group is empty"))
483
498
484 class headerlessfixup(object):
499 class headerlessfixup(object):
485 def __init__(self, fh, h):
500 def __init__(self, fh, h):
486 self._h = h
501 self._h = h
487 self._fh = fh
502 self._fh = fh
488 def read(self, n):
503 def read(self, n):
489 if self._h:
504 if self._h:
490 d, self._h = self._h[:n], self._h[n:]
505 d, self._h = self._h[:n], self._h[n:]
491 if len(d) < n:
506 if len(d) < n:
492 d += readexactly(self._fh, n - len(d))
507 d += readexactly(self._fh, n - len(d))
493 return d
508 return d
494 return readexactly(self._fh, n)
509 return readexactly(self._fh, n)
495
510
496 def _revisiondeltatochunks(delta, headerfn):
511 def _revisiondeltatochunks(delta, headerfn):
497 """Serialize a revisiondelta to changegroup chunks."""
512 """Serialize a revisiondelta to changegroup chunks."""
498
513
499 # The captured revision delta may be encoded as a delta against
514 # The captured revision delta may be encoded as a delta against
500 # a base revision or as a full revision. The changegroup format
515 # a base revision or as a full revision. The changegroup format
501 # requires that everything on the wire be deltas. So for full
516 # requires that everything on the wire be deltas. So for full
502 # revisions, we need to invent a header that says to rewrite
517 # revisions, we need to invent a header that says to rewrite
503 # data.
518 # data.
504
519
505 if delta.delta is not None:
520 if delta.delta is not None:
506 prefix, data = b'', delta.delta
521 prefix, data = b'', delta.delta
507 elif delta.basenode == nullid:
522 elif delta.basenode == nullid:
508 data = delta.revision
523 data = delta.revision
509 prefix = mdiff.trivialdiffheader(len(data))
524 prefix = mdiff.trivialdiffheader(len(data))
510 else:
525 else:
511 data = delta.revision
526 data = delta.revision
512 prefix = mdiff.replacediffheader(delta.baserevisionsize,
527 prefix = mdiff.replacediffheader(delta.baserevisionsize,
513 len(data))
528 len(data))
514
529
515 meta = headerfn(delta)
530 meta = headerfn(delta)
516
531
517 yield chunkheader(len(meta) + len(prefix) + len(data))
532 yield chunkheader(len(meta) + len(prefix) + len(data))
518 yield meta
533 yield meta
519 if prefix:
534 if prefix:
520 yield prefix
535 yield prefix
521 yield data
536 yield data
522
537
523 def _sortnodesellipsis(store, nodes, cl, lookup):
538 def _sortnodesellipsis(store, nodes, cl, lookup):
524 """Sort nodes for changegroup generation."""
539 """Sort nodes for changegroup generation."""
525 # Ellipses serving mode.
540 # Ellipses serving mode.
526 #
541 #
527 # In a perfect world, we'd generate better ellipsis-ified graphs
542 # In a perfect world, we'd generate better ellipsis-ified graphs
528 # for non-changelog revlogs. In practice, we haven't started doing
543 # for non-changelog revlogs. In practice, we haven't started doing
529 # that yet, so the resulting DAGs for the manifestlog and filelogs
544 # that yet, so the resulting DAGs for the manifestlog and filelogs
530 # are actually full of bogus parentage on all the ellipsis
545 # are actually full of bogus parentage on all the ellipsis
531 # nodes. This has the side effect that, while the contents are
546 # nodes. This has the side effect that, while the contents are
532 # correct, the individual DAGs might be completely out of whack in
547 # correct, the individual DAGs might be completely out of whack in
533 # a case like 882681bc3166 and its ancestors (back about 10
548 # a case like 882681bc3166 and its ancestors (back about 10
534 # revisions or so) in the main hg repo.
549 # revisions or so) in the main hg repo.
535 #
550 #
536 # The one invariant we *know* holds is that the new (potentially
551 # The one invariant we *know* holds is that the new (potentially
537 # bogus) DAG shape will be valid if we order the nodes in the
552 # bogus) DAG shape will be valid if we order the nodes in the
538 # order that they're introduced in dramatis personae by the
553 # order that they're introduced in dramatis personae by the
539 # changelog, so what we do is we sort the non-changelog histories
554 # changelog, so what we do is we sort the non-changelog histories
540 # by the order in which they are used by the changelog.
555 # by the order in which they are used by the changelog.
541 key = lambda n: cl.rev(lookup(n))
556 key = lambda n: cl.rev(lookup(n))
542 return sorted(nodes, key=key)
557 return sorted(nodes, key=key)
543
558
544 def _resolvenarrowrevisioninfo(cl, store, ischangelog, rev, linkrev,
559 def _resolvenarrowrevisioninfo(cl, store, ischangelog, rev, linkrev,
545 linknode, clrevtolocalrev, fullclnodes,
560 linknode, clrevtolocalrev, fullclnodes,
546 precomputedellipsis):
561 precomputedellipsis):
547 linkparents = precomputedellipsis[linkrev]
562 linkparents = precomputedellipsis[linkrev]
548 def local(clrev):
563 def local(clrev):
549 """Turn a changelog revnum into a local revnum.
564 """Turn a changelog revnum into a local revnum.
550
565
551 The ellipsis dag is stored as revnums on the changelog,
566 The ellipsis dag is stored as revnums on the changelog,
552 but when we're producing ellipsis entries for
567 but when we're producing ellipsis entries for
553 non-changelog revlogs, we need to turn those numbers into
568 non-changelog revlogs, we need to turn those numbers into
554 something local. This does that for us, and during the
569 something local. This does that for us, and during the
555 changelog sending phase will also expand the stored
570 changelog sending phase will also expand the stored
556 mappings as needed.
571 mappings as needed.
557 """
572 """
558 if clrev == nullrev:
573 if clrev == nullrev:
559 return nullrev
574 return nullrev
560
575
561 if ischangelog:
576 if ischangelog:
562 return clrev
577 return clrev
563
578
564 # Walk the ellipsis-ized changelog breadth-first looking for a
579 # Walk the ellipsis-ized changelog breadth-first looking for a
565 # change that has been linked from the current revlog.
580 # change that has been linked from the current revlog.
566 #
581 #
567 # For a flat manifest revlog only a single step should be necessary
582 # For a flat manifest revlog only a single step should be necessary
568 # as all relevant changelog entries are relevant to the flat
583 # as all relevant changelog entries are relevant to the flat
569 # manifest.
584 # manifest.
570 #
585 #
571 # For a filelog or tree manifest dirlog however not every changelog
586 # For a filelog or tree manifest dirlog however not every changelog
572 # entry will have been relevant, so we need to skip some changelog
587 # entry will have been relevant, so we need to skip some changelog
573 # nodes even after ellipsis-izing.
588 # nodes even after ellipsis-izing.
574 walk = [clrev]
589 walk = [clrev]
575 while walk:
590 while walk:
576 p = walk[0]
591 p = walk[0]
577 walk = walk[1:]
592 walk = walk[1:]
578 if p in clrevtolocalrev:
593 if p in clrevtolocalrev:
579 return clrevtolocalrev[p]
594 return clrevtolocalrev[p]
580 elif p in fullclnodes:
595 elif p in fullclnodes:
581 walk.extend([pp for pp in cl.parentrevs(p)
596 walk.extend([pp for pp in cl.parentrevs(p)
582 if pp != nullrev])
597 if pp != nullrev])
583 elif p in precomputedellipsis:
598 elif p in precomputedellipsis:
584 walk.extend([pp for pp in precomputedellipsis[p]
599 walk.extend([pp for pp in precomputedellipsis[p]
585 if pp != nullrev])
600 if pp != nullrev])
586 else:
601 else:
587 # In this case, we've got an ellipsis with parents
602 # In this case, we've got an ellipsis with parents
588 # outside the current bundle (likely an
603 # outside the current bundle (likely an
589 # incremental pull). We "know" that we can use the
604 # incremental pull). We "know" that we can use the
590 # value of this same revlog at whatever revision
605 # value of this same revlog at whatever revision
591 # is pointed to by linknode. "Know" is in scare
606 # is pointed to by linknode. "Know" is in scare
592 # quotes because I haven't done enough examination
607 # quotes because I haven't done enough examination
593 # of edge cases to convince myself this is really
608 # of edge cases to convince myself this is really
594 # a fact - it works for all the (admittedly
609 # a fact - it works for all the (admittedly
595 # thorough) cases in our testsuite, but I would be
610 # thorough) cases in our testsuite, but I would be
596 # somewhat unsurprised to find a case in the wild
611 # somewhat unsurprised to find a case in the wild
597 # where this breaks down a bit. That said, I don't
612 # where this breaks down a bit. That said, I don't
598 # know if it would hurt anything.
613 # know if it would hurt anything.
599 for i in pycompat.xrange(rev, 0, -1):
614 for i in pycompat.xrange(rev, 0, -1):
600 if store.linkrev(i) == clrev:
615 if store.linkrev(i) == clrev:
601 return i
616 return i
602 # We failed to resolve a parent for this node, so
617 # We failed to resolve a parent for this node, so
603 # we crash the changegroup construction.
618 # we crash the changegroup construction.
604 raise error.Abort(
619 raise error.Abort(
605 'unable to resolve parent while packing %r %r'
620 'unable to resolve parent while packing %r %r'
606 ' for changeset %r' % (store.indexfile, rev, clrev))
621 ' for changeset %r' % (store.indexfile, rev, clrev))
607
622
608 return nullrev
623 return nullrev
609
624
610 if not linkparents or (
625 if not linkparents or (
611 store.parentrevs(rev) == (nullrev, nullrev)):
626 store.parentrevs(rev) == (nullrev, nullrev)):
612 p1, p2 = nullrev, nullrev
627 p1, p2 = nullrev, nullrev
613 elif len(linkparents) == 1:
628 elif len(linkparents) == 1:
614 p1, = sorted(local(p) for p in linkparents)
629 p1, = sorted(local(p) for p in linkparents)
615 p2 = nullrev
630 p2 = nullrev
616 else:
631 else:
617 p1, p2 = sorted(local(p) for p in linkparents)
632 p1, p2 = sorted(local(p) for p in linkparents)
618
633
619 p1node, p2node = store.node(p1), store.node(p2)
634 p1node, p2node = store.node(p1), store.node(p2)
620
635
621 return p1node, p2node, linknode
636 return p1node, p2node, linknode
622
637
623 def deltagroup(repo, store, nodes, ischangelog, lookup, forcedeltaparentprev,
638 def deltagroup(repo, store, nodes, ischangelog, lookup, forcedeltaparentprev,
624 topic=None,
639 topic=None,
625 ellipses=False, clrevtolocalrev=None, fullclnodes=None,
640 ellipses=False, clrevtolocalrev=None, fullclnodes=None,
626 precomputedellipsis=None):
641 precomputedellipsis=None):
627 """Calculate deltas for a set of revisions.
642 """Calculate deltas for a set of revisions.
628
643
629 Is a generator of ``revisiondelta`` instances.
644 Is a generator of ``revisiondelta`` instances.
630
645
631 If topic is not None, progress detail will be generated using this
646 If topic is not None, progress detail will be generated using this
632 topic name (e.g. changesets, manifests, etc).
647 topic name (e.g. changesets, manifests, etc).
633 """
648 """
634 if not nodes:
649 if not nodes:
635 return
650 return
636
651
637 cl = repo.changelog
652 cl = repo.changelog
638
653
639 if ischangelog:
654 if ischangelog:
640 # `hg log` shows changesets in storage order. To preserve order
655 # `hg log` shows changesets in storage order. To preserve order
641 # across clones, send out changesets in storage order.
656 # across clones, send out changesets in storage order.
642 nodesorder = 'storage'
657 nodesorder = 'storage'
643 elif ellipses:
658 elif ellipses:
644 nodes = _sortnodesellipsis(store, nodes, cl, lookup)
659 nodes = _sortnodesellipsis(store, nodes, cl, lookup)
645 nodesorder = 'nodes'
660 nodesorder = 'nodes'
646 else:
661 else:
647 nodesorder = None
662 nodesorder = None
648
663
649 # Perform ellipses filtering and revision massaging. We do this before
664 # Perform ellipses filtering and revision massaging. We do this before
650 # emitrevisions() because a) filtering out revisions creates less work
665 # emitrevisions() because a) filtering out revisions creates less work
651 # for emitrevisions() b) dropping revisions would break emitrevisions()'s
666 # for emitrevisions() b) dropping revisions would break emitrevisions()'s
652 # assumptions about delta choices and we would possibly send a delta
667 # assumptions about delta choices and we would possibly send a delta
653 # referencing a missing base revision.
668 # referencing a missing base revision.
654 #
669 #
655 # Also, calling lookup() has side-effects with regards to populating
670 # Also, calling lookup() has side-effects with regards to populating
656 # data structures. If we don't call lookup() for each node or if we call
671 # data structures. If we don't call lookup() for each node or if we call
657 # lookup() after the first pass through each node, things can break -
672 # lookup() after the first pass through each node, things can break -
658 # possibly intermittently depending on the python hash seed! For that
673 # possibly intermittently depending on the python hash seed! For that
659 # reason, we store a mapping of all linknodes during the initial node
674 # reason, we store a mapping of all linknodes during the initial node
660 # pass rather than use lookup() on the output side.
675 # pass rather than use lookup() on the output side.
661 if ellipses:
676 if ellipses:
662 filtered = []
677 filtered = []
663 adjustedparents = {}
678 adjustedparents = {}
664 linknodes = {}
679 linknodes = {}
665
680
666 for node in nodes:
681 for node in nodes:
667 rev = store.rev(node)
682 rev = store.rev(node)
668 linknode = lookup(node)
683 linknode = lookup(node)
669 linkrev = cl.rev(linknode)
684 linkrev = cl.rev(linknode)
670 clrevtolocalrev[linkrev] = rev
685 clrevtolocalrev[linkrev] = rev
671
686
672 # If linknode is in fullclnodes, it means the corresponding
687 # If linknode is in fullclnodes, it means the corresponding
673 # changeset was a full changeset and is being sent unaltered.
688 # changeset was a full changeset and is being sent unaltered.
674 if linknode in fullclnodes:
689 if linknode in fullclnodes:
675 linknodes[node] = linknode
690 linknodes[node] = linknode
676
691
677 # If the corresponding changeset wasn't in the set computed
692 # If the corresponding changeset wasn't in the set computed
678 # as relevant to us, it should be dropped outright.
693 # as relevant to us, it should be dropped outright.
679 elif linkrev not in precomputedellipsis:
694 elif linkrev not in precomputedellipsis:
680 continue
695 continue
681
696
682 else:
697 else:
683 # We could probably do this later and avoid the dict
698 # We could probably do this later and avoid the dict
684 # holding state. But it likely doesn't matter.
699 # holding state. But it likely doesn't matter.
685 p1node, p2node, linknode = _resolvenarrowrevisioninfo(
700 p1node, p2node, linknode = _resolvenarrowrevisioninfo(
686 cl, store, ischangelog, rev, linkrev, linknode,
701 cl, store, ischangelog, rev, linkrev, linknode,
687 clrevtolocalrev, fullclnodes, precomputedellipsis)
702 clrevtolocalrev, fullclnodes, precomputedellipsis)
688
703
689 adjustedparents[node] = (p1node, p2node)
704 adjustedparents[node] = (p1node, p2node)
690 linknodes[node] = linknode
705 linknodes[node] = linknode
691
706
692 filtered.append(node)
707 filtered.append(node)
693
708
694 nodes = filtered
709 nodes = filtered
695
710
696 # We expect the first pass to be fast, so we only engage the progress
711 # We expect the first pass to be fast, so we only engage the progress
697 # meter for constructing the revision deltas.
712 # meter for constructing the revision deltas.
698 progress = None
713 progress = None
699 if topic is not None:
714 if topic is not None:
700 progress = repo.ui.makeprogress(topic, unit=_('chunks'),
715 progress = repo.ui.makeprogress(topic, unit=_('chunks'),
701 total=len(nodes))
716 total=len(nodes))
702
717
703 configtarget = repo.ui.config('devel', 'bundle.delta')
718 configtarget = repo.ui.config('devel', 'bundle.delta')
704 if configtarget not in ('', 'p1', 'full'):
719 if configtarget not in ('', 'p1', 'full'):
705 msg = _("""config "devel.bundle.delta" as unknown value: %s""")
720 msg = _("""config "devel.bundle.delta" as unknown value: %s""")
706 repo.ui.warn(msg % configtarget)
721 repo.ui.warn(msg % configtarget)
707
722
708 deltamode = repository.CG_DELTAMODE_STD
723 deltamode = repository.CG_DELTAMODE_STD
709 if forcedeltaparentprev:
724 if forcedeltaparentprev:
710 deltamode = repository.CG_DELTAMODE_PREV
725 deltamode = repository.CG_DELTAMODE_PREV
711 elif configtarget == 'p1':
726 elif configtarget == 'p1':
712 deltamode = repository.CG_DELTAMODE_P1
727 deltamode = repository.CG_DELTAMODE_P1
713 elif configtarget == 'full':
728 elif configtarget == 'full':
714 deltamode = repository.CG_DELTAMODE_FULL
729 deltamode = repository.CG_DELTAMODE_FULL
715
730
716 revisions = store.emitrevisions(
731 revisions = store.emitrevisions(
717 nodes,
732 nodes,
718 nodesorder=nodesorder,
733 nodesorder=nodesorder,
719 revisiondata=True,
734 revisiondata=True,
720 assumehaveparentrevisions=not ellipses,
735 assumehaveparentrevisions=not ellipses,
721 deltamode=deltamode)
736 deltamode=deltamode)
722
737
723 for i, revision in enumerate(revisions):
738 for i, revision in enumerate(revisions):
724 if progress:
739 if progress:
725 progress.update(i + 1)
740 progress.update(i + 1)
726
741
727 if ellipses:
742 if ellipses:
728 linknode = linknodes[revision.node]
743 linknode = linknodes[revision.node]
729
744
730 if revision.node in adjustedparents:
745 if revision.node in adjustedparents:
731 p1node, p2node = adjustedparents[revision.node]
746 p1node, p2node = adjustedparents[revision.node]
732 revision.p1node = p1node
747 revision.p1node = p1node
733 revision.p2node = p2node
748 revision.p2node = p2node
734 revision.flags |= repository.REVISION_FLAG_ELLIPSIS
749 revision.flags |= repository.REVISION_FLAG_ELLIPSIS
735
750
736 else:
751 else:
737 linknode = lookup(revision.node)
752 linknode = lookup(revision.node)
738
753
739 revision.linknode = linknode
754 revision.linknode = linknode
740 yield revision
755 yield revision
741
756
742 if progress:
757 if progress:
743 progress.complete()
758 progress.complete()
744
759
745 class cgpacker(object):
760 class cgpacker(object):
746 def __init__(self, repo, oldmatcher, matcher, version,
761 def __init__(self, repo, oldmatcher, matcher, version,
747 builddeltaheader, manifestsend,
762 builddeltaheader, manifestsend,
748 forcedeltaparentprev=False,
763 forcedeltaparentprev=False,
749 bundlecaps=None, ellipses=False,
764 bundlecaps=None, ellipses=False,
750 shallow=False, ellipsisroots=None, fullnodes=None):
765 shallow=False, ellipsisroots=None, fullnodes=None):
751 """Given a source repo, construct a bundler.
766 """Given a source repo, construct a bundler.
752
767
753 oldmatcher is a matcher that matches on files the client already has.
768 oldmatcher is a matcher that matches on files the client already has.
754 These will not be included in the changegroup.
769 These will not be included in the changegroup.
755
770
756 matcher is a matcher that matches on files to include in the
771 matcher is a matcher that matches on files to include in the
757 changegroup. Used to facilitate sparse changegroups.
772 changegroup. Used to facilitate sparse changegroups.
758
773
759 forcedeltaparentprev indicates whether delta parents must be against
774 forcedeltaparentprev indicates whether delta parents must be against
760 the previous revision in a delta group. This should only be used for
775 the previous revision in a delta group. This should only be used for
761 compatibility with changegroup version 1.
776 compatibility with changegroup version 1.
762
777
763 builddeltaheader is a callable that constructs the header for a group
778 builddeltaheader is a callable that constructs the header for a group
764 delta.
779 delta.
765
780
766 manifestsend is a chunk to send after manifests have been fully emitted.
781 manifestsend is a chunk to send after manifests have been fully emitted.
767
782
768 ellipses indicates whether ellipsis serving mode is enabled.
783 ellipses indicates whether ellipsis serving mode is enabled.
769
784
770 bundlecaps is optional and can be used to specify the set of
785 bundlecaps is optional and can be used to specify the set of
771 capabilities which can be used to build the bundle. While bundlecaps is
786 capabilities which can be used to build the bundle. While bundlecaps is
772 unused in core Mercurial, extensions rely on this feature to communicate
787 unused in core Mercurial, extensions rely on this feature to communicate
773 capabilities to customize the changegroup packer.
788 capabilities to customize the changegroup packer.
774
789
775 shallow indicates whether shallow data might be sent. The packer may
790 shallow indicates whether shallow data might be sent. The packer may
776 need to pack file contents not introduced by the changes being packed.
791 need to pack file contents not introduced by the changes being packed.
777
792
778 fullnodes is the set of changelog nodes which should not be ellipsis
793 fullnodes is the set of changelog nodes which should not be ellipsis
779 nodes. We store this rather than the set of nodes that should be
794 nodes. We store this rather than the set of nodes that should be
780 ellipsis because for very large histories we expect this to be
795 ellipsis because for very large histories we expect this to be
781 significantly smaller.
796 significantly smaller.
782 """
797 """
783 assert oldmatcher
798 assert oldmatcher
784 assert matcher
799 assert matcher
785 self._oldmatcher = oldmatcher
800 self._oldmatcher = oldmatcher
786 self._matcher = matcher
801 self._matcher = matcher
787
802
788 self.version = version
803 self.version = version
789 self._forcedeltaparentprev = forcedeltaparentprev
804 self._forcedeltaparentprev = forcedeltaparentprev
790 self._builddeltaheader = builddeltaheader
805 self._builddeltaheader = builddeltaheader
791 self._manifestsend = manifestsend
806 self._manifestsend = manifestsend
792 self._ellipses = ellipses
807 self._ellipses = ellipses
793
808
794 # Set of capabilities we can use to build the bundle.
809 # Set of capabilities we can use to build the bundle.
795 if bundlecaps is None:
810 if bundlecaps is None:
796 bundlecaps = set()
811 bundlecaps = set()
797 self._bundlecaps = bundlecaps
812 self._bundlecaps = bundlecaps
798 self._isshallow = shallow
813 self._isshallow = shallow
799 self._fullclnodes = fullnodes
814 self._fullclnodes = fullnodes
800
815
801 # Maps ellipsis revs to their roots at the changelog level.
816 # Maps ellipsis revs to their roots at the changelog level.
802 self._precomputedellipsis = ellipsisroots
817 self._precomputedellipsis = ellipsisroots
803
818
804 self._repo = repo
819 self._repo = repo
805
820
806 if self._repo.ui.verbose and not self._repo.ui.debugflag:
821 if self._repo.ui.verbose and not self._repo.ui.debugflag:
807 self._verbosenote = self._repo.ui.note
822 self._verbosenote = self._repo.ui.note
808 else:
823 else:
809 self._verbosenote = lambda s: None
824 self._verbosenote = lambda s: None
810
825
811 def generate(self, commonrevs, clnodes, fastpathlinkrev, source,
826 def generate(self, commonrevs, clnodes, fastpathlinkrev, source,
812 changelog=True):
827 changelog=True):
813 """Yield a sequence of changegroup byte chunks.
828 """Yield a sequence of changegroup byte chunks.
814 If changelog is False, changelog data won't be added to changegroup
829 If changelog is False, changelog data won't be added to changegroup
815 """
830 """
816
831
817 repo = self._repo
832 repo = self._repo
818 cl = repo.changelog
833 cl = repo.changelog
819
834
820 self._verbosenote(_('uncompressed size of bundle content:\n'))
835 self._verbosenote(_('uncompressed size of bundle content:\n'))
821 size = 0
836 size = 0
822
837
823 clstate, deltas = self._generatechangelog(cl, clnodes,
838 clstate, deltas = self._generatechangelog(cl, clnodes,
824 generate=changelog)
839 generate=changelog)
825 for delta in deltas:
840 for delta in deltas:
826 for chunk in _revisiondeltatochunks(delta,
841 for chunk in _revisiondeltatochunks(delta,
827 self._builddeltaheader):
842 self._builddeltaheader):
828 size += len(chunk)
843 size += len(chunk)
829 yield chunk
844 yield chunk
830
845
831 close = closechunk()
846 close = closechunk()
832 size += len(close)
847 size += len(close)
833 yield closechunk()
848 yield closechunk()
834
849
835 self._verbosenote(_('%8.i (changelog)\n') % size)
850 self._verbosenote(_('%8.i (changelog)\n') % size)
836
851
837 clrevorder = clstate['clrevorder']
852 clrevorder = clstate['clrevorder']
838 manifests = clstate['manifests']
853 manifests = clstate['manifests']
839 changedfiles = clstate['changedfiles']
854 changedfiles = clstate['changedfiles']
840
855
841 # We need to make sure that the linkrev in the changegroup refers to
856 # We need to make sure that the linkrev in the changegroup refers to
842 # the first changeset that introduced the manifest or file revision.
857 # the first changeset that introduced the manifest or file revision.
843 # The fastpath is usually safer than the slowpath, because the filelogs
858 # The fastpath is usually safer than the slowpath, because the filelogs
844 # are walked in revlog order.
859 # are walked in revlog order.
845 #
860 #
846 # When taking the slowpath when the manifest revlog uses generaldelta,
861 # When taking the slowpath when the manifest revlog uses generaldelta,
847 # the manifest may be walked in the "wrong" order. Without 'clrevorder',
862 # the manifest may be walked in the "wrong" order. Without 'clrevorder',
848 # we would get an incorrect linkrev (see fix in cc0ff93d0c0c).
863 # we would get an incorrect linkrev (see fix in cc0ff93d0c0c).
849 #
864 #
850 # When taking the fastpath, we are only vulnerable to reordering
865 # When taking the fastpath, we are only vulnerable to reordering
851 # of the changelog itself. The changelog never uses generaldelta and is
866 # of the changelog itself. The changelog never uses generaldelta and is
852 # never reordered. To handle this case, we simply take the slowpath,
867 # never reordered. To handle this case, we simply take the slowpath,
853 # which already has the 'clrevorder' logic. This was also fixed in
868 # which already has the 'clrevorder' logic. This was also fixed in
854 # cc0ff93d0c0c.
869 # cc0ff93d0c0c.
855
870
856 # Treemanifests don't work correctly with fastpathlinkrev
871 # Treemanifests don't work correctly with fastpathlinkrev
857 # either, because we don't discover which directory nodes to
872 # either, because we don't discover which directory nodes to
858 # send along with files. This could probably be fixed.
873 # send along with files. This could probably be fixed.
859 fastpathlinkrev = fastpathlinkrev and (
874 fastpathlinkrev = fastpathlinkrev and (
860 'treemanifest' not in repo.requirements)
875 'treemanifest' not in repo.requirements)
861
876
862 fnodes = {} # needed file nodes
877 fnodes = {} # needed file nodes
863
878
864 size = 0
879 size = 0
865 it = self.generatemanifests(
880 it = self.generatemanifests(
866 commonrevs, clrevorder, fastpathlinkrev, manifests, fnodes, source,
881 commonrevs, clrevorder, fastpathlinkrev, manifests, fnodes, source,
867 clstate['clrevtomanifestrev'])
882 clstate['clrevtomanifestrev'])
868
883
869 for tree, deltas in it:
884 for tree, deltas in it:
870 if tree:
885 if tree:
871 assert self.version == b'03'
886 assert self.version == b'03'
872 chunk = _fileheader(tree)
887 chunk = _fileheader(tree)
873 size += len(chunk)
888 size += len(chunk)
874 yield chunk
889 yield chunk
875
890
876 for delta in deltas:
891 for delta in deltas:
877 chunks = _revisiondeltatochunks(delta, self._builddeltaheader)
892 chunks = _revisiondeltatochunks(delta, self._builddeltaheader)
878 for chunk in chunks:
893 for chunk in chunks:
879 size += len(chunk)
894 size += len(chunk)
880 yield chunk
895 yield chunk
881
896
882 close = closechunk()
897 close = closechunk()
883 size += len(close)
898 size += len(close)
884 yield close
899 yield close
885
900
886 self._verbosenote(_('%8.i (manifests)\n') % size)
901 self._verbosenote(_('%8.i (manifests)\n') % size)
887 yield self._manifestsend
902 yield self._manifestsend
888
903
889 mfdicts = None
904 mfdicts = None
890 if self._ellipses and self._isshallow:
905 if self._ellipses and self._isshallow:
891 mfdicts = [(self._repo.manifestlog[n].read(), lr)
906 mfdicts = [(self._repo.manifestlog[n].read(), lr)
892 for (n, lr) in manifests.iteritems()]
907 for (n, lr) in manifests.iteritems()]
893
908
894 manifests.clear()
909 manifests.clear()
895 clrevs = set(cl.rev(x) for x in clnodes)
910 clrevs = set(cl.rev(x) for x in clnodes)
896
911
897 it = self.generatefiles(changedfiles, commonrevs,
912 it = self.generatefiles(changedfiles, commonrevs,
898 source, mfdicts, fastpathlinkrev,
913 source, mfdicts, fastpathlinkrev,
899 fnodes, clrevs)
914 fnodes, clrevs)
900
915
901 for path, deltas in it:
916 for path, deltas in it:
902 h = _fileheader(path)
917 h = _fileheader(path)
903 size = len(h)
918 size = len(h)
904 yield h
919 yield h
905
920
906 for delta in deltas:
921 for delta in deltas:
907 chunks = _revisiondeltatochunks(delta, self._builddeltaheader)
922 chunks = _revisiondeltatochunks(delta, self._builddeltaheader)
908 for chunk in chunks:
923 for chunk in chunks:
909 size += len(chunk)
924 size += len(chunk)
910 yield chunk
925 yield chunk
911
926
912 close = closechunk()
927 close = closechunk()
913 size += len(close)
928 size += len(close)
914 yield close
929 yield close
915
930
916 self._verbosenote(_('%8.i %s\n') % (size, path))
931 self._verbosenote(_('%8.i %s\n') % (size, path))
917
932
918 yield closechunk()
933 yield closechunk()
919
934
920 if clnodes:
935 if clnodes:
921 repo.hook('outgoing', node=hex(clnodes[0]), source=source)
936 repo.hook('outgoing', node=hex(clnodes[0]), source=source)
922
937
923 def _generatechangelog(self, cl, nodes, generate=True):
938 def _generatechangelog(self, cl, nodes, generate=True):
924 """Generate data for changelog chunks.
939 """Generate data for changelog chunks.
925
940
926 Returns a 2-tuple of a dict containing state and an iterable of
941 Returns a 2-tuple of a dict containing state and an iterable of
927 byte chunks. The state will not be fully populated until the
942 byte chunks. The state will not be fully populated until the
928 chunk stream has been fully consumed.
943 chunk stream has been fully consumed.
929
944
930 if generate is False, the state will be fully populated and no chunk
945 if generate is False, the state will be fully populated and no chunk
931 stream will be yielded
946 stream will be yielded
932 """
947 """
933 clrevorder = {}
948 clrevorder = {}
934 manifests = {}
949 manifests = {}
935 mfl = self._repo.manifestlog
950 mfl = self._repo.manifestlog
936 changedfiles = set()
951 changedfiles = set()
937 clrevtomanifestrev = {}
952 clrevtomanifestrev = {}
938
953
939 state = {
954 state = {
940 'clrevorder': clrevorder,
955 'clrevorder': clrevorder,
941 'manifests': manifests,
956 'manifests': manifests,
942 'changedfiles': changedfiles,
957 'changedfiles': changedfiles,
943 'clrevtomanifestrev': clrevtomanifestrev,
958 'clrevtomanifestrev': clrevtomanifestrev,
944 }
959 }
945
960
946 if not (generate or self._ellipses):
961 if not (generate or self._ellipses):
947 # sort the nodes in storage order
962 # sort the nodes in storage order
948 nodes = sorted(nodes, key=cl.rev)
963 nodes = sorted(nodes, key=cl.rev)
949 for node in nodes:
964 for node in nodes:
950 c = cl.changelogrevision(node)
965 c = cl.changelogrevision(node)
951 clrevorder[node] = len(clrevorder)
966 clrevorder[node] = len(clrevorder)
952 # record the first changeset introducing this manifest version
967 # record the first changeset introducing this manifest version
953 manifests.setdefault(c.manifest, node)
968 manifests.setdefault(c.manifest, node)
954 # Record a complete list of potentially-changed files in
969 # Record a complete list of potentially-changed files in
955 # this manifest.
970 # this manifest.
956 changedfiles.update(c.files)
971 changedfiles.update(c.files)
957
972
958 return state, ()
973 return state, ()
959
974
960 # Callback for the changelog, used to collect changed files and
975 # Callback for the changelog, used to collect changed files and
961 # manifest nodes.
976 # manifest nodes.
962 # Returns the linkrev node (identity in the changelog case).
977 # Returns the linkrev node (identity in the changelog case).
963 def lookupcl(x):
978 def lookupcl(x):
964 c = cl.changelogrevision(x)
979 c = cl.changelogrevision(x)
965 clrevorder[x] = len(clrevorder)
980 clrevorder[x] = len(clrevorder)
966
981
967 if self._ellipses:
982 if self._ellipses:
968 # Only update manifests if x is going to be sent. Otherwise we
983 # Only update manifests if x is going to be sent. Otherwise we
969 # end up with bogus linkrevs specified for manifests and
984 # end up with bogus linkrevs specified for manifests and
970 # we skip some manifest nodes that we should otherwise
985 # we skip some manifest nodes that we should otherwise
971 # have sent.
986 # have sent.
972 if (x in self._fullclnodes
987 if (x in self._fullclnodes
973 or cl.rev(x) in self._precomputedellipsis):
988 or cl.rev(x) in self._precomputedellipsis):
974
989
975 manifestnode = c.manifest
990 manifestnode = c.manifest
976 # Record the first changeset introducing this manifest
991 # Record the first changeset introducing this manifest
977 # version.
992 # version.
978 manifests.setdefault(manifestnode, x)
993 manifests.setdefault(manifestnode, x)
979 # Set this narrow-specific dict so we have the lowest
994 # Set this narrow-specific dict so we have the lowest
980 # manifest revnum to look up for this cl revnum. (Part of
995 # manifest revnum to look up for this cl revnum. (Part of
981 # mapping changelog ellipsis parents to manifest ellipsis
996 # mapping changelog ellipsis parents to manifest ellipsis
982 # parents)
997 # parents)
983 clrevtomanifestrev.setdefault(
998 clrevtomanifestrev.setdefault(
984 cl.rev(x), mfl.rev(manifestnode))
999 cl.rev(x), mfl.rev(manifestnode))
985 # We can't trust the changed files list in the changeset if the
1000 # We can't trust the changed files list in the changeset if the
986 # client requested a shallow clone.
1001 # client requested a shallow clone.
987 if self._isshallow:
1002 if self._isshallow:
988 changedfiles.update(mfl[c.manifest].read().keys())
1003 changedfiles.update(mfl[c.manifest].read().keys())
989 else:
1004 else:
990 changedfiles.update(c.files)
1005 changedfiles.update(c.files)
991 else:
1006 else:
992 # record the first changeset introducing this manifest version
1007 # record the first changeset introducing this manifest version
993 manifests.setdefault(c.manifest, x)
1008 manifests.setdefault(c.manifest, x)
994 # Record a complete list of potentially-changed files in
1009 # Record a complete list of potentially-changed files in
995 # this manifest.
1010 # this manifest.
996 changedfiles.update(c.files)
1011 changedfiles.update(c.files)
997
1012
998 return x
1013 return x
999
1014
1000 gen = deltagroup(
1015 gen = deltagroup(
1001 self._repo, cl, nodes, True, lookupcl,
1016 self._repo, cl, nodes, True, lookupcl,
1002 self._forcedeltaparentprev,
1017 self._forcedeltaparentprev,
1003 ellipses=self._ellipses,
1018 ellipses=self._ellipses,
1004 topic=_('changesets'),
1019 topic=_('changesets'),
1005 clrevtolocalrev={},
1020 clrevtolocalrev={},
1006 fullclnodes=self._fullclnodes,
1021 fullclnodes=self._fullclnodes,
1007 precomputedellipsis=self._precomputedellipsis)
1022 precomputedellipsis=self._precomputedellipsis)
1008
1023
1009 return state, gen
1024 return state, gen
1010
1025
1011 def generatemanifests(self, commonrevs, clrevorder, fastpathlinkrev,
1026 def generatemanifests(self, commonrevs, clrevorder, fastpathlinkrev,
1012 manifests, fnodes, source, clrevtolocalrev):
1027 manifests, fnodes, source, clrevtolocalrev):
1013 """Returns an iterator of changegroup chunks containing manifests.
1028 """Returns an iterator of changegroup chunks containing manifests.
1014
1029
1015 `source` is unused here, but is used by extensions like remotefilelog to
1030 `source` is unused here, but is used by extensions like remotefilelog to
1016 change what is sent based in pulls vs pushes, etc.
1031 change what is sent based in pulls vs pushes, etc.
1017 """
1032 """
1018 repo = self._repo
1033 repo = self._repo
1019 mfl = repo.manifestlog
1034 mfl = repo.manifestlog
1020 tmfnodes = {'': manifests}
1035 tmfnodes = {'': manifests}
1021
1036
1022 # Callback for the manifest, used to collect linkrevs for filelog
1037 # Callback for the manifest, used to collect linkrevs for filelog
1023 # revisions.
1038 # revisions.
1024 # Returns the linkrev node (collected in lookupcl).
1039 # Returns the linkrev node (collected in lookupcl).
1025 def makelookupmflinknode(tree, nodes):
1040 def makelookupmflinknode(tree, nodes):
1026 if fastpathlinkrev:
1041 if fastpathlinkrev:
1027 assert not tree
1042 assert not tree
1028 return manifests.__getitem__
1043 return manifests.__getitem__
1029
1044
1030 def lookupmflinknode(x):
1045 def lookupmflinknode(x):
1031 """Callback for looking up the linknode for manifests.
1046 """Callback for looking up the linknode for manifests.
1032
1047
1033 Returns the linkrev node for the specified manifest.
1048 Returns the linkrev node for the specified manifest.
1034
1049
1035 SIDE EFFECT:
1050 SIDE EFFECT:
1036
1051
1037 1) fclnodes gets populated with the list of relevant
1052 1) fclnodes gets populated with the list of relevant
1038 file nodes if we're not using fastpathlinkrev
1053 file nodes if we're not using fastpathlinkrev
1039 2) When treemanifests are in use, collects treemanifest nodes
1054 2) When treemanifests are in use, collects treemanifest nodes
1040 to send
1055 to send
1041
1056
1042 Note that this means manifests must be completely sent to
1057 Note that this means manifests must be completely sent to
1043 the client before you can trust the list of files and
1058 the client before you can trust the list of files and
1044 treemanifests to send.
1059 treemanifests to send.
1045 """
1060 """
1046 clnode = nodes[x]
1061 clnode = nodes[x]
1047 mdata = mfl.get(tree, x).readfast(shallow=True)
1062 mdata = mfl.get(tree, x).readfast(shallow=True)
1048 for p, n, fl in mdata.iterentries():
1063 for p, n, fl in mdata.iterentries():
1049 if fl == 't': # subdirectory manifest
1064 if fl == 't': # subdirectory manifest
1050 subtree = tree + p + '/'
1065 subtree = tree + p + '/'
1051 tmfclnodes = tmfnodes.setdefault(subtree, {})
1066 tmfclnodes = tmfnodes.setdefault(subtree, {})
1052 tmfclnode = tmfclnodes.setdefault(n, clnode)
1067 tmfclnode = tmfclnodes.setdefault(n, clnode)
1053 if clrevorder[clnode] < clrevorder[tmfclnode]:
1068 if clrevorder[clnode] < clrevorder[tmfclnode]:
1054 tmfclnodes[n] = clnode
1069 tmfclnodes[n] = clnode
1055 else:
1070 else:
1056 f = tree + p
1071 f = tree + p
1057 fclnodes = fnodes.setdefault(f, {})
1072 fclnodes = fnodes.setdefault(f, {})
1058 fclnode = fclnodes.setdefault(n, clnode)
1073 fclnode = fclnodes.setdefault(n, clnode)
1059 if clrevorder[clnode] < clrevorder[fclnode]:
1074 if clrevorder[clnode] < clrevorder[fclnode]:
1060 fclnodes[n] = clnode
1075 fclnodes[n] = clnode
1061 return clnode
1076 return clnode
1062 return lookupmflinknode
1077 return lookupmflinknode
1063
1078
1064 while tmfnodes:
1079 while tmfnodes:
1065 tree, nodes = tmfnodes.popitem()
1080 tree, nodes = tmfnodes.popitem()
1066
1081
1067 should_visit = self._matcher.visitdir(tree[:-1])
1082 should_visit = self._matcher.visitdir(tree[:-1])
1068 if tree and not should_visit:
1083 if tree and not should_visit:
1069 continue
1084 continue
1070
1085
1071 store = mfl.getstorage(tree)
1086 store = mfl.getstorage(tree)
1072
1087
1073 if not should_visit:
1088 if not should_visit:
1074 # No nodes to send because this directory is out of
1089 # No nodes to send because this directory is out of
1075 # the client's view of the repository (probably
1090 # the client's view of the repository (probably
1076 # because of narrow clones). Do this even for the root
1091 # because of narrow clones). Do this even for the root
1077 # directory (tree=='')
1092 # directory (tree=='')
1078 prunednodes = []
1093 prunednodes = []
1079 else:
1094 else:
1080 # Avoid sending any manifest nodes we can prove the
1095 # Avoid sending any manifest nodes we can prove the
1081 # client already has by checking linkrevs. See the
1096 # client already has by checking linkrevs. See the
1082 # related comment in generatefiles().
1097 # related comment in generatefiles().
1083 prunednodes = self._prunemanifests(store, nodes, commonrevs)
1098 prunednodes = self._prunemanifests(store, nodes, commonrevs)
1084
1099
1085 if tree and not prunednodes:
1100 if tree and not prunednodes:
1086 continue
1101 continue
1087
1102
1088 lookupfn = makelookupmflinknode(tree, nodes)
1103 lookupfn = makelookupmflinknode(tree, nodes)
1089
1104
1090 deltas = deltagroup(
1105 deltas = deltagroup(
1091 self._repo, store, prunednodes, False, lookupfn,
1106 self._repo, store, prunednodes, False, lookupfn,
1092 self._forcedeltaparentprev,
1107 self._forcedeltaparentprev,
1093 ellipses=self._ellipses,
1108 ellipses=self._ellipses,
1094 topic=_('manifests'),
1109 topic=_('manifests'),
1095 clrevtolocalrev=clrevtolocalrev,
1110 clrevtolocalrev=clrevtolocalrev,
1096 fullclnodes=self._fullclnodes,
1111 fullclnodes=self._fullclnodes,
1097 precomputedellipsis=self._precomputedellipsis)
1112 precomputedellipsis=self._precomputedellipsis)
1098
1113
1099 if not self._oldmatcher.visitdir(store.tree[:-1]):
1114 if not self._oldmatcher.visitdir(store.tree[:-1]):
1100 yield tree, deltas
1115 yield tree, deltas
1101 else:
1116 else:
1102 # 'deltas' is a generator and we need to consume it even if
1117 # 'deltas' is a generator and we need to consume it even if
1103 # we are not going to send it because a side-effect is that
1118 # we are not going to send it because a side-effect is that
1104 # it updates tmdnodes (via lookupfn)
1119 # it updates tmdnodes (via lookupfn)
1105 for d in deltas:
1120 for d in deltas:
1106 pass
1121 pass
1107 if not tree:
1122 if not tree:
1108 yield tree, []
1123 yield tree, []
1109
1124
1110 def _prunemanifests(self, store, nodes, commonrevs):
1125 def _prunemanifests(self, store, nodes, commonrevs):
1111 if not self._ellipses:
1126 if not self._ellipses:
1112 # In non-ellipses case and large repositories, it is better to
1127 # In non-ellipses case and large repositories, it is better to
1113 # prevent calling of store.rev and store.linkrev on a lot of
1128 # prevent calling of store.rev and store.linkrev on a lot of
1114 # nodes as compared to sending some extra data
1129 # nodes as compared to sending some extra data
1115 return nodes.copy()
1130 return nodes.copy()
1116 # This is split out as a separate method to allow filtering
1131 # This is split out as a separate method to allow filtering
1117 # commonrevs in extension code.
1132 # commonrevs in extension code.
1118 #
1133 #
1119 # TODO(augie): this shouldn't be required, instead we should
1134 # TODO(augie): this shouldn't be required, instead we should
1120 # make filtering of revisions to send delegated to the store
1135 # make filtering of revisions to send delegated to the store
1121 # layer.
1136 # layer.
1122 frev, flr = store.rev, store.linkrev
1137 frev, flr = store.rev, store.linkrev
1123 return [n for n in nodes if flr(frev(n)) not in commonrevs]
1138 return [n for n in nodes if flr(frev(n)) not in commonrevs]
1124
1139
1125 # The 'source' parameter is useful for extensions
1140 # The 'source' parameter is useful for extensions
1126 def generatefiles(self, changedfiles, commonrevs, source,
1141 def generatefiles(self, changedfiles, commonrevs, source,
1127 mfdicts, fastpathlinkrev, fnodes, clrevs):
1142 mfdicts, fastpathlinkrev, fnodes, clrevs):
1128 changedfiles = [f for f in changedfiles
1143 changedfiles = [f for f in changedfiles
1129 if self._matcher(f) and not self._oldmatcher(f)]
1144 if self._matcher(f) and not self._oldmatcher(f)]
1130
1145
1131 if not fastpathlinkrev:
1146 if not fastpathlinkrev:
1132 def normallinknodes(unused, fname):
1147 def normallinknodes(unused, fname):
1133 return fnodes.get(fname, {})
1148 return fnodes.get(fname, {})
1134 else:
1149 else:
1135 cln = self._repo.changelog.node
1150 cln = self._repo.changelog.node
1136
1151
1137 def normallinknodes(store, fname):
1152 def normallinknodes(store, fname):
1138 flinkrev = store.linkrev
1153 flinkrev = store.linkrev
1139 fnode = store.node
1154 fnode = store.node
1140 revs = ((r, flinkrev(r)) for r in store)
1155 revs = ((r, flinkrev(r)) for r in store)
1141 return dict((fnode(r), cln(lr))
1156 return dict((fnode(r), cln(lr))
1142 for r, lr in revs if lr in clrevs)
1157 for r, lr in revs if lr in clrevs)
1143
1158
1144 clrevtolocalrev = {}
1159 clrevtolocalrev = {}
1145
1160
1146 if self._isshallow:
1161 if self._isshallow:
1147 # In a shallow clone, the linknodes callback needs to also include
1162 # In a shallow clone, the linknodes callback needs to also include
1148 # those file nodes that are in the manifests we sent but weren't
1163 # those file nodes that are in the manifests we sent but weren't
1149 # introduced by those manifests.
1164 # introduced by those manifests.
1150 commonctxs = [self._repo[c] for c in commonrevs]
1165 commonctxs = [self._repo[c] for c in commonrevs]
1151 clrev = self._repo.changelog.rev
1166 clrev = self._repo.changelog.rev
1152
1167
1153 def linknodes(flog, fname):
1168 def linknodes(flog, fname):
1154 for c in commonctxs:
1169 for c in commonctxs:
1155 try:
1170 try:
1156 fnode = c.filenode(fname)
1171 fnode = c.filenode(fname)
1157 clrevtolocalrev[c.rev()] = flog.rev(fnode)
1172 clrevtolocalrev[c.rev()] = flog.rev(fnode)
1158 except error.ManifestLookupError:
1173 except error.ManifestLookupError:
1159 pass
1174 pass
1160 links = normallinknodes(flog, fname)
1175 links = normallinknodes(flog, fname)
1161 if len(links) != len(mfdicts):
1176 if len(links) != len(mfdicts):
1162 for mf, lr in mfdicts:
1177 for mf, lr in mfdicts:
1163 fnode = mf.get(fname, None)
1178 fnode = mf.get(fname, None)
1164 if fnode in links:
1179 if fnode in links:
1165 links[fnode] = min(links[fnode], lr, key=clrev)
1180 links[fnode] = min(links[fnode], lr, key=clrev)
1166 elif fnode:
1181 elif fnode:
1167 links[fnode] = lr
1182 links[fnode] = lr
1168 return links
1183 return links
1169 else:
1184 else:
1170 linknodes = normallinknodes
1185 linknodes = normallinknodes
1171
1186
1172 repo = self._repo
1187 repo = self._repo
1173 progress = repo.ui.makeprogress(_('files'), unit=_('files'),
1188 progress = repo.ui.makeprogress(_('files'), unit=_('files'),
1174 total=len(changedfiles))
1189 total=len(changedfiles))
1175 for i, fname in enumerate(sorted(changedfiles)):
1190 for i, fname in enumerate(sorted(changedfiles)):
1176 filerevlog = repo.file(fname)
1191 filerevlog = repo.file(fname)
1177 if not filerevlog:
1192 if not filerevlog:
1178 raise error.Abort(_("empty or missing file data for %s") %
1193 raise error.Abort(_("empty or missing file data for %s") %
1179 fname)
1194 fname)
1180
1195
1181 clrevtolocalrev.clear()
1196 clrevtolocalrev.clear()
1182
1197
1183 linkrevnodes = linknodes(filerevlog, fname)
1198 linkrevnodes = linknodes(filerevlog, fname)
1184 # Lookup for filenodes, we collected the linkrev nodes above in the
1199 # Lookup for filenodes, we collected the linkrev nodes above in the
1185 # fastpath case and with lookupmf in the slowpath case.
1200 # fastpath case and with lookupmf in the slowpath case.
1186 def lookupfilelog(x):
1201 def lookupfilelog(x):
1187 return linkrevnodes[x]
1202 return linkrevnodes[x]
1188
1203
1189 frev, flr = filerevlog.rev, filerevlog.linkrev
1204 frev, flr = filerevlog.rev, filerevlog.linkrev
1190 # Skip sending any filenode we know the client already
1205 # Skip sending any filenode we know the client already
1191 # has. This avoids over-sending files relatively
1206 # has. This avoids over-sending files relatively
1192 # inexpensively, so it's not a problem if we under-filter
1207 # inexpensively, so it's not a problem if we under-filter
1193 # here.
1208 # here.
1194 filenodes = [n for n in linkrevnodes
1209 filenodes = [n for n in linkrevnodes
1195 if flr(frev(n)) not in commonrevs]
1210 if flr(frev(n)) not in commonrevs]
1196
1211
1197 if not filenodes:
1212 if not filenodes:
1198 continue
1213 continue
1199
1214
1200 progress.update(i + 1, item=fname)
1215 progress.update(i + 1, item=fname)
1201
1216
1202 deltas = deltagroup(
1217 deltas = deltagroup(
1203 self._repo, filerevlog, filenodes, False, lookupfilelog,
1218 self._repo, filerevlog, filenodes, False, lookupfilelog,
1204 self._forcedeltaparentprev,
1219 self._forcedeltaparentprev,
1205 ellipses=self._ellipses,
1220 ellipses=self._ellipses,
1206 clrevtolocalrev=clrevtolocalrev,
1221 clrevtolocalrev=clrevtolocalrev,
1207 fullclnodes=self._fullclnodes,
1222 fullclnodes=self._fullclnodes,
1208 precomputedellipsis=self._precomputedellipsis)
1223 precomputedellipsis=self._precomputedellipsis)
1209
1224
1210 yield fname, deltas
1225 yield fname, deltas
1211
1226
1212 progress.complete()
1227 progress.complete()
1213
1228
1214 def _makecg1packer(repo, oldmatcher, matcher, bundlecaps,
1229 def _makecg1packer(repo, oldmatcher, matcher, bundlecaps,
1215 ellipses=False, shallow=False, ellipsisroots=None,
1230 ellipses=False, shallow=False, ellipsisroots=None,
1216 fullnodes=None):
1231 fullnodes=None):
1217 builddeltaheader = lambda d: _CHANGEGROUPV1_DELTA_HEADER.pack(
1232 builddeltaheader = lambda d: _CHANGEGROUPV1_DELTA_HEADER.pack(
1218 d.node, d.p1node, d.p2node, d.linknode)
1233 d.node, d.p1node, d.p2node, d.linknode)
1219
1234
1220 return cgpacker(repo, oldmatcher, matcher, b'01',
1235 return cgpacker(repo, oldmatcher, matcher, b'01',
1221 builddeltaheader=builddeltaheader,
1236 builddeltaheader=builddeltaheader,
1222 manifestsend=b'',
1237 manifestsend=b'',
1223 forcedeltaparentprev=True,
1238 forcedeltaparentprev=True,
1224 bundlecaps=bundlecaps,
1239 bundlecaps=bundlecaps,
1225 ellipses=ellipses,
1240 ellipses=ellipses,
1226 shallow=shallow,
1241 shallow=shallow,
1227 ellipsisroots=ellipsisroots,
1242 ellipsisroots=ellipsisroots,
1228 fullnodes=fullnodes)
1243 fullnodes=fullnodes)
1229
1244
1230 def _makecg2packer(repo, oldmatcher, matcher, bundlecaps,
1245 def _makecg2packer(repo, oldmatcher, matcher, bundlecaps,
1231 ellipses=False, shallow=False, ellipsisroots=None,
1246 ellipses=False, shallow=False, ellipsisroots=None,
1232 fullnodes=None):
1247 fullnodes=None):
1233 builddeltaheader = lambda d: _CHANGEGROUPV2_DELTA_HEADER.pack(
1248 builddeltaheader = lambda d: _CHANGEGROUPV2_DELTA_HEADER.pack(
1234 d.node, d.p1node, d.p2node, d.basenode, d.linknode)
1249 d.node, d.p1node, d.p2node, d.basenode, d.linknode)
1235
1250
1236 return cgpacker(repo, oldmatcher, matcher, b'02',
1251 return cgpacker(repo, oldmatcher, matcher, b'02',
1237 builddeltaheader=builddeltaheader,
1252 builddeltaheader=builddeltaheader,
1238 manifestsend=b'',
1253 manifestsend=b'',
1239 bundlecaps=bundlecaps,
1254 bundlecaps=bundlecaps,
1240 ellipses=ellipses,
1255 ellipses=ellipses,
1241 shallow=shallow,
1256 shallow=shallow,
1242 ellipsisroots=ellipsisroots,
1257 ellipsisroots=ellipsisroots,
1243 fullnodes=fullnodes)
1258 fullnodes=fullnodes)
1244
1259
1245 def _makecg3packer(repo, oldmatcher, matcher, bundlecaps,
1260 def _makecg3packer(repo, oldmatcher, matcher, bundlecaps,
1246 ellipses=False, shallow=False, ellipsisroots=None,
1261 ellipses=False, shallow=False, ellipsisroots=None,
1247 fullnodes=None):
1262 fullnodes=None):
1248 builddeltaheader = lambda d: _CHANGEGROUPV3_DELTA_HEADER.pack(
1263 builddeltaheader = lambda d: _CHANGEGROUPV3_DELTA_HEADER.pack(
1249 d.node, d.p1node, d.p2node, d.basenode, d.linknode, d.flags)
1264 d.node, d.p1node, d.p2node, d.basenode, d.linknode, d.flags)
1250
1265
1251 return cgpacker(repo, oldmatcher, matcher, b'03',
1266 return cgpacker(repo, oldmatcher, matcher, b'03',
1252 builddeltaheader=builddeltaheader,
1267 builddeltaheader=builddeltaheader,
1253 manifestsend=closechunk(),
1268 manifestsend=closechunk(),
1254 bundlecaps=bundlecaps,
1269 bundlecaps=bundlecaps,
1255 ellipses=ellipses,
1270 ellipses=ellipses,
1256 shallow=shallow,
1271 shallow=shallow,
1257 ellipsisroots=ellipsisroots,
1272 ellipsisroots=ellipsisroots,
1258 fullnodes=fullnodes)
1273 fullnodes=fullnodes)
1259
1274
1260 _packermap = {'01': (_makecg1packer, cg1unpacker),
1275 _packermap = {'01': (_makecg1packer, cg1unpacker),
1261 # cg2 adds support for exchanging generaldelta
1276 # cg2 adds support for exchanging generaldelta
1262 '02': (_makecg2packer, cg2unpacker),
1277 '02': (_makecg2packer, cg2unpacker),
1263 # cg3 adds support for exchanging revlog flags and treemanifests
1278 # cg3 adds support for exchanging revlog flags and treemanifests
1264 '03': (_makecg3packer, cg3unpacker),
1279 '03': (_makecg3packer, cg3unpacker),
1265 }
1280 }
1266
1281
1267 def allsupportedversions(repo):
1282 def allsupportedversions(repo):
1268 versions = set(_packermap.keys())
1283 versions = set(_packermap.keys())
1269 if not (repo.ui.configbool('experimental', 'changegroup3') or
1284 if not (repo.ui.configbool('experimental', 'changegroup3') or
1270 repo.ui.configbool('experimental', 'treemanifest') or
1285 repo.ui.configbool('experimental', 'treemanifest') or
1271 'treemanifest' in repo.requirements):
1286 'treemanifest' in repo.requirements):
1272 versions.discard('03')
1287 versions.discard('03')
1273 return versions
1288 return versions
1274
1289
1275 # Changegroup versions that can be applied to the repo
1290 # Changegroup versions that can be applied to the repo
1276 def supportedincomingversions(repo):
1291 def supportedincomingversions(repo):
1277 return allsupportedversions(repo)
1292 return allsupportedversions(repo)
1278
1293
1279 # Changegroup versions that can be created from the repo
1294 # Changegroup versions that can be created from the repo
1280 def supportedoutgoingversions(repo):
1295 def supportedoutgoingversions(repo):
1281 versions = allsupportedversions(repo)
1296 versions = allsupportedversions(repo)
1282 if 'treemanifest' in repo.requirements:
1297 if 'treemanifest' in repo.requirements:
1283 # Versions 01 and 02 support only flat manifests and it's just too
1298 # Versions 01 and 02 support only flat manifests and it's just too
1284 # expensive to convert between the flat manifest and tree manifest on
1299 # expensive to convert between the flat manifest and tree manifest on
1285 # the fly. Since tree manifests are hashed differently, all of history
1300 # the fly. Since tree manifests are hashed differently, all of history
1286 # would have to be converted. Instead, we simply don't even pretend to
1301 # would have to be converted. Instead, we simply don't even pretend to
1287 # support versions 01 and 02.
1302 # support versions 01 and 02.
1288 versions.discard('01')
1303 versions.discard('01')
1289 versions.discard('02')
1304 versions.discard('02')
1290 if repository.NARROW_REQUIREMENT in repo.requirements:
1305 if repository.NARROW_REQUIREMENT in repo.requirements:
1291 # Versions 01 and 02 don't support revlog flags, and we need to
1306 # Versions 01 and 02 don't support revlog flags, and we need to
1292 # support that for stripping and unbundling to work.
1307 # support that for stripping and unbundling to work.
1293 versions.discard('01')
1308 versions.discard('01')
1294 versions.discard('02')
1309 versions.discard('02')
1295 if LFS_REQUIREMENT in repo.requirements:
1310 if LFS_REQUIREMENT in repo.requirements:
1296 # Versions 01 and 02 don't support revlog flags, and we need to
1311 # Versions 01 and 02 don't support revlog flags, and we need to
1297 # mark LFS entries with REVIDX_EXTSTORED.
1312 # mark LFS entries with REVIDX_EXTSTORED.
1298 versions.discard('01')
1313 versions.discard('01')
1299 versions.discard('02')
1314 versions.discard('02')
1300
1315
1301 return versions
1316 return versions
1302
1317
1303 def localversion(repo):
1318 def localversion(repo):
1304 # Finds the best version to use for bundles that are meant to be used
1319 # Finds the best version to use for bundles that are meant to be used
1305 # locally, such as those from strip and shelve, and temporary bundles.
1320 # locally, such as those from strip and shelve, and temporary bundles.
1306 return max(supportedoutgoingversions(repo))
1321 return max(supportedoutgoingversions(repo))
1307
1322
1308 def safeversion(repo):
1323 def safeversion(repo):
1309 # Finds the smallest version that it's safe to assume clients of the repo
1324 # Finds the smallest version that it's safe to assume clients of the repo
1310 # will support. For example, all hg versions that support generaldelta also
1325 # will support. For example, all hg versions that support generaldelta also
1311 # support changegroup 02.
1326 # support changegroup 02.
1312 versions = supportedoutgoingversions(repo)
1327 versions = supportedoutgoingversions(repo)
1313 if 'generaldelta' in repo.requirements:
1328 if 'generaldelta' in repo.requirements:
1314 versions.discard('01')
1329 versions.discard('01')
1315 assert versions
1330 assert versions
1316 return min(versions)
1331 return min(versions)
1317
1332
1318 def getbundler(version, repo, bundlecaps=None, oldmatcher=None,
1333 def getbundler(version, repo, bundlecaps=None, oldmatcher=None,
1319 matcher=None, ellipses=False, shallow=False,
1334 matcher=None, ellipses=False, shallow=False,
1320 ellipsisroots=None, fullnodes=None):
1335 ellipsisroots=None, fullnodes=None):
1321 assert version in supportedoutgoingversions(repo)
1336 assert version in supportedoutgoingversions(repo)
1322
1337
1323 if matcher is None:
1338 if matcher is None:
1324 matcher = matchmod.always()
1339 matcher = matchmod.always()
1325 if oldmatcher is None:
1340 if oldmatcher is None:
1326 oldmatcher = matchmod.never()
1341 oldmatcher = matchmod.never()
1327
1342
1328 if version == '01' and not matcher.always():
1343 if version == '01' and not matcher.always():
1329 raise error.ProgrammingError('version 01 changegroups do not support '
1344 raise error.ProgrammingError('version 01 changegroups do not support '
1330 'sparse file matchers')
1345 'sparse file matchers')
1331
1346
1332 if ellipses and version in (b'01', b'02'):
1347 if ellipses and version in (b'01', b'02'):
1333 raise error.Abort(
1348 raise error.Abort(
1334 _('ellipsis nodes require at least cg3 on client and server, '
1349 _('ellipsis nodes require at least cg3 on client and server, '
1335 'but negotiated version %s') % version)
1350 'but negotiated version %s') % version)
1336
1351
1337 # Requested files could include files not in the local store. So
1352 # Requested files could include files not in the local store. So
1338 # filter those out.
1353 # filter those out.
1339 matcher = repo.narrowmatch(matcher)
1354 matcher = repo.narrowmatch(matcher)
1340
1355
1341 fn = _packermap[version][0]
1356 fn = _packermap[version][0]
1342 return fn(repo, oldmatcher, matcher, bundlecaps, ellipses=ellipses,
1357 return fn(repo, oldmatcher, matcher, bundlecaps, ellipses=ellipses,
1343 shallow=shallow, ellipsisroots=ellipsisroots,
1358 shallow=shallow, ellipsisroots=ellipsisroots,
1344 fullnodes=fullnodes)
1359 fullnodes=fullnodes)
1345
1360
1346 def getunbundler(version, fh, alg, extras=None):
1361 def getunbundler(version, fh, alg, extras=None):
1347 return _packermap[version][1](fh, alg, extras=extras)
1362 return _packermap[version][1](fh, alg, extras=extras)
1348
1363
1349 def _changegroupinfo(repo, nodes, source):
1364 def _changegroupinfo(repo, nodes, source):
1350 if repo.ui.verbose or source == 'bundle':
1365 if repo.ui.verbose or source == 'bundle':
1351 repo.ui.status(_("%d changesets found\n") % len(nodes))
1366 repo.ui.status(_("%d changesets found\n") % len(nodes))
1352 if repo.ui.debugflag:
1367 if repo.ui.debugflag:
1353 repo.ui.debug("list of changesets:\n")
1368 repo.ui.debug("list of changesets:\n")
1354 for node in nodes:
1369 for node in nodes:
1355 repo.ui.debug("%s\n" % hex(node))
1370 repo.ui.debug("%s\n" % hex(node))
1356
1371
1357 def makechangegroup(repo, outgoing, version, source, fastpath=False,
1372 def makechangegroup(repo, outgoing, version, source, fastpath=False,
1358 bundlecaps=None):
1373 bundlecaps=None):
1359 cgstream = makestream(repo, outgoing, version, source,
1374 cgstream = makestream(repo, outgoing, version, source,
1360 fastpath=fastpath, bundlecaps=bundlecaps)
1375 fastpath=fastpath, bundlecaps=bundlecaps)
1361 return getunbundler(version, util.chunkbuffer(cgstream), None,
1376 return getunbundler(version, util.chunkbuffer(cgstream), None,
1362 {'clcount': len(outgoing.missing) })
1377 {'clcount': len(outgoing.missing) })
1363
1378
1364 def makestream(repo, outgoing, version, source, fastpath=False,
1379 def makestream(repo, outgoing, version, source, fastpath=False,
1365 bundlecaps=None, matcher=None):
1380 bundlecaps=None, matcher=None):
1366 bundler = getbundler(version, repo, bundlecaps=bundlecaps,
1381 bundler = getbundler(version, repo, bundlecaps=bundlecaps,
1367 matcher=matcher)
1382 matcher=matcher)
1368
1383
1369 repo = repo.unfiltered()
1384 repo = repo.unfiltered()
1370 commonrevs = outgoing.common
1385 commonrevs = outgoing.common
1371 csets = outgoing.missing
1386 csets = outgoing.missing
1372 heads = outgoing.missingheads
1387 heads = outgoing.missingheads
1373 # We go through the fast path if we get told to, or if all (unfiltered
1388 # We go through the fast path if we get told to, or if all (unfiltered
1374 # heads have been requested (since we then know there all linkrevs will
1389 # heads have been requested (since we then know there all linkrevs will
1375 # be pulled by the client).
1390 # be pulled by the client).
1376 heads.sort()
1391 heads.sort()
1377 fastpathlinkrev = fastpath or (
1392 fastpathlinkrev = fastpath or (
1378 repo.filtername is None and heads == sorted(repo.heads()))
1393 repo.filtername is None and heads == sorted(repo.heads()))
1379
1394
1380 repo.hook('preoutgoing', throw=True, source=source)
1395 repo.hook('preoutgoing', throw=True, source=source)
1381 _changegroupinfo(repo, csets, source)
1396 _changegroupinfo(repo, csets, source)
1382 return bundler.generate(commonrevs, csets, fastpathlinkrev, source)
1397 return bundler.generate(commonrevs, csets, fastpathlinkrev, source)
1383
1398
1384 def _addchangegroupfiles(repo, source, revmap, trp, expectedfiles, needfiles):
1399 def _addchangegroupfiles(repo, source, revmap, trp, expectedfiles, needfiles):
1385 revisions = 0
1400 revisions = 0
1386 files = 0
1401 files = 0
1387 progress = repo.ui.makeprogress(_('files'), unit=_('files'),
1402 progress = repo.ui.makeprogress(_('files'), unit=_('files'),
1388 total=expectedfiles)
1403 total=expectedfiles)
1389 for chunkdata in iter(source.filelogheader, {}):
1404 for chunkdata in iter(source.filelogheader, {}):
1390 files += 1
1405 files += 1
1391 f = chunkdata["filename"]
1406 f = chunkdata["filename"]
1392 repo.ui.debug("adding %s revisions\n" % f)
1407 repo.ui.debug("adding %s revisions\n" % f)
1393 progress.increment()
1408 progress.increment()
1394 fl = repo.file(f)
1409 fl = repo.file(f)
1395 o = len(fl)
1410 o = len(fl)
1396 try:
1411 try:
1397 deltas = source.deltaiter()
1412 deltas = source.deltaiter()
1398 if not fl.addgroup(deltas, revmap, trp):
1413 if not fl.addgroup(deltas, revmap, trp):
1399 raise error.Abort(_("received file revlog group is empty"))
1414 raise error.Abort(_("received file revlog group is empty"))
1400 except error.CensoredBaseError as e:
1415 except error.CensoredBaseError as e:
1401 raise error.Abort(_("received delta base is censored: %s") % e)
1416 raise error.Abort(_("received delta base is censored: %s") % e)
1402 revisions += len(fl) - o
1417 revisions += len(fl) - o
1403 if f in needfiles:
1418 if f in needfiles:
1404 needs = needfiles[f]
1419 needs = needfiles[f]
1405 for new in pycompat.xrange(o, len(fl)):
1420 for new in pycompat.xrange(o, len(fl)):
1406 n = fl.node(new)
1421 n = fl.node(new)
1407 if n in needs:
1422 if n in needs:
1408 needs.remove(n)
1423 needs.remove(n)
1409 else:
1424 else:
1410 raise error.Abort(
1425 raise error.Abort(
1411 _("received spurious file revlog entry"))
1426 _("received spurious file revlog entry"))
1412 if not needs:
1427 if not needs:
1413 del needfiles[f]
1428 del needfiles[f]
1414 progress.complete()
1429 progress.complete()
1415
1430
1416 for f, needs in needfiles.iteritems():
1431 for f, needs in needfiles.iteritems():
1417 fl = repo.file(f)
1432 fl = repo.file(f)
1418 for n in needs:
1433 for n in needs:
1419 try:
1434 try:
1420 fl.rev(n)
1435 fl.rev(n)
1421 except error.LookupError:
1436 except error.LookupError:
1422 raise error.Abort(
1437 raise error.Abort(
1423 _('missing file data for %s:%s - run hg verify') %
1438 _('missing file data for %s:%s - run hg verify') %
1424 (f, hex(n)))
1439 (f, hex(n)))
1425
1440
1426 return revisions, files
1441 return revisions, files
@@ -1,2007 +1,2021 b''
1 # scmutil.py - Mercurial core utility functions
1 # scmutil.py - Mercurial core utility functions
2 #
2 #
3 # Copyright Matt Mackall <mpm@selenic.com>
3 # Copyright Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import errno
10 import errno
11 import glob
11 import glob
12 import hashlib
12 import hashlib
13 import os
13 import os
14 import posixpath
14 import posixpath
15 import re
15 import re
16 import subprocess
16 import subprocess
17 import weakref
17 import weakref
18
18
19 from .i18n import _
19 from .i18n import _
20 from .node import (
20 from .node import (
21 bin,
21 bin,
22 hex,
22 hex,
23 nullid,
23 nullid,
24 nullrev,
24 nullrev,
25 short,
25 short,
26 wdirid,
26 wdirid,
27 wdirrev,
27 wdirrev,
28 )
28 )
29
29
30 from . import (
30 from . import (
31 copies as copiesmod,
31 copies as copiesmod,
32 encoding,
32 encoding,
33 error,
33 error,
34 match as matchmod,
34 match as matchmod,
35 obsolete,
35 obsolete,
36 obsutil,
36 obsutil,
37 pathutil,
37 pathutil,
38 phases,
38 phases,
39 policy,
39 policy,
40 pycompat,
40 pycompat,
41 revsetlang,
41 revsetlang,
42 similar,
42 similar,
43 smartset,
43 smartset,
44 url,
44 url,
45 util,
45 util,
46 vfs,
46 vfs,
47 )
47 )
48
48
49 from .utils import (
49 from .utils import (
50 procutil,
50 procutil,
51 stringutil,
51 stringutil,
52 )
52 )
53
53
54 if pycompat.iswindows:
54 if pycompat.iswindows:
55 from . import scmwindows as scmplatform
55 from . import scmwindows as scmplatform
56 else:
56 else:
57 from . import scmposix as scmplatform
57 from . import scmposix as scmplatform
58
58
59 parsers = policy.importmod(r'parsers')
59 parsers = policy.importmod(r'parsers')
60
60
61 termsize = scmplatform.termsize
61 termsize = scmplatform.termsize
62
62
63 class status(tuple):
63 class status(tuple):
64 '''Named tuple with a list of files per status. The 'deleted', 'unknown'
64 '''Named tuple with a list of files per status. The 'deleted', 'unknown'
65 and 'ignored' properties are only relevant to the working copy.
65 and 'ignored' properties are only relevant to the working copy.
66 '''
66 '''
67
67
68 __slots__ = ()
68 __slots__ = ()
69
69
70 def __new__(cls, modified, added, removed, deleted, unknown, ignored,
70 def __new__(cls, modified, added, removed, deleted, unknown, ignored,
71 clean):
71 clean):
72 return tuple.__new__(cls, (modified, added, removed, deleted, unknown,
72 return tuple.__new__(cls, (modified, added, removed, deleted, unknown,
73 ignored, clean))
73 ignored, clean))
74
74
75 @property
75 @property
76 def modified(self):
76 def modified(self):
77 '''files that have been modified'''
77 '''files that have been modified'''
78 return self[0]
78 return self[0]
79
79
80 @property
80 @property
81 def added(self):
81 def added(self):
82 '''files that have been added'''
82 '''files that have been added'''
83 return self[1]
83 return self[1]
84
84
85 @property
85 @property
86 def removed(self):
86 def removed(self):
87 '''files that have been removed'''
87 '''files that have been removed'''
88 return self[2]
88 return self[2]
89
89
90 @property
90 @property
91 def deleted(self):
91 def deleted(self):
92 '''files that are in the dirstate, but have been deleted from the
92 '''files that are in the dirstate, but have been deleted from the
93 working copy (aka "missing")
93 working copy (aka "missing")
94 '''
94 '''
95 return self[3]
95 return self[3]
96
96
97 @property
97 @property
98 def unknown(self):
98 def unknown(self):
99 '''files not in the dirstate that are not ignored'''
99 '''files not in the dirstate that are not ignored'''
100 return self[4]
100 return self[4]
101
101
102 @property
102 @property
103 def ignored(self):
103 def ignored(self):
104 '''files not in the dirstate that are ignored (by _dirignore())'''
104 '''files not in the dirstate that are ignored (by _dirignore())'''
105 return self[5]
105 return self[5]
106
106
107 @property
107 @property
108 def clean(self):
108 def clean(self):
109 '''files that have not been modified'''
109 '''files that have not been modified'''
110 return self[6]
110 return self[6]
111
111
112 def __repr__(self, *args, **kwargs):
112 def __repr__(self, *args, **kwargs):
113 return ((r'<status modified=%s, added=%s, removed=%s, deleted=%s, '
113 return ((r'<status modified=%s, added=%s, removed=%s, deleted=%s, '
114 r'unknown=%s, ignored=%s, clean=%s>') %
114 r'unknown=%s, ignored=%s, clean=%s>') %
115 tuple(pycompat.sysstr(stringutil.pprint(v)) for v in self))
115 tuple(pycompat.sysstr(stringutil.pprint(v)) for v in self))
116
116
117 def itersubrepos(ctx1, ctx2):
117 def itersubrepos(ctx1, ctx2):
118 """find subrepos in ctx1 or ctx2"""
118 """find subrepos in ctx1 or ctx2"""
119 # Create a (subpath, ctx) mapping where we prefer subpaths from
119 # Create a (subpath, ctx) mapping where we prefer subpaths from
120 # ctx1. The subpaths from ctx2 are important when the .hgsub file
120 # ctx1. The subpaths from ctx2 are important when the .hgsub file
121 # has been modified (in ctx2) but not yet committed (in ctx1).
121 # has been modified (in ctx2) but not yet committed (in ctx1).
122 subpaths = dict.fromkeys(ctx2.substate, ctx2)
122 subpaths = dict.fromkeys(ctx2.substate, ctx2)
123 subpaths.update(dict.fromkeys(ctx1.substate, ctx1))
123 subpaths.update(dict.fromkeys(ctx1.substate, ctx1))
124
124
125 missing = set()
125 missing = set()
126
126
127 for subpath in ctx2.substate:
127 for subpath in ctx2.substate:
128 if subpath not in ctx1.substate:
128 if subpath not in ctx1.substate:
129 del subpaths[subpath]
129 del subpaths[subpath]
130 missing.add(subpath)
130 missing.add(subpath)
131
131
132 for subpath, ctx in sorted(subpaths.iteritems()):
132 for subpath, ctx in sorted(subpaths.iteritems()):
133 yield subpath, ctx.sub(subpath)
133 yield subpath, ctx.sub(subpath)
134
134
135 # Yield an empty subrepo based on ctx1 for anything only in ctx2. That way,
135 # Yield an empty subrepo based on ctx1 for anything only in ctx2. That way,
136 # status and diff will have an accurate result when it does
136 # status and diff will have an accurate result when it does
137 # 'sub.{status|diff}(rev2)'. Otherwise, the ctx2 subrepo is compared
137 # 'sub.{status|diff}(rev2)'. Otherwise, the ctx2 subrepo is compared
138 # against itself.
138 # against itself.
139 for subpath in missing:
139 for subpath in missing:
140 yield subpath, ctx2.nullsub(subpath, ctx1)
140 yield subpath, ctx2.nullsub(subpath, ctx1)
141
141
142 def nochangesfound(ui, repo, excluded=None):
142 def nochangesfound(ui, repo, excluded=None):
143 '''Report no changes for push/pull, excluded is None or a list of
143 '''Report no changes for push/pull, excluded is None or a list of
144 nodes excluded from the push/pull.
144 nodes excluded from the push/pull.
145 '''
145 '''
146 secretlist = []
146 secretlist = []
147 if excluded:
147 if excluded:
148 for n in excluded:
148 for n in excluded:
149 ctx = repo[n]
149 ctx = repo[n]
150 if ctx.phase() >= phases.secret and not ctx.extinct():
150 if ctx.phase() >= phases.secret and not ctx.extinct():
151 secretlist.append(n)
151 secretlist.append(n)
152
152
153 if secretlist:
153 if secretlist:
154 ui.status(_("no changes found (ignored %d secret changesets)\n")
154 ui.status(_("no changes found (ignored %d secret changesets)\n")
155 % len(secretlist))
155 % len(secretlist))
156 else:
156 else:
157 ui.status(_("no changes found\n"))
157 ui.status(_("no changes found\n"))
158
158
159 def callcatch(ui, func):
159 def callcatch(ui, func):
160 """call func() with global exception handling
160 """call func() with global exception handling
161
161
162 return func() if no exception happens. otherwise do some error handling
162 return func() if no exception happens. otherwise do some error handling
163 and return an exit code accordingly. does not handle all exceptions.
163 and return an exit code accordingly. does not handle all exceptions.
164 """
164 """
165 try:
165 try:
166 try:
166 try:
167 return func()
167 return func()
168 except: # re-raises
168 except: # re-raises
169 ui.traceback()
169 ui.traceback()
170 raise
170 raise
171 # Global exception handling, alphabetically
171 # Global exception handling, alphabetically
172 # Mercurial-specific first, followed by built-in and library exceptions
172 # Mercurial-specific first, followed by built-in and library exceptions
173 except error.LockHeld as inst:
173 except error.LockHeld as inst:
174 if inst.errno == errno.ETIMEDOUT:
174 if inst.errno == errno.ETIMEDOUT:
175 reason = _('timed out waiting for lock held by %r') % (
175 reason = _('timed out waiting for lock held by %r') % (
176 pycompat.bytestr(inst.locker))
176 pycompat.bytestr(inst.locker))
177 else:
177 else:
178 reason = _('lock held by %r') % inst.locker
178 reason = _('lock held by %r') % inst.locker
179 ui.error(_("abort: %s: %s\n") % (
179 ui.error(_("abort: %s: %s\n") % (
180 inst.desc or stringutil.forcebytestr(inst.filename), reason))
180 inst.desc or stringutil.forcebytestr(inst.filename), reason))
181 if not inst.locker:
181 if not inst.locker:
182 ui.error(_("(lock might be very busy)\n"))
182 ui.error(_("(lock might be very busy)\n"))
183 except error.LockUnavailable as inst:
183 except error.LockUnavailable as inst:
184 ui.error(_("abort: could not lock %s: %s\n") %
184 ui.error(_("abort: could not lock %s: %s\n") %
185 (inst.desc or stringutil.forcebytestr(inst.filename),
185 (inst.desc or stringutil.forcebytestr(inst.filename),
186 encoding.strtolocal(inst.strerror)))
186 encoding.strtolocal(inst.strerror)))
187 except error.OutOfBandError as inst:
187 except error.OutOfBandError as inst:
188 if inst.args:
188 if inst.args:
189 msg = _("abort: remote error:\n")
189 msg = _("abort: remote error:\n")
190 else:
190 else:
191 msg = _("abort: remote error\n")
191 msg = _("abort: remote error\n")
192 ui.error(msg)
192 ui.error(msg)
193 if inst.args:
193 if inst.args:
194 ui.error(''.join(inst.args))
194 ui.error(''.join(inst.args))
195 if inst.hint:
195 if inst.hint:
196 ui.error('(%s)\n' % inst.hint)
196 ui.error('(%s)\n' % inst.hint)
197 except error.RepoError as inst:
197 except error.RepoError as inst:
198 ui.error(_("abort: %s!\n") % inst)
198 ui.error(_("abort: %s!\n") % inst)
199 if inst.hint:
199 if inst.hint:
200 ui.error(_("(%s)\n") % inst.hint)
200 ui.error(_("(%s)\n") % inst.hint)
201 except error.ResponseError as inst:
201 except error.ResponseError as inst:
202 ui.error(_("abort: %s") % inst.args[0])
202 ui.error(_("abort: %s") % inst.args[0])
203 msg = inst.args[1]
203 msg = inst.args[1]
204 if isinstance(msg, type(u'')):
204 if isinstance(msg, type(u'')):
205 msg = pycompat.sysbytes(msg)
205 msg = pycompat.sysbytes(msg)
206 if not isinstance(msg, bytes):
206 if not isinstance(msg, bytes):
207 ui.error(" %r\n" % (msg,))
207 ui.error(" %r\n" % (msg,))
208 elif not msg:
208 elif not msg:
209 ui.error(_(" empty string\n"))
209 ui.error(_(" empty string\n"))
210 else:
210 else:
211 ui.error("\n%r\n" % pycompat.bytestr(stringutil.ellipsis(msg)))
211 ui.error("\n%r\n" % pycompat.bytestr(stringutil.ellipsis(msg)))
212 except error.CensoredNodeError as inst:
212 except error.CensoredNodeError as inst:
213 ui.error(_("abort: file censored %s!\n") % inst)
213 ui.error(_("abort: file censored %s!\n") % inst)
214 except error.StorageError as inst:
214 except error.StorageError as inst:
215 ui.error(_("abort: %s!\n") % inst)
215 ui.error(_("abort: %s!\n") % inst)
216 if inst.hint:
216 if inst.hint:
217 ui.error(_("(%s)\n") % inst.hint)
217 ui.error(_("(%s)\n") % inst.hint)
218 except error.InterventionRequired as inst:
218 except error.InterventionRequired as inst:
219 ui.error("%s\n" % inst)
219 ui.error("%s\n" % inst)
220 if inst.hint:
220 if inst.hint:
221 ui.error(_("(%s)\n") % inst.hint)
221 ui.error(_("(%s)\n") % inst.hint)
222 return 1
222 return 1
223 except error.WdirUnsupported:
223 except error.WdirUnsupported:
224 ui.error(_("abort: working directory revision cannot be specified\n"))
224 ui.error(_("abort: working directory revision cannot be specified\n"))
225 except error.Abort as inst:
225 except error.Abort as inst:
226 ui.error(_("abort: %s\n") % inst)
226 ui.error(_("abort: %s\n") % inst)
227 if inst.hint:
227 if inst.hint:
228 ui.error(_("(%s)\n") % inst.hint)
228 ui.error(_("(%s)\n") % inst.hint)
229 except ImportError as inst:
229 except ImportError as inst:
230 ui.error(_("abort: %s!\n") % stringutil.forcebytestr(inst))
230 ui.error(_("abort: %s!\n") % stringutil.forcebytestr(inst))
231 m = stringutil.forcebytestr(inst).split()[-1]
231 m = stringutil.forcebytestr(inst).split()[-1]
232 if m in "mpatch bdiff".split():
232 if m in "mpatch bdiff".split():
233 ui.error(_("(did you forget to compile extensions?)\n"))
233 ui.error(_("(did you forget to compile extensions?)\n"))
234 elif m in "zlib".split():
234 elif m in "zlib".split():
235 ui.error(_("(is your Python install correct?)\n"))
235 ui.error(_("(is your Python install correct?)\n"))
236 except (IOError, OSError) as inst:
236 except (IOError, OSError) as inst:
237 if util.safehasattr(inst, "code"): # HTTPError
237 if util.safehasattr(inst, "code"): # HTTPError
238 ui.error(_("abort: %s\n") % stringutil.forcebytestr(inst))
238 ui.error(_("abort: %s\n") % stringutil.forcebytestr(inst))
239 elif util.safehasattr(inst, "reason"): # URLError or SSLError
239 elif util.safehasattr(inst, "reason"): # URLError or SSLError
240 try: # usually it is in the form (errno, strerror)
240 try: # usually it is in the form (errno, strerror)
241 reason = inst.reason.args[1]
241 reason = inst.reason.args[1]
242 except (AttributeError, IndexError):
242 except (AttributeError, IndexError):
243 # it might be anything, for example a string
243 # it might be anything, for example a string
244 reason = inst.reason
244 reason = inst.reason
245 if isinstance(reason, pycompat.unicode):
245 if isinstance(reason, pycompat.unicode):
246 # SSLError of Python 2.7.9 contains a unicode
246 # SSLError of Python 2.7.9 contains a unicode
247 reason = encoding.unitolocal(reason)
247 reason = encoding.unitolocal(reason)
248 ui.error(_("abort: error: %s\n") % reason)
248 ui.error(_("abort: error: %s\n") % reason)
249 elif (util.safehasattr(inst, "args")
249 elif (util.safehasattr(inst, "args")
250 and inst.args and inst.args[0] == errno.EPIPE):
250 and inst.args and inst.args[0] == errno.EPIPE):
251 pass
251 pass
252 elif getattr(inst, "strerror", None): # common IOError or OSError
252 elif getattr(inst, "strerror", None): # common IOError or OSError
253 if getattr(inst, "filename", None) is not None:
253 if getattr(inst, "filename", None) is not None:
254 ui.error(_("abort: %s: '%s'\n") % (
254 ui.error(_("abort: %s: '%s'\n") % (
255 encoding.strtolocal(inst.strerror),
255 encoding.strtolocal(inst.strerror),
256 stringutil.forcebytestr(inst.filename)))
256 stringutil.forcebytestr(inst.filename)))
257 else:
257 else:
258 ui.error(_("abort: %s\n") % encoding.strtolocal(inst.strerror))
258 ui.error(_("abort: %s\n") % encoding.strtolocal(inst.strerror))
259 else: # suspicious IOError
259 else: # suspicious IOError
260 raise
260 raise
261 except MemoryError:
261 except MemoryError:
262 ui.error(_("abort: out of memory\n"))
262 ui.error(_("abort: out of memory\n"))
263 except SystemExit as inst:
263 except SystemExit as inst:
264 # Commands shouldn't sys.exit directly, but give a return code.
264 # Commands shouldn't sys.exit directly, but give a return code.
265 # Just in case catch this and and pass exit code to caller.
265 # Just in case catch this and and pass exit code to caller.
266 return inst.code
266 return inst.code
267
267
268 return -1
268 return -1
269
269
270 def checknewlabel(repo, lbl, kind):
270 def checknewlabel(repo, lbl, kind):
271 # Do not use the "kind" parameter in ui output.
271 # Do not use the "kind" parameter in ui output.
272 # It makes strings difficult to translate.
272 # It makes strings difficult to translate.
273 if lbl in ['tip', '.', 'null']:
273 if lbl in ['tip', '.', 'null']:
274 raise error.Abort(_("the name '%s' is reserved") % lbl)
274 raise error.Abort(_("the name '%s' is reserved") % lbl)
275 for c in (':', '\0', '\n', '\r'):
275 for c in (':', '\0', '\n', '\r'):
276 if c in lbl:
276 if c in lbl:
277 raise error.Abort(
277 raise error.Abort(
278 _("%r cannot be used in a name") % pycompat.bytestr(c))
278 _("%r cannot be used in a name") % pycompat.bytestr(c))
279 try:
279 try:
280 int(lbl)
280 int(lbl)
281 raise error.Abort(_("cannot use an integer as a name"))
281 raise error.Abort(_("cannot use an integer as a name"))
282 except ValueError:
282 except ValueError:
283 pass
283 pass
284 if lbl.strip() != lbl:
284 if lbl.strip() != lbl:
285 raise error.Abort(_("leading or trailing whitespace in name %r") % lbl)
285 raise error.Abort(_("leading or trailing whitespace in name %r") % lbl)
286
286
287 def checkfilename(f):
287 def checkfilename(f):
288 '''Check that the filename f is an acceptable filename for a tracked file'''
288 '''Check that the filename f is an acceptable filename for a tracked file'''
289 if '\r' in f or '\n' in f:
289 if '\r' in f or '\n' in f:
290 raise error.Abort(_("'\\n' and '\\r' disallowed in filenames: %r")
290 raise error.Abort(_("'\\n' and '\\r' disallowed in filenames: %r")
291 % pycompat.bytestr(f))
291 % pycompat.bytestr(f))
292
292
293 def checkportable(ui, f):
293 def checkportable(ui, f):
294 '''Check if filename f is portable and warn or abort depending on config'''
294 '''Check if filename f is portable and warn or abort depending on config'''
295 checkfilename(f)
295 checkfilename(f)
296 abort, warn = checkportabilityalert(ui)
296 abort, warn = checkportabilityalert(ui)
297 if abort or warn:
297 if abort or warn:
298 msg = util.checkwinfilename(f)
298 msg = util.checkwinfilename(f)
299 if msg:
299 if msg:
300 msg = "%s: %s" % (msg, procutil.shellquote(f))
300 msg = "%s: %s" % (msg, procutil.shellquote(f))
301 if abort:
301 if abort:
302 raise error.Abort(msg)
302 raise error.Abort(msg)
303 ui.warn(_("warning: %s\n") % msg)
303 ui.warn(_("warning: %s\n") % msg)
304
304
305 def checkportabilityalert(ui):
305 def checkportabilityalert(ui):
306 '''check if the user's config requests nothing, a warning, or abort for
306 '''check if the user's config requests nothing, a warning, or abort for
307 non-portable filenames'''
307 non-portable filenames'''
308 val = ui.config('ui', 'portablefilenames')
308 val = ui.config('ui', 'portablefilenames')
309 lval = val.lower()
309 lval = val.lower()
310 bval = stringutil.parsebool(val)
310 bval = stringutil.parsebool(val)
311 abort = pycompat.iswindows or lval == 'abort'
311 abort = pycompat.iswindows or lval == 'abort'
312 warn = bval or lval == 'warn'
312 warn = bval or lval == 'warn'
313 if bval is None and not (warn or abort or lval == 'ignore'):
313 if bval is None and not (warn or abort or lval == 'ignore'):
314 raise error.ConfigError(
314 raise error.ConfigError(
315 _("ui.portablefilenames value is invalid ('%s')") % val)
315 _("ui.portablefilenames value is invalid ('%s')") % val)
316 return abort, warn
316 return abort, warn
317
317
318 class casecollisionauditor(object):
318 class casecollisionauditor(object):
319 def __init__(self, ui, abort, dirstate):
319 def __init__(self, ui, abort, dirstate):
320 self._ui = ui
320 self._ui = ui
321 self._abort = abort
321 self._abort = abort
322 allfiles = '\0'.join(dirstate._map)
322 allfiles = '\0'.join(dirstate._map)
323 self._loweredfiles = set(encoding.lower(allfiles).split('\0'))
323 self._loweredfiles = set(encoding.lower(allfiles).split('\0'))
324 self._dirstate = dirstate
324 self._dirstate = dirstate
325 # The purpose of _newfiles is so that we don't complain about
325 # The purpose of _newfiles is so that we don't complain about
326 # case collisions if someone were to call this object with the
326 # case collisions if someone were to call this object with the
327 # same filename twice.
327 # same filename twice.
328 self._newfiles = set()
328 self._newfiles = set()
329
329
330 def __call__(self, f):
330 def __call__(self, f):
331 if f in self._newfiles:
331 if f in self._newfiles:
332 return
332 return
333 fl = encoding.lower(f)
333 fl = encoding.lower(f)
334 if fl in self._loweredfiles and f not in self._dirstate:
334 if fl in self._loweredfiles and f not in self._dirstate:
335 msg = _('possible case-folding collision for %s') % f
335 msg = _('possible case-folding collision for %s') % f
336 if self._abort:
336 if self._abort:
337 raise error.Abort(msg)
337 raise error.Abort(msg)
338 self._ui.warn(_("warning: %s\n") % msg)
338 self._ui.warn(_("warning: %s\n") % msg)
339 self._loweredfiles.add(fl)
339 self._loweredfiles.add(fl)
340 self._newfiles.add(f)
340 self._newfiles.add(f)
341
341
342 def filteredhash(repo, maxrev):
342 def filteredhash(repo, maxrev):
343 """build hash of filtered revisions in the current repoview.
343 """build hash of filtered revisions in the current repoview.
344
344
345 Multiple caches perform up-to-date validation by checking that the
345 Multiple caches perform up-to-date validation by checking that the
346 tiprev and tipnode stored in the cache file match the current repository.
346 tiprev and tipnode stored in the cache file match the current repository.
347 However, this is not sufficient for validating repoviews because the set
347 However, this is not sufficient for validating repoviews because the set
348 of revisions in the view may change without the repository tiprev and
348 of revisions in the view may change without the repository tiprev and
349 tipnode changing.
349 tipnode changing.
350
350
351 This function hashes all the revs filtered from the view and returns
351 This function hashes all the revs filtered from the view and returns
352 that SHA-1 digest.
352 that SHA-1 digest.
353 """
353 """
354 cl = repo.changelog
354 cl = repo.changelog
355 if not cl.filteredrevs:
355 if not cl.filteredrevs:
356 return None
356 return None
357 key = None
357 key = None
358 revs = sorted(r for r in cl.filteredrevs if r <= maxrev)
358 revs = sorted(r for r in cl.filteredrevs if r <= maxrev)
359 if revs:
359 if revs:
360 s = hashlib.sha1()
360 s = hashlib.sha1()
361 for rev in revs:
361 for rev in revs:
362 s.update('%d;' % rev)
362 s.update('%d;' % rev)
363 key = s.digest()
363 key = s.digest()
364 return key
364 return key
365
365
366 def walkrepos(path, followsym=False, seen_dirs=None, recurse=False):
366 def walkrepos(path, followsym=False, seen_dirs=None, recurse=False):
367 '''yield every hg repository under path, always recursively.
367 '''yield every hg repository under path, always recursively.
368 The recurse flag will only control recursion into repo working dirs'''
368 The recurse flag will only control recursion into repo working dirs'''
369 def errhandler(err):
369 def errhandler(err):
370 if err.filename == path:
370 if err.filename == path:
371 raise err
371 raise err
372 samestat = getattr(os.path, 'samestat', None)
372 samestat = getattr(os.path, 'samestat', None)
373 if followsym and samestat is not None:
373 if followsym and samestat is not None:
374 def adddir(dirlst, dirname):
374 def adddir(dirlst, dirname):
375 dirstat = os.stat(dirname)
375 dirstat = os.stat(dirname)
376 match = any(samestat(dirstat, lstdirstat) for lstdirstat in dirlst)
376 match = any(samestat(dirstat, lstdirstat) for lstdirstat in dirlst)
377 if not match:
377 if not match:
378 dirlst.append(dirstat)
378 dirlst.append(dirstat)
379 return not match
379 return not match
380 else:
380 else:
381 followsym = False
381 followsym = False
382
382
383 if (seen_dirs is None) and followsym:
383 if (seen_dirs is None) and followsym:
384 seen_dirs = []
384 seen_dirs = []
385 adddir(seen_dirs, path)
385 adddir(seen_dirs, path)
386 for root, dirs, files in os.walk(path, topdown=True, onerror=errhandler):
386 for root, dirs, files in os.walk(path, topdown=True, onerror=errhandler):
387 dirs.sort()
387 dirs.sort()
388 if '.hg' in dirs:
388 if '.hg' in dirs:
389 yield root # found a repository
389 yield root # found a repository
390 qroot = os.path.join(root, '.hg', 'patches')
390 qroot = os.path.join(root, '.hg', 'patches')
391 if os.path.isdir(os.path.join(qroot, '.hg')):
391 if os.path.isdir(os.path.join(qroot, '.hg')):
392 yield qroot # we have a patch queue repo here
392 yield qroot # we have a patch queue repo here
393 if recurse:
393 if recurse:
394 # avoid recursing inside the .hg directory
394 # avoid recursing inside the .hg directory
395 dirs.remove('.hg')
395 dirs.remove('.hg')
396 else:
396 else:
397 dirs[:] = [] # don't descend further
397 dirs[:] = [] # don't descend further
398 elif followsym:
398 elif followsym:
399 newdirs = []
399 newdirs = []
400 for d in dirs:
400 for d in dirs:
401 fname = os.path.join(root, d)
401 fname = os.path.join(root, d)
402 if adddir(seen_dirs, fname):
402 if adddir(seen_dirs, fname):
403 if os.path.islink(fname):
403 if os.path.islink(fname):
404 for hgname in walkrepos(fname, True, seen_dirs):
404 for hgname in walkrepos(fname, True, seen_dirs):
405 yield hgname
405 yield hgname
406 else:
406 else:
407 newdirs.append(d)
407 newdirs.append(d)
408 dirs[:] = newdirs
408 dirs[:] = newdirs
409
409
410 def binnode(ctx):
410 def binnode(ctx):
411 """Return binary node id for a given basectx"""
411 """Return binary node id for a given basectx"""
412 node = ctx.node()
412 node = ctx.node()
413 if node is None:
413 if node is None:
414 return wdirid
414 return wdirid
415 return node
415 return node
416
416
417 def intrev(ctx):
417 def intrev(ctx):
418 """Return integer for a given basectx that can be used in comparison or
418 """Return integer for a given basectx that can be used in comparison or
419 arithmetic operation"""
419 arithmetic operation"""
420 rev = ctx.rev()
420 rev = ctx.rev()
421 if rev is None:
421 if rev is None:
422 return wdirrev
422 return wdirrev
423 return rev
423 return rev
424
424
425 def formatchangeid(ctx):
425 def formatchangeid(ctx):
426 """Format changectx as '{rev}:{node|formatnode}', which is the default
426 """Format changectx as '{rev}:{node|formatnode}', which is the default
427 template provided by logcmdutil.changesettemplater"""
427 template provided by logcmdutil.changesettemplater"""
428 repo = ctx.repo()
428 repo = ctx.repo()
429 return formatrevnode(repo.ui, intrev(ctx), binnode(ctx))
429 return formatrevnode(repo.ui, intrev(ctx), binnode(ctx))
430
430
431 def formatrevnode(ui, rev, node):
431 def formatrevnode(ui, rev, node):
432 """Format given revision and node depending on the current verbosity"""
432 """Format given revision and node depending on the current verbosity"""
433 if ui.debugflag:
433 if ui.debugflag:
434 hexfunc = hex
434 hexfunc = hex
435 else:
435 else:
436 hexfunc = short
436 hexfunc = short
437 return '%d:%s' % (rev, hexfunc(node))
437 return '%d:%s' % (rev, hexfunc(node))
438
438
439 def resolvehexnodeidprefix(repo, prefix):
439 def resolvehexnodeidprefix(repo, prefix):
440 if (prefix.startswith('x') and
440 if (prefix.startswith('x') and
441 repo.ui.configbool('experimental', 'revisions.prefixhexnode')):
441 repo.ui.configbool('experimental', 'revisions.prefixhexnode')):
442 prefix = prefix[1:]
442 prefix = prefix[1:]
443 try:
443 try:
444 # Uses unfiltered repo because it's faster when prefix is ambiguous/
444 # Uses unfiltered repo because it's faster when prefix is ambiguous/
445 # This matches the shortesthexnodeidprefix() function below.
445 # This matches the shortesthexnodeidprefix() function below.
446 node = repo.unfiltered().changelog._partialmatch(prefix)
446 node = repo.unfiltered().changelog._partialmatch(prefix)
447 except error.AmbiguousPrefixLookupError:
447 except error.AmbiguousPrefixLookupError:
448 revset = repo.ui.config('experimental', 'revisions.disambiguatewithin')
448 revset = repo.ui.config('experimental', 'revisions.disambiguatewithin')
449 if revset:
449 if revset:
450 # Clear config to avoid infinite recursion
450 # Clear config to avoid infinite recursion
451 configoverrides = {('experimental',
451 configoverrides = {('experimental',
452 'revisions.disambiguatewithin'): None}
452 'revisions.disambiguatewithin'): None}
453 with repo.ui.configoverride(configoverrides):
453 with repo.ui.configoverride(configoverrides):
454 revs = repo.anyrevs([revset], user=True)
454 revs = repo.anyrevs([revset], user=True)
455 matches = []
455 matches = []
456 for rev in revs:
456 for rev in revs:
457 node = repo.changelog.node(rev)
457 node = repo.changelog.node(rev)
458 if hex(node).startswith(prefix):
458 if hex(node).startswith(prefix):
459 matches.append(node)
459 matches.append(node)
460 if len(matches) == 1:
460 if len(matches) == 1:
461 return matches[0]
461 return matches[0]
462 raise
462 raise
463 if node is None:
463 if node is None:
464 return
464 return
465 repo.changelog.rev(node) # make sure node isn't filtered
465 repo.changelog.rev(node) # make sure node isn't filtered
466 return node
466 return node
467
467
468 def mayberevnum(repo, prefix):
468 def mayberevnum(repo, prefix):
469 """Checks if the given prefix may be mistaken for a revision number"""
469 """Checks if the given prefix may be mistaken for a revision number"""
470 try:
470 try:
471 i = int(prefix)
471 i = int(prefix)
472 # if we are a pure int, then starting with zero will not be
472 # if we are a pure int, then starting with zero will not be
473 # confused as a rev; or, obviously, if the int is larger
473 # confused as a rev; or, obviously, if the int is larger
474 # than the value of the tip rev. We still need to disambiguate if
474 # than the value of the tip rev. We still need to disambiguate if
475 # prefix == '0', since that *is* a valid revnum.
475 # prefix == '0', since that *is* a valid revnum.
476 if (prefix != b'0' and prefix[0:1] == b'0') or i >= len(repo):
476 if (prefix != b'0' and prefix[0:1] == b'0') or i >= len(repo):
477 return False
477 return False
478 return True
478 return True
479 except ValueError:
479 except ValueError:
480 return False
480 return False
481
481
482 def shortesthexnodeidprefix(repo, node, minlength=1, cache=None):
482 def shortesthexnodeidprefix(repo, node, minlength=1, cache=None):
483 """Find the shortest unambiguous prefix that matches hexnode.
483 """Find the shortest unambiguous prefix that matches hexnode.
484
484
485 If "cache" is not None, it must be a dictionary that can be used for
485 If "cache" is not None, it must be a dictionary that can be used for
486 caching between calls to this method.
486 caching between calls to this method.
487 """
487 """
488 # _partialmatch() of filtered changelog could take O(len(repo)) time,
488 # _partialmatch() of filtered changelog could take O(len(repo)) time,
489 # which would be unacceptably slow. so we look for hash collision in
489 # which would be unacceptably slow. so we look for hash collision in
490 # unfiltered space, which means some hashes may be slightly longer.
490 # unfiltered space, which means some hashes may be slightly longer.
491
491
492 minlength=max(minlength, 1)
492 minlength=max(minlength, 1)
493
493
494 def disambiguate(prefix):
494 def disambiguate(prefix):
495 """Disambiguate against revnums."""
495 """Disambiguate against revnums."""
496 if repo.ui.configbool('experimental', 'revisions.prefixhexnode'):
496 if repo.ui.configbool('experimental', 'revisions.prefixhexnode'):
497 if mayberevnum(repo, prefix):
497 if mayberevnum(repo, prefix):
498 return 'x' + prefix
498 return 'x' + prefix
499 else:
499 else:
500 return prefix
500 return prefix
501
501
502 hexnode = hex(node)
502 hexnode = hex(node)
503 for length in range(len(prefix), len(hexnode) + 1):
503 for length in range(len(prefix), len(hexnode) + 1):
504 prefix = hexnode[:length]
504 prefix = hexnode[:length]
505 if not mayberevnum(repo, prefix):
505 if not mayberevnum(repo, prefix):
506 return prefix
506 return prefix
507
507
508 cl = repo.unfiltered().changelog
508 cl = repo.unfiltered().changelog
509 revset = repo.ui.config('experimental', 'revisions.disambiguatewithin')
509 revset = repo.ui.config('experimental', 'revisions.disambiguatewithin')
510 if revset:
510 if revset:
511 revs = None
511 revs = None
512 if cache is not None:
512 if cache is not None:
513 revs = cache.get('disambiguationrevset')
513 revs = cache.get('disambiguationrevset')
514 if revs is None:
514 if revs is None:
515 revs = repo.anyrevs([revset], user=True)
515 revs = repo.anyrevs([revset], user=True)
516 if cache is not None:
516 if cache is not None:
517 cache['disambiguationrevset'] = revs
517 cache['disambiguationrevset'] = revs
518 if cl.rev(node) in revs:
518 if cl.rev(node) in revs:
519 hexnode = hex(node)
519 hexnode = hex(node)
520 nodetree = None
520 nodetree = None
521 if cache is not None:
521 if cache is not None:
522 nodetree = cache.get('disambiguationnodetree')
522 nodetree = cache.get('disambiguationnodetree')
523 if not nodetree:
523 if not nodetree:
524 try:
524 try:
525 nodetree = parsers.nodetree(cl.index, len(revs))
525 nodetree = parsers.nodetree(cl.index, len(revs))
526 except AttributeError:
526 except AttributeError:
527 # no native nodetree
527 # no native nodetree
528 pass
528 pass
529 else:
529 else:
530 for r in revs:
530 for r in revs:
531 nodetree.insert(r)
531 nodetree.insert(r)
532 if cache is not None:
532 if cache is not None:
533 cache['disambiguationnodetree'] = nodetree
533 cache['disambiguationnodetree'] = nodetree
534 if nodetree is not None:
534 if nodetree is not None:
535 length = max(nodetree.shortest(node), minlength)
535 length = max(nodetree.shortest(node), minlength)
536 prefix = hexnode[:length]
536 prefix = hexnode[:length]
537 return disambiguate(prefix)
537 return disambiguate(prefix)
538 for length in range(minlength, len(hexnode) + 1):
538 for length in range(minlength, len(hexnode) + 1):
539 matches = []
539 matches = []
540 prefix = hexnode[:length]
540 prefix = hexnode[:length]
541 for rev in revs:
541 for rev in revs:
542 otherhexnode = repo[rev].hex()
542 otherhexnode = repo[rev].hex()
543 if prefix == otherhexnode[:length]:
543 if prefix == otherhexnode[:length]:
544 matches.append(otherhexnode)
544 matches.append(otherhexnode)
545 if len(matches) == 1:
545 if len(matches) == 1:
546 return disambiguate(prefix)
546 return disambiguate(prefix)
547
547
548 try:
548 try:
549 return disambiguate(cl.shortest(node, minlength))
549 return disambiguate(cl.shortest(node, minlength))
550 except error.LookupError:
550 except error.LookupError:
551 raise error.RepoLookupError()
551 raise error.RepoLookupError()
552
552
553 def isrevsymbol(repo, symbol):
553 def isrevsymbol(repo, symbol):
554 """Checks if a symbol exists in the repo.
554 """Checks if a symbol exists in the repo.
555
555
556 See revsymbol() for details. Raises error.AmbiguousPrefixLookupError if the
556 See revsymbol() for details. Raises error.AmbiguousPrefixLookupError if the
557 symbol is an ambiguous nodeid prefix.
557 symbol is an ambiguous nodeid prefix.
558 """
558 """
559 try:
559 try:
560 revsymbol(repo, symbol)
560 revsymbol(repo, symbol)
561 return True
561 return True
562 except error.RepoLookupError:
562 except error.RepoLookupError:
563 return False
563 return False
564
564
565 def revsymbol(repo, symbol):
565 def revsymbol(repo, symbol):
566 """Returns a context given a single revision symbol (as string).
566 """Returns a context given a single revision symbol (as string).
567
567
568 This is similar to revsingle(), but accepts only a single revision symbol,
568 This is similar to revsingle(), but accepts only a single revision symbol,
569 i.e. things like ".", "tip", "1234", "deadbeef", "my-bookmark" work, but
569 i.e. things like ".", "tip", "1234", "deadbeef", "my-bookmark" work, but
570 not "max(public())".
570 not "max(public())".
571 """
571 """
572 if not isinstance(symbol, bytes):
572 if not isinstance(symbol, bytes):
573 msg = ("symbol (%s of type %s) was not a string, did you mean "
573 msg = ("symbol (%s of type %s) was not a string, did you mean "
574 "repo[symbol]?" % (symbol, type(symbol)))
574 "repo[symbol]?" % (symbol, type(symbol)))
575 raise error.ProgrammingError(msg)
575 raise error.ProgrammingError(msg)
576 try:
576 try:
577 if symbol in ('.', 'tip', 'null'):
577 if symbol in ('.', 'tip', 'null'):
578 return repo[symbol]
578 return repo[symbol]
579
579
580 try:
580 try:
581 r = int(symbol)
581 r = int(symbol)
582 if '%d' % r != symbol:
582 if '%d' % r != symbol:
583 raise ValueError
583 raise ValueError
584 l = len(repo.changelog)
584 l = len(repo.changelog)
585 if r < 0:
585 if r < 0:
586 r += l
586 r += l
587 if r < 0 or r >= l and r != wdirrev:
587 if r < 0 or r >= l and r != wdirrev:
588 raise ValueError
588 raise ValueError
589 return repo[r]
589 return repo[r]
590 except error.FilteredIndexError:
590 except error.FilteredIndexError:
591 raise
591 raise
592 except (ValueError, OverflowError, IndexError):
592 except (ValueError, OverflowError, IndexError):
593 pass
593 pass
594
594
595 if len(symbol) == 40:
595 if len(symbol) == 40:
596 try:
596 try:
597 node = bin(symbol)
597 node = bin(symbol)
598 rev = repo.changelog.rev(node)
598 rev = repo.changelog.rev(node)
599 return repo[rev]
599 return repo[rev]
600 except error.FilteredLookupError:
600 except error.FilteredLookupError:
601 raise
601 raise
602 except (TypeError, LookupError):
602 except (TypeError, LookupError):
603 pass
603 pass
604
604
605 # look up bookmarks through the name interface
605 # look up bookmarks through the name interface
606 try:
606 try:
607 node = repo.names.singlenode(repo, symbol)
607 node = repo.names.singlenode(repo, symbol)
608 rev = repo.changelog.rev(node)
608 rev = repo.changelog.rev(node)
609 return repo[rev]
609 return repo[rev]
610 except KeyError:
610 except KeyError:
611 pass
611 pass
612
612
613 node = resolvehexnodeidprefix(repo, symbol)
613 node = resolvehexnodeidprefix(repo, symbol)
614 if node is not None:
614 if node is not None:
615 rev = repo.changelog.rev(node)
615 rev = repo.changelog.rev(node)
616 return repo[rev]
616 return repo[rev]
617
617
618 raise error.RepoLookupError(_("unknown revision '%s'") % symbol)
618 raise error.RepoLookupError(_("unknown revision '%s'") % symbol)
619
619
620 except error.WdirUnsupported:
620 except error.WdirUnsupported:
621 return repo[None]
621 return repo[None]
622 except (error.FilteredIndexError, error.FilteredLookupError,
622 except (error.FilteredIndexError, error.FilteredLookupError,
623 error.FilteredRepoLookupError):
623 error.FilteredRepoLookupError):
624 raise _filterederror(repo, symbol)
624 raise _filterederror(repo, symbol)
625
625
626 def _filterederror(repo, changeid):
626 def _filterederror(repo, changeid):
627 """build an exception to be raised about a filtered changeid
627 """build an exception to be raised about a filtered changeid
628
628
629 This is extracted in a function to help extensions (eg: evolve) to
629 This is extracted in a function to help extensions (eg: evolve) to
630 experiment with various message variants."""
630 experiment with various message variants."""
631 if repo.filtername.startswith('visible'):
631 if repo.filtername.startswith('visible'):
632
632
633 # Check if the changeset is obsolete
633 # Check if the changeset is obsolete
634 unfilteredrepo = repo.unfiltered()
634 unfilteredrepo = repo.unfiltered()
635 ctx = revsymbol(unfilteredrepo, changeid)
635 ctx = revsymbol(unfilteredrepo, changeid)
636
636
637 # If the changeset is obsolete, enrich the message with the reason
637 # If the changeset is obsolete, enrich the message with the reason
638 # that made this changeset not visible
638 # that made this changeset not visible
639 if ctx.obsolete():
639 if ctx.obsolete():
640 msg = obsutil._getfilteredreason(repo, changeid, ctx)
640 msg = obsutil._getfilteredreason(repo, changeid, ctx)
641 else:
641 else:
642 msg = _("hidden revision '%s'") % changeid
642 msg = _("hidden revision '%s'") % changeid
643
643
644 hint = _('use --hidden to access hidden revisions')
644 hint = _('use --hidden to access hidden revisions')
645
645
646 return error.FilteredRepoLookupError(msg, hint=hint)
646 return error.FilteredRepoLookupError(msg, hint=hint)
647 msg = _("filtered revision '%s' (not in '%s' subset)")
647 msg = _("filtered revision '%s' (not in '%s' subset)")
648 msg %= (changeid, repo.filtername)
648 msg %= (changeid, repo.filtername)
649 return error.FilteredRepoLookupError(msg)
649 return error.FilteredRepoLookupError(msg)
650
650
651 def revsingle(repo, revspec, default='.', localalias=None):
651 def revsingle(repo, revspec, default='.', localalias=None):
652 if not revspec and revspec != 0:
652 if not revspec and revspec != 0:
653 return repo[default]
653 return repo[default]
654
654
655 l = revrange(repo, [revspec], localalias=localalias)
655 l = revrange(repo, [revspec], localalias=localalias)
656 if not l:
656 if not l:
657 raise error.Abort(_('empty revision set'))
657 raise error.Abort(_('empty revision set'))
658 return repo[l.last()]
658 return repo[l.last()]
659
659
660 def _pairspec(revspec):
660 def _pairspec(revspec):
661 tree = revsetlang.parse(revspec)
661 tree = revsetlang.parse(revspec)
662 return tree and tree[0] in ('range', 'rangepre', 'rangepost', 'rangeall')
662 return tree and tree[0] in ('range', 'rangepre', 'rangepost', 'rangeall')
663
663
664 def revpair(repo, revs):
664 def revpair(repo, revs):
665 if not revs:
665 if not revs:
666 return repo['.'], repo[None]
666 return repo['.'], repo[None]
667
667
668 l = revrange(repo, revs)
668 l = revrange(repo, revs)
669
669
670 if not l:
670 if not l:
671 raise error.Abort(_('empty revision range'))
671 raise error.Abort(_('empty revision range'))
672
672
673 first = l.first()
673 first = l.first()
674 second = l.last()
674 second = l.last()
675
675
676 if (first == second and len(revs) >= 2
676 if (first == second and len(revs) >= 2
677 and not all(revrange(repo, [r]) for r in revs)):
677 and not all(revrange(repo, [r]) for r in revs)):
678 raise error.Abort(_('empty revision on one side of range'))
678 raise error.Abort(_('empty revision on one side of range'))
679
679
680 # if top-level is range expression, the result must always be a pair
680 # if top-level is range expression, the result must always be a pair
681 if first == second and len(revs) == 1 and not _pairspec(revs[0]):
681 if first == second and len(revs) == 1 and not _pairspec(revs[0]):
682 return repo[first], repo[None]
682 return repo[first], repo[None]
683
683
684 return repo[first], repo[second]
684 return repo[first], repo[second]
685
685
686 def revrange(repo, specs, localalias=None):
686 def revrange(repo, specs, localalias=None):
687 """Execute 1 to many revsets and return the union.
687 """Execute 1 to many revsets and return the union.
688
688
689 This is the preferred mechanism for executing revsets using user-specified
689 This is the preferred mechanism for executing revsets using user-specified
690 config options, such as revset aliases.
690 config options, such as revset aliases.
691
691
692 The revsets specified by ``specs`` will be executed via a chained ``OR``
692 The revsets specified by ``specs`` will be executed via a chained ``OR``
693 expression. If ``specs`` is empty, an empty result is returned.
693 expression. If ``specs`` is empty, an empty result is returned.
694
694
695 ``specs`` can contain integers, in which case they are assumed to be
695 ``specs`` can contain integers, in which case they are assumed to be
696 revision numbers.
696 revision numbers.
697
697
698 It is assumed the revsets are already formatted. If you have arguments
698 It is assumed the revsets are already formatted. If you have arguments
699 that need to be expanded in the revset, call ``revsetlang.formatspec()``
699 that need to be expanded in the revset, call ``revsetlang.formatspec()``
700 and pass the result as an element of ``specs``.
700 and pass the result as an element of ``specs``.
701
701
702 Specifying a single revset is allowed.
702 Specifying a single revset is allowed.
703
703
704 Returns a ``revset.abstractsmartset`` which is a list-like interface over
704 Returns a ``revset.abstractsmartset`` which is a list-like interface over
705 integer revisions.
705 integer revisions.
706 """
706 """
707 allspecs = []
707 allspecs = []
708 for spec in specs:
708 for spec in specs:
709 if isinstance(spec, int):
709 if isinstance(spec, int):
710 spec = revsetlang.formatspec('%d', spec)
710 spec = revsetlang.formatspec('%d', spec)
711 allspecs.append(spec)
711 allspecs.append(spec)
712 return repo.anyrevs(allspecs, user=True, localalias=localalias)
712 return repo.anyrevs(allspecs, user=True, localalias=localalias)
713
713
714 def meaningfulparents(repo, ctx):
714 def meaningfulparents(repo, ctx):
715 """Return list of meaningful (or all if debug) parentrevs for rev.
715 """Return list of meaningful (or all if debug) parentrevs for rev.
716
716
717 For merges (two non-nullrev revisions) both parents are meaningful.
717 For merges (two non-nullrev revisions) both parents are meaningful.
718 Otherwise the first parent revision is considered meaningful if it
718 Otherwise the first parent revision is considered meaningful if it
719 is not the preceding revision.
719 is not the preceding revision.
720 """
720 """
721 parents = ctx.parents()
721 parents = ctx.parents()
722 if len(parents) > 1:
722 if len(parents) > 1:
723 return parents
723 return parents
724 if repo.ui.debugflag:
724 if repo.ui.debugflag:
725 return [parents[0], repo[nullrev]]
725 return [parents[0], repo[nullrev]]
726 if parents[0].rev() >= intrev(ctx) - 1:
726 if parents[0].rev() >= intrev(ctx) - 1:
727 return []
727 return []
728 return parents
728 return parents
729
729
730 def getuipathfn(repo, legacyrelativevalue=False, forcerelativevalue=None):
730 def getuipathfn(repo, legacyrelativevalue=False, forcerelativevalue=None):
731 """Return a function that produced paths for presenting to the user.
731 """Return a function that produced paths for presenting to the user.
732
732
733 The returned function takes a repo-relative path and produces a path
733 The returned function takes a repo-relative path and produces a path
734 that can be presented in the UI.
734 that can be presented in the UI.
735
735
736 Depending on the value of ui.relative-paths, either a repo-relative or
736 Depending on the value of ui.relative-paths, either a repo-relative or
737 cwd-relative path will be produced.
737 cwd-relative path will be produced.
738
738
739 legacyrelativevalue is the value to use if ui.relative-paths=legacy
739 legacyrelativevalue is the value to use if ui.relative-paths=legacy
740
740
741 If forcerelativevalue is not None, then that value will be used regardless
741 If forcerelativevalue is not None, then that value will be used regardless
742 of what ui.relative-paths is set to.
742 of what ui.relative-paths is set to.
743 """
743 """
744 if forcerelativevalue is not None:
744 if forcerelativevalue is not None:
745 relative = forcerelativevalue
745 relative = forcerelativevalue
746 else:
746 else:
747 config = repo.ui.config('ui', 'relative-paths')
747 config = repo.ui.config('ui', 'relative-paths')
748 if config == 'legacy':
748 if config == 'legacy':
749 relative = legacyrelativevalue
749 relative = legacyrelativevalue
750 else:
750 else:
751 relative = stringutil.parsebool(config)
751 relative = stringutil.parsebool(config)
752 if relative is None:
752 if relative is None:
753 raise error.ConfigError(
753 raise error.ConfigError(
754 _("ui.relative-paths is not a boolean ('%s')") % config)
754 _("ui.relative-paths is not a boolean ('%s')") % config)
755
755
756 if relative:
756 if relative:
757 cwd = repo.getcwd()
757 cwd = repo.getcwd()
758 pathto = repo.pathto
758 pathto = repo.pathto
759 return lambda f: pathto(f, cwd)
759 return lambda f: pathto(f, cwd)
760 elif repo.ui.configbool('ui', 'slash'):
760 elif repo.ui.configbool('ui', 'slash'):
761 return lambda f: f
761 return lambda f: f
762 else:
762 else:
763 return util.localpath
763 return util.localpath
764
764
765 def subdiruipathfn(subpath, uipathfn):
765 def subdiruipathfn(subpath, uipathfn):
766 '''Create a new uipathfn that treats the file as relative to subpath.'''
766 '''Create a new uipathfn that treats the file as relative to subpath.'''
767 return lambda f: uipathfn(posixpath.join(subpath, f))
767 return lambda f: uipathfn(posixpath.join(subpath, f))
768
768
769 def anypats(pats, opts):
769 def anypats(pats, opts):
770 '''Checks if any patterns, including --include and --exclude were given.
770 '''Checks if any patterns, including --include and --exclude were given.
771
771
772 Some commands (e.g. addremove) use this condition for deciding whether to
772 Some commands (e.g. addremove) use this condition for deciding whether to
773 print absolute or relative paths.
773 print absolute or relative paths.
774 '''
774 '''
775 return bool(pats or opts.get('include') or opts.get('exclude'))
775 return bool(pats or opts.get('include') or opts.get('exclude'))
776
776
777 def expandpats(pats):
777 def expandpats(pats):
778 '''Expand bare globs when running on windows.
778 '''Expand bare globs when running on windows.
779 On posix we assume it already has already been done by sh.'''
779 On posix we assume it already has already been done by sh.'''
780 if not util.expandglobs:
780 if not util.expandglobs:
781 return list(pats)
781 return list(pats)
782 ret = []
782 ret = []
783 for kindpat in pats:
783 for kindpat in pats:
784 kind, pat = matchmod._patsplit(kindpat, None)
784 kind, pat = matchmod._patsplit(kindpat, None)
785 if kind is None:
785 if kind is None:
786 try:
786 try:
787 globbed = glob.glob(pat)
787 globbed = glob.glob(pat)
788 except re.error:
788 except re.error:
789 globbed = [pat]
789 globbed = [pat]
790 if globbed:
790 if globbed:
791 ret.extend(globbed)
791 ret.extend(globbed)
792 continue
792 continue
793 ret.append(kindpat)
793 ret.append(kindpat)
794 return ret
794 return ret
795
795
796 def matchandpats(ctx, pats=(), opts=None, globbed=False, default='relpath',
796 def matchandpats(ctx, pats=(), opts=None, globbed=False, default='relpath',
797 badfn=None):
797 badfn=None):
798 '''Return a matcher and the patterns that were used.
798 '''Return a matcher and the patterns that were used.
799 The matcher will warn about bad matches, unless an alternate badfn callback
799 The matcher will warn about bad matches, unless an alternate badfn callback
800 is provided.'''
800 is provided.'''
801 if opts is None:
801 if opts is None:
802 opts = {}
802 opts = {}
803 if not globbed and default == 'relpath':
803 if not globbed and default == 'relpath':
804 pats = expandpats(pats or [])
804 pats = expandpats(pats or [])
805
805
806 uipathfn = getuipathfn(ctx.repo(), legacyrelativevalue=True)
806 uipathfn = getuipathfn(ctx.repo(), legacyrelativevalue=True)
807 def bad(f, msg):
807 def bad(f, msg):
808 ctx.repo().ui.warn("%s: %s\n" % (uipathfn(f), msg))
808 ctx.repo().ui.warn("%s: %s\n" % (uipathfn(f), msg))
809
809
810 if badfn is None:
810 if badfn is None:
811 badfn = bad
811 badfn = bad
812
812
813 m = ctx.match(pats, opts.get('include'), opts.get('exclude'),
813 m = ctx.match(pats, opts.get('include'), opts.get('exclude'),
814 default, listsubrepos=opts.get('subrepos'), badfn=badfn)
814 default, listsubrepos=opts.get('subrepos'), badfn=badfn)
815
815
816 if m.always():
816 if m.always():
817 pats = []
817 pats = []
818 return m, pats
818 return m, pats
819
819
820 def match(ctx, pats=(), opts=None, globbed=False, default='relpath',
820 def match(ctx, pats=(), opts=None, globbed=False, default='relpath',
821 badfn=None):
821 badfn=None):
822 '''Return a matcher that will warn about bad matches.'''
822 '''Return a matcher that will warn about bad matches.'''
823 return matchandpats(ctx, pats, opts, globbed, default, badfn=badfn)[0]
823 return matchandpats(ctx, pats, opts, globbed, default, badfn=badfn)[0]
824
824
825 def matchall(repo):
825 def matchall(repo):
826 '''Return a matcher that will efficiently match everything.'''
826 '''Return a matcher that will efficiently match everything.'''
827 return matchmod.always()
827 return matchmod.always()
828
828
829 def matchfiles(repo, files, badfn=None):
829 def matchfiles(repo, files, badfn=None):
830 '''Return a matcher that will efficiently match exactly these files.'''
830 '''Return a matcher that will efficiently match exactly these files.'''
831 return matchmod.exact(files, badfn=badfn)
831 return matchmod.exact(files, badfn=badfn)
832
832
833 def parsefollowlinespattern(repo, rev, pat, msg):
833 def parsefollowlinespattern(repo, rev, pat, msg):
834 """Return a file name from `pat` pattern suitable for usage in followlines
834 """Return a file name from `pat` pattern suitable for usage in followlines
835 logic.
835 logic.
836 """
836 """
837 if not matchmod.patkind(pat):
837 if not matchmod.patkind(pat):
838 return pathutil.canonpath(repo.root, repo.getcwd(), pat)
838 return pathutil.canonpath(repo.root, repo.getcwd(), pat)
839 else:
839 else:
840 ctx = repo[rev]
840 ctx = repo[rev]
841 m = matchmod.match(repo.root, repo.getcwd(), [pat], ctx=ctx)
841 m = matchmod.match(repo.root, repo.getcwd(), [pat], ctx=ctx)
842 files = [f for f in ctx if m(f)]
842 files = [f for f in ctx if m(f)]
843 if len(files) != 1:
843 if len(files) != 1:
844 raise error.ParseError(msg)
844 raise error.ParseError(msg)
845 return files[0]
845 return files[0]
846
846
847 def getorigvfs(ui, repo):
847 def getorigvfs(ui, repo):
848 """return a vfs suitable to save 'orig' file
848 """return a vfs suitable to save 'orig' file
849
849
850 return None if no special directory is configured"""
850 return None if no special directory is configured"""
851 origbackuppath = ui.config('ui', 'origbackuppath')
851 origbackuppath = ui.config('ui', 'origbackuppath')
852 if not origbackuppath:
852 if not origbackuppath:
853 return None
853 return None
854 return vfs.vfs(repo.wvfs.join(origbackuppath))
854 return vfs.vfs(repo.wvfs.join(origbackuppath))
855
855
856 def backuppath(ui, repo, filepath):
856 def backuppath(ui, repo, filepath):
857 '''customize where working copy backup files (.orig files) are created
857 '''customize where working copy backup files (.orig files) are created
858
858
859 Fetch user defined path from config file: [ui] origbackuppath = <path>
859 Fetch user defined path from config file: [ui] origbackuppath = <path>
860 Fall back to default (filepath with .orig suffix) if not specified
860 Fall back to default (filepath with .orig suffix) if not specified
861
861
862 filepath is repo-relative
862 filepath is repo-relative
863
863
864 Returns an absolute path
864 Returns an absolute path
865 '''
865 '''
866 origvfs = getorigvfs(ui, repo)
866 origvfs = getorigvfs(ui, repo)
867 if origvfs is None:
867 if origvfs is None:
868 return repo.wjoin(filepath + ".orig")
868 return repo.wjoin(filepath + ".orig")
869
869
870 origbackupdir = origvfs.dirname(filepath)
870 origbackupdir = origvfs.dirname(filepath)
871 if not origvfs.isdir(origbackupdir) or origvfs.islink(origbackupdir):
871 if not origvfs.isdir(origbackupdir) or origvfs.islink(origbackupdir):
872 ui.note(_('creating directory: %s\n') % origvfs.join(origbackupdir))
872 ui.note(_('creating directory: %s\n') % origvfs.join(origbackupdir))
873
873
874 # Remove any files that conflict with the backup file's path
874 # Remove any files that conflict with the backup file's path
875 for f in reversed(list(util.finddirs(filepath))):
875 for f in reversed(list(util.finddirs(filepath))):
876 if origvfs.isfileorlink(f):
876 if origvfs.isfileorlink(f):
877 ui.note(_('removing conflicting file: %s\n')
877 ui.note(_('removing conflicting file: %s\n')
878 % origvfs.join(f))
878 % origvfs.join(f))
879 origvfs.unlink(f)
879 origvfs.unlink(f)
880 break
880 break
881
881
882 origvfs.makedirs(origbackupdir)
882 origvfs.makedirs(origbackupdir)
883
883
884 if origvfs.isdir(filepath) and not origvfs.islink(filepath):
884 if origvfs.isdir(filepath) and not origvfs.islink(filepath):
885 ui.note(_('removing conflicting directory: %s\n')
885 ui.note(_('removing conflicting directory: %s\n')
886 % origvfs.join(filepath))
886 % origvfs.join(filepath))
887 origvfs.rmtree(filepath, forcibly=True)
887 origvfs.rmtree(filepath, forcibly=True)
888
888
889 return origvfs.join(filepath)
889 return origvfs.join(filepath)
890
890
891 class _containsnode(object):
891 class _containsnode(object):
892 """proxy __contains__(node) to container.__contains__ which accepts revs"""
892 """proxy __contains__(node) to container.__contains__ which accepts revs"""
893
893
894 def __init__(self, repo, revcontainer):
894 def __init__(self, repo, revcontainer):
895 self._torev = repo.changelog.rev
895 self._torev = repo.changelog.rev
896 self._revcontains = revcontainer.__contains__
896 self._revcontains = revcontainer.__contains__
897
897
898 def __contains__(self, node):
898 def __contains__(self, node):
899 return self._revcontains(self._torev(node))
899 return self._revcontains(self._torev(node))
900
900
901 def cleanupnodes(repo, replacements, operation, moves=None, metadata=None,
901 def cleanupnodes(repo, replacements, operation, moves=None, metadata=None,
902 fixphase=False, targetphase=None, backup=True):
902 fixphase=False, targetphase=None, backup=True):
903 """do common cleanups when old nodes are replaced by new nodes
903 """do common cleanups when old nodes are replaced by new nodes
904
904
905 That includes writing obsmarkers or stripping nodes, and moving bookmarks.
905 That includes writing obsmarkers or stripping nodes, and moving bookmarks.
906 (we might also want to move working directory parent in the future)
906 (we might also want to move working directory parent in the future)
907
907
908 By default, bookmark moves are calculated automatically from 'replacements',
908 By default, bookmark moves are calculated automatically from 'replacements',
909 but 'moves' can be used to override that. Also, 'moves' may include
909 but 'moves' can be used to override that. Also, 'moves' may include
910 additional bookmark moves that should not have associated obsmarkers.
910 additional bookmark moves that should not have associated obsmarkers.
911
911
912 replacements is {oldnode: [newnode]} or a iterable of nodes if they do not
912 replacements is {oldnode: [newnode]} or a iterable of nodes if they do not
913 have replacements. operation is a string, like "rebase".
913 have replacements. operation is a string, like "rebase".
914
914
915 metadata is dictionary containing metadata to be stored in obsmarker if
915 metadata is dictionary containing metadata to be stored in obsmarker if
916 obsolescence is enabled.
916 obsolescence is enabled.
917 """
917 """
918 assert fixphase or targetphase is None
918 assert fixphase or targetphase is None
919 if not replacements and not moves:
919 if not replacements and not moves:
920 return
920 return
921
921
922 # translate mapping's other forms
922 # translate mapping's other forms
923 if not util.safehasattr(replacements, 'items'):
923 if not util.safehasattr(replacements, 'items'):
924 replacements = {(n,): () for n in replacements}
924 replacements = {(n,): () for n in replacements}
925 else:
925 else:
926 # upgrading non tuple "source" to tuple ones for BC
926 # upgrading non tuple "source" to tuple ones for BC
927 repls = {}
927 repls = {}
928 for key, value in replacements.items():
928 for key, value in replacements.items():
929 if not isinstance(key, tuple):
929 if not isinstance(key, tuple):
930 key = (key,)
930 key = (key,)
931 repls[key] = value
931 repls[key] = value
932 replacements = repls
932 replacements = repls
933
933
934 # Unfiltered repo is needed since nodes in replacements might be hidden.
934 # Unfiltered repo is needed since nodes in replacements might be hidden.
935 unfi = repo.unfiltered()
935 unfi = repo.unfiltered()
936
936
937 # Calculate bookmark movements
937 # Calculate bookmark movements
938 if moves is None:
938 if moves is None:
939 moves = {}
939 moves = {}
940 for oldnodes, newnodes in replacements.items():
940 for oldnodes, newnodes in replacements.items():
941 for oldnode in oldnodes:
941 for oldnode in oldnodes:
942 if oldnode in moves:
942 if oldnode in moves:
943 continue
943 continue
944 if len(newnodes) > 1:
944 if len(newnodes) > 1:
945 # usually a split, take the one with biggest rev number
945 # usually a split, take the one with biggest rev number
946 newnode = next(unfi.set('max(%ln)', newnodes)).node()
946 newnode = next(unfi.set('max(%ln)', newnodes)).node()
947 elif len(newnodes) == 0:
947 elif len(newnodes) == 0:
948 # move bookmark backwards
948 # move bookmark backwards
949 allreplaced = []
949 allreplaced = []
950 for rep in replacements:
950 for rep in replacements:
951 allreplaced.extend(rep)
951 allreplaced.extend(rep)
952 roots = list(unfi.set('max((::%n) - %ln)', oldnode,
952 roots = list(unfi.set('max((::%n) - %ln)', oldnode,
953 allreplaced))
953 allreplaced))
954 if roots:
954 if roots:
955 newnode = roots[0].node()
955 newnode = roots[0].node()
956 else:
956 else:
957 newnode = nullid
957 newnode = nullid
958 else:
958 else:
959 newnode = newnodes[0]
959 newnode = newnodes[0]
960 moves[oldnode] = newnode
960 moves[oldnode] = newnode
961
961
962 allnewnodes = [n for ns in replacements.values() for n in ns]
962 allnewnodes = [n for ns in replacements.values() for n in ns]
963 toretract = {}
963 toretract = {}
964 toadvance = {}
964 toadvance = {}
965 if fixphase:
965 if fixphase:
966 precursors = {}
966 precursors = {}
967 for oldnodes, newnodes in replacements.items():
967 for oldnodes, newnodes in replacements.items():
968 for oldnode in oldnodes:
968 for oldnode in oldnodes:
969 for newnode in newnodes:
969 for newnode in newnodes:
970 precursors.setdefault(newnode, []).append(oldnode)
970 precursors.setdefault(newnode, []).append(oldnode)
971
971
972 allnewnodes.sort(key=lambda n: unfi[n].rev())
972 allnewnodes.sort(key=lambda n: unfi[n].rev())
973 newphases = {}
973 newphases = {}
974 def phase(ctx):
974 def phase(ctx):
975 return newphases.get(ctx.node(), ctx.phase())
975 return newphases.get(ctx.node(), ctx.phase())
976 for newnode in allnewnodes:
976 for newnode in allnewnodes:
977 ctx = unfi[newnode]
977 ctx = unfi[newnode]
978 parentphase = max(phase(p) for p in ctx.parents())
978 parentphase = max(phase(p) for p in ctx.parents())
979 if targetphase is None:
979 if targetphase is None:
980 oldphase = max(unfi[oldnode].phase()
980 oldphase = max(unfi[oldnode].phase()
981 for oldnode in precursors[newnode])
981 for oldnode in precursors[newnode])
982 newphase = max(oldphase, parentphase)
982 newphase = max(oldphase, parentphase)
983 else:
983 else:
984 newphase = max(targetphase, parentphase)
984 newphase = max(targetphase, parentphase)
985 newphases[newnode] = newphase
985 newphases[newnode] = newphase
986 if newphase > ctx.phase():
986 if newphase > ctx.phase():
987 toretract.setdefault(newphase, []).append(newnode)
987 toretract.setdefault(newphase, []).append(newnode)
988 elif newphase < ctx.phase():
988 elif newphase < ctx.phase():
989 toadvance.setdefault(newphase, []).append(newnode)
989 toadvance.setdefault(newphase, []).append(newnode)
990
990
991 with repo.transaction('cleanup') as tr:
991 with repo.transaction('cleanup') as tr:
992 # Move bookmarks
992 # Move bookmarks
993 bmarks = repo._bookmarks
993 bmarks = repo._bookmarks
994 bmarkchanges = []
994 bmarkchanges = []
995 for oldnode, newnode in moves.items():
995 for oldnode, newnode in moves.items():
996 oldbmarks = repo.nodebookmarks(oldnode)
996 oldbmarks = repo.nodebookmarks(oldnode)
997 if not oldbmarks:
997 if not oldbmarks:
998 continue
998 continue
999 from . import bookmarks # avoid import cycle
999 from . import bookmarks # avoid import cycle
1000 repo.ui.debug('moving bookmarks %r from %s to %s\n' %
1000 repo.ui.debug('moving bookmarks %r from %s to %s\n' %
1001 (pycompat.rapply(pycompat.maybebytestr, oldbmarks),
1001 (pycompat.rapply(pycompat.maybebytestr, oldbmarks),
1002 hex(oldnode), hex(newnode)))
1002 hex(oldnode), hex(newnode)))
1003 # Delete divergent bookmarks being parents of related newnodes
1003 # Delete divergent bookmarks being parents of related newnodes
1004 deleterevs = repo.revs('parents(roots(%ln & (::%n))) - parents(%n)',
1004 deleterevs = repo.revs('parents(roots(%ln & (::%n))) - parents(%n)',
1005 allnewnodes, newnode, oldnode)
1005 allnewnodes, newnode, oldnode)
1006 deletenodes = _containsnode(repo, deleterevs)
1006 deletenodes = _containsnode(repo, deleterevs)
1007 for name in oldbmarks:
1007 for name in oldbmarks:
1008 bmarkchanges.append((name, newnode))
1008 bmarkchanges.append((name, newnode))
1009 for b in bookmarks.divergent2delete(repo, deletenodes, name):
1009 for b in bookmarks.divergent2delete(repo, deletenodes, name):
1010 bmarkchanges.append((b, None))
1010 bmarkchanges.append((b, None))
1011
1011
1012 if bmarkchanges:
1012 if bmarkchanges:
1013 bmarks.applychanges(repo, tr, bmarkchanges)
1013 bmarks.applychanges(repo, tr, bmarkchanges)
1014
1014
1015 for phase, nodes in toretract.items():
1015 for phase, nodes in toretract.items():
1016 phases.retractboundary(repo, tr, phase, nodes)
1016 phases.retractboundary(repo, tr, phase, nodes)
1017 for phase, nodes in toadvance.items():
1017 for phase, nodes in toadvance.items():
1018 phases.advanceboundary(repo, tr, phase, nodes)
1018 phases.advanceboundary(repo, tr, phase, nodes)
1019
1019
1020 mayusearchived = repo.ui.config('experimental', 'cleanup-as-archived')
1020 mayusearchived = repo.ui.config('experimental', 'cleanup-as-archived')
1021 # Obsolete or strip nodes
1021 # Obsolete or strip nodes
1022 if obsolete.isenabled(repo, obsolete.createmarkersopt):
1022 if obsolete.isenabled(repo, obsolete.createmarkersopt):
1023 # If a node is already obsoleted, and we want to obsolete it
1023 # If a node is already obsoleted, and we want to obsolete it
1024 # without a successor, skip that obssolete request since it's
1024 # without a successor, skip that obssolete request since it's
1025 # unnecessary. That's the "if s or not isobs(n)" check below.
1025 # unnecessary. That's the "if s or not isobs(n)" check below.
1026 # Also sort the node in topology order, that might be useful for
1026 # Also sort the node in topology order, that might be useful for
1027 # some obsstore logic.
1027 # some obsstore logic.
1028 # NOTE: the sorting might belong to createmarkers.
1028 # NOTE: the sorting might belong to createmarkers.
1029 torev = unfi.changelog.rev
1029 torev = unfi.changelog.rev
1030 sortfunc = lambda ns: torev(ns[0][0])
1030 sortfunc = lambda ns: torev(ns[0][0])
1031 rels = []
1031 rels = []
1032 for ns, s in sorted(replacements.items(), key=sortfunc):
1032 for ns, s in sorted(replacements.items(), key=sortfunc):
1033 rel = (tuple(unfi[n] for n in ns), tuple(unfi[m] for m in s))
1033 rel = (tuple(unfi[n] for n in ns), tuple(unfi[m] for m in s))
1034 rels.append(rel)
1034 rels.append(rel)
1035 if rels:
1035 if rels:
1036 obsolete.createmarkers(repo, rels, operation=operation,
1036 obsolete.createmarkers(repo, rels, operation=operation,
1037 metadata=metadata)
1037 metadata=metadata)
1038 elif phases.supportinternal(repo) and mayusearchived:
1038 elif phases.supportinternal(repo) and mayusearchived:
1039 # this assume we do not have "unstable" nodes above the cleaned ones
1039 # this assume we do not have "unstable" nodes above the cleaned ones
1040 allreplaced = set()
1040 allreplaced = set()
1041 for ns in replacements.keys():
1041 for ns in replacements.keys():
1042 allreplaced.update(ns)
1042 allreplaced.update(ns)
1043 if backup:
1043 if backup:
1044 from . import repair # avoid import cycle
1044 from . import repair # avoid import cycle
1045 node = min(allreplaced, key=repo.changelog.rev)
1045 node = min(allreplaced, key=repo.changelog.rev)
1046 repair.backupbundle(repo, allreplaced, allreplaced, node,
1046 repair.backupbundle(repo, allreplaced, allreplaced, node,
1047 operation)
1047 operation)
1048 phases.retractboundary(repo, tr, phases.archived, allreplaced)
1048 phases.retractboundary(repo, tr, phases.archived, allreplaced)
1049 else:
1049 else:
1050 from . import repair # avoid import cycle
1050 from . import repair # avoid import cycle
1051 tostrip = list(n for ns in replacements for n in ns)
1051 tostrip = list(n for ns in replacements for n in ns)
1052 if tostrip:
1052 if tostrip:
1053 repair.delayedstrip(repo.ui, repo, tostrip, operation,
1053 repair.delayedstrip(repo.ui, repo, tostrip, operation,
1054 backup=backup)
1054 backup=backup)
1055
1055
1056 def addremove(repo, matcher, prefix, uipathfn, opts=None):
1056 def addremove(repo, matcher, prefix, uipathfn, opts=None):
1057 if opts is None:
1057 if opts is None:
1058 opts = {}
1058 opts = {}
1059 m = matcher
1059 m = matcher
1060 dry_run = opts.get('dry_run')
1060 dry_run = opts.get('dry_run')
1061 try:
1061 try:
1062 similarity = float(opts.get('similarity') or 0)
1062 similarity = float(opts.get('similarity') or 0)
1063 except ValueError:
1063 except ValueError:
1064 raise error.Abort(_('similarity must be a number'))
1064 raise error.Abort(_('similarity must be a number'))
1065 if similarity < 0 or similarity > 100:
1065 if similarity < 0 or similarity > 100:
1066 raise error.Abort(_('similarity must be between 0 and 100'))
1066 raise error.Abort(_('similarity must be between 0 and 100'))
1067 similarity /= 100.0
1067 similarity /= 100.0
1068
1068
1069 ret = 0
1069 ret = 0
1070
1070
1071 wctx = repo[None]
1071 wctx = repo[None]
1072 for subpath in sorted(wctx.substate):
1072 for subpath in sorted(wctx.substate):
1073 submatch = matchmod.subdirmatcher(subpath, m)
1073 submatch = matchmod.subdirmatcher(subpath, m)
1074 if opts.get('subrepos') or m.exact(subpath) or any(submatch.files()):
1074 if opts.get('subrepos') or m.exact(subpath) or any(submatch.files()):
1075 sub = wctx.sub(subpath)
1075 sub = wctx.sub(subpath)
1076 subprefix = repo.wvfs.reljoin(prefix, subpath)
1076 subprefix = repo.wvfs.reljoin(prefix, subpath)
1077 subuipathfn = subdiruipathfn(subpath, uipathfn)
1077 subuipathfn = subdiruipathfn(subpath, uipathfn)
1078 try:
1078 try:
1079 if sub.addremove(submatch, subprefix, subuipathfn, opts):
1079 if sub.addremove(submatch, subprefix, subuipathfn, opts):
1080 ret = 1
1080 ret = 1
1081 except error.LookupError:
1081 except error.LookupError:
1082 repo.ui.status(_("skipping missing subrepository: %s\n")
1082 repo.ui.status(_("skipping missing subrepository: %s\n")
1083 % uipathfn(subpath))
1083 % uipathfn(subpath))
1084
1084
1085 rejected = []
1085 rejected = []
1086 def badfn(f, msg):
1086 def badfn(f, msg):
1087 if f in m.files():
1087 if f in m.files():
1088 m.bad(f, msg)
1088 m.bad(f, msg)
1089 rejected.append(f)
1089 rejected.append(f)
1090
1090
1091 badmatch = matchmod.badmatch(m, badfn)
1091 badmatch = matchmod.badmatch(m, badfn)
1092 added, unknown, deleted, removed, forgotten = _interestingfiles(repo,
1092 added, unknown, deleted, removed, forgotten = _interestingfiles(repo,
1093 badmatch)
1093 badmatch)
1094
1094
1095 unknownset = set(unknown + forgotten)
1095 unknownset = set(unknown + forgotten)
1096 toprint = unknownset.copy()
1096 toprint = unknownset.copy()
1097 toprint.update(deleted)
1097 toprint.update(deleted)
1098 for abs in sorted(toprint):
1098 for abs in sorted(toprint):
1099 if repo.ui.verbose or not m.exact(abs):
1099 if repo.ui.verbose or not m.exact(abs):
1100 if abs in unknownset:
1100 if abs in unknownset:
1101 status = _('adding %s\n') % uipathfn(abs)
1101 status = _('adding %s\n') % uipathfn(abs)
1102 label = 'ui.addremove.added'
1102 label = 'ui.addremove.added'
1103 else:
1103 else:
1104 status = _('removing %s\n') % uipathfn(abs)
1104 status = _('removing %s\n') % uipathfn(abs)
1105 label = 'ui.addremove.removed'
1105 label = 'ui.addremove.removed'
1106 repo.ui.status(status, label=label)
1106 repo.ui.status(status, label=label)
1107
1107
1108 renames = _findrenames(repo, m, added + unknown, removed + deleted,
1108 renames = _findrenames(repo, m, added + unknown, removed + deleted,
1109 similarity, uipathfn)
1109 similarity, uipathfn)
1110
1110
1111 if not dry_run:
1111 if not dry_run:
1112 _markchanges(repo, unknown + forgotten, deleted, renames)
1112 _markchanges(repo, unknown + forgotten, deleted, renames)
1113
1113
1114 for f in rejected:
1114 for f in rejected:
1115 if f in m.files():
1115 if f in m.files():
1116 return 1
1116 return 1
1117 return ret
1117 return ret
1118
1118
1119 def marktouched(repo, files, similarity=0.0):
1119 def marktouched(repo, files, similarity=0.0):
1120 '''Assert that files have somehow been operated upon. files are relative to
1120 '''Assert that files have somehow been operated upon. files are relative to
1121 the repo root.'''
1121 the repo root.'''
1122 m = matchfiles(repo, files, badfn=lambda x, y: rejected.append(x))
1122 m = matchfiles(repo, files, badfn=lambda x, y: rejected.append(x))
1123 rejected = []
1123 rejected = []
1124
1124
1125 added, unknown, deleted, removed, forgotten = _interestingfiles(repo, m)
1125 added, unknown, deleted, removed, forgotten = _interestingfiles(repo, m)
1126
1126
1127 if repo.ui.verbose:
1127 if repo.ui.verbose:
1128 unknownset = set(unknown + forgotten)
1128 unknownset = set(unknown + forgotten)
1129 toprint = unknownset.copy()
1129 toprint = unknownset.copy()
1130 toprint.update(deleted)
1130 toprint.update(deleted)
1131 for abs in sorted(toprint):
1131 for abs in sorted(toprint):
1132 if abs in unknownset:
1132 if abs in unknownset:
1133 status = _('adding %s\n') % abs
1133 status = _('adding %s\n') % abs
1134 else:
1134 else:
1135 status = _('removing %s\n') % abs
1135 status = _('removing %s\n') % abs
1136 repo.ui.status(status)
1136 repo.ui.status(status)
1137
1137
1138 # TODO: We should probably have the caller pass in uipathfn and apply it to
1138 # TODO: We should probably have the caller pass in uipathfn and apply it to
1139 # the messages above too. legacyrelativevalue=True is consistent with how
1139 # the messages above too. legacyrelativevalue=True is consistent with how
1140 # it used to work.
1140 # it used to work.
1141 uipathfn = getuipathfn(repo, legacyrelativevalue=True)
1141 uipathfn = getuipathfn(repo, legacyrelativevalue=True)
1142 renames = _findrenames(repo, m, added + unknown, removed + deleted,
1142 renames = _findrenames(repo, m, added + unknown, removed + deleted,
1143 similarity, uipathfn)
1143 similarity, uipathfn)
1144
1144
1145 _markchanges(repo, unknown + forgotten, deleted, renames)
1145 _markchanges(repo, unknown + forgotten, deleted, renames)
1146
1146
1147 for f in rejected:
1147 for f in rejected:
1148 if f in m.files():
1148 if f in m.files():
1149 return 1
1149 return 1
1150 return 0
1150 return 0
1151
1151
1152 def _interestingfiles(repo, matcher):
1152 def _interestingfiles(repo, matcher):
1153 '''Walk dirstate with matcher, looking for files that addremove would care
1153 '''Walk dirstate with matcher, looking for files that addremove would care
1154 about.
1154 about.
1155
1155
1156 This is different from dirstate.status because it doesn't care about
1156 This is different from dirstate.status because it doesn't care about
1157 whether files are modified or clean.'''
1157 whether files are modified or clean.'''
1158 added, unknown, deleted, removed, forgotten = [], [], [], [], []
1158 added, unknown, deleted, removed, forgotten = [], [], [], [], []
1159 audit_path = pathutil.pathauditor(repo.root, cached=True)
1159 audit_path = pathutil.pathauditor(repo.root, cached=True)
1160
1160
1161 ctx = repo[None]
1161 ctx = repo[None]
1162 dirstate = repo.dirstate
1162 dirstate = repo.dirstate
1163 matcher = repo.narrowmatch(matcher, includeexact=True)
1163 matcher = repo.narrowmatch(matcher, includeexact=True)
1164 walkresults = dirstate.walk(matcher, subrepos=sorted(ctx.substate),
1164 walkresults = dirstate.walk(matcher, subrepos=sorted(ctx.substate),
1165 unknown=True, ignored=False, full=False)
1165 unknown=True, ignored=False, full=False)
1166 for abs, st in walkresults.iteritems():
1166 for abs, st in walkresults.iteritems():
1167 dstate = dirstate[abs]
1167 dstate = dirstate[abs]
1168 if dstate == '?' and audit_path.check(abs):
1168 if dstate == '?' and audit_path.check(abs):
1169 unknown.append(abs)
1169 unknown.append(abs)
1170 elif dstate != 'r' and not st:
1170 elif dstate != 'r' and not st:
1171 deleted.append(abs)
1171 deleted.append(abs)
1172 elif dstate == 'r' and st:
1172 elif dstate == 'r' and st:
1173 forgotten.append(abs)
1173 forgotten.append(abs)
1174 # for finding renames
1174 # for finding renames
1175 elif dstate == 'r' and not st:
1175 elif dstate == 'r' and not st:
1176 removed.append(abs)
1176 removed.append(abs)
1177 elif dstate == 'a':
1177 elif dstate == 'a':
1178 added.append(abs)
1178 added.append(abs)
1179
1179
1180 return added, unknown, deleted, removed, forgotten
1180 return added, unknown, deleted, removed, forgotten
1181
1181
1182 def _findrenames(repo, matcher, added, removed, similarity, uipathfn):
1182 def _findrenames(repo, matcher, added, removed, similarity, uipathfn):
1183 '''Find renames from removed files to added ones.'''
1183 '''Find renames from removed files to added ones.'''
1184 renames = {}
1184 renames = {}
1185 if similarity > 0:
1185 if similarity > 0:
1186 for old, new, score in similar.findrenames(repo, added, removed,
1186 for old, new, score in similar.findrenames(repo, added, removed,
1187 similarity):
1187 similarity):
1188 if (repo.ui.verbose or not matcher.exact(old)
1188 if (repo.ui.verbose or not matcher.exact(old)
1189 or not matcher.exact(new)):
1189 or not matcher.exact(new)):
1190 repo.ui.status(_('recording removal of %s as rename to %s '
1190 repo.ui.status(_('recording removal of %s as rename to %s '
1191 '(%d%% similar)\n') %
1191 '(%d%% similar)\n') %
1192 (uipathfn(old), uipathfn(new),
1192 (uipathfn(old), uipathfn(new),
1193 score * 100))
1193 score * 100))
1194 renames[new] = old
1194 renames[new] = old
1195 return renames
1195 return renames
1196
1196
1197 def _markchanges(repo, unknown, deleted, renames):
1197 def _markchanges(repo, unknown, deleted, renames):
1198 '''Marks the files in unknown as added, the files in deleted as removed,
1198 '''Marks the files in unknown as added, the files in deleted as removed,
1199 and the files in renames as copied.'''
1199 and the files in renames as copied.'''
1200 wctx = repo[None]
1200 wctx = repo[None]
1201 with repo.wlock():
1201 with repo.wlock():
1202 wctx.forget(deleted)
1202 wctx.forget(deleted)
1203 wctx.add(unknown)
1203 wctx.add(unknown)
1204 for new, old in renames.iteritems():
1204 for new, old in renames.iteritems():
1205 wctx.copy(old, new)
1205 wctx.copy(old, new)
1206
1206
1207 def getrenamedfn(repo, endrev=None):
1207 def getrenamedfn(repo, endrev=None):
1208 if copiesmod.usechangesetcentricalgo(repo):
1208 if copiesmod.usechangesetcentricalgo(repo):
1209 def getrenamed(fn, rev):
1209 def getrenamed(fn, rev):
1210 ctx = repo[rev]
1210 ctx = repo[rev]
1211 p1copies = ctx.p1copies()
1211 p1copies = ctx.p1copies()
1212 if fn in p1copies:
1212 if fn in p1copies:
1213 return p1copies[fn]
1213 return p1copies[fn]
1214 p2copies = ctx.p2copies()
1214 p2copies = ctx.p2copies()
1215 if fn in p2copies:
1215 if fn in p2copies:
1216 return p2copies[fn]
1216 return p2copies[fn]
1217 return None
1217 return None
1218 return getrenamed
1218 return getrenamed
1219
1219
1220 rcache = {}
1220 rcache = {}
1221 if endrev is None:
1221 if endrev is None:
1222 endrev = len(repo)
1222 endrev = len(repo)
1223
1223
1224 def getrenamed(fn, rev):
1224 def getrenamed(fn, rev):
1225 '''looks up all renames for a file (up to endrev) the first
1225 '''looks up all renames for a file (up to endrev) the first
1226 time the file is given. It indexes on the changerev and only
1226 time the file is given. It indexes on the changerev and only
1227 parses the manifest if linkrev != changerev.
1227 parses the manifest if linkrev != changerev.
1228 Returns rename info for fn at changerev rev.'''
1228 Returns rename info for fn at changerev rev.'''
1229 if fn not in rcache:
1229 if fn not in rcache:
1230 rcache[fn] = {}
1230 rcache[fn] = {}
1231 fl = repo.file(fn)
1231 fl = repo.file(fn)
1232 for i in fl:
1232 for i in fl:
1233 lr = fl.linkrev(i)
1233 lr = fl.linkrev(i)
1234 renamed = fl.renamed(fl.node(i))
1234 renamed = fl.renamed(fl.node(i))
1235 rcache[fn][lr] = renamed and renamed[0]
1235 rcache[fn][lr] = renamed and renamed[0]
1236 if lr >= endrev:
1236 if lr >= endrev:
1237 break
1237 break
1238 if rev in rcache[fn]:
1238 if rev in rcache[fn]:
1239 return rcache[fn][rev]
1239 return rcache[fn][rev]
1240
1240
1241 # If linkrev != rev (i.e. rev not found in rcache) fallback to
1241 # If linkrev != rev (i.e. rev not found in rcache) fallback to
1242 # filectx logic.
1242 # filectx logic.
1243 try:
1243 try:
1244 return repo[rev][fn].copysource()
1244 return repo[rev][fn].copysource()
1245 except error.LookupError:
1245 except error.LookupError:
1246 return None
1246 return None
1247
1247
1248 return getrenamed
1248 return getrenamed
1249
1249
1250 def getcopiesfn(repo, endrev=None):
1250 def getcopiesfn(repo, endrev=None):
1251 if copiesmod.usechangesetcentricalgo(repo):
1251 if copiesmod.usechangesetcentricalgo(repo):
1252 def copiesfn(ctx):
1252 def copiesfn(ctx):
1253 if ctx.p2copies():
1253 if ctx.p2copies():
1254 allcopies = ctx.p1copies().copy()
1254 allcopies = ctx.p1copies().copy()
1255 # There should be no overlap
1255 # There should be no overlap
1256 allcopies.update(ctx.p2copies())
1256 allcopies.update(ctx.p2copies())
1257 return sorted(allcopies.items())
1257 return sorted(allcopies.items())
1258 else:
1258 else:
1259 return sorted(ctx.p1copies().items())
1259 return sorted(ctx.p1copies().items())
1260 else:
1260 else:
1261 getrenamed = getrenamedfn(repo, endrev)
1261 getrenamed = getrenamedfn(repo, endrev)
1262 def copiesfn(ctx):
1262 def copiesfn(ctx):
1263 copies = []
1263 copies = []
1264 for fn in ctx.files():
1264 for fn in ctx.files():
1265 rename = getrenamed(fn, ctx.rev())
1265 rename = getrenamed(fn, ctx.rev())
1266 if rename:
1266 if rename:
1267 copies.append((fn, rename))
1267 copies.append((fn, rename))
1268 return copies
1268 return copies
1269
1269
1270 return copiesfn
1270 return copiesfn
1271
1271
1272 def dirstatecopy(ui, repo, wctx, src, dst, dryrun=False, cwd=None):
1272 def dirstatecopy(ui, repo, wctx, src, dst, dryrun=False, cwd=None):
1273 """Update the dirstate to reflect the intent of copying src to dst. For
1273 """Update the dirstate to reflect the intent of copying src to dst. For
1274 different reasons it might not end with dst being marked as copied from src.
1274 different reasons it might not end with dst being marked as copied from src.
1275 """
1275 """
1276 origsrc = repo.dirstate.copied(src) or src
1276 origsrc = repo.dirstate.copied(src) or src
1277 if dst == origsrc: # copying back a copy?
1277 if dst == origsrc: # copying back a copy?
1278 if repo.dirstate[dst] not in 'mn' and not dryrun:
1278 if repo.dirstate[dst] not in 'mn' and not dryrun:
1279 repo.dirstate.normallookup(dst)
1279 repo.dirstate.normallookup(dst)
1280 else:
1280 else:
1281 if repo.dirstate[origsrc] == 'a' and origsrc == src:
1281 if repo.dirstate[origsrc] == 'a' and origsrc == src:
1282 if not ui.quiet:
1282 if not ui.quiet:
1283 ui.warn(_("%s has not been committed yet, so no copy "
1283 ui.warn(_("%s has not been committed yet, so no copy "
1284 "data will be stored for %s.\n")
1284 "data will be stored for %s.\n")
1285 % (repo.pathto(origsrc, cwd), repo.pathto(dst, cwd)))
1285 % (repo.pathto(origsrc, cwd), repo.pathto(dst, cwd)))
1286 if repo.dirstate[dst] in '?r' and not dryrun:
1286 if repo.dirstate[dst] in '?r' and not dryrun:
1287 wctx.add([dst])
1287 wctx.add([dst])
1288 elif not dryrun:
1288 elif not dryrun:
1289 wctx.copy(origsrc, dst)
1289 wctx.copy(origsrc, dst)
1290
1290
1291 def movedirstate(repo, newctx, match=None):
1291 def movedirstate(repo, newctx, match=None):
1292 """Move the dirstate to newctx and adjust it as necessary.
1292 """Move the dirstate to newctx and adjust it as necessary.
1293
1293
1294 A matcher can be provided as an optimization. It is probably a bug to pass
1294 A matcher can be provided as an optimization. It is probably a bug to pass
1295 a matcher that doesn't match all the differences between the parent of the
1295 a matcher that doesn't match all the differences between the parent of the
1296 working copy and newctx.
1296 working copy and newctx.
1297 """
1297 """
1298 oldctx = repo['.']
1298 oldctx = repo['.']
1299 ds = repo.dirstate
1299 ds = repo.dirstate
1300 ds.setparents(newctx.node(), nullid)
1300 ds.setparents(newctx.node(), nullid)
1301 copies = dict(ds.copies())
1301 copies = dict(ds.copies())
1302 s = newctx.status(oldctx, match=match)
1302 s = newctx.status(oldctx, match=match)
1303 for f in s.modified:
1303 for f in s.modified:
1304 if ds[f] == 'r':
1304 if ds[f] == 'r':
1305 # modified + removed -> removed
1305 # modified + removed -> removed
1306 continue
1306 continue
1307 ds.normallookup(f)
1307 ds.normallookup(f)
1308
1308
1309 for f in s.added:
1309 for f in s.added:
1310 if ds[f] == 'r':
1310 if ds[f] == 'r':
1311 # added + removed -> unknown
1311 # added + removed -> unknown
1312 ds.drop(f)
1312 ds.drop(f)
1313 elif ds[f] != 'a':
1313 elif ds[f] != 'a':
1314 ds.add(f)
1314 ds.add(f)
1315
1315
1316 for f in s.removed:
1316 for f in s.removed:
1317 if ds[f] == 'a':
1317 if ds[f] == 'a':
1318 # removed + added -> normal
1318 # removed + added -> normal
1319 ds.normallookup(f)
1319 ds.normallookup(f)
1320 elif ds[f] != 'r':
1320 elif ds[f] != 'r':
1321 ds.remove(f)
1321 ds.remove(f)
1322
1322
1323 # Merge old parent and old working dir copies
1323 # Merge old parent and old working dir copies
1324 oldcopies = copiesmod.pathcopies(newctx, oldctx, match)
1324 oldcopies = copiesmod.pathcopies(newctx, oldctx, match)
1325 oldcopies.update(copies)
1325 oldcopies.update(copies)
1326 copies = dict((dst, oldcopies.get(src, src))
1326 copies = dict((dst, oldcopies.get(src, src))
1327 for dst, src in oldcopies.iteritems())
1327 for dst, src in oldcopies.iteritems())
1328 # Adjust the dirstate copies
1328 # Adjust the dirstate copies
1329 for dst, src in copies.iteritems():
1329 for dst, src in copies.iteritems():
1330 if (src not in newctx or dst in newctx or ds[dst] != 'a'):
1330 if (src not in newctx or dst in newctx or ds[dst] != 'a'):
1331 src = None
1331 src = None
1332 ds.copy(src, dst)
1332 ds.copy(src, dst)
1333
1333
1334 def writerequires(opener, requirements):
1334 def writerequires(opener, requirements):
1335 with opener('requires', 'w', atomictemp=True) as fp:
1335 with opener('requires', 'w', atomictemp=True) as fp:
1336 for r in sorted(requirements):
1336 for r in sorted(requirements):
1337 fp.write("%s\n" % r)
1337 fp.write("%s\n" % r)
1338
1338
1339 class filecachesubentry(object):
1339 class filecachesubentry(object):
1340 def __init__(self, path, stat):
1340 def __init__(self, path, stat):
1341 self.path = path
1341 self.path = path
1342 self.cachestat = None
1342 self.cachestat = None
1343 self._cacheable = None
1343 self._cacheable = None
1344
1344
1345 if stat:
1345 if stat:
1346 self.cachestat = filecachesubentry.stat(self.path)
1346 self.cachestat = filecachesubentry.stat(self.path)
1347
1347
1348 if self.cachestat:
1348 if self.cachestat:
1349 self._cacheable = self.cachestat.cacheable()
1349 self._cacheable = self.cachestat.cacheable()
1350 else:
1350 else:
1351 # None means we don't know yet
1351 # None means we don't know yet
1352 self._cacheable = None
1352 self._cacheable = None
1353
1353
1354 def refresh(self):
1354 def refresh(self):
1355 if self.cacheable():
1355 if self.cacheable():
1356 self.cachestat = filecachesubentry.stat(self.path)
1356 self.cachestat = filecachesubentry.stat(self.path)
1357
1357
1358 def cacheable(self):
1358 def cacheable(self):
1359 if self._cacheable is not None:
1359 if self._cacheable is not None:
1360 return self._cacheable
1360 return self._cacheable
1361
1361
1362 # we don't know yet, assume it is for now
1362 # we don't know yet, assume it is for now
1363 return True
1363 return True
1364
1364
1365 def changed(self):
1365 def changed(self):
1366 # no point in going further if we can't cache it
1366 # no point in going further if we can't cache it
1367 if not self.cacheable():
1367 if not self.cacheable():
1368 return True
1368 return True
1369
1369
1370 newstat = filecachesubentry.stat(self.path)
1370 newstat = filecachesubentry.stat(self.path)
1371
1371
1372 # we may not know if it's cacheable yet, check again now
1372 # we may not know if it's cacheable yet, check again now
1373 if newstat and self._cacheable is None:
1373 if newstat and self._cacheable is None:
1374 self._cacheable = newstat.cacheable()
1374 self._cacheable = newstat.cacheable()
1375
1375
1376 # check again
1376 # check again
1377 if not self._cacheable:
1377 if not self._cacheable:
1378 return True
1378 return True
1379
1379
1380 if self.cachestat != newstat:
1380 if self.cachestat != newstat:
1381 self.cachestat = newstat
1381 self.cachestat = newstat
1382 return True
1382 return True
1383 else:
1383 else:
1384 return False
1384 return False
1385
1385
1386 @staticmethod
1386 @staticmethod
1387 def stat(path):
1387 def stat(path):
1388 try:
1388 try:
1389 return util.cachestat(path)
1389 return util.cachestat(path)
1390 except OSError as e:
1390 except OSError as e:
1391 if e.errno != errno.ENOENT:
1391 if e.errno != errno.ENOENT:
1392 raise
1392 raise
1393
1393
1394 class filecacheentry(object):
1394 class filecacheentry(object):
1395 def __init__(self, paths, stat=True):
1395 def __init__(self, paths, stat=True):
1396 self._entries = []
1396 self._entries = []
1397 for path in paths:
1397 for path in paths:
1398 self._entries.append(filecachesubentry(path, stat))
1398 self._entries.append(filecachesubentry(path, stat))
1399
1399
1400 def changed(self):
1400 def changed(self):
1401 '''true if any entry has changed'''
1401 '''true if any entry has changed'''
1402 for entry in self._entries:
1402 for entry in self._entries:
1403 if entry.changed():
1403 if entry.changed():
1404 return True
1404 return True
1405 return False
1405 return False
1406
1406
1407 def refresh(self):
1407 def refresh(self):
1408 for entry in self._entries:
1408 for entry in self._entries:
1409 entry.refresh()
1409 entry.refresh()
1410
1410
1411 class filecache(object):
1411 class filecache(object):
1412 """A property like decorator that tracks files under .hg/ for updates.
1412 """A property like decorator that tracks files under .hg/ for updates.
1413
1413
1414 On first access, the files defined as arguments are stat()ed and the
1414 On first access, the files defined as arguments are stat()ed and the
1415 results cached. The decorated function is called. The results are stashed
1415 results cached. The decorated function is called. The results are stashed
1416 away in a ``_filecache`` dict on the object whose method is decorated.
1416 away in a ``_filecache`` dict on the object whose method is decorated.
1417
1417
1418 On subsequent access, the cached result is used as it is set to the
1418 On subsequent access, the cached result is used as it is set to the
1419 instance dictionary.
1419 instance dictionary.
1420
1420
1421 On external property set/delete operations, the caller must update the
1421 On external property set/delete operations, the caller must update the
1422 corresponding _filecache entry appropriately. Use __class__.<attr>.set()
1422 corresponding _filecache entry appropriately. Use __class__.<attr>.set()
1423 instead of directly setting <attr>.
1423 instead of directly setting <attr>.
1424
1424
1425 When using the property API, the cached data is always used if available.
1425 When using the property API, the cached data is always used if available.
1426 No stat() is performed to check if the file has changed.
1426 No stat() is performed to check if the file has changed.
1427
1427
1428 Others can muck about with the state of the ``_filecache`` dict. e.g. they
1428 Others can muck about with the state of the ``_filecache`` dict. e.g. they
1429 can populate an entry before the property's getter is called. In this case,
1429 can populate an entry before the property's getter is called. In this case,
1430 entries in ``_filecache`` will be used during property operations,
1430 entries in ``_filecache`` will be used during property operations,
1431 if available. If the underlying file changes, it is up to external callers
1431 if available. If the underlying file changes, it is up to external callers
1432 to reflect this by e.g. calling ``delattr(obj, attr)`` to remove the cached
1432 to reflect this by e.g. calling ``delattr(obj, attr)`` to remove the cached
1433 method result as well as possibly calling ``del obj._filecache[attr]`` to
1433 method result as well as possibly calling ``del obj._filecache[attr]`` to
1434 remove the ``filecacheentry``.
1434 remove the ``filecacheentry``.
1435 """
1435 """
1436
1436
1437 def __init__(self, *paths):
1437 def __init__(self, *paths):
1438 self.paths = paths
1438 self.paths = paths
1439
1439
1440 def join(self, obj, fname):
1440 def join(self, obj, fname):
1441 """Used to compute the runtime path of a cached file.
1441 """Used to compute the runtime path of a cached file.
1442
1442
1443 Users should subclass filecache and provide their own version of this
1443 Users should subclass filecache and provide their own version of this
1444 function to call the appropriate join function on 'obj' (an instance
1444 function to call the appropriate join function on 'obj' (an instance
1445 of the class that its member function was decorated).
1445 of the class that its member function was decorated).
1446 """
1446 """
1447 raise NotImplementedError
1447 raise NotImplementedError
1448
1448
1449 def __call__(self, func):
1449 def __call__(self, func):
1450 self.func = func
1450 self.func = func
1451 self.sname = func.__name__
1451 self.sname = func.__name__
1452 self.name = pycompat.sysbytes(self.sname)
1452 self.name = pycompat.sysbytes(self.sname)
1453 return self
1453 return self
1454
1454
1455 def __get__(self, obj, type=None):
1455 def __get__(self, obj, type=None):
1456 # if accessed on the class, return the descriptor itself.
1456 # if accessed on the class, return the descriptor itself.
1457 if obj is None:
1457 if obj is None:
1458 return self
1458 return self
1459
1459
1460 assert self.sname not in obj.__dict__
1460 assert self.sname not in obj.__dict__
1461
1461
1462 entry = obj._filecache.get(self.name)
1462 entry = obj._filecache.get(self.name)
1463
1463
1464 if entry:
1464 if entry:
1465 if entry.changed():
1465 if entry.changed():
1466 entry.obj = self.func(obj)
1466 entry.obj = self.func(obj)
1467 else:
1467 else:
1468 paths = [self.join(obj, path) for path in self.paths]
1468 paths = [self.join(obj, path) for path in self.paths]
1469
1469
1470 # We stat -before- creating the object so our cache doesn't lie if
1470 # We stat -before- creating the object so our cache doesn't lie if
1471 # a writer modified between the time we read and stat
1471 # a writer modified between the time we read and stat
1472 entry = filecacheentry(paths, True)
1472 entry = filecacheentry(paths, True)
1473 entry.obj = self.func(obj)
1473 entry.obj = self.func(obj)
1474
1474
1475 obj._filecache[self.name] = entry
1475 obj._filecache[self.name] = entry
1476
1476
1477 obj.__dict__[self.sname] = entry.obj
1477 obj.__dict__[self.sname] = entry.obj
1478 return entry.obj
1478 return entry.obj
1479
1479
1480 # don't implement __set__(), which would make __dict__ lookup as slow as
1480 # don't implement __set__(), which would make __dict__ lookup as slow as
1481 # function call.
1481 # function call.
1482
1482
1483 def set(self, obj, value):
1483 def set(self, obj, value):
1484 if self.name not in obj._filecache:
1484 if self.name not in obj._filecache:
1485 # we add an entry for the missing value because X in __dict__
1485 # we add an entry for the missing value because X in __dict__
1486 # implies X in _filecache
1486 # implies X in _filecache
1487 paths = [self.join(obj, path) for path in self.paths]
1487 paths = [self.join(obj, path) for path in self.paths]
1488 ce = filecacheentry(paths, False)
1488 ce = filecacheentry(paths, False)
1489 obj._filecache[self.name] = ce
1489 obj._filecache[self.name] = ce
1490 else:
1490 else:
1491 ce = obj._filecache[self.name]
1491 ce = obj._filecache[self.name]
1492
1492
1493 ce.obj = value # update cached copy
1493 ce.obj = value # update cached copy
1494 obj.__dict__[self.sname] = value # update copy returned by obj.x
1494 obj.__dict__[self.sname] = value # update copy returned by obj.x
1495
1495
1496 def extdatasource(repo, source):
1496 def extdatasource(repo, source):
1497 """Gather a map of rev -> value dict from the specified source
1497 """Gather a map of rev -> value dict from the specified source
1498
1498
1499 A source spec is treated as a URL, with a special case shell: type
1499 A source spec is treated as a URL, with a special case shell: type
1500 for parsing the output from a shell command.
1500 for parsing the output from a shell command.
1501
1501
1502 The data is parsed as a series of newline-separated records where
1502 The data is parsed as a series of newline-separated records where
1503 each record is a revision specifier optionally followed by a space
1503 each record is a revision specifier optionally followed by a space
1504 and a freeform string value. If the revision is known locally, it
1504 and a freeform string value. If the revision is known locally, it
1505 is converted to a rev, otherwise the record is skipped.
1505 is converted to a rev, otherwise the record is skipped.
1506
1506
1507 Note that both key and value are treated as UTF-8 and converted to
1507 Note that both key and value are treated as UTF-8 and converted to
1508 the local encoding. This allows uniformity between local and
1508 the local encoding. This allows uniformity between local and
1509 remote data sources.
1509 remote data sources.
1510 """
1510 """
1511
1511
1512 spec = repo.ui.config("extdata", source)
1512 spec = repo.ui.config("extdata", source)
1513 if not spec:
1513 if not spec:
1514 raise error.Abort(_("unknown extdata source '%s'") % source)
1514 raise error.Abort(_("unknown extdata source '%s'") % source)
1515
1515
1516 data = {}
1516 data = {}
1517 src = proc = None
1517 src = proc = None
1518 try:
1518 try:
1519 if spec.startswith("shell:"):
1519 if spec.startswith("shell:"):
1520 # external commands should be run relative to the repo root
1520 # external commands should be run relative to the repo root
1521 cmd = spec[6:]
1521 cmd = spec[6:]
1522 proc = subprocess.Popen(procutil.tonativestr(cmd),
1522 proc = subprocess.Popen(procutil.tonativestr(cmd),
1523 shell=True, bufsize=-1,
1523 shell=True, bufsize=-1,
1524 close_fds=procutil.closefds,
1524 close_fds=procutil.closefds,
1525 stdout=subprocess.PIPE,
1525 stdout=subprocess.PIPE,
1526 cwd=procutil.tonativestr(repo.root))
1526 cwd=procutil.tonativestr(repo.root))
1527 src = proc.stdout
1527 src = proc.stdout
1528 else:
1528 else:
1529 # treat as a URL or file
1529 # treat as a URL or file
1530 src = url.open(repo.ui, spec)
1530 src = url.open(repo.ui, spec)
1531 for l in src:
1531 for l in src:
1532 if " " in l:
1532 if " " in l:
1533 k, v = l.strip().split(" ", 1)
1533 k, v = l.strip().split(" ", 1)
1534 else:
1534 else:
1535 k, v = l.strip(), ""
1535 k, v = l.strip(), ""
1536
1536
1537 k = encoding.tolocal(k)
1537 k = encoding.tolocal(k)
1538 try:
1538 try:
1539 data[revsingle(repo, k).rev()] = encoding.tolocal(v)
1539 data[revsingle(repo, k).rev()] = encoding.tolocal(v)
1540 except (error.LookupError, error.RepoLookupError):
1540 except (error.LookupError, error.RepoLookupError):
1541 pass # we ignore data for nodes that don't exist locally
1541 pass # we ignore data for nodes that don't exist locally
1542 finally:
1542 finally:
1543 if proc:
1543 if proc:
1544 try:
1544 try:
1545 proc.communicate()
1545 proc.communicate()
1546 except ValueError:
1546 except ValueError:
1547 # This happens if we started iterating src and then
1547 # This happens if we started iterating src and then
1548 # get a parse error on a line. It should be safe to ignore.
1548 # get a parse error on a line. It should be safe to ignore.
1549 pass
1549 pass
1550 if src:
1550 if src:
1551 src.close()
1551 src.close()
1552 if proc and proc.returncode != 0:
1552 if proc and proc.returncode != 0:
1553 raise error.Abort(_("extdata command '%s' failed: %s")
1553 raise error.Abort(_("extdata command '%s' failed: %s")
1554 % (cmd, procutil.explainexit(proc.returncode)))
1554 % (cmd, procutil.explainexit(proc.returncode)))
1555
1555
1556 return data
1556 return data
1557
1557
1558 def _locksub(repo, lock, envvar, cmd, environ=None, *args, **kwargs):
1558 def _locksub(repo, lock, envvar, cmd, environ=None, *args, **kwargs):
1559 if lock is None:
1559 if lock is None:
1560 raise error.LockInheritanceContractViolation(
1560 raise error.LockInheritanceContractViolation(
1561 'lock can only be inherited while held')
1561 'lock can only be inherited while held')
1562 if environ is None:
1562 if environ is None:
1563 environ = {}
1563 environ = {}
1564 with lock.inherit() as locker:
1564 with lock.inherit() as locker:
1565 environ[envvar] = locker
1565 environ[envvar] = locker
1566 return repo.ui.system(cmd, environ=environ, *args, **kwargs)
1566 return repo.ui.system(cmd, environ=environ, *args, **kwargs)
1567
1567
1568 def wlocksub(repo, cmd, *args, **kwargs):
1568 def wlocksub(repo, cmd, *args, **kwargs):
1569 """run cmd as a subprocess that allows inheriting repo's wlock
1569 """run cmd as a subprocess that allows inheriting repo's wlock
1570
1570
1571 This can only be called while the wlock is held. This takes all the
1571 This can only be called while the wlock is held. This takes all the
1572 arguments that ui.system does, and returns the exit code of the
1572 arguments that ui.system does, and returns the exit code of the
1573 subprocess."""
1573 subprocess."""
1574 return _locksub(repo, repo.currentwlock(), 'HG_WLOCK_LOCKER', cmd, *args,
1574 return _locksub(repo, repo.currentwlock(), 'HG_WLOCK_LOCKER', cmd, *args,
1575 **kwargs)
1575 **kwargs)
1576
1576
1577 class progress(object):
1577 class progress(object):
1578 def __init__(self, ui, updatebar, topic, unit="", total=None):
1578 def __init__(self, ui, updatebar, topic, unit="", total=None):
1579 self.ui = ui
1579 self.ui = ui
1580 self.pos = 0
1580 self.pos = 0
1581 self.topic = topic
1581 self.topic = topic
1582 self.unit = unit
1582 self.unit = unit
1583 self.total = total
1583 self.total = total
1584 self.debug = ui.configbool('progress', 'debug')
1584 self.debug = ui.configbool('progress', 'debug')
1585 self._updatebar = updatebar
1585 self._updatebar = updatebar
1586
1586
1587 def __enter__(self):
1587 def __enter__(self):
1588 return self
1588 return self
1589
1589
1590 def __exit__(self, exc_type, exc_value, exc_tb):
1590 def __exit__(self, exc_type, exc_value, exc_tb):
1591 self.complete()
1591 self.complete()
1592
1592
1593 def update(self, pos, item="", total=None):
1593 def update(self, pos, item="", total=None):
1594 assert pos is not None
1594 assert pos is not None
1595 if total:
1595 if total:
1596 self.total = total
1596 self.total = total
1597 self.pos = pos
1597 self.pos = pos
1598 self._updatebar(self.topic, self.pos, item, self.unit, self.total)
1598 self._updatebar(self.topic, self.pos, item, self.unit, self.total)
1599 if self.debug:
1599 if self.debug:
1600 self._printdebug(item)
1600 self._printdebug(item)
1601
1601
1602 def increment(self, step=1, item="", total=None):
1602 def increment(self, step=1, item="", total=None):
1603 self.update(self.pos + step, item, total)
1603 self.update(self.pos + step, item, total)
1604
1604
1605 def complete(self):
1605 def complete(self):
1606 self.pos = None
1606 self.pos = None
1607 self.unit = ""
1607 self.unit = ""
1608 self.total = None
1608 self.total = None
1609 self._updatebar(self.topic, self.pos, "", self.unit, self.total)
1609 self._updatebar(self.topic, self.pos, "", self.unit, self.total)
1610
1610
1611 def _printdebug(self, item):
1611 def _printdebug(self, item):
1612 if self.unit:
1612 if self.unit:
1613 unit = ' ' + self.unit
1613 unit = ' ' + self.unit
1614 if item:
1614 if item:
1615 item = ' ' + item
1615 item = ' ' + item
1616
1616
1617 if self.total:
1617 if self.total:
1618 pct = 100.0 * self.pos / self.total
1618 pct = 100.0 * self.pos / self.total
1619 self.ui.debug('%s:%s %d/%d%s (%4.2f%%)\n'
1619 self.ui.debug('%s:%s %d/%d%s (%4.2f%%)\n'
1620 % (self.topic, item, self.pos, self.total, unit, pct))
1620 % (self.topic, item, self.pos, self.total, unit, pct))
1621 else:
1621 else:
1622 self.ui.debug('%s:%s %d%s\n' % (self.topic, item, self.pos, unit))
1622 self.ui.debug('%s:%s %d%s\n' % (self.topic, item, self.pos, unit))
1623
1623
1624 def gdinitconfig(ui):
1624 def gdinitconfig(ui):
1625 """helper function to know if a repo should be created as general delta
1625 """helper function to know if a repo should be created as general delta
1626 """
1626 """
1627 # experimental config: format.generaldelta
1627 # experimental config: format.generaldelta
1628 return (ui.configbool('format', 'generaldelta')
1628 return (ui.configbool('format', 'generaldelta')
1629 or ui.configbool('format', 'usegeneraldelta'))
1629 or ui.configbool('format', 'usegeneraldelta'))
1630
1630
1631 def gddeltaconfig(ui):
1631 def gddeltaconfig(ui):
1632 """helper function to know if incoming delta should be optimised
1632 """helper function to know if incoming delta should be optimised
1633 """
1633 """
1634 # experimental config: format.generaldelta
1634 # experimental config: format.generaldelta
1635 return ui.configbool('format', 'generaldelta')
1635 return ui.configbool('format', 'generaldelta')
1636
1636
1637 class simplekeyvaluefile(object):
1637 class simplekeyvaluefile(object):
1638 """A simple file with key=value lines
1638 """A simple file with key=value lines
1639
1639
1640 Keys must be alphanumerics and start with a letter, values must not
1640 Keys must be alphanumerics and start with a letter, values must not
1641 contain '\n' characters"""
1641 contain '\n' characters"""
1642 firstlinekey = '__firstline'
1642 firstlinekey = '__firstline'
1643
1643
1644 def __init__(self, vfs, path, keys=None):
1644 def __init__(self, vfs, path, keys=None):
1645 self.vfs = vfs
1645 self.vfs = vfs
1646 self.path = path
1646 self.path = path
1647
1647
1648 def read(self, firstlinenonkeyval=False):
1648 def read(self, firstlinenonkeyval=False):
1649 """Read the contents of a simple key-value file
1649 """Read the contents of a simple key-value file
1650
1650
1651 'firstlinenonkeyval' indicates whether the first line of file should
1651 'firstlinenonkeyval' indicates whether the first line of file should
1652 be treated as a key-value pair or reuturned fully under the
1652 be treated as a key-value pair or reuturned fully under the
1653 __firstline key."""
1653 __firstline key."""
1654 lines = self.vfs.readlines(self.path)
1654 lines = self.vfs.readlines(self.path)
1655 d = {}
1655 d = {}
1656 if firstlinenonkeyval:
1656 if firstlinenonkeyval:
1657 if not lines:
1657 if not lines:
1658 e = _("empty simplekeyvalue file")
1658 e = _("empty simplekeyvalue file")
1659 raise error.CorruptedState(e)
1659 raise error.CorruptedState(e)
1660 # we don't want to include '\n' in the __firstline
1660 # we don't want to include '\n' in the __firstline
1661 d[self.firstlinekey] = lines[0][:-1]
1661 d[self.firstlinekey] = lines[0][:-1]
1662 del lines[0]
1662 del lines[0]
1663
1663
1664 try:
1664 try:
1665 # the 'if line.strip()' part prevents us from failing on empty
1665 # the 'if line.strip()' part prevents us from failing on empty
1666 # lines which only contain '\n' therefore are not skipped
1666 # lines which only contain '\n' therefore are not skipped
1667 # by 'if line'
1667 # by 'if line'
1668 updatedict = dict(line[:-1].split('=', 1) for line in lines
1668 updatedict = dict(line[:-1].split('=', 1) for line in lines
1669 if line.strip())
1669 if line.strip())
1670 if self.firstlinekey in updatedict:
1670 if self.firstlinekey in updatedict:
1671 e = _("%r can't be used as a key")
1671 e = _("%r can't be used as a key")
1672 raise error.CorruptedState(e % self.firstlinekey)
1672 raise error.CorruptedState(e % self.firstlinekey)
1673 d.update(updatedict)
1673 d.update(updatedict)
1674 except ValueError as e:
1674 except ValueError as e:
1675 raise error.CorruptedState(str(e))
1675 raise error.CorruptedState(str(e))
1676 return d
1676 return d
1677
1677
1678 def write(self, data, firstline=None):
1678 def write(self, data, firstline=None):
1679 """Write key=>value mapping to a file
1679 """Write key=>value mapping to a file
1680 data is a dict. Keys must be alphanumerical and start with a letter.
1680 data is a dict. Keys must be alphanumerical and start with a letter.
1681 Values must not contain newline characters.
1681 Values must not contain newline characters.
1682
1682
1683 If 'firstline' is not None, it is written to file before
1683 If 'firstline' is not None, it is written to file before
1684 everything else, as it is, not in a key=value form"""
1684 everything else, as it is, not in a key=value form"""
1685 lines = []
1685 lines = []
1686 if firstline is not None:
1686 if firstline is not None:
1687 lines.append('%s\n' % firstline)
1687 lines.append('%s\n' % firstline)
1688
1688
1689 for k, v in data.items():
1689 for k, v in data.items():
1690 if k == self.firstlinekey:
1690 if k == self.firstlinekey:
1691 e = "key name '%s' is reserved" % self.firstlinekey
1691 e = "key name '%s' is reserved" % self.firstlinekey
1692 raise error.ProgrammingError(e)
1692 raise error.ProgrammingError(e)
1693 if not k[0:1].isalpha():
1693 if not k[0:1].isalpha():
1694 e = "keys must start with a letter in a key-value file"
1694 e = "keys must start with a letter in a key-value file"
1695 raise error.ProgrammingError(e)
1695 raise error.ProgrammingError(e)
1696 if not k.isalnum():
1696 if not k.isalnum():
1697 e = "invalid key name in a simple key-value file"
1697 e = "invalid key name in a simple key-value file"
1698 raise error.ProgrammingError(e)
1698 raise error.ProgrammingError(e)
1699 if '\n' in v:
1699 if '\n' in v:
1700 e = "invalid value in a simple key-value file"
1700 e = "invalid value in a simple key-value file"
1701 raise error.ProgrammingError(e)
1701 raise error.ProgrammingError(e)
1702 lines.append("%s=%s\n" % (k, v))
1702 lines.append("%s=%s\n" % (k, v))
1703 with self.vfs(self.path, mode='wb', atomictemp=True) as fp:
1703 with self.vfs(self.path, mode='wb', atomictemp=True) as fp:
1704 fp.write(''.join(lines))
1704 fp.write(''.join(lines))
1705
1705
1706 _reportobsoletedsource = [
1706 _reportobsoletedsource = [
1707 'debugobsolete',
1707 'debugobsolete',
1708 'pull',
1708 'pull',
1709 'push',
1709 'push',
1710 'serve',
1710 'serve',
1711 'unbundle',
1711 'unbundle',
1712 ]
1712 ]
1713
1713
1714 _reportnewcssource = [
1714 _reportnewcssource = [
1715 'pull',
1715 'pull',
1716 'unbundle',
1716 'unbundle',
1717 ]
1717 ]
1718
1718
1719 def prefetchfiles(repo, revs, match):
1719 def prefetchfiles(repo, revs, match):
1720 """Invokes the registered file prefetch functions, allowing extensions to
1720 """Invokes the registered file prefetch functions, allowing extensions to
1721 ensure the corresponding files are available locally, before the command
1721 ensure the corresponding files are available locally, before the command
1722 uses them."""
1722 uses them."""
1723 if match:
1723 if match:
1724 # The command itself will complain about files that don't exist, so
1724 # The command itself will complain about files that don't exist, so
1725 # don't duplicate the message.
1725 # don't duplicate the message.
1726 match = matchmod.badmatch(match, lambda fn, msg: None)
1726 match = matchmod.badmatch(match, lambda fn, msg: None)
1727 else:
1727 else:
1728 match = matchall(repo)
1728 match = matchall(repo)
1729
1729
1730 fileprefetchhooks(repo, revs, match)
1730 fileprefetchhooks(repo, revs, match)
1731
1731
1732 # a list of (repo, revs, match) prefetch functions
1732 # a list of (repo, revs, match) prefetch functions
1733 fileprefetchhooks = util.hooks()
1733 fileprefetchhooks = util.hooks()
1734
1734
1735 # A marker that tells the evolve extension to suppress its own reporting
1735 # A marker that tells the evolve extension to suppress its own reporting
1736 _reportstroubledchangesets = True
1736 _reportstroubledchangesets = True
1737
1737
1738 def registersummarycallback(repo, otr, txnname=''):
1738 def registersummarycallback(repo, otr, txnname=''):
1739 """register a callback to issue a summary after the transaction is closed
1739 """register a callback to issue a summary after the transaction is closed
1740 """
1740 """
1741 def txmatch(sources):
1741 def txmatch(sources):
1742 return any(txnname.startswith(source) for source in sources)
1742 return any(txnname.startswith(source) for source in sources)
1743
1743
1744 categories = []
1744 categories = []
1745
1745
1746 def reportsummary(func):
1746 def reportsummary(func):
1747 """decorator for report callbacks."""
1747 """decorator for report callbacks."""
1748 # The repoview life cycle is shorter than the one of the actual
1748 # The repoview life cycle is shorter than the one of the actual
1749 # underlying repository. So the filtered object can die before the
1749 # underlying repository. So the filtered object can die before the
1750 # weakref is used leading to troubles. We keep a reference to the
1750 # weakref is used leading to troubles. We keep a reference to the
1751 # unfiltered object and restore the filtering when retrieving the
1751 # unfiltered object and restore the filtering when retrieving the
1752 # repository through the weakref.
1752 # repository through the weakref.
1753 filtername = repo.filtername
1753 filtername = repo.filtername
1754 reporef = weakref.ref(repo.unfiltered())
1754 reporef = weakref.ref(repo.unfiltered())
1755 def wrapped(tr):
1755 def wrapped(tr):
1756 repo = reporef()
1756 repo = reporef()
1757 if filtername:
1757 if filtername:
1758 repo = repo.filtered(filtername)
1758 repo = repo.filtered(filtername)
1759 func(repo, tr)
1759 func(repo, tr)
1760 newcat = '%02i-txnreport' % len(categories)
1760 newcat = '%02i-txnreport' % len(categories)
1761 otr.addpostclose(newcat, wrapped)
1761 otr.addpostclose(newcat, wrapped)
1762 categories.append(newcat)
1762 categories.append(newcat)
1763 return wrapped
1763 return wrapped
1764
1764
1765
1766 @reportsummary
1767 def reportchangegroup(repo, tr):
1768 cgchangesets = tr.changes.get('changegroup-count-changesets', 0)
1769 cgrevisions = tr.changes.get('changegroup-count-revisions', 0)
1770 cgfiles = tr.changes.get('changegroup-count-files', 0)
1771 cgheads = tr.changes.get('changegroup-count-heads', 0)
1772 if cgchangesets or cgrevisions or cgfiles:
1773 htext = ""
1774 if cgheads:
1775 htext = _(" (%+d heads)") % cgheads
1776 msg = _("added %d changesets with %d changes to %d files%s\n")
1777 repo.ui.status(msg % (cgchangesets, cgrevisions, cgfiles, htext))
1778
1765 if txmatch(_reportobsoletedsource):
1779 if txmatch(_reportobsoletedsource):
1766 @reportsummary
1780 @reportsummary
1767 def reportobsoleted(repo, tr):
1781 def reportobsoleted(repo, tr):
1768 obsoleted = obsutil.getobsoleted(repo, tr)
1782 obsoleted = obsutil.getobsoleted(repo, tr)
1769 newmarkers = len(tr.changes.get('obsmarkers', ()))
1783 newmarkers = len(tr.changes.get('obsmarkers', ()))
1770 if newmarkers:
1784 if newmarkers:
1771 repo.ui.status(_('%i new obsolescence markers\n') % newmarkers)
1785 repo.ui.status(_('%i new obsolescence markers\n') % newmarkers)
1772 if obsoleted:
1786 if obsoleted:
1773 repo.ui.status(_('obsoleted %i changesets\n')
1787 repo.ui.status(_('obsoleted %i changesets\n')
1774 % len(obsoleted))
1788 % len(obsoleted))
1775
1789
1776 if (obsolete.isenabled(repo, obsolete.createmarkersopt) and
1790 if (obsolete.isenabled(repo, obsolete.createmarkersopt) and
1777 repo.ui.configbool('experimental', 'evolution.report-instabilities')):
1791 repo.ui.configbool('experimental', 'evolution.report-instabilities')):
1778 instabilitytypes = [
1792 instabilitytypes = [
1779 ('orphan', 'orphan'),
1793 ('orphan', 'orphan'),
1780 ('phase-divergent', 'phasedivergent'),
1794 ('phase-divergent', 'phasedivergent'),
1781 ('content-divergent', 'contentdivergent'),
1795 ('content-divergent', 'contentdivergent'),
1782 ]
1796 ]
1783
1797
1784 def getinstabilitycounts(repo):
1798 def getinstabilitycounts(repo):
1785 filtered = repo.changelog.filteredrevs
1799 filtered = repo.changelog.filteredrevs
1786 counts = {}
1800 counts = {}
1787 for instability, revset in instabilitytypes:
1801 for instability, revset in instabilitytypes:
1788 counts[instability] = len(set(obsolete.getrevs(repo, revset)) -
1802 counts[instability] = len(set(obsolete.getrevs(repo, revset)) -
1789 filtered)
1803 filtered)
1790 return counts
1804 return counts
1791
1805
1792 oldinstabilitycounts = getinstabilitycounts(repo)
1806 oldinstabilitycounts = getinstabilitycounts(repo)
1793 @reportsummary
1807 @reportsummary
1794 def reportnewinstabilities(repo, tr):
1808 def reportnewinstabilities(repo, tr):
1795 newinstabilitycounts = getinstabilitycounts(repo)
1809 newinstabilitycounts = getinstabilitycounts(repo)
1796 for instability, revset in instabilitytypes:
1810 for instability, revset in instabilitytypes:
1797 delta = (newinstabilitycounts[instability] -
1811 delta = (newinstabilitycounts[instability] -
1798 oldinstabilitycounts[instability])
1812 oldinstabilitycounts[instability])
1799 msg = getinstabilitymessage(delta, instability)
1813 msg = getinstabilitymessage(delta, instability)
1800 if msg:
1814 if msg:
1801 repo.ui.warn(msg)
1815 repo.ui.warn(msg)
1802
1816
1803 if txmatch(_reportnewcssource):
1817 if txmatch(_reportnewcssource):
1804 @reportsummary
1818 @reportsummary
1805 def reportnewcs(repo, tr):
1819 def reportnewcs(repo, tr):
1806 """Report the range of new revisions pulled/unbundled."""
1820 """Report the range of new revisions pulled/unbundled."""
1807 origrepolen = tr.changes.get('origrepolen', len(repo))
1821 origrepolen = tr.changes.get('origrepolen', len(repo))
1808 unfi = repo.unfiltered()
1822 unfi = repo.unfiltered()
1809 if origrepolen >= len(unfi):
1823 if origrepolen >= len(unfi):
1810 return
1824 return
1811
1825
1812 # Compute the bounds of new visible revisions' range.
1826 # Compute the bounds of new visible revisions' range.
1813 revs = smartset.spanset(repo, start=origrepolen)
1827 revs = smartset.spanset(repo, start=origrepolen)
1814 if revs:
1828 if revs:
1815 minrev, maxrev = repo[revs.min()], repo[revs.max()]
1829 minrev, maxrev = repo[revs.min()], repo[revs.max()]
1816
1830
1817 if minrev == maxrev:
1831 if minrev == maxrev:
1818 revrange = minrev
1832 revrange = minrev
1819 else:
1833 else:
1820 revrange = '%s:%s' % (minrev, maxrev)
1834 revrange = '%s:%s' % (minrev, maxrev)
1821 draft = len(repo.revs('%ld and draft()', revs))
1835 draft = len(repo.revs('%ld and draft()', revs))
1822 secret = len(repo.revs('%ld and secret()', revs))
1836 secret = len(repo.revs('%ld and secret()', revs))
1823 if not (draft or secret):
1837 if not (draft or secret):
1824 msg = _('new changesets %s\n') % revrange
1838 msg = _('new changesets %s\n') % revrange
1825 elif draft and secret:
1839 elif draft and secret:
1826 msg = _('new changesets %s (%d drafts, %d secrets)\n')
1840 msg = _('new changesets %s (%d drafts, %d secrets)\n')
1827 msg %= (revrange, draft, secret)
1841 msg %= (revrange, draft, secret)
1828 elif draft:
1842 elif draft:
1829 msg = _('new changesets %s (%d drafts)\n')
1843 msg = _('new changesets %s (%d drafts)\n')
1830 msg %= (revrange, draft)
1844 msg %= (revrange, draft)
1831 elif secret:
1845 elif secret:
1832 msg = _('new changesets %s (%d secrets)\n')
1846 msg = _('new changesets %s (%d secrets)\n')
1833 msg %= (revrange, secret)
1847 msg %= (revrange, secret)
1834 else:
1848 else:
1835 errormsg = 'entered unreachable condition'
1849 errormsg = 'entered unreachable condition'
1836 raise error.ProgrammingError(errormsg)
1850 raise error.ProgrammingError(errormsg)
1837 repo.ui.status(msg)
1851 repo.ui.status(msg)
1838
1852
1839 # search new changesets directly pulled as obsolete
1853 # search new changesets directly pulled as obsolete
1840 duplicates = tr.changes.get('revduplicates', ())
1854 duplicates = tr.changes.get('revduplicates', ())
1841 obsadded = unfi.revs('(%d: + %ld) and obsolete()',
1855 obsadded = unfi.revs('(%d: + %ld) and obsolete()',
1842 origrepolen, duplicates)
1856 origrepolen, duplicates)
1843 cl = repo.changelog
1857 cl = repo.changelog
1844 extinctadded = [r for r in obsadded if r not in cl]
1858 extinctadded = [r for r in obsadded if r not in cl]
1845 if extinctadded:
1859 if extinctadded:
1846 # They are not just obsolete, but obsolete and invisible
1860 # They are not just obsolete, but obsolete and invisible
1847 # we call them "extinct" internally but the terms have not been
1861 # we call them "extinct" internally but the terms have not been
1848 # exposed to users.
1862 # exposed to users.
1849 msg = '(%d other changesets obsolete on arrival)\n'
1863 msg = '(%d other changesets obsolete on arrival)\n'
1850 repo.ui.status(msg % len(extinctadded))
1864 repo.ui.status(msg % len(extinctadded))
1851
1865
1852 @reportsummary
1866 @reportsummary
1853 def reportphasechanges(repo, tr):
1867 def reportphasechanges(repo, tr):
1854 """Report statistics of phase changes for changesets pre-existing
1868 """Report statistics of phase changes for changesets pre-existing
1855 pull/unbundle.
1869 pull/unbundle.
1856 """
1870 """
1857 origrepolen = tr.changes.get('origrepolen', len(repo))
1871 origrepolen = tr.changes.get('origrepolen', len(repo))
1858 phasetracking = tr.changes.get('phases', {})
1872 phasetracking = tr.changes.get('phases', {})
1859 if not phasetracking:
1873 if not phasetracking:
1860 return
1874 return
1861 published = [
1875 published = [
1862 rev for rev, (old, new) in phasetracking.iteritems()
1876 rev for rev, (old, new) in phasetracking.iteritems()
1863 if new == phases.public and rev < origrepolen
1877 if new == phases.public and rev < origrepolen
1864 ]
1878 ]
1865 if not published:
1879 if not published:
1866 return
1880 return
1867 repo.ui.status(_('%d local changesets published\n')
1881 repo.ui.status(_('%d local changesets published\n')
1868 % len(published))
1882 % len(published))
1869
1883
1870 def getinstabilitymessage(delta, instability):
1884 def getinstabilitymessage(delta, instability):
1871 """function to return the message to show warning about new instabilities
1885 """function to return the message to show warning about new instabilities
1872
1886
1873 exists as a separate function so that extension can wrap to show more
1887 exists as a separate function so that extension can wrap to show more
1874 information like how to fix instabilities"""
1888 information like how to fix instabilities"""
1875 if delta > 0:
1889 if delta > 0:
1876 return _('%i new %s changesets\n') % (delta, instability)
1890 return _('%i new %s changesets\n') % (delta, instability)
1877
1891
1878 def nodesummaries(repo, nodes, maxnumnodes=4):
1892 def nodesummaries(repo, nodes, maxnumnodes=4):
1879 if len(nodes) <= maxnumnodes or repo.ui.verbose:
1893 if len(nodes) <= maxnumnodes or repo.ui.verbose:
1880 return ' '.join(short(h) for h in nodes)
1894 return ' '.join(short(h) for h in nodes)
1881 first = ' '.join(short(h) for h in nodes[:maxnumnodes])
1895 first = ' '.join(short(h) for h in nodes[:maxnumnodes])
1882 return _("%s and %d others") % (first, len(nodes) - maxnumnodes)
1896 return _("%s and %d others") % (first, len(nodes) - maxnumnodes)
1883
1897
1884 def enforcesinglehead(repo, tr, desc):
1898 def enforcesinglehead(repo, tr, desc):
1885 """check that no named branch has multiple heads"""
1899 """check that no named branch has multiple heads"""
1886 if desc in ('strip', 'repair'):
1900 if desc in ('strip', 'repair'):
1887 # skip the logic during strip
1901 # skip the logic during strip
1888 return
1902 return
1889 visible = repo.filtered('visible')
1903 visible = repo.filtered('visible')
1890 # possible improvement: we could restrict the check to affected branch
1904 # possible improvement: we could restrict the check to affected branch
1891 for name, heads in visible.branchmap().iteritems():
1905 for name, heads in visible.branchmap().iteritems():
1892 if len(heads) > 1:
1906 if len(heads) > 1:
1893 msg = _('rejecting multiple heads on branch "%s"')
1907 msg = _('rejecting multiple heads on branch "%s"')
1894 msg %= name
1908 msg %= name
1895 hint = _('%d heads: %s')
1909 hint = _('%d heads: %s')
1896 hint %= (len(heads), nodesummaries(repo, heads))
1910 hint %= (len(heads), nodesummaries(repo, heads))
1897 raise error.Abort(msg, hint=hint)
1911 raise error.Abort(msg, hint=hint)
1898
1912
1899 def wrapconvertsink(sink):
1913 def wrapconvertsink(sink):
1900 """Allow extensions to wrap the sink returned by convcmd.convertsink()
1914 """Allow extensions to wrap the sink returned by convcmd.convertsink()
1901 before it is used, whether or not the convert extension was formally loaded.
1915 before it is used, whether or not the convert extension was formally loaded.
1902 """
1916 """
1903 return sink
1917 return sink
1904
1918
1905 def unhidehashlikerevs(repo, specs, hiddentype):
1919 def unhidehashlikerevs(repo, specs, hiddentype):
1906 """parse the user specs and unhide changesets whose hash or revision number
1920 """parse the user specs and unhide changesets whose hash or revision number
1907 is passed.
1921 is passed.
1908
1922
1909 hiddentype can be: 1) 'warn': warn while unhiding changesets
1923 hiddentype can be: 1) 'warn': warn while unhiding changesets
1910 2) 'nowarn': don't warn while unhiding changesets
1924 2) 'nowarn': don't warn while unhiding changesets
1911
1925
1912 returns a repo object with the required changesets unhidden
1926 returns a repo object with the required changesets unhidden
1913 """
1927 """
1914 if not repo.filtername or not repo.ui.configbool('experimental',
1928 if not repo.filtername or not repo.ui.configbool('experimental',
1915 'directaccess'):
1929 'directaccess'):
1916 return repo
1930 return repo
1917
1931
1918 if repo.filtername not in ('visible', 'visible-hidden'):
1932 if repo.filtername not in ('visible', 'visible-hidden'):
1919 return repo
1933 return repo
1920
1934
1921 symbols = set()
1935 symbols = set()
1922 for spec in specs:
1936 for spec in specs:
1923 try:
1937 try:
1924 tree = revsetlang.parse(spec)
1938 tree = revsetlang.parse(spec)
1925 except error.ParseError: # will be reported by scmutil.revrange()
1939 except error.ParseError: # will be reported by scmutil.revrange()
1926 continue
1940 continue
1927
1941
1928 symbols.update(revsetlang.gethashlikesymbols(tree))
1942 symbols.update(revsetlang.gethashlikesymbols(tree))
1929
1943
1930 if not symbols:
1944 if not symbols:
1931 return repo
1945 return repo
1932
1946
1933 revs = _getrevsfromsymbols(repo, symbols)
1947 revs = _getrevsfromsymbols(repo, symbols)
1934
1948
1935 if not revs:
1949 if not revs:
1936 return repo
1950 return repo
1937
1951
1938 if hiddentype == 'warn':
1952 if hiddentype == 'warn':
1939 unfi = repo.unfiltered()
1953 unfi = repo.unfiltered()
1940 revstr = ", ".join([pycompat.bytestr(unfi[l]) for l in revs])
1954 revstr = ", ".join([pycompat.bytestr(unfi[l]) for l in revs])
1941 repo.ui.warn(_("warning: accessing hidden changesets for write "
1955 repo.ui.warn(_("warning: accessing hidden changesets for write "
1942 "operation: %s\n") % revstr)
1956 "operation: %s\n") % revstr)
1943
1957
1944 # we have to use new filtername to separate branch/tags cache until we can
1958 # we have to use new filtername to separate branch/tags cache until we can
1945 # disbale these cache when revisions are dynamically pinned.
1959 # disbale these cache when revisions are dynamically pinned.
1946 return repo.filtered('visible-hidden', revs)
1960 return repo.filtered('visible-hidden', revs)
1947
1961
1948 def _getrevsfromsymbols(repo, symbols):
1962 def _getrevsfromsymbols(repo, symbols):
1949 """parse the list of symbols and returns a set of revision numbers of hidden
1963 """parse the list of symbols and returns a set of revision numbers of hidden
1950 changesets present in symbols"""
1964 changesets present in symbols"""
1951 revs = set()
1965 revs = set()
1952 unfi = repo.unfiltered()
1966 unfi = repo.unfiltered()
1953 unficl = unfi.changelog
1967 unficl = unfi.changelog
1954 cl = repo.changelog
1968 cl = repo.changelog
1955 tiprev = len(unficl)
1969 tiprev = len(unficl)
1956 allowrevnums = repo.ui.configbool('experimental', 'directaccess.revnums')
1970 allowrevnums = repo.ui.configbool('experimental', 'directaccess.revnums')
1957 for s in symbols:
1971 for s in symbols:
1958 try:
1972 try:
1959 n = int(s)
1973 n = int(s)
1960 if n <= tiprev:
1974 if n <= tiprev:
1961 if not allowrevnums:
1975 if not allowrevnums:
1962 continue
1976 continue
1963 else:
1977 else:
1964 if n not in cl:
1978 if n not in cl:
1965 revs.add(n)
1979 revs.add(n)
1966 continue
1980 continue
1967 except ValueError:
1981 except ValueError:
1968 pass
1982 pass
1969
1983
1970 try:
1984 try:
1971 s = resolvehexnodeidprefix(unfi, s)
1985 s = resolvehexnodeidprefix(unfi, s)
1972 except (error.LookupError, error.WdirUnsupported):
1986 except (error.LookupError, error.WdirUnsupported):
1973 s = None
1987 s = None
1974
1988
1975 if s is not None:
1989 if s is not None:
1976 rev = unficl.rev(s)
1990 rev = unficl.rev(s)
1977 if rev not in cl:
1991 if rev not in cl:
1978 revs.add(rev)
1992 revs.add(rev)
1979
1993
1980 return revs
1994 return revs
1981
1995
1982 def bookmarkrevs(repo, mark):
1996 def bookmarkrevs(repo, mark):
1983 """
1997 """
1984 Select revisions reachable by a given bookmark
1998 Select revisions reachable by a given bookmark
1985 """
1999 """
1986 return repo.revs("ancestors(bookmark(%s)) - "
2000 return repo.revs("ancestors(bookmark(%s)) - "
1987 "ancestors(head() and not bookmark(%s)) - "
2001 "ancestors(head() and not bookmark(%s)) - "
1988 "ancestors(bookmark() and not bookmark(%s))",
2002 "ancestors(bookmark() and not bookmark(%s))",
1989 mark, mark, mark)
2003 mark, mark, mark)
1990
2004
1991 def computechangesetfilesadded(ctx):
2005 def computechangesetfilesadded(ctx):
1992 """return the list of files added in a changeset
2006 """return the list of files added in a changeset
1993 """
2007 """
1994 added = []
2008 added = []
1995 for f in ctx.files():
2009 for f in ctx.files():
1996 if not any(f in p for p in ctx.parents()):
2010 if not any(f in p for p in ctx.parents()):
1997 added.append(f)
2011 added.append(f)
1998 return added
2012 return added
1999
2013
2000 def computechangesetfilesremoved(ctx):
2014 def computechangesetfilesremoved(ctx):
2001 """return the list of files removed in a changeset
2015 """return the list of files removed in a changeset
2002 """
2016 """
2003 removed = []
2017 removed = []
2004 for f in ctx.files():
2018 for f in ctx.files():
2005 if f not in ctx:
2019 if f not in ctx:
2006 removed.append(f)
2020 removed.append(f)
2007 return removed
2021 return removed
@@ -1,2411 +1,2394 b''
1 > do_push()
1 > do_push()
2 > {
2 > {
3 > user=$1
3 > user=$1
4 > shift
4 > shift
5 > echo "Pushing as user $user"
5 > echo "Pushing as user $user"
6 > echo 'hgrc = """'
6 > echo 'hgrc = """'
7 > sed -n '/\[[ha]/,$p' b/.hg/hgrc | grep -v fakegroups.py
7 > sed -n '/\[[ha]/,$p' b/.hg/hgrc | grep -v fakegroups.py
8 > echo '"""'
8 > echo '"""'
9 > if test -f acl.config; then
9 > if test -f acl.config; then
10 > echo 'acl.config = """'
10 > echo 'acl.config = """'
11 > cat acl.config
11 > cat acl.config
12 > echo '"""'
12 > echo '"""'
13 > fi
13 > fi
14 > # On AIX /etc/profile sets LOGNAME read-only. So
14 > # On AIX /etc/profile sets LOGNAME read-only. So
15 > # LOGNAME=$user hg --cws a --debug push ../b
15 > # LOGNAME=$user hg --cws a --debug push ../b
16 > # fails with "This variable is read only."
16 > # fails with "This variable is read only."
17 > # Use env to work around this.
17 > # Use env to work around this.
18 > env LOGNAME=$user hg --cwd a --debug push ../b $*
18 > env LOGNAME=$user hg --cwd a --debug push ../b $*
19 > hg --cwd b rollback
19 > hg --cwd b rollback
20 > hg --cwd b --quiet tip
20 > hg --cwd b --quiet tip
21 > echo
21 > echo
22 > }
22 > }
23
23
24 > cat > posixgetuser.py <<'EOF'
24 > cat > posixgetuser.py <<'EOF'
25 > import getpass
25 > import getpass
26 > from mercurial import pycompat
26 > from mercurial import pycompat
27 > from mercurial.utils import procutil
27 > from mercurial.utils import procutil
28 > def posixgetuser():
28 > def posixgetuser():
29 > return pycompat.fsencode(getpass.getuser())
29 > return pycompat.fsencode(getpass.getuser())
30 > if not pycompat.isposix:
30 > if not pycompat.isposix:
31 > procutil.getuser = posixgetuser # forcibly trust $LOGNAME
31 > procutil.getuser = posixgetuser # forcibly trust $LOGNAME
32 > EOF
32 > EOF
33
33
34 > init_config()
34 > init_config()
35 > {
35 > {
36 > cat > fakegroups.py <<EOF
36 > cat > fakegroups.py <<EOF
37 > from hgext import acl
37 > from hgext import acl
38 > def fakegetusers(ui, group):
38 > def fakegetusers(ui, group):
39 > try:
39 > try:
40 > return acl._getusersorig(ui, group)
40 > return acl._getusersorig(ui, group)
41 > except BaseException:
41 > except BaseException:
42 > return [b"fred", b"betty"]
42 > return [b"fred", b"betty"]
43 > acl._getusersorig = acl._getusers
43 > acl._getusersorig = acl._getusers
44 > acl._getusers = fakegetusers
44 > acl._getusers = fakegetusers
45 > EOF
45 > EOF
46 > rm -f acl.config
46 > rm -f acl.config
47 > cat > $config <<EOF
47 > cat > $config <<EOF
48 > [hooks]
48 > [hooks]
49 > pretxnchangegroup.acl = python:hgext.acl.hook
49 > pretxnchangegroup.acl = python:hgext.acl.hook
50 > prepushkey.acl = python:hgext.acl.hook
50 > prepushkey.acl = python:hgext.acl.hook
51 > [acl]
51 > [acl]
52 > sources = push
52 > sources = push
53 > [extensions]
53 > [extensions]
54 > f=`pwd`/fakegroups.py
54 > f=`pwd`/fakegroups.py
55 > posixgetuser=$TESTTMP/posixgetuser.py
55 > posixgetuser=$TESTTMP/posixgetuser.py
56 > EOF
56 > EOF
57 > }
57 > }
58
58
59 $ hg init a
59 $ hg init a
60 $ cd a
60 $ cd a
61 $ mkdir foo foo/Bar quux
61 $ mkdir foo foo/Bar quux
62 $ echo 'in foo' > foo/file.txt
62 $ echo 'in foo' > foo/file.txt
63 $ echo 'in foo/Bar' > foo/Bar/file.txt
63 $ echo 'in foo/Bar' > foo/Bar/file.txt
64 $ echo 'in quux' > quux/file.py
64 $ echo 'in quux' > quux/file.py
65 $ hg add -q
65 $ hg add -q
66 $ hg ci -m 'add files' -d '1000000 0'
66 $ hg ci -m 'add files' -d '1000000 0'
67 $ echo >> foo/file.txt
67 $ echo >> foo/file.txt
68 $ hg ci -m 'change foo/file' -d '1000001 0'
68 $ hg ci -m 'change foo/file' -d '1000001 0'
69 $ echo >> foo/Bar/file.txt
69 $ echo >> foo/Bar/file.txt
70 $ hg ci -m 'change foo/Bar/file' -d '1000002 0'
70 $ hg ci -m 'change foo/Bar/file' -d '1000002 0'
71 $ echo >> quux/file.py
71 $ echo >> quux/file.py
72 $ hg ci -m 'change quux/file' -d '1000003 0'
72 $ hg ci -m 'change quux/file' -d '1000003 0'
73 $ hg tip --quiet
73 $ hg tip --quiet
74 3:911600dab2ae
74 3:911600dab2ae
75
75
76 $ cd ..
76 $ cd ..
77 $ hg clone -r 0 a b
77 $ hg clone -r 0 a b
78 adding changesets
78 adding changesets
79 adding manifests
79 adding manifests
80 adding file changes
80 adding file changes
81 added 1 changesets with 3 changes to 3 files
81 added 1 changesets with 3 changes to 3 files
82 new changesets 6675d58eff77
82 new changesets 6675d58eff77
83 updating to branch default
83 updating to branch default
84 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
84 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
85
85
86 $ config=b/.hg/hgrc
86 $ config=b/.hg/hgrc
87 $ cat >> "$config" <<EOF
87 $ cat >> "$config" <<EOF
88 > [extensions]
88 > [extensions]
89 > posixgetuser=$TESTTMP/posixgetuser.py
89 > posixgetuser=$TESTTMP/posixgetuser.py
90 > EOF
90 > EOF
91
91
92 Extension disabled for lack of a hook
92 Extension disabled for lack of a hook
93
93
94 $ do_push fred
94 $ do_push fred
95 Pushing as user fred
95 Pushing as user fred
96 hgrc = """
96 hgrc = """
97 """
97 """
98 pushing to ../b
98 pushing to ../b
99 query 1; heads
99 query 1; heads
100 searching for changes
100 searching for changes
101 all remote heads known locally
101 all remote heads known locally
102 listing keys for "phases"
102 listing keys for "phases"
103 checking for updated bookmarks
103 checking for updated bookmarks
104 listing keys for "bookmarks"
104 listing keys for "bookmarks"
105 listing keys for "bookmarks"
105 listing keys for "bookmarks"
106 3 changesets found
106 3 changesets found
107 list of changesets:
107 list of changesets:
108 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
108 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
109 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
109 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
110 911600dab2ae7a9baff75958b84fe606851ce955
110 911600dab2ae7a9baff75958b84fe606851ce955
111 bundle2-output-bundle: "HG20", 5 parts total
111 bundle2-output-bundle: "HG20", 5 parts total
112 bundle2-output-part: "replycaps" 205 bytes payload
112 bundle2-output-part: "replycaps" 205 bytes payload
113 bundle2-output-part: "check:phases" 24 bytes payload
113 bundle2-output-part: "check:phases" 24 bytes payload
114 bundle2-output-part: "check:heads" streamed payload
114 bundle2-output-part: "check:heads" streamed payload
115 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
115 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
116 bundle2-output-part: "phase-heads" 24 bytes payload
116 bundle2-output-part: "phase-heads" 24 bytes payload
117 bundle2-input-bundle: with-transaction
117 bundle2-input-bundle: with-transaction
118 bundle2-input-part: "replycaps" supported
118 bundle2-input-part: "replycaps" supported
119 bundle2-input-part: total payload size 205
119 bundle2-input-part: total payload size 205
120 bundle2-input-part: "check:phases" supported
120 bundle2-input-part: "check:phases" supported
121 bundle2-input-part: total payload size 24
121 bundle2-input-part: total payload size 24
122 bundle2-input-part: "check:heads" supported
122 bundle2-input-part: "check:heads" supported
123 bundle2-input-part: total payload size 20
123 bundle2-input-part: total payload size 20
124 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
124 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
125 adding changesets
125 adding changesets
126 add changeset ef1ea85a6374
126 add changeset ef1ea85a6374
127 add changeset f9cafe1212c8
127 add changeset f9cafe1212c8
128 add changeset 911600dab2ae
128 add changeset 911600dab2ae
129 adding manifests
129 adding manifests
130 adding file changes
130 adding file changes
131 adding foo/Bar/file.txt revisions
131 adding foo/Bar/file.txt revisions
132 adding foo/file.txt revisions
132 adding foo/file.txt revisions
133 adding quux/file.py revisions
133 adding quux/file.py revisions
134 added 3 changesets with 3 changes to 3 files
135 bundle2-input-part: total payload size 1553
134 bundle2-input-part: total payload size 1553
136 bundle2-input-part: "phase-heads" supported
135 bundle2-input-part: "phase-heads" supported
137 bundle2-input-part: total payload size 24
136 bundle2-input-part: total payload size 24
138 bundle2-input-bundle: 4 parts total
137 bundle2-input-bundle: 4 parts total
139 updating the branch cache
138 updating the branch cache
139 added 3 changesets with 3 changes to 3 files
140 bundle2-output-bundle: "HG20", 1 parts total
140 bundle2-output-bundle: "HG20", 1 parts total
141 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
141 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
142 bundle2-input-bundle: no-transaction
142 bundle2-input-bundle: no-transaction
143 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
143 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
144 bundle2-input-bundle: 0 parts total
144 bundle2-input-bundle: 0 parts total
145 listing keys for "phases"
145 listing keys for "phases"
146 repository tip rolled back to revision 0 (undo push)
146 repository tip rolled back to revision 0 (undo push)
147 0:6675d58eff77
147 0:6675d58eff77
148
148
149
149
150 $ echo '[hooks]' >> $config
150 $ echo '[hooks]' >> $config
151 $ echo 'pretxnchangegroup.acl = python:hgext.acl.hook' >> $config
151 $ echo 'pretxnchangegroup.acl = python:hgext.acl.hook' >> $config
152 $ echo 'prepushkey.acl = python:hgext.acl.hook' >> $config
152 $ echo 'prepushkey.acl = python:hgext.acl.hook' >> $config
153
153
154 Extension disabled for lack of acl.sources
154 Extension disabled for lack of acl.sources
155
155
156 $ do_push fred
156 $ do_push fred
157 Pushing as user fred
157 Pushing as user fred
158 hgrc = """
158 hgrc = """
159 [hooks]
159 [hooks]
160 pretxnchangegroup.acl = python:hgext.acl.hook
160 pretxnchangegroup.acl = python:hgext.acl.hook
161 prepushkey.acl = python:hgext.acl.hook
161 prepushkey.acl = python:hgext.acl.hook
162 """
162 """
163 pushing to ../b
163 pushing to ../b
164 query 1; heads
164 query 1; heads
165 searching for changes
165 searching for changes
166 all remote heads known locally
166 all remote heads known locally
167 listing keys for "phases"
167 listing keys for "phases"
168 checking for updated bookmarks
168 checking for updated bookmarks
169 listing keys for "bookmarks"
169 listing keys for "bookmarks"
170 listing keys for "bookmarks"
170 listing keys for "bookmarks"
171 3 changesets found
171 3 changesets found
172 list of changesets:
172 list of changesets:
173 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
173 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
174 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
174 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
175 911600dab2ae7a9baff75958b84fe606851ce955
175 911600dab2ae7a9baff75958b84fe606851ce955
176 bundle2-output-bundle: "HG20", 5 parts total
176 bundle2-output-bundle: "HG20", 5 parts total
177 bundle2-output-part: "replycaps" 205 bytes payload
177 bundle2-output-part: "replycaps" 205 bytes payload
178 bundle2-output-part: "check:phases" 24 bytes payload
178 bundle2-output-part: "check:phases" 24 bytes payload
179 bundle2-output-part: "check:heads" streamed payload
179 bundle2-output-part: "check:heads" streamed payload
180 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
180 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
181 bundle2-output-part: "phase-heads" 24 bytes payload
181 bundle2-output-part: "phase-heads" 24 bytes payload
182 bundle2-input-bundle: with-transaction
182 bundle2-input-bundle: with-transaction
183 bundle2-input-part: "replycaps" supported
183 bundle2-input-part: "replycaps" supported
184 bundle2-input-part: total payload size 205
184 bundle2-input-part: total payload size 205
185 bundle2-input-part: "check:phases" supported
185 bundle2-input-part: "check:phases" supported
186 bundle2-input-part: total payload size 24
186 bundle2-input-part: total payload size 24
187 bundle2-input-part: "check:heads" supported
187 bundle2-input-part: "check:heads" supported
188 bundle2-input-part: total payload size 20
188 bundle2-input-part: total payload size 20
189 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
189 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
190 adding changesets
190 adding changesets
191 add changeset ef1ea85a6374
191 add changeset ef1ea85a6374
192 add changeset f9cafe1212c8
192 add changeset f9cafe1212c8
193 add changeset 911600dab2ae
193 add changeset 911600dab2ae
194 adding manifests
194 adding manifests
195 adding file changes
195 adding file changes
196 adding foo/Bar/file.txt revisions
196 adding foo/Bar/file.txt revisions
197 adding foo/file.txt revisions
197 adding foo/file.txt revisions
198 adding quux/file.py revisions
198 adding quux/file.py revisions
199 added 3 changesets with 3 changes to 3 files
200 calling hook pretxnchangegroup.acl: hgext.acl.hook
199 calling hook pretxnchangegroup.acl: hgext.acl.hook
201 acl: changes have source "push" - skipping
200 acl: changes have source "push" - skipping
202 bundle2-input-part: total payload size 1553
201 bundle2-input-part: total payload size 1553
203 bundle2-input-part: "phase-heads" supported
202 bundle2-input-part: "phase-heads" supported
204 bundle2-input-part: total payload size 24
203 bundle2-input-part: total payload size 24
205 bundle2-input-bundle: 4 parts total
204 bundle2-input-bundle: 4 parts total
206 updating the branch cache
205 updating the branch cache
206 added 3 changesets with 3 changes to 3 files
207 bundle2-output-bundle: "HG20", 1 parts total
207 bundle2-output-bundle: "HG20", 1 parts total
208 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
208 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
209 bundle2-input-bundle: no-transaction
209 bundle2-input-bundle: no-transaction
210 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
210 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
211 bundle2-input-bundle: 0 parts total
211 bundle2-input-bundle: 0 parts total
212 listing keys for "phases"
212 listing keys for "phases"
213 repository tip rolled back to revision 0 (undo push)
213 repository tip rolled back to revision 0 (undo push)
214 0:6675d58eff77
214 0:6675d58eff77
215
215
216
216
217 No [acl.allow]/[acl.deny]
217 No [acl.allow]/[acl.deny]
218
218
219 $ echo '[acl]' >> $config
219 $ echo '[acl]' >> $config
220 $ echo 'sources = push' >> $config
220 $ echo 'sources = push' >> $config
221 $ do_push fred
221 $ do_push fred
222 Pushing as user fred
222 Pushing as user fred
223 hgrc = """
223 hgrc = """
224 [hooks]
224 [hooks]
225 pretxnchangegroup.acl = python:hgext.acl.hook
225 pretxnchangegroup.acl = python:hgext.acl.hook
226 prepushkey.acl = python:hgext.acl.hook
226 prepushkey.acl = python:hgext.acl.hook
227 [acl]
227 [acl]
228 sources = push
228 sources = push
229 """
229 """
230 pushing to ../b
230 pushing to ../b
231 query 1; heads
231 query 1; heads
232 searching for changes
232 searching for changes
233 all remote heads known locally
233 all remote heads known locally
234 listing keys for "phases"
234 listing keys for "phases"
235 checking for updated bookmarks
235 checking for updated bookmarks
236 listing keys for "bookmarks"
236 listing keys for "bookmarks"
237 listing keys for "bookmarks"
237 listing keys for "bookmarks"
238 3 changesets found
238 3 changesets found
239 list of changesets:
239 list of changesets:
240 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
240 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
241 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
241 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
242 911600dab2ae7a9baff75958b84fe606851ce955
242 911600dab2ae7a9baff75958b84fe606851ce955
243 bundle2-output-bundle: "HG20", 5 parts total
243 bundle2-output-bundle: "HG20", 5 parts total
244 bundle2-output-part: "replycaps" 205 bytes payload
244 bundle2-output-part: "replycaps" 205 bytes payload
245 bundle2-output-part: "check:phases" 24 bytes payload
245 bundle2-output-part: "check:phases" 24 bytes payload
246 bundle2-output-part: "check:heads" streamed payload
246 bundle2-output-part: "check:heads" streamed payload
247 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
247 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
248 bundle2-output-part: "phase-heads" 24 bytes payload
248 bundle2-output-part: "phase-heads" 24 bytes payload
249 bundle2-input-bundle: with-transaction
249 bundle2-input-bundle: with-transaction
250 bundle2-input-part: "replycaps" supported
250 bundle2-input-part: "replycaps" supported
251 bundle2-input-part: total payload size 205
251 bundle2-input-part: total payload size 205
252 bundle2-input-part: "check:phases" supported
252 bundle2-input-part: "check:phases" supported
253 bundle2-input-part: total payload size 24
253 bundle2-input-part: total payload size 24
254 bundle2-input-part: "check:heads" supported
254 bundle2-input-part: "check:heads" supported
255 bundle2-input-part: total payload size 20
255 bundle2-input-part: total payload size 20
256 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
256 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
257 adding changesets
257 adding changesets
258 add changeset ef1ea85a6374
258 add changeset ef1ea85a6374
259 add changeset f9cafe1212c8
259 add changeset f9cafe1212c8
260 add changeset 911600dab2ae
260 add changeset 911600dab2ae
261 adding manifests
261 adding manifests
262 adding file changes
262 adding file changes
263 adding foo/Bar/file.txt revisions
263 adding foo/Bar/file.txt revisions
264 adding foo/file.txt revisions
264 adding foo/file.txt revisions
265 adding quux/file.py revisions
265 adding quux/file.py revisions
266 added 3 changesets with 3 changes to 3 files
267 calling hook pretxnchangegroup.acl: hgext.acl.hook
266 calling hook pretxnchangegroup.acl: hgext.acl.hook
268 acl: checking access for user "fred"
267 acl: checking access for user "fred"
269 acl: acl.allow.branches not enabled
268 acl: acl.allow.branches not enabled
270 acl: acl.deny.branches not enabled
269 acl: acl.deny.branches not enabled
271 acl: acl.allow not enabled
270 acl: acl.allow not enabled
272 acl: acl.deny not enabled
271 acl: acl.deny not enabled
273 acl: branch access granted: "ef1ea85a6374" on branch "default"
272 acl: branch access granted: "ef1ea85a6374" on branch "default"
274 acl: path access granted: "ef1ea85a6374"
273 acl: path access granted: "ef1ea85a6374"
275 acl: branch access granted: "f9cafe1212c8" on branch "default"
274 acl: branch access granted: "f9cafe1212c8" on branch "default"
276 acl: path access granted: "f9cafe1212c8"
275 acl: path access granted: "f9cafe1212c8"
277 acl: branch access granted: "911600dab2ae" on branch "default"
276 acl: branch access granted: "911600dab2ae" on branch "default"
278 acl: path access granted: "911600dab2ae"
277 acl: path access granted: "911600dab2ae"
279 bundle2-input-part: total payload size 1553
278 bundle2-input-part: total payload size 1553
280 bundle2-input-part: "phase-heads" supported
279 bundle2-input-part: "phase-heads" supported
281 bundle2-input-part: total payload size 24
280 bundle2-input-part: total payload size 24
282 bundle2-input-bundle: 4 parts total
281 bundle2-input-bundle: 4 parts total
283 updating the branch cache
282 updating the branch cache
283 added 3 changesets with 3 changes to 3 files
284 bundle2-output-bundle: "HG20", 1 parts total
284 bundle2-output-bundle: "HG20", 1 parts total
285 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
285 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
286 bundle2-input-bundle: no-transaction
286 bundle2-input-bundle: no-transaction
287 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
287 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
288 bundle2-input-bundle: 0 parts total
288 bundle2-input-bundle: 0 parts total
289 listing keys for "phases"
289 listing keys for "phases"
290 repository tip rolled back to revision 0 (undo push)
290 repository tip rolled back to revision 0 (undo push)
291 0:6675d58eff77
291 0:6675d58eff77
292
292
293
293
294 Empty [acl.allow]
294 Empty [acl.allow]
295
295
296 $ echo '[acl.allow]' >> $config
296 $ echo '[acl.allow]' >> $config
297 $ do_push fred
297 $ do_push fred
298 Pushing as user fred
298 Pushing as user fred
299 hgrc = """
299 hgrc = """
300 [hooks]
300 [hooks]
301 pretxnchangegroup.acl = python:hgext.acl.hook
301 pretxnchangegroup.acl = python:hgext.acl.hook
302 prepushkey.acl = python:hgext.acl.hook
302 prepushkey.acl = python:hgext.acl.hook
303 [acl]
303 [acl]
304 sources = push
304 sources = push
305 [acl.allow]
305 [acl.allow]
306 """
306 """
307 pushing to ../b
307 pushing to ../b
308 query 1; heads
308 query 1; heads
309 searching for changes
309 searching for changes
310 all remote heads known locally
310 all remote heads known locally
311 listing keys for "phases"
311 listing keys for "phases"
312 checking for updated bookmarks
312 checking for updated bookmarks
313 listing keys for "bookmarks"
313 listing keys for "bookmarks"
314 listing keys for "bookmarks"
314 listing keys for "bookmarks"
315 3 changesets found
315 3 changesets found
316 list of changesets:
316 list of changesets:
317 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
317 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
318 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
318 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
319 911600dab2ae7a9baff75958b84fe606851ce955
319 911600dab2ae7a9baff75958b84fe606851ce955
320 bundle2-output-bundle: "HG20", 5 parts total
320 bundle2-output-bundle: "HG20", 5 parts total
321 bundle2-output-part: "replycaps" 205 bytes payload
321 bundle2-output-part: "replycaps" 205 bytes payload
322 bundle2-output-part: "check:phases" 24 bytes payload
322 bundle2-output-part: "check:phases" 24 bytes payload
323 bundle2-output-part: "check:heads" streamed payload
323 bundle2-output-part: "check:heads" streamed payload
324 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
324 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
325 bundle2-output-part: "phase-heads" 24 bytes payload
325 bundle2-output-part: "phase-heads" 24 bytes payload
326 bundle2-input-bundle: with-transaction
326 bundle2-input-bundle: with-transaction
327 bundle2-input-part: "replycaps" supported
327 bundle2-input-part: "replycaps" supported
328 bundle2-input-part: total payload size 205
328 bundle2-input-part: total payload size 205
329 bundle2-input-part: "check:phases" supported
329 bundle2-input-part: "check:phases" supported
330 bundle2-input-part: total payload size 24
330 bundle2-input-part: total payload size 24
331 bundle2-input-part: "check:heads" supported
331 bundle2-input-part: "check:heads" supported
332 bundle2-input-part: total payload size 20
332 bundle2-input-part: total payload size 20
333 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
333 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
334 adding changesets
334 adding changesets
335 add changeset ef1ea85a6374
335 add changeset ef1ea85a6374
336 add changeset f9cafe1212c8
336 add changeset f9cafe1212c8
337 add changeset 911600dab2ae
337 add changeset 911600dab2ae
338 adding manifests
338 adding manifests
339 adding file changes
339 adding file changes
340 adding foo/Bar/file.txt revisions
340 adding foo/Bar/file.txt revisions
341 adding foo/file.txt revisions
341 adding foo/file.txt revisions
342 adding quux/file.py revisions
342 adding quux/file.py revisions
343 added 3 changesets with 3 changes to 3 files
344 calling hook pretxnchangegroup.acl: hgext.acl.hook
343 calling hook pretxnchangegroup.acl: hgext.acl.hook
345 acl: checking access for user "fred"
344 acl: checking access for user "fred"
346 acl: acl.allow.branches not enabled
345 acl: acl.allow.branches not enabled
347 acl: acl.deny.branches not enabled
346 acl: acl.deny.branches not enabled
348 acl: acl.allow enabled, 0 entries for user fred
347 acl: acl.allow enabled, 0 entries for user fred
349 acl: acl.deny not enabled
348 acl: acl.deny not enabled
350 acl: branch access granted: "ef1ea85a6374" on branch "default"
349 acl: branch access granted: "ef1ea85a6374" on branch "default"
351 error: pretxnchangegroup.acl hook failed: acl: user "fred" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
350 error: pretxnchangegroup.acl hook failed: acl: user "fred" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
352 bundle2-input-part: total payload size 1553
351 bundle2-input-part: total payload size 1553
353 bundle2-input-part: total payload size 24
352 bundle2-input-part: total payload size 24
354 bundle2-input-bundle: 4 parts total
353 bundle2-input-bundle: 4 parts total
355 transaction abort!
354 transaction abort!
356 rollback completed
355 rollback completed
357 abort: acl: user "fred" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
356 abort: acl: user "fred" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
358 no rollback information available
357 no rollback information available
359 0:6675d58eff77
358 0:6675d58eff77
360
359
361
360
362 fred is allowed inside foo/
361 fred is allowed inside foo/
363
362
364 $ echo 'foo/** = fred' >> $config
363 $ echo 'foo/** = fred' >> $config
365 $ do_push fred
364 $ do_push fred
366 Pushing as user fred
365 Pushing as user fred
367 hgrc = """
366 hgrc = """
368 [hooks]
367 [hooks]
369 pretxnchangegroup.acl = python:hgext.acl.hook
368 pretxnchangegroup.acl = python:hgext.acl.hook
370 prepushkey.acl = python:hgext.acl.hook
369 prepushkey.acl = python:hgext.acl.hook
371 [acl]
370 [acl]
372 sources = push
371 sources = push
373 [acl.allow]
372 [acl.allow]
374 foo/** = fred
373 foo/** = fred
375 """
374 """
376 pushing to ../b
375 pushing to ../b
377 query 1; heads
376 query 1; heads
378 searching for changes
377 searching for changes
379 all remote heads known locally
378 all remote heads known locally
380 listing keys for "phases"
379 listing keys for "phases"
381 checking for updated bookmarks
380 checking for updated bookmarks
382 listing keys for "bookmarks"
381 listing keys for "bookmarks"
383 listing keys for "bookmarks"
382 listing keys for "bookmarks"
384 3 changesets found
383 3 changesets found
385 list of changesets:
384 list of changesets:
386 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
385 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
387 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
386 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
388 911600dab2ae7a9baff75958b84fe606851ce955
387 911600dab2ae7a9baff75958b84fe606851ce955
389 bundle2-output-bundle: "HG20", 5 parts total
388 bundle2-output-bundle: "HG20", 5 parts total
390 bundle2-output-part: "replycaps" 205 bytes payload
389 bundle2-output-part: "replycaps" 205 bytes payload
391 bundle2-output-part: "check:phases" 24 bytes payload
390 bundle2-output-part: "check:phases" 24 bytes payload
392 bundle2-output-part: "check:heads" streamed payload
391 bundle2-output-part: "check:heads" streamed payload
393 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
392 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
394 bundle2-output-part: "phase-heads" 24 bytes payload
393 bundle2-output-part: "phase-heads" 24 bytes payload
395 bundle2-input-bundle: with-transaction
394 bundle2-input-bundle: with-transaction
396 bundle2-input-part: "replycaps" supported
395 bundle2-input-part: "replycaps" supported
397 bundle2-input-part: total payload size 205
396 bundle2-input-part: total payload size 205
398 bundle2-input-part: "check:phases" supported
397 bundle2-input-part: "check:phases" supported
399 bundle2-input-part: total payload size 24
398 bundle2-input-part: total payload size 24
400 bundle2-input-part: "check:heads" supported
399 bundle2-input-part: "check:heads" supported
401 bundle2-input-part: total payload size 20
400 bundle2-input-part: total payload size 20
402 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
401 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
403 adding changesets
402 adding changesets
404 add changeset ef1ea85a6374
403 add changeset ef1ea85a6374
405 add changeset f9cafe1212c8
404 add changeset f9cafe1212c8
406 add changeset 911600dab2ae
405 add changeset 911600dab2ae
407 adding manifests
406 adding manifests
408 adding file changes
407 adding file changes
409 adding foo/Bar/file.txt revisions
408 adding foo/Bar/file.txt revisions
410 adding foo/file.txt revisions
409 adding foo/file.txt revisions
411 adding quux/file.py revisions
410 adding quux/file.py revisions
412 added 3 changesets with 3 changes to 3 files
413 calling hook pretxnchangegroup.acl: hgext.acl.hook
411 calling hook pretxnchangegroup.acl: hgext.acl.hook
414 acl: checking access for user "fred"
412 acl: checking access for user "fred"
415 acl: acl.allow.branches not enabled
413 acl: acl.allow.branches not enabled
416 acl: acl.deny.branches not enabled
414 acl: acl.deny.branches not enabled
417 acl: acl.allow enabled, 1 entries for user fred
415 acl: acl.allow enabled, 1 entries for user fred
418 acl: acl.deny not enabled
416 acl: acl.deny not enabled
419 acl: branch access granted: "ef1ea85a6374" on branch "default"
417 acl: branch access granted: "ef1ea85a6374" on branch "default"
420 acl: path access granted: "ef1ea85a6374"
418 acl: path access granted: "ef1ea85a6374"
421 acl: branch access granted: "f9cafe1212c8" on branch "default"
419 acl: branch access granted: "f9cafe1212c8" on branch "default"
422 acl: path access granted: "f9cafe1212c8"
420 acl: path access granted: "f9cafe1212c8"
423 acl: branch access granted: "911600dab2ae" on branch "default"
421 acl: branch access granted: "911600dab2ae" on branch "default"
424 error: pretxnchangegroup.acl hook failed: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
422 error: pretxnchangegroup.acl hook failed: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
425 bundle2-input-part: total payload size 1553
423 bundle2-input-part: total payload size 1553
426 bundle2-input-part: total payload size 24
424 bundle2-input-part: total payload size 24
427 bundle2-input-bundle: 4 parts total
425 bundle2-input-bundle: 4 parts total
428 transaction abort!
426 transaction abort!
429 rollback completed
427 rollback completed
430 abort: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
428 abort: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
431 no rollback information available
429 no rollback information available
432 0:6675d58eff77
430 0:6675d58eff77
433
431
434
432
435 Empty [acl.deny]
433 Empty [acl.deny]
436
434
437 $ echo '[acl.deny]' >> $config
435 $ echo '[acl.deny]' >> $config
438 $ do_push barney
436 $ do_push barney
439 Pushing as user barney
437 Pushing as user barney
440 hgrc = """
438 hgrc = """
441 [hooks]
439 [hooks]
442 pretxnchangegroup.acl = python:hgext.acl.hook
440 pretxnchangegroup.acl = python:hgext.acl.hook
443 prepushkey.acl = python:hgext.acl.hook
441 prepushkey.acl = python:hgext.acl.hook
444 [acl]
442 [acl]
445 sources = push
443 sources = push
446 [acl.allow]
444 [acl.allow]
447 foo/** = fred
445 foo/** = fred
448 [acl.deny]
446 [acl.deny]
449 """
447 """
450 pushing to ../b
448 pushing to ../b
451 query 1; heads
449 query 1; heads
452 searching for changes
450 searching for changes
453 all remote heads known locally
451 all remote heads known locally
454 listing keys for "phases"
452 listing keys for "phases"
455 checking for updated bookmarks
453 checking for updated bookmarks
456 listing keys for "bookmarks"
454 listing keys for "bookmarks"
457 listing keys for "bookmarks"
455 listing keys for "bookmarks"
458 3 changesets found
456 3 changesets found
459 list of changesets:
457 list of changesets:
460 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
458 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
461 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
459 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
462 911600dab2ae7a9baff75958b84fe606851ce955
460 911600dab2ae7a9baff75958b84fe606851ce955
463 bundle2-output-bundle: "HG20", 5 parts total
461 bundle2-output-bundle: "HG20", 5 parts total
464 bundle2-output-part: "replycaps" 205 bytes payload
462 bundle2-output-part: "replycaps" 205 bytes payload
465 bundle2-output-part: "check:phases" 24 bytes payload
463 bundle2-output-part: "check:phases" 24 bytes payload
466 bundle2-output-part: "check:heads" streamed payload
464 bundle2-output-part: "check:heads" streamed payload
467 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
465 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
468 bundle2-output-part: "phase-heads" 24 bytes payload
466 bundle2-output-part: "phase-heads" 24 bytes payload
469 bundle2-input-bundle: with-transaction
467 bundle2-input-bundle: with-transaction
470 bundle2-input-part: "replycaps" supported
468 bundle2-input-part: "replycaps" supported
471 bundle2-input-part: total payload size 205
469 bundle2-input-part: total payload size 205
472 bundle2-input-part: "check:phases" supported
470 bundle2-input-part: "check:phases" supported
473 bundle2-input-part: total payload size 24
471 bundle2-input-part: total payload size 24
474 bundle2-input-part: "check:heads" supported
472 bundle2-input-part: "check:heads" supported
475 bundle2-input-part: total payload size 20
473 bundle2-input-part: total payload size 20
476 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
474 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
477 adding changesets
475 adding changesets
478 add changeset ef1ea85a6374
476 add changeset ef1ea85a6374
479 add changeset f9cafe1212c8
477 add changeset f9cafe1212c8
480 add changeset 911600dab2ae
478 add changeset 911600dab2ae
481 adding manifests
479 adding manifests
482 adding file changes
480 adding file changes
483 adding foo/Bar/file.txt revisions
481 adding foo/Bar/file.txt revisions
484 adding foo/file.txt revisions
482 adding foo/file.txt revisions
485 adding quux/file.py revisions
483 adding quux/file.py revisions
486 added 3 changesets with 3 changes to 3 files
487 calling hook pretxnchangegroup.acl: hgext.acl.hook
484 calling hook pretxnchangegroup.acl: hgext.acl.hook
488 acl: checking access for user "barney"
485 acl: checking access for user "barney"
489 acl: acl.allow.branches not enabled
486 acl: acl.allow.branches not enabled
490 acl: acl.deny.branches not enabled
487 acl: acl.deny.branches not enabled
491 acl: acl.allow enabled, 0 entries for user barney
488 acl: acl.allow enabled, 0 entries for user barney
492 acl: acl.deny enabled, 0 entries for user barney
489 acl: acl.deny enabled, 0 entries for user barney
493 acl: branch access granted: "ef1ea85a6374" on branch "default"
490 acl: branch access granted: "ef1ea85a6374" on branch "default"
494 error: pretxnchangegroup.acl hook failed: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
491 error: pretxnchangegroup.acl hook failed: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
495 bundle2-input-part: total payload size 1553
492 bundle2-input-part: total payload size 1553
496 bundle2-input-part: total payload size 24
493 bundle2-input-part: total payload size 24
497 bundle2-input-bundle: 4 parts total
494 bundle2-input-bundle: 4 parts total
498 transaction abort!
495 transaction abort!
499 rollback completed
496 rollback completed
500 abort: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
497 abort: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
501 no rollback information available
498 no rollback information available
502 0:6675d58eff77
499 0:6675d58eff77
503
500
504
501
505 fred is allowed inside foo/, but not foo/bar/ (case matters)
502 fred is allowed inside foo/, but not foo/bar/ (case matters)
506
503
507 $ echo 'foo/bar/** = fred' >> $config
504 $ echo 'foo/bar/** = fred' >> $config
508 $ do_push fred
505 $ do_push fred
509 Pushing as user fred
506 Pushing as user fred
510 hgrc = """
507 hgrc = """
511 [hooks]
508 [hooks]
512 pretxnchangegroup.acl = python:hgext.acl.hook
509 pretxnchangegroup.acl = python:hgext.acl.hook
513 prepushkey.acl = python:hgext.acl.hook
510 prepushkey.acl = python:hgext.acl.hook
514 [acl]
511 [acl]
515 sources = push
512 sources = push
516 [acl.allow]
513 [acl.allow]
517 foo/** = fred
514 foo/** = fred
518 [acl.deny]
515 [acl.deny]
519 foo/bar/** = fred
516 foo/bar/** = fred
520 """
517 """
521 pushing to ../b
518 pushing to ../b
522 query 1; heads
519 query 1; heads
523 searching for changes
520 searching for changes
524 all remote heads known locally
521 all remote heads known locally
525 listing keys for "phases"
522 listing keys for "phases"
526 checking for updated bookmarks
523 checking for updated bookmarks
527 listing keys for "bookmarks"
524 listing keys for "bookmarks"
528 listing keys for "bookmarks"
525 listing keys for "bookmarks"
529 3 changesets found
526 3 changesets found
530 list of changesets:
527 list of changesets:
531 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
528 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
532 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
529 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
533 911600dab2ae7a9baff75958b84fe606851ce955
530 911600dab2ae7a9baff75958b84fe606851ce955
534 bundle2-output-bundle: "HG20", 5 parts total
531 bundle2-output-bundle: "HG20", 5 parts total
535 bundle2-output-part: "replycaps" 205 bytes payload
532 bundle2-output-part: "replycaps" 205 bytes payload
536 bundle2-output-part: "check:phases" 24 bytes payload
533 bundle2-output-part: "check:phases" 24 bytes payload
537 bundle2-output-part: "check:heads" streamed payload
534 bundle2-output-part: "check:heads" streamed payload
538 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
535 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
539 bundle2-output-part: "phase-heads" 24 bytes payload
536 bundle2-output-part: "phase-heads" 24 bytes payload
540 bundle2-input-bundle: with-transaction
537 bundle2-input-bundle: with-transaction
541 bundle2-input-part: "replycaps" supported
538 bundle2-input-part: "replycaps" supported
542 bundle2-input-part: total payload size 205
539 bundle2-input-part: total payload size 205
543 bundle2-input-part: "check:phases" supported
540 bundle2-input-part: "check:phases" supported
544 bundle2-input-part: total payload size 24
541 bundle2-input-part: total payload size 24
545 bundle2-input-part: "check:heads" supported
542 bundle2-input-part: "check:heads" supported
546 bundle2-input-part: total payload size 20
543 bundle2-input-part: total payload size 20
547 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
544 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
548 adding changesets
545 adding changesets
549 add changeset ef1ea85a6374
546 add changeset ef1ea85a6374
550 add changeset f9cafe1212c8
547 add changeset f9cafe1212c8
551 add changeset 911600dab2ae
548 add changeset 911600dab2ae
552 adding manifests
549 adding manifests
553 adding file changes
550 adding file changes
554 adding foo/Bar/file.txt revisions
551 adding foo/Bar/file.txt revisions
555 adding foo/file.txt revisions
552 adding foo/file.txt revisions
556 adding quux/file.py revisions
553 adding quux/file.py revisions
557 added 3 changesets with 3 changes to 3 files
558 calling hook pretxnchangegroup.acl: hgext.acl.hook
554 calling hook pretxnchangegroup.acl: hgext.acl.hook
559 acl: checking access for user "fred"
555 acl: checking access for user "fred"
560 acl: acl.allow.branches not enabled
556 acl: acl.allow.branches not enabled
561 acl: acl.deny.branches not enabled
557 acl: acl.deny.branches not enabled
562 acl: acl.allow enabled, 1 entries for user fred
558 acl: acl.allow enabled, 1 entries for user fred
563 acl: acl.deny enabled, 1 entries for user fred
559 acl: acl.deny enabled, 1 entries for user fred
564 acl: branch access granted: "ef1ea85a6374" on branch "default"
560 acl: branch access granted: "ef1ea85a6374" on branch "default"
565 acl: path access granted: "ef1ea85a6374"
561 acl: path access granted: "ef1ea85a6374"
566 acl: branch access granted: "f9cafe1212c8" on branch "default"
562 acl: branch access granted: "f9cafe1212c8" on branch "default"
567 acl: path access granted: "f9cafe1212c8"
563 acl: path access granted: "f9cafe1212c8"
568 acl: branch access granted: "911600dab2ae" on branch "default"
564 acl: branch access granted: "911600dab2ae" on branch "default"
569 error: pretxnchangegroup.acl hook failed: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
565 error: pretxnchangegroup.acl hook failed: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
570 bundle2-input-part: total payload size 1553
566 bundle2-input-part: total payload size 1553
571 bundle2-input-part: total payload size 24
567 bundle2-input-part: total payload size 24
572 bundle2-input-bundle: 4 parts total
568 bundle2-input-bundle: 4 parts total
573 transaction abort!
569 transaction abort!
574 rollback completed
570 rollback completed
575 abort: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
571 abort: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
576 no rollback information available
572 no rollback information available
577 0:6675d58eff77
573 0:6675d58eff77
578
574
579
575
580 fred is allowed inside foo/, but not foo/Bar/
576 fred is allowed inside foo/, but not foo/Bar/
581
577
582 $ echo 'foo/Bar/** = fred' >> $config
578 $ echo 'foo/Bar/** = fred' >> $config
583 $ do_push fred
579 $ do_push fred
584 Pushing as user fred
580 Pushing as user fred
585 hgrc = """
581 hgrc = """
586 [hooks]
582 [hooks]
587 pretxnchangegroup.acl = python:hgext.acl.hook
583 pretxnchangegroup.acl = python:hgext.acl.hook
588 prepushkey.acl = python:hgext.acl.hook
584 prepushkey.acl = python:hgext.acl.hook
589 [acl]
585 [acl]
590 sources = push
586 sources = push
591 [acl.allow]
587 [acl.allow]
592 foo/** = fred
588 foo/** = fred
593 [acl.deny]
589 [acl.deny]
594 foo/bar/** = fred
590 foo/bar/** = fred
595 foo/Bar/** = fred
591 foo/Bar/** = fred
596 """
592 """
597 pushing to ../b
593 pushing to ../b
598 query 1; heads
594 query 1; heads
599 searching for changes
595 searching for changes
600 all remote heads known locally
596 all remote heads known locally
601 listing keys for "phases"
597 listing keys for "phases"
602 checking for updated bookmarks
598 checking for updated bookmarks
603 listing keys for "bookmarks"
599 listing keys for "bookmarks"
604 listing keys for "bookmarks"
600 listing keys for "bookmarks"
605 3 changesets found
601 3 changesets found
606 list of changesets:
602 list of changesets:
607 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
603 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
608 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
604 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
609 911600dab2ae7a9baff75958b84fe606851ce955
605 911600dab2ae7a9baff75958b84fe606851ce955
610 bundle2-output-bundle: "HG20", 5 parts total
606 bundle2-output-bundle: "HG20", 5 parts total
611 bundle2-output-part: "replycaps" 205 bytes payload
607 bundle2-output-part: "replycaps" 205 bytes payload
612 bundle2-output-part: "check:phases" 24 bytes payload
608 bundle2-output-part: "check:phases" 24 bytes payload
613 bundle2-output-part: "check:heads" streamed payload
609 bundle2-output-part: "check:heads" streamed payload
614 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
610 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
615 bundle2-output-part: "phase-heads" 24 bytes payload
611 bundle2-output-part: "phase-heads" 24 bytes payload
616 bundle2-input-bundle: with-transaction
612 bundle2-input-bundle: with-transaction
617 bundle2-input-part: "replycaps" supported
613 bundle2-input-part: "replycaps" supported
618 bundle2-input-part: total payload size 205
614 bundle2-input-part: total payload size 205
619 bundle2-input-part: "check:phases" supported
615 bundle2-input-part: "check:phases" supported
620 bundle2-input-part: total payload size 24
616 bundle2-input-part: total payload size 24
621 bundle2-input-part: "check:heads" supported
617 bundle2-input-part: "check:heads" supported
622 bundle2-input-part: total payload size 20
618 bundle2-input-part: total payload size 20
623 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
619 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
624 adding changesets
620 adding changesets
625 add changeset ef1ea85a6374
621 add changeset ef1ea85a6374
626 add changeset f9cafe1212c8
622 add changeset f9cafe1212c8
627 add changeset 911600dab2ae
623 add changeset 911600dab2ae
628 adding manifests
624 adding manifests
629 adding file changes
625 adding file changes
630 adding foo/Bar/file.txt revisions
626 adding foo/Bar/file.txt revisions
631 adding foo/file.txt revisions
627 adding foo/file.txt revisions
632 adding quux/file.py revisions
628 adding quux/file.py revisions
633 added 3 changesets with 3 changes to 3 files
634 calling hook pretxnchangegroup.acl: hgext.acl.hook
629 calling hook pretxnchangegroup.acl: hgext.acl.hook
635 acl: checking access for user "fred"
630 acl: checking access for user "fred"
636 acl: acl.allow.branches not enabled
631 acl: acl.allow.branches not enabled
637 acl: acl.deny.branches not enabled
632 acl: acl.deny.branches not enabled
638 acl: acl.allow enabled, 1 entries for user fred
633 acl: acl.allow enabled, 1 entries for user fred
639 acl: acl.deny enabled, 2 entries for user fred
634 acl: acl.deny enabled, 2 entries for user fred
640 acl: branch access granted: "ef1ea85a6374" on branch "default"
635 acl: branch access granted: "ef1ea85a6374" on branch "default"
641 acl: path access granted: "ef1ea85a6374"
636 acl: path access granted: "ef1ea85a6374"
642 acl: branch access granted: "f9cafe1212c8" on branch "default"
637 acl: branch access granted: "f9cafe1212c8" on branch "default"
643 error: pretxnchangegroup.acl hook failed: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
638 error: pretxnchangegroup.acl hook failed: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
644 bundle2-input-part: total payload size 1553
639 bundle2-input-part: total payload size 1553
645 bundle2-input-part: total payload size 24
640 bundle2-input-part: total payload size 24
646 bundle2-input-bundle: 4 parts total
641 bundle2-input-bundle: 4 parts total
647 transaction abort!
642 transaction abort!
648 rollback completed
643 rollback completed
649 abort: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
644 abort: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
650 no rollback information available
645 no rollback information available
651 0:6675d58eff77
646 0:6675d58eff77
652
647
653
648
654 $ echo 'barney is not mentioned => not allowed anywhere'
649 $ echo 'barney is not mentioned => not allowed anywhere'
655 barney is not mentioned => not allowed anywhere
650 barney is not mentioned => not allowed anywhere
656 $ do_push barney
651 $ do_push barney
657 Pushing as user barney
652 Pushing as user barney
658 hgrc = """
653 hgrc = """
659 [hooks]
654 [hooks]
660 pretxnchangegroup.acl = python:hgext.acl.hook
655 pretxnchangegroup.acl = python:hgext.acl.hook
661 prepushkey.acl = python:hgext.acl.hook
656 prepushkey.acl = python:hgext.acl.hook
662 [acl]
657 [acl]
663 sources = push
658 sources = push
664 [acl.allow]
659 [acl.allow]
665 foo/** = fred
660 foo/** = fred
666 [acl.deny]
661 [acl.deny]
667 foo/bar/** = fred
662 foo/bar/** = fred
668 foo/Bar/** = fred
663 foo/Bar/** = fred
669 """
664 """
670 pushing to ../b
665 pushing to ../b
671 query 1; heads
666 query 1; heads
672 searching for changes
667 searching for changes
673 all remote heads known locally
668 all remote heads known locally
674 listing keys for "phases"
669 listing keys for "phases"
675 checking for updated bookmarks
670 checking for updated bookmarks
676 listing keys for "bookmarks"
671 listing keys for "bookmarks"
677 listing keys for "bookmarks"
672 listing keys for "bookmarks"
678 3 changesets found
673 3 changesets found
679 list of changesets:
674 list of changesets:
680 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
675 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
681 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
676 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
682 911600dab2ae7a9baff75958b84fe606851ce955
677 911600dab2ae7a9baff75958b84fe606851ce955
683 bundle2-output-bundle: "HG20", 5 parts total
678 bundle2-output-bundle: "HG20", 5 parts total
684 bundle2-output-part: "replycaps" 205 bytes payload
679 bundle2-output-part: "replycaps" 205 bytes payload
685 bundle2-output-part: "check:phases" 24 bytes payload
680 bundle2-output-part: "check:phases" 24 bytes payload
686 bundle2-output-part: "check:heads" streamed payload
681 bundle2-output-part: "check:heads" streamed payload
687 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
682 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
688 bundle2-output-part: "phase-heads" 24 bytes payload
683 bundle2-output-part: "phase-heads" 24 bytes payload
689 bundle2-input-bundle: with-transaction
684 bundle2-input-bundle: with-transaction
690 bundle2-input-part: "replycaps" supported
685 bundle2-input-part: "replycaps" supported
691 bundle2-input-part: total payload size 205
686 bundle2-input-part: total payload size 205
692 bundle2-input-part: "check:phases" supported
687 bundle2-input-part: "check:phases" supported
693 bundle2-input-part: total payload size 24
688 bundle2-input-part: total payload size 24
694 bundle2-input-part: "check:heads" supported
689 bundle2-input-part: "check:heads" supported
695 bundle2-input-part: total payload size 20
690 bundle2-input-part: total payload size 20
696 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
691 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
697 adding changesets
692 adding changesets
698 add changeset ef1ea85a6374
693 add changeset ef1ea85a6374
699 add changeset f9cafe1212c8
694 add changeset f9cafe1212c8
700 add changeset 911600dab2ae
695 add changeset 911600dab2ae
701 adding manifests
696 adding manifests
702 adding file changes
697 adding file changes
703 adding foo/Bar/file.txt revisions
698 adding foo/Bar/file.txt revisions
704 adding foo/file.txt revisions
699 adding foo/file.txt revisions
705 adding quux/file.py revisions
700 adding quux/file.py revisions
706 added 3 changesets with 3 changes to 3 files
707 calling hook pretxnchangegroup.acl: hgext.acl.hook
701 calling hook pretxnchangegroup.acl: hgext.acl.hook
708 acl: checking access for user "barney"
702 acl: checking access for user "barney"
709 acl: acl.allow.branches not enabled
703 acl: acl.allow.branches not enabled
710 acl: acl.deny.branches not enabled
704 acl: acl.deny.branches not enabled
711 acl: acl.allow enabled, 0 entries for user barney
705 acl: acl.allow enabled, 0 entries for user barney
712 acl: acl.deny enabled, 0 entries for user barney
706 acl: acl.deny enabled, 0 entries for user barney
713 acl: branch access granted: "ef1ea85a6374" on branch "default"
707 acl: branch access granted: "ef1ea85a6374" on branch "default"
714 error: pretxnchangegroup.acl hook failed: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
708 error: pretxnchangegroup.acl hook failed: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
715 bundle2-input-part: total payload size 1553
709 bundle2-input-part: total payload size 1553
716 bundle2-input-part: total payload size 24
710 bundle2-input-part: total payload size 24
717 bundle2-input-bundle: 4 parts total
711 bundle2-input-bundle: 4 parts total
718 transaction abort!
712 transaction abort!
719 rollback completed
713 rollback completed
720 abort: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
714 abort: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
721 no rollback information available
715 no rollback information available
722 0:6675d58eff77
716 0:6675d58eff77
723
717
724
718
725 fred is not blocked from moving bookmarks
719 fred is not blocked from moving bookmarks
726
720
727 $ hg -R a book -q moving-bookmark -r 1
721 $ hg -R a book -q moving-bookmark -r 1
728 $ hg -R b book -q moving-bookmark -r 0
722 $ hg -R b book -q moving-bookmark -r 0
729 $ cp $config normalconfig
723 $ cp $config normalconfig
730 $ do_push fred -r 1
724 $ do_push fred -r 1
731 Pushing as user fred
725 Pushing as user fred
732 hgrc = """
726 hgrc = """
733 [hooks]
727 [hooks]
734 pretxnchangegroup.acl = python:hgext.acl.hook
728 pretxnchangegroup.acl = python:hgext.acl.hook
735 prepushkey.acl = python:hgext.acl.hook
729 prepushkey.acl = python:hgext.acl.hook
736 [acl]
730 [acl]
737 sources = push
731 sources = push
738 [acl.allow]
732 [acl.allow]
739 foo/** = fred
733 foo/** = fred
740 [acl.deny]
734 [acl.deny]
741 foo/bar/** = fred
735 foo/bar/** = fred
742 foo/Bar/** = fred
736 foo/Bar/** = fred
743 """
737 """
744 pushing to ../b
738 pushing to ../b
745 query 1; heads
739 query 1; heads
746 searching for changes
740 searching for changes
747 all remote heads known locally
741 all remote heads known locally
748 listing keys for "phases"
742 listing keys for "phases"
749 checking for updated bookmarks
743 checking for updated bookmarks
750 listing keys for "bookmarks"
744 listing keys for "bookmarks"
751 listing keys for "bookmarks"
745 listing keys for "bookmarks"
752 1 changesets found
746 1 changesets found
753 list of changesets:
747 list of changesets:
754 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
748 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
755 bundle2-output-bundle: "HG20", 7 parts total
749 bundle2-output-bundle: "HG20", 7 parts total
756 bundle2-output-part: "replycaps" 205 bytes payload
750 bundle2-output-part: "replycaps" 205 bytes payload
757 bundle2-output-part: "check:bookmarks" 37 bytes payload
751 bundle2-output-part: "check:bookmarks" 37 bytes payload
758 bundle2-output-part: "check:phases" 24 bytes payload
752 bundle2-output-part: "check:phases" 24 bytes payload
759 bundle2-output-part: "check:heads" streamed payload
753 bundle2-output-part: "check:heads" streamed payload
760 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
754 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
761 bundle2-output-part: "phase-heads" 24 bytes payload
755 bundle2-output-part: "phase-heads" 24 bytes payload
762 bundle2-output-part: "bookmarks" 37 bytes payload
756 bundle2-output-part: "bookmarks" 37 bytes payload
763 bundle2-input-bundle: with-transaction
757 bundle2-input-bundle: with-transaction
764 bundle2-input-part: "replycaps" supported
758 bundle2-input-part: "replycaps" supported
765 bundle2-input-part: total payload size 205
759 bundle2-input-part: total payload size 205
766 bundle2-input-part: "check:bookmarks" supported
760 bundle2-input-part: "check:bookmarks" supported
767 bundle2-input-part: total payload size 37
761 bundle2-input-part: total payload size 37
768 bundle2-input-part: "check:phases" supported
762 bundle2-input-part: "check:phases" supported
769 bundle2-input-part: total payload size 24
763 bundle2-input-part: total payload size 24
770 bundle2-input-part: "check:heads" supported
764 bundle2-input-part: "check:heads" supported
771 bundle2-input-part: total payload size 20
765 bundle2-input-part: total payload size 20
772 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
766 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
773 adding changesets
767 adding changesets
774 add changeset ef1ea85a6374
768 add changeset ef1ea85a6374
775 adding manifests
769 adding manifests
776 adding file changes
770 adding file changes
777 adding foo/file.txt revisions
771 adding foo/file.txt revisions
778 added 1 changesets with 1 changes to 1 files
779 calling hook pretxnchangegroup.acl: hgext.acl.hook
772 calling hook pretxnchangegroup.acl: hgext.acl.hook
780 acl: checking access for user "fred"
773 acl: checking access for user "fred"
781 acl: acl.allow.branches not enabled
774 acl: acl.allow.branches not enabled
782 acl: acl.deny.branches not enabled
775 acl: acl.deny.branches not enabled
783 acl: acl.allow enabled, 1 entries for user fred
776 acl: acl.allow enabled, 1 entries for user fred
784 acl: acl.deny enabled, 2 entries for user fred
777 acl: acl.deny enabled, 2 entries for user fred
785 acl: branch access granted: "ef1ea85a6374" on branch "default"
778 acl: branch access granted: "ef1ea85a6374" on branch "default"
786 acl: path access granted: "ef1ea85a6374"
779 acl: path access granted: "ef1ea85a6374"
787 bundle2-input-part: total payload size 520
780 bundle2-input-part: total payload size 520
788 bundle2-input-part: "phase-heads" supported
781 bundle2-input-part: "phase-heads" supported
789 bundle2-input-part: total payload size 24
782 bundle2-input-part: total payload size 24
790 bundle2-input-part: "bookmarks" supported
783 bundle2-input-part: "bookmarks" supported
791 bundle2-input-part: total payload size 37
784 bundle2-input-part: total payload size 37
792 calling hook prepushkey.acl: hgext.acl.hook
785 calling hook prepushkey.acl: hgext.acl.hook
793 acl: checking access for user "fred"
786 acl: checking access for user "fred"
794 acl: acl.allow.bookmarks not enabled
787 acl: acl.allow.bookmarks not enabled
795 acl: acl.deny.bookmarks not enabled
788 acl: acl.deny.bookmarks not enabled
796 acl: bookmark access granted: "ef1ea85a6374b77d6da9dcda9541f498f2d17df7" on bookmark "moving-bookmark"
789 acl: bookmark access granted: "ef1ea85a6374b77d6da9dcda9541f498f2d17df7" on bookmark "moving-bookmark"
797 bundle2-input-bundle: 6 parts total
790 bundle2-input-bundle: 6 parts total
798 updating the branch cache
791 updating the branch cache
792 added 1 changesets with 1 changes to 1 files
799 bundle2-output-bundle: "HG20", 1 parts total
793 bundle2-output-bundle: "HG20", 1 parts total
800 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
794 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
801 bundle2-input-bundle: no-transaction
795 bundle2-input-bundle: no-transaction
802 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
796 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
803 bundle2-input-bundle: 0 parts total
797 bundle2-input-bundle: 0 parts total
804 updating bookmark moving-bookmark
798 updating bookmark moving-bookmark
805 listing keys for "phases"
799 listing keys for "phases"
806 repository tip rolled back to revision 0 (undo push)
800 repository tip rolled back to revision 0 (undo push)
807 0:6675d58eff77
801 0:6675d58eff77
808
802
809
803
810 fred is not allowed to move bookmarks
804 fred is not allowed to move bookmarks
811
805
812 $ echo '[acl.deny.bookmarks]' >> $config
806 $ echo '[acl.deny.bookmarks]' >> $config
813 $ echo '* = fred' >> $config
807 $ echo '* = fred' >> $config
814 $ do_push fred -r 1
808 $ do_push fred -r 1
815 Pushing as user fred
809 Pushing as user fred
816 hgrc = """
810 hgrc = """
817 [hooks]
811 [hooks]
818 pretxnchangegroup.acl = python:hgext.acl.hook
812 pretxnchangegroup.acl = python:hgext.acl.hook
819 prepushkey.acl = python:hgext.acl.hook
813 prepushkey.acl = python:hgext.acl.hook
820 [acl]
814 [acl]
821 sources = push
815 sources = push
822 [acl.allow]
816 [acl.allow]
823 foo/** = fred
817 foo/** = fred
824 [acl.deny]
818 [acl.deny]
825 foo/bar/** = fred
819 foo/bar/** = fred
826 foo/Bar/** = fred
820 foo/Bar/** = fred
827 [acl.deny.bookmarks]
821 [acl.deny.bookmarks]
828 * = fred
822 * = fred
829 """
823 """
830 pushing to ../b
824 pushing to ../b
831 query 1; heads
825 query 1; heads
832 searching for changes
826 searching for changes
833 all remote heads known locally
827 all remote heads known locally
834 listing keys for "phases"
828 listing keys for "phases"
835 checking for updated bookmarks
829 checking for updated bookmarks
836 listing keys for "bookmarks"
830 listing keys for "bookmarks"
837 listing keys for "bookmarks"
831 listing keys for "bookmarks"
838 1 changesets found
832 1 changesets found
839 list of changesets:
833 list of changesets:
840 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
834 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
841 bundle2-output-bundle: "HG20", 7 parts total
835 bundle2-output-bundle: "HG20", 7 parts total
842 bundle2-output-part: "replycaps" 205 bytes payload
836 bundle2-output-part: "replycaps" 205 bytes payload
843 bundle2-output-part: "check:bookmarks" 37 bytes payload
837 bundle2-output-part: "check:bookmarks" 37 bytes payload
844 bundle2-output-part: "check:phases" 24 bytes payload
838 bundle2-output-part: "check:phases" 24 bytes payload
845 bundle2-output-part: "check:heads" streamed payload
839 bundle2-output-part: "check:heads" streamed payload
846 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
840 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
847 bundle2-output-part: "phase-heads" 24 bytes payload
841 bundle2-output-part: "phase-heads" 24 bytes payload
848 bundle2-output-part: "bookmarks" 37 bytes payload
842 bundle2-output-part: "bookmarks" 37 bytes payload
849 bundle2-input-bundle: with-transaction
843 bundle2-input-bundle: with-transaction
850 bundle2-input-part: "replycaps" supported
844 bundle2-input-part: "replycaps" supported
851 bundle2-input-part: total payload size 205
845 bundle2-input-part: total payload size 205
852 bundle2-input-part: "check:bookmarks" supported
846 bundle2-input-part: "check:bookmarks" supported
853 bundle2-input-part: total payload size 37
847 bundle2-input-part: total payload size 37
854 bundle2-input-part: "check:phases" supported
848 bundle2-input-part: "check:phases" supported
855 bundle2-input-part: total payload size 24
849 bundle2-input-part: total payload size 24
856 bundle2-input-part: "check:heads" supported
850 bundle2-input-part: "check:heads" supported
857 bundle2-input-part: total payload size 20
851 bundle2-input-part: total payload size 20
858 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
852 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
859 adding changesets
853 adding changesets
860 add changeset ef1ea85a6374
854 add changeset ef1ea85a6374
861 adding manifests
855 adding manifests
862 adding file changes
856 adding file changes
863 adding foo/file.txt revisions
857 adding foo/file.txt revisions
864 added 1 changesets with 1 changes to 1 files
865 calling hook pretxnchangegroup.acl: hgext.acl.hook
858 calling hook pretxnchangegroup.acl: hgext.acl.hook
866 acl: checking access for user "fred"
859 acl: checking access for user "fred"
867 acl: acl.allow.branches not enabled
860 acl: acl.allow.branches not enabled
868 acl: acl.deny.branches not enabled
861 acl: acl.deny.branches not enabled
869 acl: acl.allow enabled, 1 entries for user fred
862 acl: acl.allow enabled, 1 entries for user fred
870 acl: acl.deny enabled, 2 entries for user fred
863 acl: acl.deny enabled, 2 entries for user fred
871 acl: branch access granted: "ef1ea85a6374" on branch "default"
864 acl: branch access granted: "ef1ea85a6374" on branch "default"
872 acl: path access granted: "ef1ea85a6374"
865 acl: path access granted: "ef1ea85a6374"
873 bundle2-input-part: total payload size 520
866 bundle2-input-part: total payload size 520
874 bundle2-input-part: "phase-heads" supported
867 bundle2-input-part: "phase-heads" supported
875 bundle2-input-part: total payload size 24
868 bundle2-input-part: total payload size 24
876 bundle2-input-part: "bookmarks" supported
869 bundle2-input-part: "bookmarks" supported
877 bundle2-input-part: total payload size 37
870 bundle2-input-part: total payload size 37
878 calling hook prepushkey.acl: hgext.acl.hook
871 calling hook prepushkey.acl: hgext.acl.hook
879 acl: checking access for user "fred"
872 acl: checking access for user "fred"
880 acl: acl.allow.bookmarks not enabled
873 acl: acl.allow.bookmarks not enabled
881 acl: acl.deny.bookmarks enabled, 1 entries for user fred
874 acl: acl.deny.bookmarks enabled, 1 entries for user fred
882 error: prepushkey.acl hook failed: acl: user "fred" denied on bookmark "moving-bookmark" (changeset "ef1ea85a6374b77d6da9dcda9541f498f2d17df7")
875 error: prepushkey.acl hook failed: acl: user "fred" denied on bookmark "moving-bookmark" (changeset "ef1ea85a6374b77d6da9dcda9541f498f2d17df7")
883 bundle2-input-bundle: 6 parts total
876 bundle2-input-bundle: 6 parts total
884 transaction abort!
877 transaction abort!
885 rollback completed
878 rollback completed
886 abort: acl: user "fred" denied on bookmark "moving-bookmark" (changeset "ef1ea85a6374b77d6da9dcda9541f498f2d17df7")
879 abort: acl: user "fred" denied on bookmark "moving-bookmark" (changeset "ef1ea85a6374b77d6da9dcda9541f498f2d17df7")
887 no rollback information available
880 no rollback information available
888 0:6675d58eff77
881 0:6675d58eff77
889
882
890
883
891 cleanup bookmark stuff
884 cleanup bookmark stuff
892
885
893 $ hg book -R a -d moving-bookmark
886 $ hg book -R a -d moving-bookmark
894 $ hg book -R b -d moving-bookmark
887 $ hg book -R b -d moving-bookmark
895 $ cp normalconfig $config
888 $ cp normalconfig $config
896
889
897 barney is allowed everywhere
890 barney is allowed everywhere
898
891
899 $ echo '[acl.allow]' >> $config
892 $ echo '[acl.allow]' >> $config
900 $ echo '** = barney' >> $config
893 $ echo '** = barney' >> $config
901 $ do_push barney
894 $ do_push barney
902 Pushing as user barney
895 Pushing as user barney
903 hgrc = """
896 hgrc = """
904 [hooks]
897 [hooks]
905 pretxnchangegroup.acl = python:hgext.acl.hook
898 pretxnchangegroup.acl = python:hgext.acl.hook
906 prepushkey.acl = python:hgext.acl.hook
899 prepushkey.acl = python:hgext.acl.hook
907 [acl]
900 [acl]
908 sources = push
901 sources = push
909 [acl.allow]
902 [acl.allow]
910 foo/** = fred
903 foo/** = fred
911 [acl.deny]
904 [acl.deny]
912 foo/bar/** = fred
905 foo/bar/** = fred
913 foo/Bar/** = fred
906 foo/Bar/** = fred
914 [acl.allow]
907 [acl.allow]
915 ** = barney
908 ** = barney
916 """
909 """
917 pushing to ../b
910 pushing to ../b
918 query 1; heads
911 query 1; heads
919 searching for changes
912 searching for changes
920 all remote heads known locally
913 all remote heads known locally
921 listing keys for "phases"
914 listing keys for "phases"
922 checking for updated bookmarks
915 checking for updated bookmarks
923 listing keys for "bookmarks"
916 listing keys for "bookmarks"
924 listing keys for "bookmarks"
917 listing keys for "bookmarks"
925 3 changesets found
918 3 changesets found
926 list of changesets:
919 list of changesets:
927 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
920 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
928 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
921 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
929 911600dab2ae7a9baff75958b84fe606851ce955
922 911600dab2ae7a9baff75958b84fe606851ce955
930 bundle2-output-bundle: "HG20", 5 parts total
923 bundle2-output-bundle: "HG20", 5 parts total
931 bundle2-output-part: "replycaps" 205 bytes payload
924 bundle2-output-part: "replycaps" 205 bytes payload
932 bundle2-output-part: "check:phases" 24 bytes payload
925 bundle2-output-part: "check:phases" 24 bytes payload
933 bundle2-output-part: "check:heads" streamed payload
926 bundle2-output-part: "check:heads" streamed payload
934 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
927 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
935 bundle2-output-part: "phase-heads" 24 bytes payload
928 bundle2-output-part: "phase-heads" 24 bytes payload
936 bundle2-input-bundle: with-transaction
929 bundle2-input-bundle: with-transaction
937 bundle2-input-part: "replycaps" supported
930 bundle2-input-part: "replycaps" supported
938 bundle2-input-part: total payload size 205
931 bundle2-input-part: total payload size 205
939 bundle2-input-part: "check:phases" supported
932 bundle2-input-part: "check:phases" supported
940 bundle2-input-part: total payload size 24
933 bundle2-input-part: total payload size 24
941 bundle2-input-part: "check:heads" supported
934 bundle2-input-part: "check:heads" supported
942 bundle2-input-part: total payload size 20
935 bundle2-input-part: total payload size 20
943 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
936 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
944 adding changesets
937 adding changesets
945 add changeset ef1ea85a6374
938 add changeset ef1ea85a6374
946 add changeset f9cafe1212c8
939 add changeset f9cafe1212c8
947 add changeset 911600dab2ae
940 add changeset 911600dab2ae
948 adding manifests
941 adding manifests
949 adding file changes
942 adding file changes
950 adding foo/Bar/file.txt revisions
943 adding foo/Bar/file.txt revisions
951 adding foo/file.txt revisions
944 adding foo/file.txt revisions
952 adding quux/file.py revisions
945 adding quux/file.py revisions
953 added 3 changesets with 3 changes to 3 files
954 calling hook pretxnchangegroup.acl: hgext.acl.hook
946 calling hook pretxnchangegroup.acl: hgext.acl.hook
955 acl: checking access for user "barney"
947 acl: checking access for user "barney"
956 acl: acl.allow.branches not enabled
948 acl: acl.allow.branches not enabled
957 acl: acl.deny.branches not enabled
949 acl: acl.deny.branches not enabled
958 acl: acl.allow enabled, 1 entries for user barney
950 acl: acl.allow enabled, 1 entries for user barney
959 acl: acl.deny enabled, 0 entries for user barney
951 acl: acl.deny enabled, 0 entries for user barney
960 acl: branch access granted: "ef1ea85a6374" on branch "default"
952 acl: branch access granted: "ef1ea85a6374" on branch "default"
961 acl: path access granted: "ef1ea85a6374"
953 acl: path access granted: "ef1ea85a6374"
962 acl: branch access granted: "f9cafe1212c8" on branch "default"
954 acl: branch access granted: "f9cafe1212c8" on branch "default"
963 acl: path access granted: "f9cafe1212c8"
955 acl: path access granted: "f9cafe1212c8"
964 acl: branch access granted: "911600dab2ae" on branch "default"
956 acl: branch access granted: "911600dab2ae" on branch "default"
965 acl: path access granted: "911600dab2ae"
957 acl: path access granted: "911600dab2ae"
966 bundle2-input-part: total payload size 1553
958 bundle2-input-part: total payload size 1553
967 bundle2-input-part: "phase-heads" supported
959 bundle2-input-part: "phase-heads" supported
968 bundle2-input-part: total payload size 24
960 bundle2-input-part: total payload size 24
969 bundle2-input-bundle: 4 parts total
961 bundle2-input-bundle: 4 parts total
970 updating the branch cache
962 updating the branch cache
963 added 3 changesets with 3 changes to 3 files
971 bundle2-output-bundle: "HG20", 1 parts total
964 bundle2-output-bundle: "HG20", 1 parts total
972 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
965 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
973 bundle2-input-bundle: no-transaction
966 bundle2-input-bundle: no-transaction
974 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
967 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
975 bundle2-input-bundle: 0 parts total
968 bundle2-input-bundle: 0 parts total
976 listing keys for "phases"
969 listing keys for "phases"
977 repository tip rolled back to revision 0 (undo push)
970 repository tip rolled back to revision 0 (undo push)
978 0:6675d58eff77
971 0:6675d58eff77
979
972
980
973
981 wilma can change files with a .txt extension
974 wilma can change files with a .txt extension
982
975
983 $ echo '**/*.txt = wilma' >> $config
976 $ echo '**/*.txt = wilma' >> $config
984 $ do_push wilma
977 $ do_push wilma
985 Pushing as user wilma
978 Pushing as user wilma
986 hgrc = """
979 hgrc = """
987 [hooks]
980 [hooks]
988 pretxnchangegroup.acl = python:hgext.acl.hook
981 pretxnchangegroup.acl = python:hgext.acl.hook
989 prepushkey.acl = python:hgext.acl.hook
982 prepushkey.acl = python:hgext.acl.hook
990 [acl]
983 [acl]
991 sources = push
984 sources = push
992 [acl.allow]
985 [acl.allow]
993 foo/** = fred
986 foo/** = fred
994 [acl.deny]
987 [acl.deny]
995 foo/bar/** = fred
988 foo/bar/** = fred
996 foo/Bar/** = fred
989 foo/Bar/** = fred
997 [acl.allow]
990 [acl.allow]
998 ** = barney
991 ** = barney
999 **/*.txt = wilma
992 **/*.txt = wilma
1000 """
993 """
1001 pushing to ../b
994 pushing to ../b
1002 query 1; heads
995 query 1; heads
1003 searching for changes
996 searching for changes
1004 all remote heads known locally
997 all remote heads known locally
1005 listing keys for "phases"
998 listing keys for "phases"
1006 checking for updated bookmarks
999 checking for updated bookmarks
1007 listing keys for "bookmarks"
1000 listing keys for "bookmarks"
1008 listing keys for "bookmarks"
1001 listing keys for "bookmarks"
1009 3 changesets found
1002 3 changesets found
1010 list of changesets:
1003 list of changesets:
1011 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1004 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1012 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1005 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1013 911600dab2ae7a9baff75958b84fe606851ce955
1006 911600dab2ae7a9baff75958b84fe606851ce955
1014 bundle2-output-bundle: "HG20", 5 parts total
1007 bundle2-output-bundle: "HG20", 5 parts total
1015 bundle2-output-part: "replycaps" 205 bytes payload
1008 bundle2-output-part: "replycaps" 205 bytes payload
1016 bundle2-output-part: "check:phases" 24 bytes payload
1009 bundle2-output-part: "check:phases" 24 bytes payload
1017 bundle2-output-part: "check:heads" streamed payload
1010 bundle2-output-part: "check:heads" streamed payload
1018 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1011 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1019 bundle2-output-part: "phase-heads" 24 bytes payload
1012 bundle2-output-part: "phase-heads" 24 bytes payload
1020 bundle2-input-bundle: with-transaction
1013 bundle2-input-bundle: with-transaction
1021 bundle2-input-part: "replycaps" supported
1014 bundle2-input-part: "replycaps" supported
1022 bundle2-input-part: total payload size 205
1015 bundle2-input-part: total payload size 205
1023 bundle2-input-part: "check:phases" supported
1016 bundle2-input-part: "check:phases" supported
1024 bundle2-input-part: total payload size 24
1017 bundle2-input-part: total payload size 24
1025 bundle2-input-part: "check:heads" supported
1018 bundle2-input-part: "check:heads" supported
1026 bundle2-input-part: total payload size 20
1019 bundle2-input-part: total payload size 20
1027 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1020 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1028 adding changesets
1021 adding changesets
1029 add changeset ef1ea85a6374
1022 add changeset ef1ea85a6374
1030 add changeset f9cafe1212c8
1023 add changeset f9cafe1212c8
1031 add changeset 911600dab2ae
1024 add changeset 911600dab2ae
1032 adding manifests
1025 adding manifests
1033 adding file changes
1026 adding file changes
1034 adding foo/Bar/file.txt revisions
1027 adding foo/Bar/file.txt revisions
1035 adding foo/file.txt revisions
1028 adding foo/file.txt revisions
1036 adding quux/file.py revisions
1029 adding quux/file.py revisions
1037 added 3 changesets with 3 changes to 3 files
1038 calling hook pretxnchangegroup.acl: hgext.acl.hook
1030 calling hook pretxnchangegroup.acl: hgext.acl.hook
1039 acl: checking access for user "wilma"
1031 acl: checking access for user "wilma"
1040 acl: acl.allow.branches not enabled
1032 acl: acl.allow.branches not enabled
1041 acl: acl.deny.branches not enabled
1033 acl: acl.deny.branches not enabled
1042 acl: acl.allow enabled, 1 entries for user wilma
1034 acl: acl.allow enabled, 1 entries for user wilma
1043 acl: acl.deny enabled, 0 entries for user wilma
1035 acl: acl.deny enabled, 0 entries for user wilma
1044 acl: branch access granted: "ef1ea85a6374" on branch "default"
1036 acl: branch access granted: "ef1ea85a6374" on branch "default"
1045 acl: path access granted: "ef1ea85a6374"
1037 acl: path access granted: "ef1ea85a6374"
1046 acl: branch access granted: "f9cafe1212c8" on branch "default"
1038 acl: branch access granted: "f9cafe1212c8" on branch "default"
1047 acl: path access granted: "f9cafe1212c8"
1039 acl: path access granted: "f9cafe1212c8"
1048 acl: branch access granted: "911600dab2ae" on branch "default"
1040 acl: branch access granted: "911600dab2ae" on branch "default"
1049 error: pretxnchangegroup.acl hook failed: acl: user "wilma" not allowed on "quux/file.py" (changeset "911600dab2ae")
1041 error: pretxnchangegroup.acl hook failed: acl: user "wilma" not allowed on "quux/file.py" (changeset "911600dab2ae")
1050 bundle2-input-part: total payload size 1553
1042 bundle2-input-part: total payload size 1553
1051 bundle2-input-part: total payload size 24
1043 bundle2-input-part: total payload size 24
1052 bundle2-input-bundle: 4 parts total
1044 bundle2-input-bundle: 4 parts total
1053 transaction abort!
1045 transaction abort!
1054 rollback completed
1046 rollback completed
1055 abort: acl: user "wilma" not allowed on "quux/file.py" (changeset "911600dab2ae")
1047 abort: acl: user "wilma" not allowed on "quux/file.py" (changeset "911600dab2ae")
1056 no rollback information available
1048 no rollback information available
1057 0:6675d58eff77
1049 0:6675d58eff77
1058
1050
1059
1051
1060 file specified by acl.config does not exist
1052 file specified by acl.config does not exist
1061
1053
1062 $ echo '[acl]' >> $config
1054 $ echo '[acl]' >> $config
1063 $ echo 'config = ../acl.config' >> $config
1055 $ echo 'config = ../acl.config' >> $config
1064 $ do_push barney
1056 $ do_push barney
1065 Pushing as user barney
1057 Pushing as user barney
1066 hgrc = """
1058 hgrc = """
1067 [hooks]
1059 [hooks]
1068 pretxnchangegroup.acl = python:hgext.acl.hook
1060 pretxnchangegroup.acl = python:hgext.acl.hook
1069 prepushkey.acl = python:hgext.acl.hook
1061 prepushkey.acl = python:hgext.acl.hook
1070 [acl]
1062 [acl]
1071 sources = push
1063 sources = push
1072 [acl.allow]
1064 [acl.allow]
1073 foo/** = fred
1065 foo/** = fred
1074 [acl.deny]
1066 [acl.deny]
1075 foo/bar/** = fred
1067 foo/bar/** = fred
1076 foo/Bar/** = fred
1068 foo/Bar/** = fred
1077 [acl.allow]
1069 [acl.allow]
1078 ** = barney
1070 ** = barney
1079 **/*.txt = wilma
1071 **/*.txt = wilma
1080 [acl]
1072 [acl]
1081 config = ../acl.config
1073 config = ../acl.config
1082 """
1074 """
1083 pushing to ../b
1075 pushing to ../b
1084 query 1; heads
1076 query 1; heads
1085 searching for changes
1077 searching for changes
1086 all remote heads known locally
1078 all remote heads known locally
1087 listing keys for "phases"
1079 listing keys for "phases"
1088 checking for updated bookmarks
1080 checking for updated bookmarks
1089 listing keys for "bookmarks"
1081 listing keys for "bookmarks"
1090 listing keys for "bookmarks"
1082 listing keys for "bookmarks"
1091 3 changesets found
1083 3 changesets found
1092 list of changesets:
1084 list of changesets:
1093 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1085 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1094 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1086 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1095 911600dab2ae7a9baff75958b84fe606851ce955
1087 911600dab2ae7a9baff75958b84fe606851ce955
1096 bundle2-output-bundle: "HG20", 5 parts total
1088 bundle2-output-bundle: "HG20", 5 parts total
1097 bundle2-output-part: "replycaps" 205 bytes payload
1089 bundle2-output-part: "replycaps" 205 bytes payload
1098 bundle2-output-part: "check:phases" 24 bytes payload
1090 bundle2-output-part: "check:phases" 24 bytes payload
1099 bundle2-output-part: "check:heads" streamed payload
1091 bundle2-output-part: "check:heads" streamed payload
1100 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1092 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1101 bundle2-output-part: "phase-heads" 24 bytes payload
1093 bundle2-output-part: "phase-heads" 24 bytes payload
1102 bundle2-input-bundle: with-transaction
1094 bundle2-input-bundle: with-transaction
1103 bundle2-input-part: "replycaps" supported
1095 bundle2-input-part: "replycaps" supported
1104 bundle2-input-part: total payload size 205
1096 bundle2-input-part: total payload size 205
1105 bundle2-input-part: "check:phases" supported
1097 bundle2-input-part: "check:phases" supported
1106 bundle2-input-part: total payload size 24
1098 bundle2-input-part: total payload size 24
1107 bundle2-input-part: "check:heads" supported
1099 bundle2-input-part: "check:heads" supported
1108 bundle2-input-part: total payload size 20
1100 bundle2-input-part: total payload size 20
1109 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1101 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1110 adding changesets
1102 adding changesets
1111 add changeset ef1ea85a6374
1103 add changeset ef1ea85a6374
1112 add changeset f9cafe1212c8
1104 add changeset f9cafe1212c8
1113 add changeset 911600dab2ae
1105 add changeset 911600dab2ae
1114 adding manifests
1106 adding manifests
1115 adding file changes
1107 adding file changes
1116 adding foo/Bar/file.txt revisions
1108 adding foo/Bar/file.txt revisions
1117 adding foo/file.txt revisions
1109 adding foo/file.txt revisions
1118 adding quux/file.py revisions
1110 adding quux/file.py revisions
1119 added 3 changesets with 3 changes to 3 files
1120 calling hook pretxnchangegroup.acl: hgext.acl.hook
1111 calling hook pretxnchangegroup.acl: hgext.acl.hook
1121 acl: checking access for user "barney"
1112 acl: checking access for user "barney"
1122 error: pretxnchangegroup.acl hook raised an exception: [Errno *] * (glob)
1113 error: pretxnchangegroup.acl hook raised an exception: [Errno *] * (glob)
1123 bundle2-input-part: total payload size 1553
1114 bundle2-input-part: total payload size 1553
1124 bundle2-input-part: total payload size 24
1115 bundle2-input-part: total payload size 24
1125 bundle2-input-bundle: 4 parts total
1116 bundle2-input-bundle: 4 parts total
1126 transaction abort!
1117 transaction abort!
1127 rollback completed
1118 rollback completed
1128 abort: $ENOENT$: '../acl.config'
1119 abort: $ENOENT$: '../acl.config'
1129 no rollback information available
1120 no rollback information available
1130 0:6675d58eff77
1121 0:6675d58eff77
1131
1122
1132
1123
1133 betty is allowed inside foo/ by a acl.config file
1124 betty is allowed inside foo/ by a acl.config file
1134
1125
1135 $ echo '[acl.allow]' >> acl.config
1126 $ echo '[acl.allow]' >> acl.config
1136 $ echo 'foo/** = betty' >> acl.config
1127 $ echo 'foo/** = betty' >> acl.config
1137 $ do_push betty
1128 $ do_push betty
1138 Pushing as user betty
1129 Pushing as user betty
1139 hgrc = """
1130 hgrc = """
1140 [hooks]
1131 [hooks]
1141 pretxnchangegroup.acl = python:hgext.acl.hook
1132 pretxnchangegroup.acl = python:hgext.acl.hook
1142 prepushkey.acl = python:hgext.acl.hook
1133 prepushkey.acl = python:hgext.acl.hook
1143 [acl]
1134 [acl]
1144 sources = push
1135 sources = push
1145 [acl.allow]
1136 [acl.allow]
1146 foo/** = fred
1137 foo/** = fred
1147 [acl.deny]
1138 [acl.deny]
1148 foo/bar/** = fred
1139 foo/bar/** = fred
1149 foo/Bar/** = fred
1140 foo/Bar/** = fred
1150 [acl.allow]
1141 [acl.allow]
1151 ** = barney
1142 ** = barney
1152 **/*.txt = wilma
1143 **/*.txt = wilma
1153 [acl]
1144 [acl]
1154 config = ../acl.config
1145 config = ../acl.config
1155 """
1146 """
1156 acl.config = """
1147 acl.config = """
1157 [acl.allow]
1148 [acl.allow]
1158 foo/** = betty
1149 foo/** = betty
1159 """
1150 """
1160 pushing to ../b
1151 pushing to ../b
1161 query 1; heads
1152 query 1; heads
1162 searching for changes
1153 searching for changes
1163 all remote heads known locally
1154 all remote heads known locally
1164 listing keys for "phases"
1155 listing keys for "phases"
1165 checking for updated bookmarks
1156 checking for updated bookmarks
1166 listing keys for "bookmarks"
1157 listing keys for "bookmarks"
1167 listing keys for "bookmarks"
1158 listing keys for "bookmarks"
1168 3 changesets found
1159 3 changesets found
1169 list of changesets:
1160 list of changesets:
1170 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1161 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1171 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1162 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1172 911600dab2ae7a9baff75958b84fe606851ce955
1163 911600dab2ae7a9baff75958b84fe606851ce955
1173 bundle2-output-bundle: "HG20", 5 parts total
1164 bundle2-output-bundle: "HG20", 5 parts total
1174 bundle2-output-part: "replycaps" 205 bytes payload
1165 bundle2-output-part: "replycaps" 205 bytes payload
1175 bundle2-output-part: "check:phases" 24 bytes payload
1166 bundle2-output-part: "check:phases" 24 bytes payload
1176 bundle2-output-part: "check:heads" streamed payload
1167 bundle2-output-part: "check:heads" streamed payload
1177 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1168 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1178 bundle2-output-part: "phase-heads" 24 bytes payload
1169 bundle2-output-part: "phase-heads" 24 bytes payload
1179 bundle2-input-bundle: with-transaction
1170 bundle2-input-bundle: with-transaction
1180 bundle2-input-part: "replycaps" supported
1171 bundle2-input-part: "replycaps" supported
1181 bundle2-input-part: total payload size 205
1172 bundle2-input-part: total payload size 205
1182 bundle2-input-part: "check:phases" supported
1173 bundle2-input-part: "check:phases" supported
1183 bundle2-input-part: total payload size 24
1174 bundle2-input-part: total payload size 24
1184 bundle2-input-part: "check:heads" supported
1175 bundle2-input-part: "check:heads" supported
1185 bundle2-input-part: total payload size 20
1176 bundle2-input-part: total payload size 20
1186 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1177 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1187 adding changesets
1178 adding changesets
1188 add changeset ef1ea85a6374
1179 add changeset ef1ea85a6374
1189 add changeset f9cafe1212c8
1180 add changeset f9cafe1212c8
1190 add changeset 911600dab2ae
1181 add changeset 911600dab2ae
1191 adding manifests
1182 adding manifests
1192 adding file changes
1183 adding file changes
1193 adding foo/Bar/file.txt revisions
1184 adding foo/Bar/file.txt revisions
1194 adding foo/file.txt revisions
1185 adding foo/file.txt revisions
1195 adding quux/file.py revisions
1186 adding quux/file.py revisions
1196 added 3 changesets with 3 changes to 3 files
1197 calling hook pretxnchangegroup.acl: hgext.acl.hook
1187 calling hook pretxnchangegroup.acl: hgext.acl.hook
1198 acl: checking access for user "betty"
1188 acl: checking access for user "betty"
1199 acl: acl.allow.branches not enabled
1189 acl: acl.allow.branches not enabled
1200 acl: acl.deny.branches not enabled
1190 acl: acl.deny.branches not enabled
1201 acl: acl.allow enabled, 1 entries for user betty
1191 acl: acl.allow enabled, 1 entries for user betty
1202 acl: acl.deny enabled, 0 entries for user betty
1192 acl: acl.deny enabled, 0 entries for user betty
1203 acl: branch access granted: "ef1ea85a6374" on branch "default"
1193 acl: branch access granted: "ef1ea85a6374" on branch "default"
1204 acl: path access granted: "ef1ea85a6374"
1194 acl: path access granted: "ef1ea85a6374"
1205 acl: branch access granted: "f9cafe1212c8" on branch "default"
1195 acl: branch access granted: "f9cafe1212c8" on branch "default"
1206 acl: path access granted: "f9cafe1212c8"
1196 acl: path access granted: "f9cafe1212c8"
1207 acl: branch access granted: "911600dab2ae" on branch "default"
1197 acl: branch access granted: "911600dab2ae" on branch "default"
1208 error: pretxnchangegroup.acl hook failed: acl: user "betty" not allowed on "quux/file.py" (changeset "911600dab2ae")
1198 error: pretxnchangegroup.acl hook failed: acl: user "betty" not allowed on "quux/file.py" (changeset "911600dab2ae")
1209 bundle2-input-part: total payload size 1553
1199 bundle2-input-part: total payload size 1553
1210 bundle2-input-part: total payload size 24
1200 bundle2-input-part: total payload size 24
1211 bundle2-input-bundle: 4 parts total
1201 bundle2-input-bundle: 4 parts total
1212 transaction abort!
1202 transaction abort!
1213 rollback completed
1203 rollback completed
1214 abort: acl: user "betty" not allowed on "quux/file.py" (changeset "911600dab2ae")
1204 abort: acl: user "betty" not allowed on "quux/file.py" (changeset "911600dab2ae")
1215 no rollback information available
1205 no rollback information available
1216 0:6675d58eff77
1206 0:6675d58eff77
1217
1207
1218
1208
1219 acl.config can set only [acl.allow]/[acl.deny]
1209 acl.config can set only [acl.allow]/[acl.deny]
1220
1210
1221 $ echo '[hooks]' >> acl.config
1211 $ echo '[hooks]' >> acl.config
1222 $ echo 'changegroup.acl = false' >> acl.config
1212 $ echo 'changegroup.acl = false' >> acl.config
1223 $ do_push barney
1213 $ do_push barney
1224 Pushing as user barney
1214 Pushing as user barney
1225 hgrc = """
1215 hgrc = """
1226 [hooks]
1216 [hooks]
1227 pretxnchangegroup.acl = python:hgext.acl.hook
1217 pretxnchangegroup.acl = python:hgext.acl.hook
1228 prepushkey.acl = python:hgext.acl.hook
1218 prepushkey.acl = python:hgext.acl.hook
1229 [acl]
1219 [acl]
1230 sources = push
1220 sources = push
1231 [acl.allow]
1221 [acl.allow]
1232 foo/** = fred
1222 foo/** = fred
1233 [acl.deny]
1223 [acl.deny]
1234 foo/bar/** = fred
1224 foo/bar/** = fred
1235 foo/Bar/** = fred
1225 foo/Bar/** = fred
1236 [acl.allow]
1226 [acl.allow]
1237 ** = barney
1227 ** = barney
1238 **/*.txt = wilma
1228 **/*.txt = wilma
1239 [acl]
1229 [acl]
1240 config = ../acl.config
1230 config = ../acl.config
1241 """
1231 """
1242 acl.config = """
1232 acl.config = """
1243 [acl.allow]
1233 [acl.allow]
1244 foo/** = betty
1234 foo/** = betty
1245 [hooks]
1235 [hooks]
1246 changegroup.acl = false
1236 changegroup.acl = false
1247 """
1237 """
1248 pushing to ../b
1238 pushing to ../b
1249 query 1; heads
1239 query 1; heads
1250 searching for changes
1240 searching for changes
1251 all remote heads known locally
1241 all remote heads known locally
1252 listing keys for "phases"
1242 listing keys for "phases"
1253 checking for updated bookmarks
1243 checking for updated bookmarks
1254 listing keys for "bookmarks"
1244 listing keys for "bookmarks"
1255 listing keys for "bookmarks"
1245 listing keys for "bookmarks"
1256 3 changesets found
1246 3 changesets found
1257 list of changesets:
1247 list of changesets:
1258 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1248 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1259 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1249 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1260 911600dab2ae7a9baff75958b84fe606851ce955
1250 911600dab2ae7a9baff75958b84fe606851ce955
1261 bundle2-output-bundle: "HG20", 5 parts total
1251 bundle2-output-bundle: "HG20", 5 parts total
1262 bundle2-output-part: "replycaps" 205 bytes payload
1252 bundle2-output-part: "replycaps" 205 bytes payload
1263 bundle2-output-part: "check:phases" 24 bytes payload
1253 bundle2-output-part: "check:phases" 24 bytes payload
1264 bundle2-output-part: "check:heads" streamed payload
1254 bundle2-output-part: "check:heads" streamed payload
1265 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1255 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1266 bundle2-output-part: "phase-heads" 24 bytes payload
1256 bundle2-output-part: "phase-heads" 24 bytes payload
1267 bundle2-input-bundle: with-transaction
1257 bundle2-input-bundle: with-transaction
1268 bundle2-input-part: "replycaps" supported
1258 bundle2-input-part: "replycaps" supported
1269 bundle2-input-part: total payload size 205
1259 bundle2-input-part: total payload size 205
1270 bundle2-input-part: "check:phases" supported
1260 bundle2-input-part: "check:phases" supported
1271 bundle2-input-part: total payload size 24
1261 bundle2-input-part: total payload size 24
1272 bundle2-input-part: "check:heads" supported
1262 bundle2-input-part: "check:heads" supported
1273 bundle2-input-part: total payload size 20
1263 bundle2-input-part: total payload size 20
1274 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1264 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1275 adding changesets
1265 adding changesets
1276 add changeset ef1ea85a6374
1266 add changeset ef1ea85a6374
1277 add changeset f9cafe1212c8
1267 add changeset f9cafe1212c8
1278 add changeset 911600dab2ae
1268 add changeset 911600dab2ae
1279 adding manifests
1269 adding manifests
1280 adding file changes
1270 adding file changes
1281 adding foo/Bar/file.txt revisions
1271 adding foo/Bar/file.txt revisions
1282 adding foo/file.txt revisions
1272 adding foo/file.txt revisions
1283 adding quux/file.py revisions
1273 adding quux/file.py revisions
1284 added 3 changesets with 3 changes to 3 files
1285 calling hook pretxnchangegroup.acl: hgext.acl.hook
1274 calling hook pretxnchangegroup.acl: hgext.acl.hook
1286 acl: checking access for user "barney"
1275 acl: checking access for user "barney"
1287 acl: acl.allow.branches not enabled
1276 acl: acl.allow.branches not enabled
1288 acl: acl.deny.branches not enabled
1277 acl: acl.deny.branches not enabled
1289 acl: acl.allow enabled, 1 entries for user barney
1278 acl: acl.allow enabled, 1 entries for user barney
1290 acl: acl.deny enabled, 0 entries for user barney
1279 acl: acl.deny enabled, 0 entries for user barney
1291 acl: branch access granted: "ef1ea85a6374" on branch "default"
1280 acl: branch access granted: "ef1ea85a6374" on branch "default"
1292 acl: path access granted: "ef1ea85a6374"
1281 acl: path access granted: "ef1ea85a6374"
1293 acl: branch access granted: "f9cafe1212c8" on branch "default"
1282 acl: branch access granted: "f9cafe1212c8" on branch "default"
1294 acl: path access granted: "f9cafe1212c8"
1283 acl: path access granted: "f9cafe1212c8"
1295 acl: branch access granted: "911600dab2ae" on branch "default"
1284 acl: branch access granted: "911600dab2ae" on branch "default"
1296 acl: path access granted: "911600dab2ae"
1285 acl: path access granted: "911600dab2ae"
1297 bundle2-input-part: total payload size 1553
1286 bundle2-input-part: total payload size 1553
1298 bundle2-input-part: "phase-heads" supported
1287 bundle2-input-part: "phase-heads" supported
1299 bundle2-input-part: total payload size 24
1288 bundle2-input-part: total payload size 24
1300 bundle2-input-bundle: 4 parts total
1289 bundle2-input-bundle: 4 parts total
1301 updating the branch cache
1290 updating the branch cache
1291 added 3 changesets with 3 changes to 3 files
1302 bundle2-output-bundle: "HG20", 1 parts total
1292 bundle2-output-bundle: "HG20", 1 parts total
1303 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
1293 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
1304 bundle2-input-bundle: no-transaction
1294 bundle2-input-bundle: no-transaction
1305 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
1295 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
1306 bundle2-input-bundle: 0 parts total
1296 bundle2-input-bundle: 0 parts total
1307 listing keys for "phases"
1297 listing keys for "phases"
1308 repository tip rolled back to revision 0 (undo push)
1298 repository tip rolled back to revision 0 (undo push)
1309 0:6675d58eff77
1299 0:6675d58eff77
1310
1300
1311
1301
1312 asterisk
1302 asterisk
1313
1303
1314 $ init_config
1304 $ init_config
1315
1305
1316 asterisk test
1306 asterisk test
1317
1307
1318 $ echo '[acl.allow]' >> $config
1308 $ echo '[acl.allow]' >> $config
1319 $ echo "** = fred" >> $config
1309 $ echo "** = fred" >> $config
1320
1310
1321 fred is always allowed
1311 fred is always allowed
1322
1312
1323 $ do_push fred
1313 $ do_push fred
1324 Pushing as user fred
1314 Pushing as user fred
1325 hgrc = """
1315 hgrc = """
1326 [hooks]
1316 [hooks]
1327 pretxnchangegroup.acl = python:hgext.acl.hook
1317 pretxnchangegroup.acl = python:hgext.acl.hook
1328 prepushkey.acl = python:hgext.acl.hook
1318 prepushkey.acl = python:hgext.acl.hook
1329 [acl]
1319 [acl]
1330 sources = push
1320 sources = push
1331 [extensions]
1321 [extensions]
1332 posixgetuser=$TESTTMP/posixgetuser.py
1322 posixgetuser=$TESTTMP/posixgetuser.py
1333 [acl.allow]
1323 [acl.allow]
1334 ** = fred
1324 ** = fred
1335 """
1325 """
1336 pushing to ../b
1326 pushing to ../b
1337 query 1; heads
1327 query 1; heads
1338 searching for changes
1328 searching for changes
1339 all remote heads known locally
1329 all remote heads known locally
1340 listing keys for "phases"
1330 listing keys for "phases"
1341 checking for updated bookmarks
1331 checking for updated bookmarks
1342 listing keys for "bookmarks"
1332 listing keys for "bookmarks"
1343 listing keys for "bookmarks"
1333 listing keys for "bookmarks"
1344 3 changesets found
1334 3 changesets found
1345 list of changesets:
1335 list of changesets:
1346 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1336 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1347 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1337 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1348 911600dab2ae7a9baff75958b84fe606851ce955
1338 911600dab2ae7a9baff75958b84fe606851ce955
1349 bundle2-output-bundle: "HG20", 5 parts total
1339 bundle2-output-bundle: "HG20", 5 parts total
1350 bundle2-output-part: "replycaps" 205 bytes payload
1340 bundle2-output-part: "replycaps" 205 bytes payload
1351 bundle2-output-part: "check:phases" 24 bytes payload
1341 bundle2-output-part: "check:phases" 24 bytes payload
1352 bundle2-output-part: "check:heads" streamed payload
1342 bundle2-output-part: "check:heads" streamed payload
1353 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1343 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1354 bundle2-output-part: "phase-heads" 24 bytes payload
1344 bundle2-output-part: "phase-heads" 24 bytes payload
1355 bundle2-input-bundle: with-transaction
1345 bundle2-input-bundle: with-transaction
1356 bundle2-input-part: "replycaps" supported
1346 bundle2-input-part: "replycaps" supported
1357 bundle2-input-part: total payload size 205
1347 bundle2-input-part: total payload size 205
1358 bundle2-input-part: "check:phases" supported
1348 bundle2-input-part: "check:phases" supported
1359 bundle2-input-part: total payload size 24
1349 bundle2-input-part: total payload size 24
1360 bundle2-input-part: "check:heads" supported
1350 bundle2-input-part: "check:heads" supported
1361 bundle2-input-part: total payload size 20
1351 bundle2-input-part: total payload size 20
1362 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1352 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1363 adding changesets
1353 adding changesets
1364 add changeset ef1ea85a6374
1354 add changeset ef1ea85a6374
1365 add changeset f9cafe1212c8
1355 add changeset f9cafe1212c8
1366 add changeset 911600dab2ae
1356 add changeset 911600dab2ae
1367 adding manifests
1357 adding manifests
1368 adding file changes
1358 adding file changes
1369 adding foo/Bar/file.txt revisions
1359 adding foo/Bar/file.txt revisions
1370 adding foo/file.txt revisions
1360 adding foo/file.txt revisions
1371 adding quux/file.py revisions
1361 adding quux/file.py revisions
1372 added 3 changesets with 3 changes to 3 files
1373 calling hook pretxnchangegroup.acl: hgext.acl.hook
1362 calling hook pretxnchangegroup.acl: hgext.acl.hook
1374 acl: checking access for user "fred"
1363 acl: checking access for user "fred"
1375 acl: acl.allow.branches not enabled
1364 acl: acl.allow.branches not enabled
1376 acl: acl.deny.branches not enabled
1365 acl: acl.deny.branches not enabled
1377 acl: acl.allow enabled, 1 entries for user fred
1366 acl: acl.allow enabled, 1 entries for user fred
1378 acl: acl.deny not enabled
1367 acl: acl.deny not enabled
1379 acl: branch access granted: "ef1ea85a6374" on branch "default"
1368 acl: branch access granted: "ef1ea85a6374" on branch "default"
1380 acl: path access granted: "ef1ea85a6374"
1369 acl: path access granted: "ef1ea85a6374"
1381 acl: branch access granted: "f9cafe1212c8" on branch "default"
1370 acl: branch access granted: "f9cafe1212c8" on branch "default"
1382 acl: path access granted: "f9cafe1212c8"
1371 acl: path access granted: "f9cafe1212c8"
1383 acl: branch access granted: "911600dab2ae" on branch "default"
1372 acl: branch access granted: "911600dab2ae" on branch "default"
1384 acl: path access granted: "911600dab2ae"
1373 acl: path access granted: "911600dab2ae"
1385 bundle2-input-part: total payload size 1553
1374 bundle2-input-part: total payload size 1553
1386 bundle2-input-part: "phase-heads" supported
1375 bundle2-input-part: "phase-heads" supported
1387 bundle2-input-part: total payload size 24
1376 bundle2-input-part: total payload size 24
1388 bundle2-input-bundle: 4 parts total
1377 bundle2-input-bundle: 4 parts total
1389 updating the branch cache
1378 updating the branch cache
1379 added 3 changesets with 3 changes to 3 files
1390 bundle2-output-bundle: "HG20", 1 parts total
1380 bundle2-output-bundle: "HG20", 1 parts total
1391 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
1381 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
1392 bundle2-input-bundle: no-transaction
1382 bundle2-input-bundle: no-transaction
1393 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
1383 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
1394 bundle2-input-bundle: 0 parts total
1384 bundle2-input-bundle: 0 parts total
1395 listing keys for "phases"
1385 listing keys for "phases"
1396 repository tip rolled back to revision 0 (undo push)
1386 repository tip rolled back to revision 0 (undo push)
1397 0:6675d58eff77
1387 0:6675d58eff77
1398
1388
1399
1389
1400 $ echo '[acl.deny]' >> $config
1390 $ echo '[acl.deny]' >> $config
1401 $ echo "foo/Bar/** = *" >> $config
1391 $ echo "foo/Bar/** = *" >> $config
1402
1392
1403 no one is allowed inside foo/Bar/
1393 no one is allowed inside foo/Bar/
1404
1394
1405 $ do_push fred
1395 $ do_push fred
1406 Pushing as user fred
1396 Pushing as user fred
1407 hgrc = """
1397 hgrc = """
1408 [hooks]
1398 [hooks]
1409 pretxnchangegroup.acl = python:hgext.acl.hook
1399 pretxnchangegroup.acl = python:hgext.acl.hook
1410 prepushkey.acl = python:hgext.acl.hook
1400 prepushkey.acl = python:hgext.acl.hook
1411 [acl]
1401 [acl]
1412 sources = push
1402 sources = push
1413 [extensions]
1403 [extensions]
1414 posixgetuser=$TESTTMP/posixgetuser.py
1404 posixgetuser=$TESTTMP/posixgetuser.py
1415 [acl.allow]
1405 [acl.allow]
1416 ** = fred
1406 ** = fred
1417 [acl.deny]
1407 [acl.deny]
1418 foo/Bar/** = *
1408 foo/Bar/** = *
1419 """
1409 """
1420 pushing to ../b
1410 pushing to ../b
1421 query 1; heads
1411 query 1; heads
1422 searching for changes
1412 searching for changes
1423 all remote heads known locally
1413 all remote heads known locally
1424 listing keys for "phases"
1414 listing keys for "phases"
1425 checking for updated bookmarks
1415 checking for updated bookmarks
1426 listing keys for "bookmarks"
1416 listing keys for "bookmarks"
1427 listing keys for "bookmarks"
1417 listing keys for "bookmarks"
1428 3 changesets found
1418 3 changesets found
1429 list of changesets:
1419 list of changesets:
1430 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1420 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1431 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1421 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1432 911600dab2ae7a9baff75958b84fe606851ce955
1422 911600dab2ae7a9baff75958b84fe606851ce955
1433 bundle2-output-bundle: "HG20", 5 parts total
1423 bundle2-output-bundle: "HG20", 5 parts total
1434 bundle2-output-part: "replycaps" 205 bytes payload
1424 bundle2-output-part: "replycaps" 205 bytes payload
1435 bundle2-output-part: "check:phases" 24 bytes payload
1425 bundle2-output-part: "check:phases" 24 bytes payload
1436 bundle2-output-part: "check:heads" streamed payload
1426 bundle2-output-part: "check:heads" streamed payload
1437 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1427 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1438 bundle2-output-part: "phase-heads" 24 bytes payload
1428 bundle2-output-part: "phase-heads" 24 bytes payload
1439 bundle2-input-bundle: with-transaction
1429 bundle2-input-bundle: with-transaction
1440 bundle2-input-part: "replycaps" supported
1430 bundle2-input-part: "replycaps" supported
1441 bundle2-input-part: total payload size 205
1431 bundle2-input-part: total payload size 205
1442 bundle2-input-part: "check:phases" supported
1432 bundle2-input-part: "check:phases" supported
1443 bundle2-input-part: total payload size 24
1433 bundle2-input-part: total payload size 24
1444 bundle2-input-part: "check:heads" supported
1434 bundle2-input-part: "check:heads" supported
1445 bundle2-input-part: total payload size 20
1435 bundle2-input-part: total payload size 20
1446 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1436 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1447 adding changesets
1437 adding changesets
1448 add changeset ef1ea85a6374
1438 add changeset ef1ea85a6374
1449 add changeset f9cafe1212c8
1439 add changeset f9cafe1212c8
1450 add changeset 911600dab2ae
1440 add changeset 911600dab2ae
1451 adding manifests
1441 adding manifests
1452 adding file changes
1442 adding file changes
1453 adding foo/Bar/file.txt revisions
1443 adding foo/Bar/file.txt revisions
1454 adding foo/file.txt revisions
1444 adding foo/file.txt revisions
1455 adding quux/file.py revisions
1445 adding quux/file.py revisions
1456 added 3 changesets with 3 changes to 3 files
1457 calling hook pretxnchangegroup.acl: hgext.acl.hook
1446 calling hook pretxnchangegroup.acl: hgext.acl.hook
1458 acl: checking access for user "fred"
1447 acl: checking access for user "fred"
1459 acl: acl.allow.branches not enabled
1448 acl: acl.allow.branches not enabled
1460 acl: acl.deny.branches not enabled
1449 acl: acl.deny.branches not enabled
1461 acl: acl.allow enabled, 1 entries for user fred
1450 acl: acl.allow enabled, 1 entries for user fred
1462 acl: acl.deny enabled, 1 entries for user fred
1451 acl: acl.deny enabled, 1 entries for user fred
1463 acl: branch access granted: "ef1ea85a6374" on branch "default"
1452 acl: branch access granted: "ef1ea85a6374" on branch "default"
1464 acl: path access granted: "ef1ea85a6374"
1453 acl: path access granted: "ef1ea85a6374"
1465 acl: branch access granted: "f9cafe1212c8" on branch "default"
1454 acl: branch access granted: "f9cafe1212c8" on branch "default"
1466 error: pretxnchangegroup.acl hook failed: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1455 error: pretxnchangegroup.acl hook failed: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1467 bundle2-input-part: total payload size 1553
1456 bundle2-input-part: total payload size 1553
1468 bundle2-input-part: total payload size 24
1457 bundle2-input-part: total payload size 24
1469 bundle2-input-bundle: 4 parts total
1458 bundle2-input-bundle: 4 parts total
1470 transaction abort!
1459 transaction abort!
1471 rollback completed
1460 rollback completed
1472 abort: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1461 abort: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1473 no rollback information available
1462 no rollback information available
1474 0:6675d58eff77
1463 0:6675d58eff77
1475
1464
1476
1465
1477 Groups
1466 Groups
1478
1467
1479 $ init_config
1468 $ init_config
1480
1469
1481 OS-level groups
1470 OS-level groups
1482
1471
1483 $ echo '[acl.allow]' >> $config
1472 $ echo '[acl.allow]' >> $config
1484 $ echo "** = @group1" >> $config
1473 $ echo "** = @group1" >> $config
1485
1474
1486 @group1 is always allowed
1475 @group1 is always allowed
1487
1476
1488 $ do_push fred
1477 $ do_push fred
1489 Pushing as user fred
1478 Pushing as user fred
1490 hgrc = """
1479 hgrc = """
1491 [hooks]
1480 [hooks]
1492 pretxnchangegroup.acl = python:hgext.acl.hook
1481 pretxnchangegroup.acl = python:hgext.acl.hook
1493 prepushkey.acl = python:hgext.acl.hook
1482 prepushkey.acl = python:hgext.acl.hook
1494 [acl]
1483 [acl]
1495 sources = push
1484 sources = push
1496 [extensions]
1485 [extensions]
1497 posixgetuser=$TESTTMP/posixgetuser.py
1486 posixgetuser=$TESTTMP/posixgetuser.py
1498 [acl.allow]
1487 [acl.allow]
1499 ** = @group1
1488 ** = @group1
1500 """
1489 """
1501 pushing to ../b
1490 pushing to ../b
1502 query 1; heads
1491 query 1; heads
1503 searching for changes
1492 searching for changes
1504 all remote heads known locally
1493 all remote heads known locally
1505 listing keys for "phases"
1494 listing keys for "phases"
1506 checking for updated bookmarks
1495 checking for updated bookmarks
1507 listing keys for "bookmarks"
1496 listing keys for "bookmarks"
1508 listing keys for "bookmarks"
1497 listing keys for "bookmarks"
1509 3 changesets found
1498 3 changesets found
1510 list of changesets:
1499 list of changesets:
1511 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1500 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1512 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1501 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1513 911600dab2ae7a9baff75958b84fe606851ce955
1502 911600dab2ae7a9baff75958b84fe606851ce955
1514 bundle2-output-bundle: "HG20", 5 parts total
1503 bundle2-output-bundle: "HG20", 5 parts total
1515 bundle2-output-part: "replycaps" 205 bytes payload
1504 bundle2-output-part: "replycaps" 205 bytes payload
1516 bundle2-output-part: "check:phases" 24 bytes payload
1505 bundle2-output-part: "check:phases" 24 bytes payload
1517 bundle2-output-part: "check:heads" streamed payload
1506 bundle2-output-part: "check:heads" streamed payload
1518 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1507 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1519 bundle2-output-part: "phase-heads" 24 bytes payload
1508 bundle2-output-part: "phase-heads" 24 bytes payload
1520 bundle2-input-bundle: with-transaction
1509 bundle2-input-bundle: with-transaction
1521 bundle2-input-part: "replycaps" supported
1510 bundle2-input-part: "replycaps" supported
1522 bundle2-input-part: total payload size 205
1511 bundle2-input-part: total payload size 205
1523 bundle2-input-part: "check:phases" supported
1512 bundle2-input-part: "check:phases" supported
1524 bundle2-input-part: total payload size 24
1513 bundle2-input-part: total payload size 24
1525 bundle2-input-part: "check:heads" supported
1514 bundle2-input-part: "check:heads" supported
1526 bundle2-input-part: total payload size 20
1515 bundle2-input-part: total payload size 20
1527 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1516 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1528 adding changesets
1517 adding changesets
1529 add changeset ef1ea85a6374
1518 add changeset ef1ea85a6374
1530 add changeset f9cafe1212c8
1519 add changeset f9cafe1212c8
1531 add changeset 911600dab2ae
1520 add changeset 911600dab2ae
1532 adding manifests
1521 adding manifests
1533 adding file changes
1522 adding file changes
1534 adding foo/Bar/file.txt revisions
1523 adding foo/Bar/file.txt revisions
1535 adding foo/file.txt revisions
1524 adding foo/file.txt revisions
1536 adding quux/file.py revisions
1525 adding quux/file.py revisions
1537 added 3 changesets with 3 changes to 3 files
1538 calling hook pretxnchangegroup.acl: hgext.acl.hook
1526 calling hook pretxnchangegroup.acl: hgext.acl.hook
1539 acl: checking access for user "fred"
1527 acl: checking access for user "fred"
1540 acl: acl.allow.branches not enabled
1528 acl: acl.allow.branches not enabled
1541 acl: acl.deny.branches not enabled
1529 acl: acl.deny.branches not enabled
1542 acl: "group1" not defined in [acl.groups]
1530 acl: "group1" not defined in [acl.groups]
1543 acl: acl.allow enabled, 1 entries for user fred
1531 acl: acl.allow enabled, 1 entries for user fred
1544 acl: acl.deny not enabled
1532 acl: acl.deny not enabled
1545 acl: branch access granted: "ef1ea85a6374" on branch "default"
1533 acl: branch access granted: "ef1ea85a6374" on branch "default"
1546 acl: path access granted: "ef1ea85a6374"
1534 acl: path access granted: "ef1ea85a6374"
1547 acl: branch access granted: "f9cafe1212c8" on branch "default"
1535 acl: branch access granted: "f9cafe1212c8" on branch "default"
1548 acl: path access granted: "f9cafe1212c8"
1536 acl: path access granted: "f9cafe1212c8"
1549 acl: branch access granted: "911600dab2ae" on branch "default"
1537 acl: branch access granted: "911600dab2ae" on branch "default"
1550 acl: path access granted: "911600dab2ae"
1538 acl: path access granted: "911600dab2ae"
1551 bundle2-input-part: total payload size 1553
1539 bundle2-input-part: total payload size 1553
1552 bundle2-input-part: "phase-heads" supported
1540 bundle2-input-part: "phase-heads" supported
1553 bundle2-input-part: total payload size 24
1541 bundle2-input-part: total payload size 24
1554 bundle2-input-bundle: 4 parts total
1542 bundle2-input-bundle: 4 parts total
1555 updating the branch cache
1543 updating the branch cache
1544 added 3 changesets with 3 changes to 3 files
1556 bundle2-output-bundle: "HG20", 1 parts total
1545 bundle2-output-bundle: "HG20", 1 parts total
1557 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
1546 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
1558 bundle2-input-bundle: no-transaction
1547 bundle2-input-bundle: no-transaction
1559 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
1548 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
1560 bundle2-input-bundle: 0 parts total
1549 bundle2-input-bundle: 0 parts total
1561 listing keys for "phases"
1550 listing keys for "phases"
1562 repository tip rolled back to revision 0 (undo push)
1551 repository tip rolled back to revision 0 (undo push)
1563 0:6675d58eff77
1552 0:6675d58eff77
1564
1553
1565
1554
1566 $ echo '[acl.deny]' >> $config
1555 $ echo '[acl.deny]' >> $config
1567 $ echo "foo/Bar/** = @group1" >> $config
1556 $ echo "foo/Bar/** = @group1" >> $config
1568
1557
1569 @group is allowed inside anything but foo/Bar/
1558 @group is allowed inside anything but foo/Bar/
1570
1559
1571 $ do_push fred
1560 $ do_push fred
1572 Pushing as user fred
1561 Pushing as user fred
1573 hgrc = """
1562 hgrc = """
1574 [hooks]
1563 [hooks]
1575 pretxnchangegroup.acl = python:hgext.acl.hook
1564 pretxnchangegroup.acl = python:hgext.acl.hook
1576 prepushkey.acl = python:hgext.acl.hook
1565 prepushkey.acl = python:hgext.acl.hook
1577 [acl]
1566 [acl]
1578 sources = push
1567 sources = push
1579 [extensions]
1568 [extensions]
1580 posixgetuser=$TESTTMP/posixgetuser.py
1569 posixgetuser=$TESTTMP/posixgetuser.py
1581 [acl.allow]
1570 [acl.allow]
1582 ** = @group1
1571 ** = @group1
1583 [acl.deny]
1572 [acl.deny]
1584 foo/Bar/** = @group1
1573 foo/Bar/** = @group1
1585 """
1574 """
1586 pushing to ../b
1575 pushing to ../b
1587 query 1; heads
1576 query 1; heads
1588 searching for changes
1577 searching for changes
1589 all remote heads known locally
1578 all remote heads known locally
1590 listing keys for "phases"
1579 listing keys for "phases"
1591 checking for updated bookmarks
1580 checking for updated bookmarks
1592 listing keys for "bookmarks"
1581 listing keys for "bookmarks"
1593 listing keys for "bookmarks"
1582 listing keys for "bookmarks"
1594 3 changesets found
1583 3 changesets found
1595 list of changesets:
1584 list of changesets:
1596 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1585 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1597 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1586 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1598 911600dab2ae7a9baff75958b84fe606851ce955
1587 911600dab2ae7a9baff75958b84fe606851ce955
1599 bundle2-output-bundle: "HG20", 5 parts total
1588 bundle2-output-bundle: "HG20", 5 parts total
1600 bundle2-output-part: "replycaps" 205 bytes payload
1589 bundle2-output-part: "replycaps" 205 bytes payload
1601 bundle2-output-part: "check:phases" 24 bytes payload
1590 bundle2-output-part: "check:phases" 24 bytes payload
1602 bundle2-output-part: "check:heads" streamed payload
1591 bundle2-output-part: "check:heads" streamed payload
1603 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1592 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1604 bundle2-output-part: "phase-heads" 24 bytes payload
1593 bundle2-output-part: "phase-heads" 24 bytes payload
1605 bundle2-input-bundle: with-transaction
1594 bundle2-input-bundle: with-transaction
1606 bundle2-input-part: "replycaps" supported
1595 bundle2-input-part: "replycaps" supported
1607 bundle2-input-part: total payload size 205
1596 bundle2-input-part: total payload size 205
1608 bundle2-input-part: "check:phases" supported
1597 bundle2-input-part: "check:phases" supported
1609 bundle2-input-part: total payload size 24
1598 bundle2-input-part: total payload size 24
1610 bundle2-input-part: "check:heads" supported
1599 bundle2-input-part: "check:heads" supported
1611 bundle2-input-part: total payload size 20
1600 bundle2-input-part: total payload size 20
1612 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1601 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1613 adding changesets
1602 adding changesets
1614 add changeset ef1ea85a6374
1603 add changeset ef1ea85a6374
1615 add changeset f9cafe1212c8
1604 add changeset f9cafe1212c8
1616 add changeset 911600dab2ae
1605 add changeset 911600dab2ae
1617 adding manifests
1606 adding manifests
1618 adding file changes
1607 adding file changes
1619 adding foo/Bar/file.txt revisions
1608 adding foo/Bar/file.txt revisions
1620 adding foo/file.txt revisions
1609 adding foo/file.txt revisions
1621 adding quux/file.py revisions
1610 adding quux/file.py revisions
1622 added 3 changesets with 3 changes to 3 files
1623 calling hook pretxnchangegroup.acl: hgext.acl.hook
1611 calling hook pretxnchangegroup.acl: hgext.acl.hook
1624 acl: checking access for user "fred"
1612 acl: checking access for user "fred"
1625 acl: acl.allow.branches not enabled
1613 acl: acl.allow.branches not enabled
1626 acl: acl.deny.branches not enabled
1614 acl: acl.deny.branches not enabled
1627 acl: "group1" not defined in [acl.groups]
1615 acl: "group1" not defined in [acl.groups]
1628 acl: acl.allow enabled, 1 entries for user fred
1616 acl: acl.allow enabled, 1 entries for user fred
1629 acl: "group1" not defined in [acl.groups]
1617 acl: "group1" not defined in [acl.groups]
1630 acl: acl.deny enabled, 1 entries for user fred
1618 acl: acl.deny enabled, 1 entries for user fred
1631 acl: branch access granted: "ef1ea85a6374" on branch "default"
1619 acl: branch access granted: "ef1ea85a6374" on branch "default"
1632 acl: path access granted: "ef1ea85a6374"
1620 acl: path access granted: "ef1ea85a6374"
1633 acl: branch access granted: "f9cafe1212c8" on branch "default"
1621 acl: branch access granted: "f9cafe1212c8" on branch "default"
1634 error: pretxnchangegroup.acl hook failed: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1622 error: pretxnchangegroup.acl hook failed: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1635 bundle2-input-part: total payload size 1553
1623 bundle2-input-part: total payload size 1553
1636 bundle2-input-part: total payload size 24
1624 bundle2-input-part: total payload size 24
1637 bundle2-input-bundle: 4 parts total
1625 bundle2-input-bundle: 4 parts total
1638 transaction abort!
1626 transaction abort!
1639 rollback completed
1627 rollback completed
1640 abort: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1628 abort: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1641 no rollback information available
1629 no rollback information available
1642 0:6675d58eff77
1630 0:6675d58eff77
1643
1631
1644
1632
1645 Invalid group
1633 Invalid group
1646
1634
1647 Disable the fakegroups trick to get real failures
1635 Disable the fakegroups trick to get real failures
1648
1636
1649 $ grep -v fakegroups $config > config.tmp
1637 $ grep -v fakegroups $config > config.tmp
1650 $ mv config.tmp $config
1638 $ mv config.tmp $config
1651 $ echo '[acl.allow]' >> $config
1639 $ echo '[acl.allow]' >> $config
1652 $ echo "** = @unlikelytoexist" >> $config
1640 $ echo "** = @unlikelytoexist" >> $config
1653 $ do_push fred 2>&1 | grep unlikelytoexist
1641 $ do_push fred 2>&1 | grep unlikelytoexist
1654 ** = @unlikelytoexist
1642 ** = @unlikelytoexist
1655 acl: "unlikelytoexist" not defined in [acl.groups]
1643 acl: "unlikelytoexist" not defined in [acl.groups]
1656 error: pretxnchangegroup.acl hook failed: group 'unlikelytoexist' is undefined
1644 error: pretxnchangegroup.acl hook failed: group 'unlikelytoexist' is undefined
1657 abort: group 'unlikelytoexist' is undefined
1645 abort: group 'unlikelytoexist' is undefined
1658
1646
1659
1647
1660 Branch acl tests setup
1648 Branch acl tests setup
1661
1649
1662 $ init_config
1650 $ init_config
1663 $ cd b
1651 $ cd b
1664 $ hg up
1652 $ hg up
1665 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1653 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1666 $ hg branch foobar
1654 $ hg branch foobar
1667 marked working directory as branch foobar
1655 marked working directory as branch foobar
1668 (branches are permanent and global, did you want a bookmark?)
1656 (branches are permanent and global, did you want a bookmark?)
1669 $ hg commit -m 'create foobar'
1657 $ hg commit -m 'create foobar'
1670 $ echo 'foo contents' > abc.txt
1658 $ echo 'foo contents' > abc.txt
1671 $ hg add abc.txt
1659 $ hg add abc.txt
1672 $ hg commit -m 'foobar contents'
1660 $ hg commit -m 'foobar contents'
1673 $ cd ..
1661 $ cd ..
1674 $ hg --cwd a pull ../b
1662 $ hg --cwd a pull ../b
1675 pulling from ../b
1663 pulling from ../b
1676 searching for changes
1664 searching for changes
1677 adding changesets
1665 adding changesets
1678 adding manifests
1666 adding manifests
1679 adding file changes
1667 adding file changes
1680 added 2 changesets with 1 changes to 1 files (+1 heads)
1668 added 2 changesets with 1 changes to 1 files (+1 heads)
1681 new changesets 81fbf4469322:fb35475503ef
1669 new changesets 81fbf4469322:fb35475503ef
1682 (run 'hg heads' to see heads)
1670 (run 'hg heads' to see heads)
1683
1671
1684 Create additional changeset on foobar branch
1672 Create additional changeset on foobar branch
1685
1673
1686 $ cd a
1674 $ cd a
1687 $ hg up -C foobar
1675 $ hg up -C foobar
1688 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
1676 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
1689 $ echo 'foo contents2' > abc.txt
1677 $ echo 'foo contents2' > abc.txt
1690 $ hg commit -m 'foobar contents2'
1678 $ hg commit -m 'foobar contents2'
1691 $ cd ..
1679 $ cd ..
1692
1680
1693
1681
1694 No branch acls specified
1682 No branch acls specified
1695
1683
1696 $ do_push astro
1684 $ do_push astro
1697 Pushing as user astro
1685 Pushing as user astro
1698 hgrc = """
1686 hgrc = """
1699 [hooks]
1687 [hooks]
1700 pretxnchangegroup.acl = python:hgext.acl.hook
1688 pretxnchangegroup.acl = python:hgext.acl.hook
1701 prepushkey.acl = python:hgext.acl.hook
1689 prepushkey.acl = python:hgext.acl.hook
1702 [acl]
1690 [acl]
1703 sources = push
1691 sources = push
1704 [extensions]
1692 [extensions]
1705 posixgetuser=$TESTTMP/posixgetuser.py
1693 posixgetuser=$TESTTMP/posixgetuser.py
1706 """
1694 """
1707 pushing to ../b
1695 pushing to ../b
1708 query 1; heads
1696 query 1; heads
1709 searching for changes
1697 searching for changes
1710 all remote heads known locally
1698 all remote heads known locally
1711 listing keys for "phases"
1699 listing keys for "phases"
1712 checking for updated bookmarks
1700 checking for updated bookmarks
1713 listing keys for "bookmarks"
1701 listing keys for "bookmarks"
1714 listing keys for "bookmarks"
1702 listing keys for "bookmarks"
1715 4 changesets found
1703 4 changesets found
1716 list of changesets:
1704 list of changesets:
1717 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1705 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1718 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1706 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1719 911600dab2ae7a9baff75958b84fe606851ce955
1707 911600dab2ae7a9baff75958b84fe606851ce955
1720 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1708 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1721 bundle2-output-bundle: "HG20", 5 parts total
1709 bundle2-output-bundle: "HG20", 5 parts total
1722 bundle2-output-part: "replycaps" 205 bytes payload
1710 bundle2-output-part: "replycaps" 205 bytes payload
1723 bundle2-output-part: "check:phases" 48 bytes payload
1711 bundle2-output-part: "check:phases" 48 bytes payload
1724 bundle2-output-part: "check:heads" streamed payload
1712 bundle2-output-part: "check:heads" streamed payload
1725 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1713 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1726 bundle2-output-part: "phase-heads" 48 bytes payload
1714 bundle2-output-part: "phase-heads" 48 bytes payload
1727 bundle2-input-bundle: with-transaction
1715 bundle2-input-bundle: with-transaction
1728 bundle2-input-part: "replycaps" supported
1716 bundle2-input-part: "replycaps" supported
1729 bundle2-input-part: total payload size 205
1717 bundle2-input-part: total payload size 205
1730 bundle2-input-part: "check:phases" supported
1718 bundle2-input-part: "check:phases" supported
1731 bundle2-input-part: total payload size 48
1719 bundle2-input-part: total payload size 48
1732 bundle2-input-part: "check:heads" supported
1720 bundle2-input-part: "check:heads" supported
1733 bundle2-input-part: total payload size 20
1721 bundle2-input-part: total payload size 20
1734 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1722 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1735 adding changesets
1723 adding changesets
1736 add changeset ef1ea85a6374
1724 add changeset ef1ea85a6374
1737 add changeset f9cafe1212c8
1725 add changeset f9cafe1212c8
1738 add changeset 911600dab2ae
1726 add changeset 911600dab2ae
1739 add changeset e8fc755d4d82
1727 add changeset e8fc755d4d82
1740 adding manifests
1728 adding manifests
1741 adding file changes
1729 adding file changes
1742 adding abc.txt revisions
1730 adding abc.txt revisions
1743 adding foo/Bar/file.txt revisions
1731 adding foo/Bar/file.txt revisions
1744 adding foo/file.txt revisions
1732 adding foo/file.txt revisions
1745 adding quux/file.py revisions
1733 adding quux/file.py revisions
1746 added 4 changesets with 4 changes to 4 files (+1 heads)
1747 calling hook pretxnchangegroup.acl: hgext.acl.hook
1734 calling hook pretxnchangegroup.acl: hgext.acl.hook
1748 acl: checking access for user "astro"
1735 acl: checking access for user "astro"
1749 acl: acl.allow.branches not enabled
1736 acl: acl.allow.branches not enabled
1750 acl: acl.deny.branches not enabled
1737 acl: acl.deny.branches not enabled
1751 acl: acl.allow not enabled
1738 acl: acl.allow not enabled
1752 acl: acl.deny not enabled
1739 acl: acl.deny not enabled
1753 acl: branch access granted: "ef1ea85a6374" on branch "default"
1740 acl: branch access granted: "ef1ea85a6374" on branch "default"
1754 acl: path access granted: "ef1ea85a6374"
1741 acl: path access granted: "ef1ea85a6374"
1755 acl: branch access granted: "f9cafe1212c8" on branch "default"
1742 acl: branch access granted: "f9cafe1212c8" on branch "default"
1756 acl: path access granted: "f9cafe1212c8"
1743 acl: path access granted: "f9cafe1212c8"
1757 acl: branch access granted: "911600dab2ae" on branch "default"
1744 acl: branch access granted: "911600dab2ae" on branch "default"
1758 acl: path access granted: "911600dab2ae"
1745 acl: path access granted: "911600dab2ae"
1759 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
1746 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
1760 acl: path access granted: "e8fc755d4d82"
1747 acl: path access granted: "e8fc755d4d82"
1761 bundle2-input-part: total payload size 2068
1748 bundle2-input-part: total payload size 2068
1762 bundle2-input-part: "phase-heads" supported
1749 bundle2-input-part: "phase-heads" supported
1763 bundle2-input-part: total payload size 48
1750 bundle2-input-part: total payload size 48
1764 bundle2-input-bundle: 4 parts total
1751 bundle2-input-bundle: 4 parts total
1765 updating the branch cache
1752 updating the branch cache
1753 added 4 changesets with 4 changes to 4 files (+1 heads)
1766 bundle2-output-bundle: "HG20", 1 parts total
1754 bundle2-output-bundle: "HG20", 1 parts total
1767 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
1755 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
1768 bundle2-input-bundle: no-transaction
1756 bundle2-input-bundle: no-transaction
1769 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
1757 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
1770 bundle2-input-bundle: 0 parts total
1758 bundle2-input-bundle: 0 parts total
1771 listing keys for "phases"
1759 listing keys for "phases"
1772 repository tip rolled back to revision 2 (undo push)
1760 repository tip rolled back to revision 2 (undo push)
1773 2:fb35475503ef
1761 2:fb35475503ef
1774
1762
1775
1763
1776 Branch acl deny test
1764 Branch acl deny test
1777
1765
1778 $ echo "[acl.deny.branches]" >> $config
1766 $ echo "[acl.deny.branches]" >> $config
1779 $ echo "foobar = *" >> $config
1767 $ echo "foobar = *" >> $config
1780 $ do_push astro
1768 $ do_push astro
1781 Pushing as user astro
1769 Pushing as user astro
1782 hgrc = """
1770 hgrc = """
1783 [hooks]
1771 [hooks]
1784 pretxnchangegroup.acl = python:hgext.acl.hook
1772 pretxnchangegroup.acl = python:hgext.acl.hook
1785 prepushkey.acl = python:hgext.acl.hook
1773 prepushkey.acl = python:hgext.acl.hook
1786 [acl]
1774 [acl]
1787 sources = push
1775 sources = push
1788 [extensions]
1776 [extensions]
1789 posixgetuser=$TESTTMP/posixgetuser.py
1777 posixgetuser=$TESTTMP/posixgetuser.py
1790 [acl.deny.branches]
1778 [acl.deny.branches]
1791 foobar = *
1779 foobar = *
1792 """
1780 """
1793 pushing to ../b
1781 pushing to ../b
1794 query 1; heads
1782 query 1; heads
1795 searching for changes
1783 searching for changes
1796 all remote heads known locally
1784 all remote heads known locally
1797 listing keys for "phases"
1785 listing keys for "phases"
1798 checking for updated bookmarks
1786 checking for updated bookmarks
1799 listing keys for "bookmarks"
1787 listing keys for "bookmarks"
1800 listing keys for "bookmarks"
1788 listing keys for "bookmarks"
1801 4 changesets found
1789 4 changesets found
1802 list of changesets:
1790 list of changesets:
1803 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1791 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1804 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1792 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1805 911600dab2ae7a9baff75958b84fe606851ce955
1793 911600dab2ae7a9baff75958b84fe606851ce955
1806 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1794 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1807 bundle2-output-bundle: "HG20", 5 parts total
1795 bundle2-output-bundle: "HG20", 5 parts total
1808 bundle2-output-part: "replycaps" 205 bytes payload
1796 bundle2-output-part: "replycaps" 205 bytes payload
1809 bundle2-output-part: "check:phases" 48 bytes payload
1797 bundle2-output-part: "check:phases" 48 bytes payload
1810 bundle2-output-part: "check:heads" streamed payload
1798 bundle2-output-part: "check:heads" streamed payload
1811 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1799 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1812 bundle2-output-part: "phase-heads" 48 bytes payload
1800 bundle2-output-part: "phase-heads" 48 bytes payload
1813 bundle2-input-bundle: with-transaction
1801 bundle2-input-bundle: with-transaction
1814 bundle2-input-part: "replycaps" supported
1802 bundle2-input-part: "replycaps" supported
1815 bundle2-input-part: total payload size 205
1803 bundle2-input-part: total payload size 205
1816 bundle2-input-part: "check:phases" supported
1804 bundle2-input-part: "check:phases" supported
1817 bundle2-input-part: total payload size 48
1805 bundle2-input-part: total payload size 48
1818 bundle2-input-part: "check:heads" supported
1806 bundle2-input-part: "check:heads" supported
1819 bundle2-input-part: total payload size 20
1807 bundle2-input-part: total payload size 20
1820 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1808 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1821 adding changesets
1809 adding changesets
1822 add changeset ef1ea85a6374
1810 add changeset ef1ea85a6374
1823 add changeset f9cafe1212c8
1811 add changeset f9cafe1212c8
1824 add changeset 911600dab2ae
1812 add changeset 911600dab2ae
1825 add changeset e8fc755d4d82
1813 add changeset e8fc755d4d82
1826 adding manifests
1814 adding manifests
1827 adding file changes
1815 adding file changes
1828 adding abc.txt revisions
1816 adding abc.txt revisions
1829 adding foo/Bar/file.txt revisions
1817 adding foo/Bar/file.txt revisions
1830 adding foo/file.txt revisions
1818 adding foo/file.txt revisions
1831 adding quux/file.py revisions
1819 adding quux/file.py revisions
1832 added 4 changesets with 4 changes to 4 files (+1 heads)
1833 calling hook pretxnchangegroup.acl: hgext.acl.hook
1820 calling hook pretxnchangegroup.acl: hgext.acl.hook
1834 acl: checking access for user "astro"
1821 acl: checking access for user "astro"
1835 acl: acl.allow.branches not enabled
1822 acl: acl.allow.branches not enabled
1836 acl: acl.deny.branches enabled, 1 entries for user astro
1823 acl: acl.deny.branches enabled, 1 entries for user astro
1837 acl: acl.allow not enabled
1824 acl: acl.allow not enabled
1838 acl: acl.deny not enabled
1825 acl: acl.deny not enabled
1839 acl: branch access granted: "ef1ea85a6374" on branch "default"
1826 acl: branch access granted: "ef1ea85a6374" on branch "default"
1840 acl: path access granted: "ef1ea85a6374"
1827 acl: path access granted: "ef1ea85a6374"
1841 acl: branch access granted: "f9cafe1212c8" on branch "default"
1828 acl: branch access granted: "f9cafe1212c8" on branch "default"
1842 acl: path access granted: "f9cafe1212c8"
1829 acl: path access granted: "f9cafe1212c8"
1843 acl: branch access granted: "911600dab2ae" on branch "default"
1830 acl: branch access granted: "911600dab2ae" on branch "default"
1844 acl: path access granted: "911600dab2ae"
1831 acl: path access granted: "911600dab2ae"
1845 error: pretxnchangegroup.acl hook failed: acl: user "astro" denied on branch "foobar" (changeset "e8fc755d4d82")
1832 error: pretxnchangegroup.acl hook failed: acl: user "astro" denied on branch "foobar" (changeset "e8fc755d4d82")
1846 bundle2-input-part: total payload size 2068
1833 bundle2-input-part: total payload size 2068
1847 bundle2-input-part: total payload size 48
1834 bundle2-input-part: total payload size 48
1848 bundle2-input-bundle: 4 parts total
1835 bundle2-input-bundle: 4 parts total
1849 transaction abort!
1836 transaction abort!
1850 rollback completed
1837 rollback completed
1851 abort: acl: user "astro" denied on branch "foobar" (changeset "e8fc755d4d82")
1838 abort: acl: user "astro" denied on branch "foobar" (changeset "e8fc755d4d82")
1852 no rollback information available
1839 no rollback information available
1853 2:fb35475503ef
1840 2:fb35475503ef
1854
1841
1855
1842
1856 Branch acl empty allow test
1843 Branch acl empty allow test
1857
1844
1858 $ init_config
1845 $ init_config
1859 $ echo "[acl.allow.branches]" >> $config
1846 $ echo "[acl.allow.branches]" >> $config
1860 $ do_push astro
1847 $ do_push astro
1861 Pushing as user astro
1848 Pushing as user astro
1862 hgrc = """
1849 hgrc = """
1863 [hooks]
1850 [hooks]
1864 pretxnchangegroup.acl = python:hgext.acl.hook
1851 pretxnchangegroup.acl = python:hgext.acl.hook
1865 prepushkey.acl = python:hgext.acl.hook
1852 prepushkey.acl = python:hgext.acl.hook
1866 [acl]
1853 [acl]
1867 sources = push
1854 sources = push
1868 [extensions]
1855 [extensions]
1869 posixgetuser=$TESTTMP/posixgetuser.py
1856 posixgetuser=$TESTTMP/posixgetuser.py
1870 [acl.allow.branches]
1857 [acl.allow.branches]
1871 """
1858 """
1872 pushing to ../b
1859 pushing to ../b
1873 query 1; heads
1860 query 1; heads
1874 searching for changes
1861 searching for changes
1875 all remote heads known locally
1862 all remote heads known locally
1876 listing keys for "phases"
1863 listing keys for "phases"
1877 checking for updated bookmarks
1864 checking for updated bookmarks
1878 listing keys for "bookmarks"
1865 listing keys for "bookmarks"
1879 listing keys for "bookmarks"
1866 listing keys for "bookmarks"
1880 4 changesets found
1867 4 changesets found
1881 list of changesets:
1868 list of changesets:
1882 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1869 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1883 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1870 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1884 911600dab2ae7a9baff75958b84fe606851ce955
1871 911600dab2ae7a9baff75958b84fe606851ce955
1885 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1872 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1886 bundle2-output-bundle: "HG20", 5 parts total
1873 bundle2-output-bundle: "HG20", 5 parts total
1887 bundle2-output-part: "replycaps" 205 bytes payload
1874 bundle2-output-part: "replycaps" 205 bytes payload
1888 bundle2-output-part: "check:phases" 48 bytes payload
1875 bundle2-output-part: "check:phases" 48 bytes payload
1889 bundle2-output-part: "check:heads" streamed payload
1876 bundle2-output-part: "check:heads" streamed payload
1890 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1877 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1891 bundle2-output-part: "phase-heads" 48 bytes payload
1878 bundle2-output-part: "phase-heads" 48 bytes payload
1892 bundle2-input-bundle: with-transaction
1879 bundle2-input-bundle: with-transaction
1893 bundle2-input-part: "replycaps" supported
1880 bundle2-input-part: "replycaps" supported
1894 bundle2-input-part: total payload size 205
1881 bundle2-input-part: total payload size 205
1895 bundle2-input-part: "check:phases" supported
1882 bundle2-input-part: "check:phases" supported
1896 bundle2-input-part: total payload size 48
1883 bundle2-input-part: total payload size 48
1897 bundle2-input-part: "check:heads" supported
1884 bundle2-input-part: "check:heads" supported
1898 bundle2-input-part: total payload size 20
1885 bundle2-input-part: total payload size 20
1899 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1886 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1900 adding changesets
1887 adding changesets
1901 add changeset ef1ea85a6374
1888 add changeset ef1ea85a6374
1902 add changeset f9cafe1212c8
1889 add changeset f9cafe1212c8
1903 add changeset 911600dab2ae
1890 add changeset 911600dab2ae
1904 add changeset e8fc755d4d82
1891 add changeset e8fc755d4d82
1905 adding manifests
1892 adding manifests
1906 adding file changes
1893 adding file changes
1907 adding abc.txt revisions
1894 adding abc.txt revisions
1908 adding foo/Bar/file.txt revisions
1895 adding foo/Bar/file.txt revisions
1909 adding foo/file.txt revisions
1896 adding foo/file.txt revisions
1910 adding quux/file.py revisions
1897 adding quux/file.py revisions
1911 added 4 changesets with 4 changes to 4 files (+1 heads)
1912 calling hook pretxnchangegroup.acl: hgext.acl.hook
1898 calling hook pretxnchangegroup.acl: hgext.acl.hook
1913 acl: checking access for user "astro"
1899 acl: checking access for user "astro"
1914 acl: acl.allow.branches enabled, 0 entries for user astro
1900 acl: acl.allow.branches enabled, 0 entries for user astro
1915 acl: acl.deny.branches not enabled
1901 acl: acl.deny.branches not enabled
1916 acl: acl.allow not enabled
1902 acl: acl.allow not enabled
1917 acl: acl.deny not enabled
1903 acl: acl.deny not enabled
1918 error: pretxnchangegroup.acl hook failed: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1904 error: pretxnchangegroup.acl hook failed: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1919 bundle2-input-part: total payload size 2068
1905 bundle2-input-part: total payload size 2068
1920 bundle2-input-part: total payload size 48
1906 bundle2-input-part: total payload size 48
1921 bundle2-input-bundle: 4 parts total
1907 bundle2-input-bundle: 4 parts total
1922 transaction abort!
1908 transaction abort!
1923 rollback completed
1909 rollback completed
1924 abort: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1910 abort: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1925 no rollback information available
1911 no rollback information available
1926 2:fb35475503ef
1912 2:fb35475503ef
1927
1913
1928
1914
1929 Branch acl allow other
1915 Branch acl allow other
1930
1916
1931 $ init_config
1917 $ init_config
1932 $ echo "[acl.allow.branches]" >> $config
1918 $ echo "[acl.allow.branches]" >> $config
1933 $ echo "* = george" >> $config
1919 $ echo "* = george" >> $config
1934 $ do_push astro
1920 $ do_push astro
1935 Pushing as user astro
1921 Pushing as user astro
1936 hgrc = """
1922 hgrc = """
1937 [hooks]
1923 [hooks]
1938 pretxnchangegroup.acl = python:hgext.acl.hook
1924 pretxnchangegroup.acl = python:hgext.acl.hook
1939 prepushkey.acl = python:hgext.acl.hook
1925 prepushkey.acl = python:hgext.acl.hook
1940 [acl]
1926 [acl]
1941 sources = push
1927 sources = push
1942 [extensions]
1928 [extensions]
1943 posixgetuser=$TESTTMP/posixgetuser.py
1929 posixgetuser=$TESTTMP/posixgetuser.py
1944 [acl.allow.branches]
1930 [acl.allow.branches]
1945 * = george
1931 * = george
1946 """
1932 """
1947 pushing to ../b
1933 pushing to ../b
1948 query 1; heads
1934 query 1; heads
1949 searching for changes
1935 searching for changes
1950 all remote heads known locally
1936 all remote heads known locally
1951 listing keys for "phases"
1937 listing keys for "phases"
1952 checking for updated bookmarks
1938 checking for updated bookmarks
1953 listing keys for "bookmarks"
1939 listing keys for "bookmarks"
1954 listing keys for "bookmarks"
1940 listing keys for "bookmarks"
1955 4 changesets found
1941 4 changesets found
1956 list of changesets:
1942 list of changesets:
1957 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1943 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1958 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1944 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1959 911600dab2ae7a9baff75958b84fe606851ce955
1945 911600dab2ae7a9baff75958b84fe606851ce955
1960 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1946 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1961 bundle2-output-bundle: "HG20", 5 parts total
1947 bundle2-output-bundle: "HG20", 5 parts total
1962 bundle2-output-part: "replycaps" 205 bytes payload
1948 bundle2-output-part: "replycaps" 205 bytes payload
1963 bundle2-output-part: "check:phases" 48 bytes payload
1949 bundle2-output-part: "check:phases" 48 bytes payload
1964 bundle2-output-part: "check:heads" streamed payload
1950 bundle2-output-part: "check:heads" streamed payload
1965 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1951 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1966 bundle2-output-part: "phase-heads" 48 bytes payload
1952 bundle2-output-part: "phase-heads" 48 bytes payload
1967 bundle2-input-bundle: with-transaction
1953 bundle2-input-bundle: with-transaction
1968 bundle2-input-part: "replycaps" supported
1954 bundle2-input-part: "replycaps" supported
1969 bundle2-input-part: total payload size 205
1955 bundle2-input-part: total payload size 205
1970 bundle2-input-part: "check:phases" supported
1956 bundle2-input-part: "check:phases" supported
1971 bundle2-input-part: total payload size 48
1957 bundle2-input-part: total payload size 48
1972 bundle2-input-part: "check:heads" supported
1958 bundle2-input-part: "check:heads" supported
1973 bundle2-input-part: total payload size 20
1959 bundle2-input-part: total payload size 20
1974 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1960 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1975 adding changesets
1961 adding changesets
1976 add changeset ef1ea85a6374
1962 add changeset ef1ea85a6374
1977 add changeset f9cafe1212c8
1963 add changeset f9cafe1212c8
1978 add changeset 911600dab2ae
1964 add changeset 911600dab2ae
1979 add changeset e8fc755d4d82
1965 add changeset e8fc755d4d82
1980 adding manifests
1966 adding manifests
1981 adding file changes
1967 adding file changes
1982 adding abc.txt revisions
1968 adding abc.txt revisions
1983 adding foo/Bar/file.txt revisions
1969 adding foo/Bar/file.txt revisions
1984 adding foo/file.txt revisions
1970 adding foo/file.txt revisions
1985 adding quux/file.py revisions
1971 adding quux/file.py revisions
1986 added 4 changesets with 4 changes to 4 files (+1 heads)
1987 calling hook pretxnchangegroup.acl: hgext.acl.hook
1972 calling hook pretxnchangegroup.acl: hgext.acl.hook
1988 acl: checking access for user "astro"
1973 acl: checking access for user "astro"
1989 acl: acl.allow.branches enabled, 0 entries for user astro
1974 acl: acl.allow.branches enabled, 0 entries for user astro
1990 acl: acl.deny.branches not enabled
1975 acl: acl.deny.branches not enabled
1991 acl: acl.allow not enabled
1976 acl: acl.allow not enabled
1992 acl: acl.deny not enabled
1977 acl: acl.deny not enabled
1993 error: pretxnchangegroup.acl hook failed: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1978 error: pretxnchangegroup.acl hook failed: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1994 bundle2-input-part: total payload size 2068
1979 bundle2-input-part: total payload size 2068
1995 bundle2-input-part: total payload size 48
1980 bundle2-input-part: total payload size 48
1996 bundle2-input-bundle: 4 parts total
1981 bundle2-input-bundle: 4 parts total
1997 transaction abort!
1982 transaction abort!
1998 rollback completed
1983 rollback completed
1999 abort: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1984 abort: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
2000 no rollback information available
1985 no rollback information available
2001 2:fb35475503ef
1986 2:fb35475503ef
2002
1987
2003 $ do_push george
1988 $ do_push george
2004 Pushing as user george
1989 Pushing as user george
2005 hgrc = """
1990 hgrc = """
2006 [hooks]
1991 [hooks]
2007 pretxnchangegroup.acl = python:hgext.acl.hook
1992 pretxnchangegroup.acl = python:hgext.acl.hook
2008 prepushkey.acl = python:hgext.acl.hook
1993 prepushkey.acl = python:hgext.acl.hook
2009 [acl]
1994 [acl]
2010 sources = push
1995 sources = push
2011 [extensions]
1996 [extensions]
2012 posixgetuser=$TESTTMP/posixgetuser.py
1997 posixgetuser=$TESTTMP/posixgetuser.py
2013 [acl.allow.branches]
1998 [acl.allow.branches]
2014 * = george
1999 * = george
2015 """
2000 """
2016 pushing to ../b
2001 pushing to ../b
2017 query 1; heads
2002 query 1; heads
2018 searching for changes
2003 searching for changes
2019 all remote heads known locally
2004 all remote heads known locally
2020 listing keys for "phases"
2005 listing keys for "phases"
2021 checking for updated bookmarks
2006 checking for updated bookmarks
2022 listing keys for "bookmarks"
2007 listing keys for "bookmarks"
2023 listing keys for "bookmarks"
2008 listing keys for "bookmarks"
2024 4 changesets found
2009 4 changesets found
2025 list of changesets:
2010 list of changesets:
2026 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
2011 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
2027 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
2012 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
2028 911600dab2ae7a9baff75958b84fe606851ce955
2013 911600dab2ae7a9baff75958b84fe606851ce955
2029 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
2014 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
2030 bundle2-output-bundle: "HG20", 5 parts total
2015 bundle2-output-bundle: "HG20", 5 parts total
2031 bundle2-output-part: "replycaps" 205 bytes payload
2016 bundle2-output-part: "replycaps" 205 bytes payload
2032 bundle2-output-part: "check:phases" 48 bytes payload
2017 bundle2-output-part: "check:phases" 48 bytes payload
2033 bundle2-output-part: "check:heads" streamed payload
2018 bundle2-output-part: "check:heads" streamed payload
2034 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
2019 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
2035 bundle2-output-part: "phase-heads" 48 bytes payload
2020 bundle2-output-part: "phase-heads" 48 bytes payload
2036 bundle2-input-bundle: with-transaction
2021 bundle2-input-bundle: with-transaction
2037 bundle2-input-part: "replycaps" supported
2022 bundle2-input-part: "replycaps" supported
2038 bundle2-input-part: total payload size 205
2023 bundle2-input-part: total payload size 205
2039 bundle2-input-part: "check:phases" supported
2024 bundle2-input-part: "check:phases" supported
2040 bundle2-input-part: total payload size 48
2025 bundle2-input-part: total payload size 48
2041 bundle2-input-part: "check:heads" supported
2026 bundle2-input-part: "check:heads" supported
2042 bundle2-input-part: total payload size 20
2027 bundle2-input-part: total payload size 20
2043 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
2028 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
2044 adding changesets
2029 adding changesets
2045 add changeset ef1ea85a6374
2030 add changeset ef1ea85a6374
2046 add changeset f9cafe1212c8
2031 add changeset f9cafe1212c8
2047 add changeset 911600dab2ae
2032 add changeset 911600dab2ae
2048 add changeset e8fc755d4d82
2033 add changeset e8fc755d4d82
2049 adding manifests
2034 adding manifests
2050 adding file changes
2035 adding file changes
2051 adding abc.txt revisions
2036 adding abc.txt revisions
2052 adding foo/Bar/file.txt revisions
2037 adding foo/Bar/file.txt revisions
2053 adding foo/file.txt revisions
2038 adding foo/file.txt revisions
2054 adding quux/file.py revisions
2039 adding quux/file.py revisions
2055 added 4 changesets with 4 changes to 4 files (+1 heads)
2056 calling hook pretxnchangegroup.acl: hgext.acl.hook
2040 calling hook pretxnchangegroup.acl: hgext.acl.hook
2057 acl: checking access for user "george"
2041 acl: checking access for user "george"
2058 acl: acl.allow.branches enabled, 1 entries for user george
2042 acl: acl.allow.branches enabled, 1 entries for user george
2059 acl: acl.deny.branches not enabled
2043 acl: acl.deny.branches not enabled
2060 acl: acl.allow not enabled
2044 acl: acl.allow not enabled
2061 acl: acl.deny not enabled
2045 acl: acl.deny not enabled
2062 acl: branch access granted: "ef1ea85a6374" on branch "default"
2046 acl: branch access granted: "ef1ea85a6374" on branch "default"
2063 acl: path access granted: "ef1ea85a6374"
2047 acl: path access granted: "ef1ea85a6374"
2064 acl: branch access granted: "f9cafe1212c8" on branch "default"
2048 acl: branch access granted: "f9cafe1212c8" on branch "default"
2065 acl: path access granted: "f9cafe1212c8"
2049 acl: path access granted: "f9cafe1212c8"
2066 acl: branch access granted: "911600dab2ae" on branch "default"
2050 acl: branch access granted: "911600dab2ae" on branch "default"
2067 acl: path access granted: "911600dab2ae"
2051 acl: path access granted: "911600dab2ae"
2068 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
2052 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
2069 acl: path access granted: "e8fc755d4d82"
2053 acl: path access granted: "e8fc755d4d82"
2070 bundle2-input-part: total payload size 2068
2054 bundle2-input-part: total payload size 2068
2071 bundle2-input-part: "phase-heads" supported
2055 bundle2-input-part: "phase-heads" supported
2072 bundle2-input-part: total payload size 48
2056 bundle2-input-part: total payload size 48
2073 bundle2-input-bundle: 4 parts total
2057 bundle2-input-bundle: 4 parts total
2074 updating the branch cache
2058 updating the branch cache
2059 added 4 changesets with 4 changes to 4 files (+1 heads)
2075 bundle2-output-bundle: "HG20", 1 parts total
2060 bundle2-output-bundle: "HG20", 1 parts total
2076 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
2061 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
2077 bundle2-input-bundle: no-transaction
2062 bundle2-input-bundle: no-transaction
2078 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
2063 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
2079 bundle2-input-bundle: 0 parts total
2064 bundle2-input-bundle: 0 parts total
2080 listing keys for "phases"
2065 listing keys for "phases"
2081 repository tip rolled back to revision 2 (undo push)
2066 repository tip rolled back to revision 2 (undo push)
2082 2:fb35475503ef
2067 2:fb35475503ef
2083
2068
2084
2069
2085 Branch acl conflicting allow
2070 Branch acl conflicting allow
2086 asterisk ends up applying to all branches and allowing george to
2071 asterisk ends up applying to all branches and allowing george to
2087 push foobar into the remote
2072 push foobar into the remote
2088
2073
2089 $ init_config
2074 $ init_config
2090 $ echo "[acl.allow.branches]" >> $config
2075 $ echo "[acl.allow.branches]" >> $config
2091 $ echo "foobar = astro" >> $config
2076 $ echo "foobar = astro" >> $config
2092 $ echo "* = george" >> $config
2077 $ echo "* = george" >> $config
2093 $ do_push george
2078 $ do_push george
2094 Pushing as user george
2079 Pushing as user george
2095 hgrc = """
2080 hgrc = """
2096 [hooks]
2081 [hooks]
2097 pretxnchangegroup.acl = python:hgext.acl.hook
2082 pretxnchangegroup.acl = python:hgext.acl.hook
2098 prepushkey.acl = python:hgext.acl.hook
2083 prepushkey.acl = python:hgext.acl.hook
2099 [acl]
2084 [acl]
2100 sources = push
2085 sources = push
2101 [extensions]
2086 [extensions]
2102 posixgetuser=$TESTTMP/posixgetuser.py
2087 posixgetuser=$TESTTMP/posixgetuser.py
2103 [acl.allow.branches]
2088 [acl.allow.branches]
2104 foobar = astro
2089 foobar = astro
2105 * = george
2090 * = george
2106 """
2091 """
2107 pushing to ../b
2092 pushing to ../b
2108 query 1; heads
2093 query 1; heads
2109 searching for changes
2094 searching for changes
2110 all remote heads known locally
2095 all remote heads known locally
2111 listing keys for "phases"
2096 listing keys for "phases"
2112 checking for updated bookmarks
2097 checking for updated bookmarks
2113 listing keys for "bookmarks"
2098 listing keys for "bookmarks"
2114 listing keys for "bookmarks"
2099 listing keys for "bookmarks"
2115 4 changesets found
2100 4 changesets found
2116 list of changesets:
2101 list of changesets:
2117 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
2102 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
2118 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
2103 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
2119 911600dab2ae7a9baff75958b84fe606851ce955
2104 911600dab2ae7a9baff75958b84fe606851ce955
2120 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
2105 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
2121 bundle2-output-bundle: "HG20", 5 parts total
2106 bundle2-output-bundle: "HG20", 5 parts total
2122 bundle2-output-part: "replycaps" 205 bytes payload
2107 bundle2-output-part: "replycaps" 205 bytes payload
2123 bundle2-output-part: "check:phases" 48 bytes payload
2108 bundle2-output-part: "check:phases" 48 bytes payload
2124 bundle2-output-part: "check:heads" streamed payload
2109 bundle2-output-part: "check:heads" streamed payload
2125 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
2110 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
2126 bundle2-output-part: "phase-heads" 48 bytes payload
2111 bundle2-output-part: "phase-heads" 48 bytes payload
2127 bundle2-input-bundle: with-transaction
2112 bundle2-input-bundle: with-transaction
2128 bundle2-input-part: "replycaps" supported
2113 bundle2-input-part: "replycaps" supported
2129 bundle2-input-part: total payload size 205
2114 bundle2-input-part: total payload size 205
2130 bundle2-input-part: "check:phases" supported
2115 bundle2-input-part: "check:phases" supported
2131 bundle2-input-part: total payload size 48
2116 bundle2-input-part: total payload size 48
2132 bundle2-input-part: "check:heads" supported
2117 bundle2-input-part: "check:heads" supported
2133 bundle2-input-part: total payload size 20
2118 bundle2-input-part: total payload size 20
2134 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
2119 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
2135 adding changesets
2120 adding changesets
2136 add changeset ef1ea85a6374
2121 add changeset ef1ea85a6374
2137 add changeset f9cafe1212c8
2122 add changeset f9cafe1212c8
2138 add changeset 911600dab2ae
2123 add changeset 911600dab2ae
2139 add changeset e8fc755d4d82
2124 add changeset e8fc755d4d82
2140 adding manifests
2125 adding manifests
2141 adding file changes
2126 adding file changes
2142 adding abc.txt revisions
2127 adding abc.txt revisions
2143 adding foo/Bar/file.txt revisions
2128 adding foo/Bar/file.txt revisions
2144 adding foo/file.txt revisions
2129 adding foo/file.txt revisions
2145 adding quux/file.py revisions
2130 adding quux/file.py revisions
2146 added 4 changesets with 4 changes to 4 files (+1 heads)
2147 calling hook pretxnchangegroup.acl: hgext.acl.hook
2131 calling hook pretxnchangegroup.acl: hgext.acl.hook
2148 acl: checking access for user "george"
2132 acl: checking access for user "george"
2149 acl: acl.allow.branches enabled, 1 entries for user george
2133 acl: acl.allow.branches enabled, 1 entries for user george
2150 acl: acl.deny.branches not enabled
2134 acl: acl.deny.branches not enabled
2151 acl: acl.allow not enabled
2135 acl: acl.allow not enabled
2152 acl: acl.deny not enabled
2136 acl: acl.deny not enabled
2153 acl: branch access granted: "ef1ea85a6374" on branch "default"
2137 acl: branch access granted: "ef1ea85a6374" on branch "default"
2154 acl: path access granted: "ef1ea85a6374"
2138 acl: path access granted: "ef1ea85a6374"
2155 acl: branch access granted: "f9cafe1212c8" on branch "default"
2139 acl: branch access granted: "f9cafe1212c8" on branch "default"
2156 acl: path access granted: "f9cafe1212c8"
2140 acl: path access granted: "f9cafe1212c8"
2157 acl: branch access granted: "911600dab2ae" on branch "default"
2141 acl: branch access granted: "911600dab2ae" on branch "default"
2158 acl: path access granted: "911600dab2ae"
2142 acl: path access granted: "911600dab2ae"
2159 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
2143 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
2160 acl: path access granted: "e8fc755d4d82"
2144 acl: path access granted: "e8fc755d4d82"
2161 bundle2-input-part: total payload size 2068
2145 bundle2-input-part: total payload size 2068
2162 bundle2-input-part: "phase-heads" supported
2146 bundle2-input-part: "phase-heads" supported
2163 bundle2-input-part: total payload size 48
2147 bundle2-input-part: total payload size 48
2164 bundle2-input-bundle: 4 parts total
2148 bundle2-input-bundle: 4 parts total
2165 updating the branch cache
2149 updating the branch cache
2150 added 4 changesets with 4 changes to 4 files (+1 heads)
2166 bundle2-output-bundle: "HG20", 1 parts total
2151 bundle2-output-bundle: "HG20", 1 parts total
2167 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
2152 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
2168 bundle2-input-bundle: no-transaction
2153 bundle2-input-bundle: no-transaction
2169 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
2154 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
2170 bundle2-input-bundle: 0 parts total
2155 bundle2-input-bundle: 0 parts total
2171 listing keys for "phases"
2156 listing keys for "phases"
2172 repository tip rolled back to revision 2 (undo push)
2157 repository tip rolled back to revision 2 (undo push)
2173 2:fb35475503ef
2158 2:fb35475503ef
2174
2159
2175 Branch acl conflicting deny
2160 Branch acl conflicting deny
2176
2161
2177 $ init_config
2162 $ init_config
2178 $ echo "[acl.deny.branches]" >> $config
2163 $ echo "[acl.deny.branches]" >> $config
2179 $ echo "foobar = astro" >> $config
2164 $ echo "foobar = astro" >> $config
2180 $ echo "default = astro" >> $config
2165 $ echo "default = astro" >> $config
2181 $ echo "* = george" >> $config
2166 $ echo "* = george" >> $config
2182 $ do_push george
2167 $ do_push george
2183 Pushing as user george
2168 Pushing as user george
2184 hgrc = """
2169 hgrc = """
2185 [hooks]
2170 [hooks]
2186 pretxnchangegroup.acl = python:hgext.acl.hook
2171 pretxnchangegroup.acl = python:hgext.acl.hook
2187 prepushkey.acl = python:hgext.acl.hook
2172 prepushkey.acl = python:hgext.acl.hook
2188 [acl]
2173 [acl]
2189 sources = push
2174 sources = push
2190 [extensions]
2175 [extensions]
2191 posixgetuser=$TESTTMP/posixgetuser.py
2176 posixgetuser=$TESTTMP/posixgetuser.py
2192 [acl.deny.branches]
2177 [acl.deny.branches]
2193 foobar = astro
2178 foobar = astro
2194 default = astro
2179 default = astro
2195 * = george
2180 * = george
2196 """
2181 """
2197 pushing to ../b
2182 pushing to ../b
2198 query 1; heads
2183 query 1; heads
2199 searching for changes
2184 searching for changes
2200 all remote heads known locally
2185 all remote heads known locally
2201 listing keys for "phases"
2186 listing keys for "phases"
2202 checking for updated bookmarks
2187 checking for updated bookmarks
2203 listing keys for "bookmarks"
2188 listing keys for "bookmarks"
2204 listing keys for "bookmarks"
2189 listing keys for "bookmarks"
2205 4 changesets found
2190 4 changesets found
2206 list of changesets:
2191 list of changesets:
2207 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
2192 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
2208 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
2193 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
2209 911600dab2ae7a9baff75958b84fe606851ce955
2194 911600dab2ae7a9baff75958b84fe606851ce955
2210 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
2195 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
2211 bundle2-output-bundle: "HG20", 5 parts total
2196 bundle2-output-bundle: "HG20", 5 parts total
2212 bundle2-output-part: "replycaps" 205 bytes payload
2197 bundle2-output-part: "replycaps" 205 bytes payload
2213 bundle2-output-part: "check:phases" 48 bytes payload
2198 bundle2-output-part: "check:phases" 48 bytes payload
2214 bundle2-output-part: "check:heads" streamed payload
2199 bundle2-output-part: "check:heads" streamed payload
2215 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
2200 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
2216 bundle2-output-part: "phase-heads" 48 bytes payload
2201 bundle2-output-part: "phase-heads" 48 bytes payload
2217 bundle2-input-bundle: with-transaction
2202 bundle2-input-bundle: with-transaction
2218 bundle2-input-part: "replycaps" supported
2203 bundle2-input-part: "replycaps" supported
2219 bundle2-input-part: total payload size 205
2204 bundle2-input-part: total payload size 205
2220 bundle2-input-part: "check:phases" supported
2205 bundle2-input-part: "check:phases" supported
2221 bundle2-input-part: total payload size 48
2206 bundle2-input-part: total payload size 48
2222 bundle2-input-part: "check:heads" supported
2207 bundle2-input-part: "check:heads" supported
2223 bundle2-input-part: total payload size 20
2208 bundle2-input-part: total payload size 20
2224 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
2209 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
2225 adding changesets
2210 adding changesets
2226 add changeset ef1ea85a6374
2211 add changeset ef1ea85a6374
2227 add changeset f9cafe1212c8
2212 add changeset f9cafe1212c8
2228 add changeset 911600dab2ae
2213 add changeset 911600dab2ae
2229 add changeset e8fc755d4d82
2214 add changeset e8fc755d4d82
2230 adding manifests
2215 adding manifests
2231 adding file changes
2216 adding file changes
2232 adding abc.txt revisions
2217 adding abc.txt revisions
2233 adding foo/Bar/file.txt revisions
2218 adding foo/Bar/file.txt revisions
2234 adding foo/file.txt revisions
2219 adding foo/file.txt revisions
2235 adding quux/file.py revisions
2220 adding quux/file.py revisions
2236 added 4 changesets with 4 changes to 4 files (+1 heads)
2237 calling hook pretxnchangegroup.acl: hgext.acl.hook
2221 calling hook pretxnchangegroup.acl: hgext.acl.hook
2238 acl: checking access for user "george"
2222 acl: checking access for user "george"
2239 acl: acl.allow.branches not enabled
2223 acl: acl.allow.branches not enabled
2240 acl: acl.deny.branches enabled, 1 entries for user george
2224 acl: acl.deny.branches enabled, 1 entries for user george
2241 acl: acl.allow not enabled
2225 acl: acl.allow not enabled
2242 acl: acl.deny not enabled
2226 acl: acl.deny not enabled
2243 error: pretxnchangegroup.acl hook failed: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
2227 error: pretxnchangegroup.acl hook failed: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
2244 bundle2-input-part: total payload size 2068
2228 bundle2-input-part: total payload size 2068
2245 bundle2-input-part: total payload size 48
2229 bundle2-input-part: total payload size 48
2246 bundle2-input-bundle: 4 parts total
2230 bundle2-input-bundle: 4 parts total
2247 transaction abort!
2231 transaction abort!
2248 rollback completed
2232 rollback completed
2249 abort: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
2233 abort: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
2250 no rollback information available
2234 no rollback information available
2251 2:fb35475503ef
2235 2:fb35475503ef
2252
2236
2253 User 'astro' must not be denied
2237 User 'astro' must not be denied
2254
2238
2255 $ init_config
2239 $ init_config
2256 $ echo "[acl.deny.branches]" >> $config
2240 $ echo "[acl.deny.branches]" >> $config
2257 $ echo "default = !astro" >> $config
2241 $ echo "default = !astro" >> $config
2258 $ do_push astro
2242 $ do_push astro
2259 Pushing as user astro
2243 Pushing as user astro
2260 hgrc = """
2244 hgrc = """
2261 [hooks]
2245 [hooks]
2262 pretxnchangegroup.acl = python:hgext.acl.hook
2246 pretxnchangegroup.acl = python:hgext.acl.hook
2263 prepushkey.acl = python:hgext.acl.hook
2247 prepushkey.acl = python:hgext.acl.hook
2264 [acl]
2248 [acl]
2265 sources = push
2249 sources = push
2266 [extensions]
2250 [extensions]
2267 posixgetuser=$TESTTMP/posixgetuser.py
2251 posixgetuser=$TESTTMP/posixgetuser.py
2268 [acl.deny.branches]
2252 [acl.deny.branches]
2269 default = !astro
2253 default = !astro
2270 """
2254 """
2271 pushing to ../b
2255 pushing to ../b
2272 query 1; heads
2256 query 1; heads
2273 searching for changes
2257 searching for changes
2274 all remote heads known locally
2258 all remote heads known locally
2275 listing keys for "phases"
2259 listing keys for "phases"
2276 checking for updated bookmarks
2260 checking for updated bookmarks
2277 listing keys for "bookmarks"
2261 listing keys for "bookmarks"
2278 listing keys for "bookmarks"
2262 listing keys for "bookmarks"
2279 4 changesets found
2263 4 changesets found
2280 list of changesets:
2264 list of changesets:
2281 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
2265 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
2282 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
2266 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
2283 911600dab2ae7a9baff75958b84fe606851ce955
2267 911600dab2ae7a9baff75958b84fe606851ce955
2284 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
2268 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
2285 bundle2-output-bundle: "HG20", 5 parts total
2269 bundle2-output-bundle: "HG20", 5 parts total
2286 bundle2-output-part: "replycaps" 205 bytes payload
2270 bundle2-output-part: "replycaps" 205 bytes payload
2287 bundle2-output-part: "check:phases" 48 bytes payload
2271 bundle2-output-part: "check:phases" 48 bytes payload
2288 bundle2-output-part: "check:heads" streamed payload
2272 bundle2-output-part: "check:heads" streamed payload
2289 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
2273 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
2290 bundle2-output-part: "phase-heads" 48 bytes payload
2274 bundle2-output-part: "phase-heads" 48 bytes payload
2291 bundle2-input-bundle: with-transaction
2275 bundle2-input-bundle: with-transaction
2292 bundle2-input-part: "replycaps" supported
2276 bundle2-input-part: "replycaps" supported
2293 bundle2-input-part: total payload size 205
2277 bundle2-input-part: total payload size 205
2294 bundle2-input-part: "check:phases" supported
2278 bundle2-input-part: "check:phases" supported
2295 bundle2-input-part: total payload size 48
2279 bundle2-input-part: total payload size 48
2296 bundle2-input-part: "check:heads" supported
2280 bundle2-input-part: "check:heads" supported
2297 bundle2-input-part: total payload size 20
2281 bundle2-input-part: total payload size 20
2298 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
2282 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
2299 adding changesets
2283 adding changesets
2300 add changeset ef1ea85a6374
2284 add changeset ef1ea85a6374
2301 add changeset f9cafe1212c8
2285 add changeset f9cafe1212c8
2302 add changeset 911600dab2ae
2286 add changeset 911600dab2ae
2303 add changeset e8fc755d4d82
2287 add changeset e8fc755d4d82
2304 adding manifests
2288 adding manifests
2305 adding file changes
2289 adding file changes
2306 adding abc.txt revisions
2290 adding abc.txt revisions
2307 adding foo/Bar/file.txt revisions
2291 adding foo/Bar/file.txt revisions
2308 adding foo/file.txt revisions
2292 adding foo/file.txt revisions
2309 adding quux/file.py revisions
2293 adding quux/file.py revisions
2310 added 4 changesets with 4 changes to 4 files (+1 heads)
2311 calling hook pretxnchangegroup.acl: hgext.acl.hook
2294 calling hook pretxnchangegroup.acl: hgext.acl.hook
2312 acl: checking access for user "astro"
2295 acl: checking access for user "astro"
2313 acl: acl.allow.branches not enabled
2296 acl: acl.allow.branches not enabled
2314 acl: acl.deny.branches enabled, 0 entries for user astro
2297 acl: acl.deny.branches enabled, 0 entries for user astro
2315 acl: acl.allow not enabled
2298 acl: acl.allow not enabled
2316 acl: acl.deny not enabled
2299 acl: acl.deny not enabled
2317 acl: branch access granted: "ef1ea85a6374" on branch "default"
2300 acl: branch access granted: "ef1ea85a6374" on branch "default"
2318 acl: path access granted: "ef1ea85a6374"
2301 acl: path access granted: "ef1ea85a6374"
2319 acl: branch access granted: "f9cafe1212c8" on branch "default"
2302 acl: branch access granted: "f9cafe1212c8" on branch "default"
2320 acl: path access granted: "f9cafe1212c8"
2303 acl: path access granted: "f9cafe1212c8"
2321 acl: branch access granted: "911600dab2ae" on branch "default"
2304 acl: branch access granted: "911600dab2ae" on branch "default"
2322 acl: path access granted: "911600dab2ae"
2305 acl: path access granted: "911600dab2ae"
2323 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
2306 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
2324 acl: path access granted: "e8fc755d4d82"
2307 acl: path access granted: "e8fc755d4d82"
2325 bundle2-input-part: total payload size 2068
2308 bundle2-input-part: total payload size 2068
2326 bundle2-input-part: "phase-heads" supported
2309 bundle2-input-part: "phase-heads" supported
2327 bundle2-input-part: total payload size 48
2310 bundle2-input-part: total payload size 48
2328 bundle2-input-bundle: 4 parts total
2311 bundle2-input-bundle: 4 parts total
2329 updating the branch cache
2312 updating the branch cache
2313 added 4 changesets with 4 changes to 4 files (+1 heads)
2330 bundle2-output-bundle: "HG20", 1 parts total
2314 bundle2-output-bundle: "HG20", 1 parts total
2331 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
2315 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
2332 bundle2-input-bundle: no-transaction
2316 bundle2-input-bundle: no-transaction
2333 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
2317 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
2334 bundle2-input-bundle: 0 parts total
2318 bundle2-input-bundle: 0 parts total
2335 listing keys for "phases"
2319 listing keys for "phases"
2336 repository tip rolled back to revision 2 (undo push)
2320 repository tip rolled back to revision 2 (undo push)
2337 2:fb35475503ef
2321 2:fb35475503ef
2338
2322
2339
2323
2340 Non-astro users must be denied
2324 Non-astro users must be denied
2341
2325
2342 $ do_push george
2326 $ do_push george
2343 Pushing as user george
2327 Pushing as user george
2344 hgrc = """
2328 hgrc = """
2345 [hooks]
2329 [hooks]
2346 pretxnchangegroup.acl = python:hgext.acl.hook
2330 pretxnchangegroup.acl = python:hgext.acl.hook
2347 prepushkey.acl = python:hgext.acl.hook
2331 prepushkey.acl = python:hgext.acl.hook
2348 [acl]
2332 [acl]
2349 sources = push
2333 sources = push
2350 [extensions]
2334 [extensions]
2351 posixgetuser=$TESTTMP/posixgetuser.py
2335 posixgetuser=$TESTTMP/posixgetuser.py
2352 [acl.deny.branches]
2336 [acl.deny.branches]
2353 default = !astro
2337 default = !astro
2354 """
2338 """
2355 pushing to ../b
2339 pushing to ../b
2356 query 1; heads
2340 query 1; heads
2357 searching for changes
2341 searching for changes
2358 all remote heads known locally
2342 all remote heads known locally
2359 listing keys for "phases"
2343 listing keys for "phases"
2360 checking for updated bookmarks
2344 checking for updated bookmarks
2361 listing keys for "bookmarks"
2345 listing keys for "bookmarks"
2362 listing keys for "bookmarks"
2346 listing keys for "bookmarks"
2363 4 changesets found
2347 4 changesets found
2364 list of changesets:
2348 list of changesets:
2365 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
2349 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
2366 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
2350 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
2367 911600dab2ae7a9baff75958b84fe606851ce955
2351 911600dab2ae7a9baff75958b84fe606851ce955
2368 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
2352 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
2369 bundle2-output-bundle: "HG20", 5 parts total
2353 bundle2-output-bundle: "HG20", 5 parts total
2370 bundle2-output-part: "replycaps" 205 bytes payload
2354 bundle2-output-part: "replycaps" 205 bytes payload
2371 bundle2-output-part: "check:phases" 48 bytes payload
2355 bundle2-output-part: "check:phases" 48 bytes payload
2372 bundle2-output-part: "check:heads" streamed payload
2356 bundle2-output-part: "check:heads" streamed payload
2373 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
2357 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
2374 bundle2-output-part: "phase-heads" 48 bytes payload
2358 bundle2-output-part: "phase-heads" 48 bytes payload
2375 bundle2-input-bundle: with-transaction
2359 bundle2-input-bundle: with-transaction
2376 bundle2-input-part: "replycaps" supported
2360 bundle2-input-part: "replycaps" supported
2377 bundle2-input-part: total payload size 205
2361 bundle2-input-part: total payload size 205
2378 bundle2-input-part: "check:phases" supported
2362 bundle2-input-part: "check:phases" supported
2379 bundle2-input-part: total payload size 48
2363 bundle2-input-part: total payload size 48
2380 bundle2-input-part: "check:heads" supported
2364 bundle2-input-part: "check:heads" supported
2381 bundle2-input-part: total payload size 20
2365 bundle2-input-part: total payload size 20
2382 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
2366 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
2383 adding changesets
2367 adding changesets
2384 add changeset ef1ea85a6374
2368 add changeset ef1ea85a6374
2385 add changeset f9cafe1212c8
2369 add changeset f9cafe1212c8
2386 add changeset 911600dab2ae
2370 add changeset 911600dab2ae
2387 add changeset e8fc755d4d82
2371 add changeset e8fc755d4d82
2388 adding manifests
2372 adding manifests
2389 adding file changes
2373 adding file changes
2390 adding abc.txt revisions
2374 adding abc.txt revisions
2391 adding foo/Bar/file.txt revisions
2375 adding foo/Bar/file.txt revisions
2392 adding foo/file.txt revisions
2376 adding foo/file.txt revisions
2393 adding quux/file.py revisions
2377 adding quux/file.py revisions
2394 added 4 changesets with 4 changes to 4 files (+1 heads)
2395 calling hook pretxnchangegroup.acl: hgext.acl.hook
2378 calling hook pretxnchangegroup.acl: hgext.acl.hook
2396 acl: checking access for user "george"
2379 acl: checking access for user "george"
2397 acl: acl.allow.branches not enabled
2380 acl: acl.allow.branches not enabled
2398 acl: acl.deny.branches enabled, 1 entries for user george
2381 acl: acl.deny.branches enabled, 1 entries for user george
2399 acl: acl.allow not enabled
2382 acl: acl.allow not enabled
2400 acl: acl.deny not enabled
2383 acl: acl.deny not enabled
2401 error: pretxnchangegroup.acl hook failed: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
2384 error: pretxnchangegroup.acl hook failed: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
2402 bundle2-input-part: total payload size 2068
2385 bundle2-input-part: total payload size 2068
2403 bundle2-input-part: total payload size 48
2386 bundle2-input-part: total payload size 48
2404 bundle2-input-bundle: 4 parts total
2387 bundle2-input-bundle: 4 parts total
2405 transaction abort!
2388 transaction abort!
2406 rollback completed
2389 rollback completed
2407 abort: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
2390 abort: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
2408 no rollback information available
2391 no rollback information available
2409 2:fb35475503ef
2392 2:fb35475503ef
2410
2393
2411
2394
@@ -1,292 +1,292 b''
1 initialize
1 initialize
2 $ make_changes() {
2 $ make_changes() {
3 > d=`pwd`
3 > d=`pwd`
4 > [ ! -z $1 ] && cd $1
4 > [ ! -z $1 ] && cd $1
5 > echo "test `basename \`pwd\``" >> test
5 > echo "test `basename \`pwd\``" >> test
6 > hg commit -Am"${2:-test}"
6 > hg commit -Am"${2:-test}"
7 > r=$?
7 > r=$?
8 > cd $d
8 > cd $d
9 > return $r
9 > return $r
10 > }
10 > }
11 $ ls -1a
11 $ ls -1a
12 .
12 .
13 ..
13 ..
14 $ hg init a
14 $ hg init a
15 $ cd a
15 $ cd a
16 $ echo 'test' > test; hg commit -Am'test'
16 $ echo 'test' > test; hg commit -Am'test'
17 adding test
17 adding test
18
18
19 clone to b
19 clone to b
20
20
21 $ mkdir ../b
21 $ mkdir ../b
22 $ cd ../b
22 $ cd ../b
23 $ hg clone ../a .
23 $ hg clone ../a .
24 updating to branch default
24 updating to branch default
25 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
25 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
26 $ echo "[extensions]" >> .hg/hgrc
26 $ echo "[extensions]" >> .hg/hgrc
27 $ echo "bookflow=" >> .hg/hgrc
27 $ echo "bookflow=" >> .hg/hgrc
28 $ hg branch X
28 $ hg branch X
29 abort: creating named branches is disabled and you should use bookmarks
29 abort: creating named branches is disabled and you should use bookmarks
30 (see 'hg help bookflow')
30 (see 'hg help bookflow')
31 [255]
31 [255]
32 $ hg bookmark X
32 $ hg bookmark X
33 $ hg bookmarks
33 $ hg bookmarks
34 * X 0:* (glob)
34 * X 0:* (glob)
35 $ hg bookmark X
35 $ hg bookmark X
36 abort: bookmark X already exists, to move use the --rev option
36 abort: bookmark X already exists, to move use the --rev option
37 [255]
37 [255]
38 $ make_changes
38 $ make_changes
39 $ hg push ../a -q
39 $ hg push ../a -q
40
40
41 $ hg bookmarks
41 $ hg bookmarks
42 \* X 1:* (glob)
42 \* X 1:* (glob)
43
43
44 change a
44 change a
45 $ cd ../a
45 $ cd ../a
46 $ hg up
46 $ hg up
47 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
47 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
48 $ echo 'test' >> test; hg commit -Am'test'
48 $ echo 'test' >> test; hg commit -Am'test'
49
49
50
50
51 pull in b
51 pull in b
52 $ cd ../b
52 $ cd ../b
53 $ hg pull -u
53 $ hg pull -u
54 pulling from $TESTTMP/a
54 pulling from $TESTTMP/a
55 searching for changes
55 searching for 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 1 changes to 1 files
59 added 1 changesets with 1 changes to 1 files
60 new changesets * (glob)
60 new changesets * (glob)
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 (leaving bookmark X)
62 (leaving bookmark X)
63 $ hg status
63 $ hg status
64 $ hg bookmarks
64 $ hg bookmarks
65 X 1:* (glob)
65 X 1:* (glob)
66
66
67 check protection of @ bookmark
67 check protection of @ bookmark
68 $ hg bookmark @
68 $ hg bookmark @
69 $ hg bookmarks
69 $ hg bookmarks
70 \* @ 2:* (glob)
70 \* @ 2:* (glob)
71 X 1:* (glob)
71 X 1:* (glob)
72 $ make_changes
72 $ make_changes
73 abort: cannot commit, bookmark @ is protected
73 abort: cannot commit, bookmark @ is protected
74 [255]
74 [255]
75
75
76 $ hg status
76 $ hg status
77 M test
77 M test
78 $ hg bookmarks
78 $ hg bookmarks
79 \* @ 2:* (glob)
79 \* @ 2:* (glob)
80 X 1:* (glob)
80 X 1:* (glob)
81
81
82 $ hg --config bookflow.protect= commit -Am"Updated test"
82 $ hg --config bookflow.protect= commit -Am"Updated test"
83
83
84 $ hg bookmarks
84 $ hg bookmarks
85 \* @ 3:* (glob)
85 \* @ 3:* (glob)
86 X 1:* (glob)
86 X 1:* (glob)
87
87
88 check requirement for an active bookmark
88 check requirement for an active bookmark
89 $ hg bookmark -i
89 $ hg bookmark -i
90 $ hg bookmarks
90 $ hg bookmarks
91 @ 3:* (glob)
91 @ 3:* (glob)
92 X 1:* (glob)
92 X 1:* (glob)
93 $ make_changes
93 $ make_changes
94 abort: cannot commit without an active bookmark
94 abort: cannot commit without an active bookmark
95 [255]
95 [255]
96 $ hg revert test
96 $ hg revert test
97 $ rm test.orig
97 $ rm test.orig
98 $ hg status
98 $ hg status
99
99
100
100
101 make the bookmark move by updating it on a, and then pulling
101 make the bookmark move by updating it on a, and then pulling
102 # add a commit to a
102 # add a commit to a
103 $ cd ../a
103 $ cd ../a
104 $ hg bookmark X
104 $ hg bookmark X
105 $ hg bookmarks
105 $ hg bookmarks
106 \* X 2:* (glob)
106 \* X 2:* (glob)
107 $ make_changes
107 $ make_changes
108 $ hg bookmarks
108 $ hg bookmarks
109 * X 3:81af7977fdb9
109 * X 3:81af7977fdb9
110
110
111 # go back to b, and check out X
111 # go back to b, and check out X
112 $ cd ../b
112 $ cd ../b
113 $ hg up X
113 $ hg up X
114 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
114 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
115 (activating bookmark X)
115 (activating bookmark X)
116 $ hg bookmarks
116 $ hg bookmarks
117 @ 3:* (glob)
117 @ 3:* (glob)
118 \* X 1:* (glob)
118 \* X 1:* (glob)
119
119
120 # pull, this should move the bookmark forward, because it was changed remotely
120 # pull, this should move the bookmark forward, because it was changed remotely
121 $ hg pull -u | grep "updating to active bookmark X"
121 $ hg pull -u | grep "updating to active bookmark X"
122 updating to active bookmark X
122 updating to active bookmark X
123
123
124 $ hg bookmarks
124 $ hg bookmarks
125 @ 3:* (glob)
125 @ 3:* (glob)
126 * X 4:81af7977fdb9
126 * X 4:81af7977fdb9
127
127
128 the bookmark should not move if it diverged from remote
128 the bookmark should not move if it diverged from remote
129 $ hg -R ../a status
129 $ hg -R ../a status
130 $ hg -R ../b status
130 $ hg -R ../b status
131 $ make_changes ../a
131 $ make_changes ../a
132 $ make_changes ../b
132 $ make_changes ../b
133 $ hg -R ../a status
133 $ hg -R ../a status
134 $ hg -R ../b status
134 $ hg -R ../b status
135 $ hg -R ../a bookmarks
135 $ hg -R ../a bookmarks
136 * X 4:238292f60a57
136 * X 4:238292f60a57
137 $ hg -R ../b bookmarks
137 $ hg -R ../b bookmarks
138 @ 3:* (glob)
138 @ 3:* (glob)
139 * X 5:096f7e86892d
139 * X 5:096f7e86892d
140 $ cd ../b
140 $ cd ../b
141 $ # make sure we cannot push after bookmarks diverged
141 $ # make sure we cannot push after bookmarks diverged
142 $ hg push -B X | grep abort
142 $ hg push -B X | grep abort
143 abort: push creates new remote head * with bookmark 'X'! (glob)
143 abort: push creates new remote head * with bookmark 'X'! (glob)
144 (pull and merge or see 'hg help push' for details about pushing new heads)
144 (pull and merge or see 'hg help push' for details about pushing new heads)
145 [1]
145 [1]
146 $ hg pull -u | grep divergent
146 $ hg pull -u | grep divergent
147 divergent bookmark X stored as X@default
147 divergent bookmark X stored as X@default
148 1 other divergent bookmarks for "X"
148 1 other divergent bookmarks for "X"
149 $ hg bookmarks
149 $ hg bookmarks
150 @ 3:* (glob)
150 @ 3:* (glob)
151 * X 5:096f7e86892d
151 * X 5:096f7e86892d
152 X@default 6:238292f60a57
152 X@default 6:238292f60a57
153 $ hg id -in
153 $ hg id -in
154 096f7e86892d 5
154 096f7e86892d 5
155 $ make_changes
155 $ make_changes
156 $ hg status
156 $ hg status
157 $ hg bookmarks
157 $ hg bookmarks
158 @ 3:* (glob)
158 @ 3:* (glob)
159 * X 7:227f941aeb07
159 * X 7:227f941aeb07
160 X@default 6:238292f60a57
160 X@default 6:238292f60a57
161
161
162 now merge with the remote bookmark
162 now merge with the remote bookmark
163 $ hg merge X@default --tool :local -q
163 $ hg merge X@default --tool :local -q
164 $ hg status
164 $ hg status
165 M test
165 M test
166 $ hg commit -m"Merged with X@default"
166 $ hg commit -m"Merged with X@default"
167 $ hg bookmarks
167 $ hg bookmarks
168 @ 3:* (glob)
168 @ 3:* (glob)
169 * X 8:26fed9bb3219
169 * X 8:26fed9bb3219
170 $ hg push -B X | grep bookmark
170 $ hg push -B X | grep bookmark
171 pushing to $TESTTMP/a (?)
171 pushing to $TESTTMP/a (?)
172 updating bookmark X
172 updating bookmark X
173 $ cd ../a
173 $ cd ../a
174 $ hg up -q
174 $ hg up -q
175 $ hg bookmarks
175 $ hg bookmarks
176 * X 7:26fed9bb3219
176 * X 7:26fed9bb3219
177
177
178 test hg pull when there is more than one descendant
178 test hg pull when there is more than one descendant
179 $ cd ../a
179 $ cd ../a
180 $ hg bookmark Z
180 $ hg bookmark Z
181 $ hg bookmark Y
181 $ hg bookmark Y
182 $ make_changes . YY
182 $ make_changes . YY
183 $ hg up Z -q
183 $ hg up Z -q
184 $ make_changes . ZZ
184 $ make_changes . ZZ
185 created new head
185 created new head
186 $ hg bookmarks
186 $ hg bookmarks
187 X 7:26fed9bb3219
187 X 7:26fed9bb3219
188 Y 8:131e663dbd2a
188 Y 8:131e663dbd2a
189 * Z 9:b74a4149df25
189 * Z 9:b74a4149df25
190 $ hg log -r 'p1(Y)' -r 'p1(Z)' -T '{rev}\n' # prove that Y and Z share the same parent
190 $ hg log -r 'p1(Y)' -r 'p1(Z)' -T '{rev}\n' # prove that Y and Z share the same parent
191 7
191 7
192 $ hg log -r 'Y%Z' -T '{rev}\n' # revs in Y but not in Z
192 $ hg log -r 'Y%Z' -T '{rev}\n' # revs in Y but not in Z
193 8
193 8
194 $ hg log -r 'Z%Y' -T '{rev}\n' # revs in Z but not in Y
194 $ hg log -r 'Z%Y' -T '{rev}\n' # revs in Z but not in Y
195 9
195 9
196 $ cd ../b
196 $ cd ../b
197 $ hg pull -uq
197 $ hg pull -uq
198 $ hg id
198 $ hg id
199 b74a4149df25 tip Z
199 b74a4149df25 tip Z
200 $ hg bookmarks | grep \* # no active bookmark
200 $ hg bookmarks | grep \* # no active bookmark
201 [1]
201 [1]
202
202
203
203
204 test shelving
204 test shelving
205 $ cd ../a
205 $ cd ../a
206 $ echo anotherfile > anotherfile # this change should not conflict
206 $ echo anotherfile > anotherfile # this change should not conflict
207 $ hg add anotherfile
207 $ hg add anotherfile
208 $ hg commit -m"Change in a"
208 $ hg commit -m"Change in a"
209 $ cd ../b
209 $ cd ../b
210 $ hg up Z | grep Z
210 $ hg up Z | grep Z
211 (activating bookmark Z)
211 (activating bookmark Z)
212 $ hg book | grep \* # make sure active bookmark
212 $ hg book | grep \* # make sure active bookmark
213 \* Z 10:* (glob)
213 \* Z 10:* (glob)
214 $ echo "test b" >> test
214 $ echo "test b" >> test
215 $ hg diff --stat
215 $ hg diff --stat
216 test | 1 +
216 test | 1 +
217 1 files changed, 1 insertions(+), 0 deletions(-)
217 1 files changed, 1 insertions(+), 0 deletions(-)
218 $ hg shelve
218 $ hg shelve
219 shelved as Z
219 shelved as Z
220 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
220 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
221 $ hg pull -uq
221 $ hg pull -uq
222 $ hg unshelve
222 $ hg unshelve
223 unshelving change 'Z'
223 unshelving change 'Z'
224 rebasing shelved changes
224 rebasing shelved changes
225 $ hg diff --stat
225 $ hg diff --stat
226 test | 1 +
226 test | 1 +
227 1 files changed, 1 insertions(+), 0 deletions(-)
227 1 files changed, 1 insertions(+), 0 deletions(-)
228
228
229
229
230 make the bookmark move by updating it on a, and then pulling with a local change
230 make the bookmark move by updating it on a, and then pulling with a local change
231 # add a commit to a
231 # add a commit to a
232 $ cd ../a
232 $ cd ../a
233 $ hg up -C X |fgrep "activating bookmark X"
233 $ hg up -C X |fgrep "activating bookmark X"
234 (activating bookmark X)
234 (activating bookmark X)
235 # go back to b, and check out X
235 # go back to b, and check out X
236 $ cd ../b
236 $ cd ../b
237 $ hg up -C X |fgrep "activating bookmark X"
237 $ hg up -C X |fgrep "activating bookmark X"
238 (activating bookmark X)
238 (activating bookmark X)
239 # update and push from a
239 # update and push from a
240 $ make_changes ../a
240 $ make_changes ../a
241 created new head
241 created new head
242 $ echo "more" >> test
242 $ echo "more" >> test
243 $ hg pull -u 2>&1 | fgrep -v TESTTMP| fgrep -v "searching for changes" | fgrep -v adding
243 $ hg pull -u 2>&1 | fgrep -v TESTTMP| fgrep -v "searching for changes" | fgrep -v adding
244 pulling from $TESTTMP/a
244 pulling from $TESTTMP/a
245 updating bookmark X
245 added 1 changesets with 0 changes to 0 files (+1 heads)
246 added 1 changesets with 0 changes to 0 files (+1 heads)
246 updating bookmark X
247 new changesets * (glob)
247 new changesets * (glob)
248 updating to active bookmark X
248 updating to active bookmark X
249 merging test
249 merging test
250 warning: conflicts while merging test! (edit, then use 'hg resolve --mark')
250 warning: conflicts while merging test! (edit, then use 'hg resolve --mark')
251 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
251 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
252 use 'hg resolve' to retry unresolved file merges
252 use 'hg resolve' to retry unresolved file merges
253 $ hg update -Cq
253 $ hg update -Cq
254 $ rm test.orig
254 $ rm test.orig
255
255
256 make sure that commits aren't possible if working directory is not pointing to active bookmark
256 make sure that commits aren't possible if working directory is not pointing to active bookmark
257 $ hg -R ../a status
257 $ hg -R ../a status
258 $ hg -R ../b status
258 $ hg -R ../b status
259 $ hg -R ../a id -i
259 $ hg -R ../a id -i
260 36a6e592ec06
260 36a6e592ec06
261 $ hg -R ../a book | grep X
261 $ hg -R ../a book | grep X
262 \* X \d+:36a6e592ec06 (re)
262 \* X \d+:36a6e592ec06 (re)
263 $ hg -R ../b id -i
263 $ hg -R ../b id -i
264 36a6e592ec06
264 36a6e592ec06
265 $ hg -R ../b book | grep X
265 $ hg -R ../b book | grep X
266 \* X \d+:36a6e592ec06 (re)
266 \* X \d+:36a6e592ec06 (re)
267 $ make_changes ../a
267 $ make_changes ../a
268 $ hg -R ../a book | grep X
268 $ hg -R ../a book | grep X
269 \* X \d+:f73a71c992b8 (re)
269 \* X \d+:f73a71c992b8 (re)
270 $ cd ../b
270 $ cd ../b
271 $ hg pull 2>&1 | grep -v add | grep -v pulling | grep -v searching | grep -v changeset
271 $ hg pull 2>&1 | grep -v add | grep -v pulling | grep -v searching | grep -v changeset
272 updating bookmark X
272 updating bookmark X
273 (run 'hg update' to get a working copy)
273 (run 'hg update' to get a working copy)
274 working directory out of sync with active bookmark, run 'hg up X'
274 working directory out of sync with active bookmark, run 'hg up X'
275 $ hg id -i # we're still on the old commit
275 $ hg id -i # we're still on the old commit
276 36a6e592ec06
276 36a6e592ec06
277 $ hg book | grep X # while the bookmark moved
277 $ hg book | grep X # while the bookmark moved
278 \* X \d+:f73a71c992b8 (re)
278 \* X \d+:f73a71c992b8 (re)
279 $ make_changes
279 $ make_changes
280 abort: cannot commit, working directory out of sync with active bookmark
280 abort: cannot commit, working directory out of sync with active bookmark
281 (run 'hg up X')
281 (run 'hg up X')
282 [255]
282 [255]
283 $ hg up -Cq -r . # cleanup local changes
283 $ hg up -Cq -r . # cleanup local changes
284 $ hg status
284 $ hg status
285 $ hg id -i # we're still on the old commit
285 $ hg id -i # we're still on the old commit
286 36a6e592ec06
286 36a6e592ec06
287 $ hg up X -q
287 $ hg up X -q
288 $ hg id -i # now we're on X
288 $ hg id -i # now we're on X
289 f73a71c992b8
289 f73a71c992b8
290 $ hg book | grep X
290 $ hg book | grep X
291 \* X \d+:f73a71c992b8 (re)
291 \* X \d+:f73a71c992b8 (re)
292
292
@@ -1,1355 +1,1355 b''
1 #testcases b2-pushkey b2-binary
1 #testcases b2-pushkey b2-binary
2
2
3 #if b2-pushkey
3 #if b2-pushkey
4 $ cat << EOF >> $HGRCPATH
4 $ cat << EOF >> $HGRCPATH
5 > [devel]
5 > [devel]
6 > legacy.exchange=bookmarks
6 > legacy.exchange=bookmarks
7 > EOF
7 > EOF
8 #endif
8 #endif
9
9
10 #require serve
10 #require serve
11
11
12 $ cat << EOF >> $HGRCPATH
12 $ cat << EOF >> $HGRCPATH
13 > [ui]
13 > [ui]
14 > logtemplate={rev}:{node|short} {desc|firstline}
14 > logtemplate={rev}:{node|short} {desc|firstline}
15 > [phases]
15 > [phases]
16 > publish=False
16 > publish=False
17 > [experimental]
17 > [experimental]
18 > evolution.createmarkers=True
18 > evolution.createmarkers=True
19 > evolution.exchange=True
19 > evolution.exchange=True
20 > EOF
20 > EOF
21
21
22 $ cat > $TESTTMP/hook.sh <<'EOF'
22 $ cat > $TESTTMP/hook.sh <<'EOF'
23 > echo "test-hook-bookmark: $HG_BOOKMARK: $HG_OLDNODE -> $HG_NODE"
23 > echo "test-hook-bookmark: $HG_BOOKMARK: $HG_OLDNODE -> $HG_NODE"
24 > EOF
24 > EOF
25 $ TESTHOOK="hooks.txnclose-bookmark.test=sh $TESTTMP/hook.sh"
25 $ TESTHOOK="hooks.txnclose-bookmark.test=sh $TESTTMP/hook.sh"
26
26
27 initialize
27 initialize
28
28
29 $ hg init a
29 $ hg init a
30 $ cd a
30 $ cd a
31 $ echo 'test' > test
31 $ echo 'test' > test
32 $ hg commit -Am'test'
32 $ hg commit -Am'test'
33 adding test
33 adding test
34
34
35 set bookmarks
35 set bookmarks
36
36
37 $ hg bookmark X
37 $ hg bookmark X
38 $ hg bookmark Y
38 $ hg bookmark Y
39 $ hg bookmark Z
39 $ hg bookmark Z
40
40
41 import bookmark by name
41 import bookmark by name
42
42
43 $ hg init ../b
43 $ hg init ../b
44 $ cd ../b
44 $ cd ../b
45 $ hg book Y
45 $ hg book Y
46 $ hg book
46 $ hg book
47 * Y -1:000000000000
47 * Y -1:000000000000
48 $ hg pull ../a --config "$TESTHOOK"
48 $ hg pull ../a --config "$TESTHOOK"
49 pulling from ../a
49 pulling from ../a
50 requesting all changes
50 requesting all changes
51 adding changesets
51 adding changesets
52 adding manifests
52 adding manifests
53 adding file changes
53 adding file changes
54 added 1 changesets with 1 changes to 1 files
55 adding remote bookmark X
54 adding remote bookmark X
56 updating bookmark Y
55 updating bookmark Y
57 adding remote bookmark Z
56 adding remote bookmark Z
57 added 1 changesets with 1 changes to 1 files
58 new changesets 4e3505fd9583 (1 drafts)
58 new changesets 4e3505fd9583 (1 drafts)
59 test-hook-bookmark: X: -> 4e3505fd95835d721066b76e75dbb8cc554d7f77
59 test-hook-bookmark: X: -> 4e3505fd95835d721066b76e75dbb8cc554d7f77
60 test-hook-bookmark: Y: 0000000000000000000000000000000000000000 -> 4e3505fd95835d721066b76e75dbb8cc554d7f77
60 test-hook-bookmark: Y: 0000000000000000000000000000000000000000 -> 4e3505fd95835d721066b76e75dbb8cc554d7f77
61 test-hook-bookmark: Z: -> 4e3505fd95835d721066b76e75dbb8cc554d7f77
61 test-hook-bookmark: Z: -> 4e3505fd95835d721066b76e75dbb8cc554d7f77
62 (run 'hg update' to get a working copy)
62 (run 'hg update' to get a working copy)
63 $ hg bookmarks
63 $ hg bookmarks
64 X 0:4e3505fd9583
64 X 0:4e3505fd9583
65 * Y 0:4e3505fd9583
65 * Y 0:4e3505fd9583
66 Z 0:4e3505fd9583
66 Z 0:4e3505fd9583
67 $ hg debugpushkey ../a namespaces
67 $ hg debugpushkey ../a namespaces
68 bookmarks
68 bookmarks
69 namespaces
69 namespaces
70 obsolete
70 obsolete
71 phases
71 phases
72 $ hg debugpushkey ../a bookmarks
72 $ hg debugpushkey ../a bookmarks
73 X 4e3505fd95835d721066b76e75dbb8cc554d7f77
73 X 4e3505fd95835d721066b76e75dbb8cc554d7f77
74 Y 4e3505fd95835d721066b76e75dbb8cc554d7f77
74 Y 4e3505fd95835d721066b76e75dbb8cc554d7f77
75 Z 4e3505fd95835d721066b76e75dbb8cc554d7f77
75 Z 4e3505fd95835d721066b76e75dbb8cc554d7f77
76
76
77 delete the bookmark to re-pull it
77 delete the bookmark to re-pull it
78
78
79 $ hg book -d X
79 $ hg book -d X
80 $ hg pull -B X ../a
80 $ hg pull -B X ../a
81 pulling from ../a
81 pulling from ../a
82 no changes found
82 no changes found
83 adding remote bookmark X
83 adding remote bookmark X
84
84
85 finally no-op pull
85 finally no-op pull
86
86
87 $ hg pull -B X ../a
87 $ hg pull -B X ../a
88 pulling from ../a
88 pulling from ../a
89 no changes found
89 no changes found
90 $ hg bookmark
90 $ hg bookmark
91 X 0:4e3505fd9583
91 X 0:4e3505fd9583
92 * Y 0:4e3505fd9583
92 * Y 0:4e3505fd9583
93 Z 0:4e3505fd9583
93 Z 0:4e3505fd9583
94
94
95 export bookmark by name
95 export bookmark by name
96
96
97 $ hg bookmark W
97 $ hg bookmark W
98 $ hg bookmark foo
98 $ hg bookmark foo
99 $ hg bookmark foobar
99 $ hg bookmark foobar
100 $ hg push -B W ../a
100 $ hg push -B W ../a
101 pushing to ../a
101 pushing to ../a
102 searching for changes
102 searching for changes
103 no changes found
103 no changes found
104 exporting bookmark W
104 exporting bookmark W
105 [1]
105 [1]
106 $ hg -R ../a bookmarks
106 $ hg -R ../a bookmarks
107 W -1:000000000000
107 W -1:000000000000
108 X 0:4e3505fd9583
108 X 0:4e3505fd9583
109 Y 0:4e3505fd9583
109 Y 0:4e3505fd9583
110 * Z 0:4e3505fd9583
110 * Z 0:4e3505fd9583
111
111
112 delete a remote bookmark
112 delete a remote bookmark
113
113
114 $ hg book -d W
114 $ hg book -d W
115
115
116 #if b2-pushkey
116 #if b2-pushkey
117
117
118 $ hg push -B W ../a --config "$TESTHOOK" --debug --config devel.bundle2.debug=yes
118 $ hg push -B W ../a --config "$TESTHOOK" --debug --config devel.bundle2.debug=yes
119 pushing to ../a
119 pushing to ../a
120 query 1; heads
120 query 1; heads
121 searching for changes
121 searching for changes
122 all remote heads known locally
122 all remote heads known locally
123 listing keys for "phases"
123 listing keys for "phases"
124 checking for updated bookmarks
124 checking for updated bookmarks
125 listing keys for "bookmarks"
125 listing keys for "bookmarks"
126 no changes found
126 no changes found
127 bundle2-output-bundle: "HG20", 4 parts total
127 bundle2-output-bundle: "HG20", 4 parts total
128 bundle2-output: start emission of HG20 stream
128 bundle2-output: start emission of HG20 stream
129 bundle2-output: bundle parameter:
129 bundle2-output: bundle parameter:
130 bundle2-output: start of parts
130 bundle2-output: start of parts
131 bundle2-output: bundle part: "replycaps"
131 bundle2-output: bundle part: "replycaps"
132 bundle2-output-part: "replycaps" 222 bytes payload
132 bundle2-output-part: "replycaps" 222 bytes payload
133 bundle2-output: part 0: "REPLYCAPS"
133 bundle2-output: part 0: "REPLYCAPS"
134 bundle2-output: header chunk size: 16
134 bundle2-output: header chunk size: 16
135 bundle2-output: payload chunk size: 222
135 bundle2-output: payload chunk size: 222
136 bundle2-output: closing payload chunk
136 bundle2-output: closing payload chunk
137 bundle2-output: bundle part: "check:bookmarks"
137 bundle2-output: bundle part: "check:bookmarks"
138 bundle2-output-part: "check:bookmarks" 23 bytes payload
138 bundle2-output-part: "check:bookmarks" 23 bytes payload
139 bundle2-output: part 1: "CHECK:BOOKMARKS"
139 bundle2-output: part 1: "CHECK:BOOKMARKS"
140 bundle2-output: header chunk size: 22
140 bundle2-output: header chunk size: 22
141 bundle2-output: payload chunk size: 23
141 bundle2-output: payload chunk size: 23
142 bundle2-output: closing payload chunk
142 bundle2-output: closing payload chunk
143 bundle2-output: bundle part: "check:phases"
143 bundle2-output: bundle part: "check:phases"
144 bundle2-output-part: "check:phases" 24 bytes payload
144 bundle2-output-part: "check:phases" 24 bytes payload
145 bundle2-output: part 2: "CHECK:PHASES"
145 bundle2-output: part 2: "CHECK:PHASES"
146 bundle2-output: header chunk size: 19
146 bundle2-output: header chunk size: 19
147 bundle2-output: payload chunk size: 24
147 bundle2-output: payload chunk size: 24
148 bundle2-output: closing payload chunk
148 bundle2-output: closing payload chunk
149 bundle2-output: bundle part: "pushkey"
149 bundle2-output: bundle part: "pushkey"
150 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
150 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
151 bundle2-output: part 3: "PUSHKEY"
151 bundle2-output: part 3: "PUSHKEY"
152 bundle2-output: header chunk size: 90
152 bundle2-output: header chunk size: 90
153 bundle2-output: closing payload chunk
153 bundle2-output: closing payload chunk
154 bundle2-output: end of bundle
154 bundle2-output: end of bundle
155 bundle2-input: start processing of HG20 stream
155 bundle2-input: start processing of HG20 stream
156 bundle2-input: reading bundle2 stream parameters
156 bundle2-input: reading bundle2 stream parameters
157 bundle2-input-bundle: with-transaction
157 bundle2-input-bundle: with-transaction
158 bundle2-input: start extraction of bundle2 parts
158 bundle2-input: start extraction of bundle2 parts
159 bundle2-input: part header size: 16
159 bundle2-input: part header size: 16
160 bundle2-input: part type: "REPLYCAPS"
160 bundle2-input: part type: "REPLYCAPS"
161 bundle2-input: part id: "0"
161 bundle2-input: part id: "0"
162 bundle2-input: part parameters: 0
162 bundle2-input: part parameters: 0
163 bundle2-input: found a handler for part replycaps
163 bundle2-input: found a handler for part replycaps
164 bundle2-input-part: "replycaps" supported
164 bundle2-input-part: "replycaps" supported
165 bundle2-input: payload chunk size: 222
165 bundle2-input: payload chunk size: 222
166 bundle2-input: payload chunk size: 0
166 bundle2-input: payload chunk size: 0
167 bundle2-input-part: total payload size 222
167 bundle2-input-part: total payload size 222
168 bundle2-input: part header size: 22
168 bundle2-input: part header size: 22
169 bundle2-input: part type: "CHECK:BOOKMARKS"
169 bundle2-input: part type: "CHECK:BOOKMARKS"
170 bundle2-input: part id: "1"
170 bundle2-input: part id: "1"
171 bundle2-input: part parameters: 0
171 bundle2-input: part parameters: 0
172 bundle2-input: found a handler for part check:bookmarks
172 bundle2-input: found a handler for part check:bookmarks
173 bundle2-input-part: "check:bookmarks" supported
173 bundle2-input-part: "check:bookmarks" supported
174 bundle2-input: payload chunk size: 23
174 bundle2-input: payload chunk size: 23
175 bundle2-input: payload chunk size: 0
175 bundle2-input: payload chunk size: 0
176 bundle2-input-part: total payload size 23
176 bundle2-input-part: total payload size 23
177 bundle2-input: part header size: 19
177 bundle2-input: part header size: 19
178 bundle2-input: part type: "CHECK:PHASES"
178 bundle2-input: part type: "CHECK:PHASES"
179 bundle2-input: part id: "2"
179 bundle2-input: part id: "2"
180 bundle2-input: part parameters: 0
180 bundle2-input: part parameters: 0
181 bundle2-input: found a handler for part check:phases
181 bundle2-input: found a handler for part check:phases
182 bundle2-input-part: "check:phases" supported
182 bundle2-input-part: "check:phases" supported
183 bundle2-input: payload chunk size: 24
183 bundle2-input: payload chunk size: 24
184 bundle2-input: payload chunk size: 0
184 bundle2-input: payload chunk size: 0
185 bundle2-input-part: total payload size 24
185 bundle2-input-part: total payload size 24
186 bundle2-input: part header size: 90
186 bundle2-input: part header size: 90
187 bundle2-input: part type: "PUSHKEY"
187 bundle2-input: part type: "PUSHKEY"
188 bundle2-input: part id: "3"
188 bundle2-input: part id: "3"
189 bundle2-input: part parameters: 4
189 bundle2-input: part parameters: 4
190 bundle2-input: found a handler for part pushkey
190 bundle2-input: found a handler for part pushkey
191 bundle2-input-part: "pushkey" (params: 4 mandatory) supported
191 bundle2-input-part: "pushkey" (params: 4 mandatory) supported
192 pushing key for "bookmarks:W"
192 pushing key for "bookmarks:W"
193 bundle2-input: payload chunk size: 0
193 bundle2-input: payload chunk size: 0
194 bundle2-input: part header size: 0
194 bundle2-input: part header size: 0
195 bundle2-input: end of bundle2 stream
195 bundle2-input: end of bundle2 stream
196 bundle2-input-bundle: 3 parts total
196 bundle2-input-bundle: 3 parts total
197 running hook txnclose-bookmark.test: sh $TESTTMP/hook.sh
197 running hook txnclose-bookmark.test: sh $TESTTMP/hook.sh
198 test-hook-bookmark: W: 0000000000000000000000000000000000000000 ->
198 test-hook-bookmark: W: 0000000000000000000000000000000000000000 ->
199 bundle2-output-bundle: "HG20", 1 parts total
199 bundle2-output-bundle: "HG20", 1 parts total
200 bundle2-output: start emission of HG20 stream
200 bundle2-output: start emission of HG20 stream
201 bundle2-output: bundle parameter:
201 bundle2-output: bundle parameter:
202 bundle2-output: start of parts
202 bundle2-output: start of parts
203 bundle2-output: bundle part: "reply:pushkey"
203 bundle2-output: bundle part: "reply:pushkey"
204 bundle2-output-part: "reply:pushkey" (params: 0 advisory) empty payload
204 bundle2-output-part: "reply:pushkey" (params: 0 advisory) empty payload
205 bundle2-output: part 0: "REPLY:PUSHKEY"
205 bundle2-output: part 0: "REPLY:PUSHKEY"
206 bundle2-output: header chunk size: 43
206 bundle2-output: header chunk size: 43
207 bundle2-output: closing payload chunk
207 bundle2-output: closing payload chunk
208 bundle2-output: end of bundle
208 bundle2-output: end of bundle
209 bundle2-input: start processing of HG20 stream
209 bundle2-input: start processing of HG20 stream
210 bundle2-input: reading bundle2 stream parameters
210 bundle2-input: reading bundle2 stream parameters
211 bundle2-input-bundle: no-transaction
211 bundle2-input-bundle: no-transaction
212 bundle2-input: start extraction of bundle2 parts
212 bundle2-input: start extraction of bundle2 parts
213 bundle2-input: part header size: 43
213 bundle2-input: part header size: 43
214 bundle2-input: part type: "REPLY:PUSHKEY"
214 bundle2-input: part type: "REPLY:PUSHKEY"
215 bundle2-input: part id: "0"
215 bundle2-input: part id: "0"
216 bundle2-input: part parameters: 2
216 bundle2-input: part parameters: 2
217 bundle2-input: found a handler for part reply:pushkey
217 bundle2-input: found a handler for part reply:pushkey
218 bundle2-input-part: "reply:pushkey" (params: 0 advisory) supported
218 bundle2-input-part: "reply:pushkey" (params: 0 advisory) supported
219 bundle2-input: payload chunk size: 0
219 bundle2-input: payload chunk size: 0
220 bundle2-input: part header size: 0
220 bundle2-input: part header size: 0
221 bundle2-input: end of bundle2 stream
221 bundle2-input: end of bundle2 stream
222 bundle2-input-bundle: 0 parts total
222 bundle2-input-bundle: 0 parts total
223 deleting remote bookmark W
223 deleting remote bookmark W
224 listing keys for "phases"
224 listing keys for "phases"
225 [1]
225 [1]
226
226
227 #endif
227 #endif
228 #if b2-binary
228 #if b2-binary
229
229
230 $ hg push -B W ../a --config "$TESTHOOK" --debug --config devel.bundle2.debug=yes
230 $ hg push -B W ../a --config "$TESTHOOK" --debug --config devel.bundle2.debug=yes
231 pushing to ../a
231 pushing to ../a
232 query 1; heads
232 query 1; heads
233 searching for changes
233 searching for changes
234 all remote heads known locally
234 all remote heads known locally
235 listing keys for "phases"
235 listing keys for "phases"
236 checking for updated bookmarks
236 checking for updated bookmarks
237 listing keys for "bookmarks"
237 listing keys for "bookmarks"
238 no changes found
238 no changes found
239 bundle2-output-bundle: "HG20", 4 parts total
239 bundle2-output-bundle: "HG20", 4 parts total
240 bundle2-output: start emission of HG20 stream
240 bundle2-output: start emission of HG20 stream
241 bundle2-output: bundle parameter:
241 bundle2-output: bundle parameter:
242 bundle2-output: start of parts
242 bundle2-output: start of parts
243 bundle2-output: bundle part: "replycaps"
243 bundle2-output: bundle part: "replycaps"
244 bundle2-output-part: "replycaps" 222 bytes payload
244 bundle2-output-part: "replycaps" 222 bytes payload
245 bundle2-output: part 0: "REPLYCAPS"
245 bundle2-output: part 0: "REPLYCAPS"
246 bundle2-output: header chunk size: 16
246 bundle2-output: header chunk size: 16
247 bundle2-output: payload chunk size: 222
247 bundle2-output: payload chunk size: 222
248 bundle2-output: closing payload chunk
248 bundle2-output: closing payload chunk
249 bundle2-output: bundle part: "check:bookmarks"
249 bundle2-output: bundle part: "check:bookmarks"
250 bundle2-output-part: "check:bookmarks" 23 bytes payload
250 bundle2-output-part: "check:bookmarks" 23 bytes payload
251 bundle2-output: part 1: "CHECK:BOOKMARKS"
251 bundle2-output: part 1: "CHECK:BOOKMARKS"
252 bundle2-output: header chunk size: 22
252 bundle2-output: header chunk size: 22
253 bundle2-output: payload chunk size: 23
253 bundle2-output: payload chunk size: 23
254 bundle2-output: closing payload chunk
254 bundle2-output: closing payload chunk
255 bundle2-output: bundle part: "check:phases"
255 bundle2-output: bundle part: "check:phases"
256 bundle2-output-part: "check:phases" 24 bytes payload
256 bundle2-output-part: "check:phases" 24 bytes payload
257 bundle2-output: part 2: "CHECK:PHASES"
257 bundle2-output: part 2: "CHECK:PHASES"
258 bundle2-output: header chunk size: 19
258 bundle2-output: header chunk size: 19
259 bundle2-output: payload chunk size: 24
259 bundle2-output: payload chunk size: 24
260 bundle2-output: closing payload chunk
260 bundle2-output: closing payload chunk
261 bundle2-output: bundle part: "bookmarks"
261 bundle2-output: bundle part: "bookmarks"
262 bundle2-output-part: "bookmarks" 23 bytes payload
262 bundle2-output-part: "bookmarks" 23 bytes payload
263 bundle2-output: part 3: "BOOKMARKS"
263 bundle2-output: part 3: "BOOKMARKS"
264 bundle2-output: header chunk size: 16
264 bundle2-output: header chunk size: 16
265 bundle2-output: payload chunk size: 23
265 bundle2-output: payload chunk size: 23
266 bundle2-output: closing payload chunk
266 bundle2-output: closing payload chunk
267 bundle2-output: end of bundle
267 bundle2-output: end of bundle
268 bundle2-input: start processing of HG20 stream
268 bundle2-input: start processing of HG20 stream
269 bundle2-input: reading bundle2 stream parameters
269 bundle2-input: reading bundle2 stream parameters
270 bundle2-input-bundle: with-transaction
270 bundle2-input-bundle: with-transaction
271 bundle2-input: start extraction of bundle2 parts
271 bundle2-input: start extraction of bundle2 parts
272 bundle2-input: part header size: 16
272 bundle2-input: part header size: 16
273 bundle2-input: part type: "REPLYCAPS"
273 bundle2-input: part type: "REPLYCAPS"
274 bundle2-input: part id: "0"
274 bundle2-input: part id: "0"
275 bundle2-input: part parameters: 0
275 bundle2-input: part parameters: 0
276 bundle2-input: found a handler for part replycaps
276 bundle2-input: found a handler for part replycaps
277 bundle2-input-part: "replycaps" supported
277 bundle2-input-part: "replycaps" supported
278 bundle2-input: payload chunk size: 222
278 bundle2-input: payload chunk size: 222
279 bundle2-input: payload chunk size: 0
279 bundle2-input: payload chunk size: 0
280 bundle2-input-part: total payload size 222
280 bundle2-input-part: total payload size 222
281 bundle2-input: part header size: 22
281 bundle2-input: part header size: 22
282 bundle2-input: part type: "CHECK:BOOKMARKS"
282 bundle2-input: part type: "CHECK:BOOKMARKS"
283 bundle2-input: part id: "1"
283 bundle2-input: part id: "1"
284 bundle2-input: part parameters: 0
284 bundle2-input: part parameters: 0
285 bundle2-input: found a handler for part check:bookmarks
285 bundle2-input: found a handler for part check:bookmarks
286 bundle2-input-part: "check:bookmarks" supported
286 bundle2-input-part: "check:bookmarks" supported
287 bundle2-input: payload chunk size: 23
287 bundle2-input: payload chunk size: 23
288 bundle2-input: payload chunk size: 0
288 bundle2-input: payload chunk size: 0
289 bundle2-input-part: total payload size 23
289 bundle2-input-part: total payload size 23
290 bundle2-input: part header size: 19
290 bundle2-input: part header size: 19
291 bundle2-input: part type: "CHECK:PHASES"
291 bundle2-input: part type: "CHECK:PHASES"
292 bundle2-input: part id: "2"
292 bundle2-input: part id: "2"
293 bundle2-input: part parameters: 0
293 bundle2-input: part parameters: 0
294 bundle2-input: found a handler for part check:phases
294 bundle2-input: found a handler for part check:phases
295 bundle2-input-part: "check:phases" supported
295 bundle2-input-part: "check:phases" supported
296 bundle2-input: payload chunk size: 24
296 bundle2-input: payload chunk size: 24
297 bundle2-input: payload chunk size: 0
297 bundle2-input: payload chunk size: 0
298 bundle2-input-part: total payload size 24
298 bundle2-input-part: total payload size 24
299 bundle2-input: part header size: 16
299 bundle2-input: part header size: 16
300 bundle2-input: part type: "BOOKMARKS"
300 bundle2-input: part type: "BOOKMARKS"
301 bundle2-input: part id: "3"
301 bundle2-input: part id: "3"
302 bundle2-input: part parameters: 0
302 bundle2-input: part parameters: 0
303 bundle2-input: found a handler for part bookmarks
303 bundle2-input: found a handler for part bookmarks
304 bundle2-input-part: "bookmarks" supported
304 bundle2-input-part: "bookmarks" supported
305 bundle2-input: payload chunk size: 23
305 bundle2-input: payload chunk size: 23
306 bundle2-input: payload chunk size: 0
306 bundle2-input: payload chunk size: 0
307 bundle2-input-part: total payload size 23
307 bundle2-input-part: total payload size 23
308 bundle2-input: part header size: 0
308 bundle2-input: part header size: 0
309 bundle2-input: end of bundle2 stream
309 bundle2-input: end of bundle2 stream
310 bundle2-input-bundle: 3 parts total
310 bundle2-input-bundle: 3 parts total
311 running hook txnclose-bookmark.test: sh $TESTTMP/hook.sh
311 running hook txnclose-bookmark.test: sh $TESTTMP/hook.sh
312 test-hook-bookmark: W: 0000000000000000000000000000000000000000 ->
312 test-hook-bookmark: W: 0000000000000000000000000000000000000000 ->
313 bundle2-output-bundle: "HG20", 0 parts total
313 bundle2-output-bundle: "HG20", 0 parts total
314 bundle2-output: start emission of HG20 stream
314 bundle2-output: start emission of HG20 stream
315 bundle2-output: bundle parameter:
315 bundle2-output: bundle parameter:
316 bundle2-output: start of parts
316 bundle2-output: start of parts
317 bundle2-output: end of bundle
317 bundle2-output: end of bundle
318 bundle2-input: start processing of HG20 stream
318 bundle2-input: start processing of HG20 stream
319 bundle2-input: reading bundle2 stream parameters
319 bundle2-input: reading bundle2 stream parameters
320 bundle2-input-bundle: no-transaction
320 bundle2-input-bundle: no-transaction
321 bundle2-input: start extraction of bundle2 parts
321 bundle2-input: start extraction of bundle2 parts
322 bundle2-input: part header size: 0
322 bundle2-input: part header size: 0
323 bundle2-input: end of bundle2 stream
323 bundle2-input: end of bundle2 stream
324 bundle2-input-bundle: 0 parts total
324 bundle2-input-bundle: 0 parts total
325 deleting remote bookmark W
325 deleting remote bookmark W
326 listing keys for "phases"
326 listing keys for "phases"
327 [1]
327 [1]
328
328
329 #endif
329 #endif
330
330
331 export the active bookmark
331 export the active bookmark
332
332
333 $ hg bookmark V
333 $ hg bookmark V
334 $ hg push -B . ../a
334 $ hg push -B . ../a
335 pushing to ../a
335 pushing to ../a
336 searching for changes
336 searching for changes
337 no changes found
337 no changes found
338 exporting bookmark V
338 exporting bookmark V
339 [1]
339 [1]
340
340
341 exporting the active bookmark with 'push -B .'
341 exporting the active bookmark with 'push -B .'
342 demand that one of the bookmarks is activated
342 demand that one of the bookmarks is activated
343
343
344 $ hg update -r default
344 $ hg update -r default
345 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
345 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
346 (leaving bookmark V)
346 (leaving bookmark V)
347 $ hg push -B . ../a
347 $ hg push -B . ../a
348 abort: no active bookmark!
348 abort: no active bookmark!
349 [255]
349 [255]
350 $ hg update -r V
350 $ hg update -r V
351 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
351 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
352 (activating bookmark V)
352 (activating bookmark V)
353
353
354 delete the bookmark
354 delete the bookmark
355
355
356 $ hg book -d V
356 $ hg book -d V
357 $ hg push -B V ../a
357 $ hg push -B V ../a
358 pushing to ../a
358 pushing to ../a
359 searching for changes
359 searching for changes
360 no changes found
360 no changes found
361 deleting remote bookmark V
361 deleting remote bookmark V
362 [1]
362 [1]
363 $ hg up foobar
363 $ hg up foobar
364 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
364 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
365 (activating bookmark foobar)
365 (activating bookmark foobar)
366
366
367 push/pull name that doesn't exist
367 push/pull name that doesn't exist
368
368
369 $ hg push -B badname ../a
369 $ hg push -B badname ../a
370 pushing to ../a
370 pushing to ../a
371 searching for changes
371 searching for changes
372 bookmark badname does not exist on the local or remote repository!
372 bookmark badname does not exist on the local or remote repository!
373 no changes found
373 no changes found
374 [2]
374 [2]
375 $ hg pull -B anotherbadname ../a
375 $ hg pull -B anotherbadname ../a
376 pulling from ../a
376 pulling from ../a
377 abort: remote bookmark anotherbadname not found!
377 abort: remote bookmark anotherbadname not found!
378 [255]
378 [255]
379
379
380 divergent bookmarks
380 divergent bookmarks
381
381
382 $ cd ../a
382 $ cd ../a
383 $ echo c1 > f1
383 $ echo c1 > f1
384 $ hg ci -Am1
384 $ hg ci -Am1
385 adding f1
385 adding f1
386 $ hg book -f @
386 $ hg book -f @
387 $ hg book -f X
387 $ hg book -f X
388 $ hg book
388 $ hg book
389 @ 1:0d2164f0ce0d
389 @ 1:0d2164f0ce0d
390 * X 1:0d2164f0ce0d
390 * X 1:0d2164f0ce0d
391 Y 0:4e3505fd9583
391 Y 0:4e3505fd9583
392 Z 1:0d2164f0ce0d
392 Z 1:0d2164f0ce0d
393
393
394 $ cd ../b
394 $ cd ../b
395 $ hg up
395 $ hg up
396 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
396 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
397 updating bookmark foobar
397 updating bookmark foobar
398 $ echo c2 > f2
398 $ echo c2 > f2
399 $ hg ci -Am2
399 $ hg ci -Am2
400 adding f2
400 adding f2
401 $ hg book -if @
401 $ hg book -if @
402 $ hg book -if X
402 $ hg book -if X
403 $ hg book
403 $ hg book
404 @ 1:9b140be10808
404 @ 1:9b140be10808
405 X 1:9b140be10808
405 X 1:9b140be10808
406 Y 0:4e3505fd9583
406 Y 0:4e3505fd9583
407 Z 0:4e3505fd9583
407 Z 0:4e3505fd9583
408 foo -1:000000000000
408 foo -1:000000000000
409 * foobar 1:9b140be10808
409 * foobar 1:9b140be10808
410
410
411 $ hg pull --config paths.foo=../a foo --config "$TESTHOOK"
411 $ hg pull --config paths.foo=../a foo --config "$TESTHOOK"
412 pulling from $TESTTMP/a
412 pulling from $TESTTMP/a
413 searching for changes
413 searching for changes
414 adding changesets
414 adding changesets
415 adding manifests
415 adding manifests
416 adding file changes
416 adding file changes
417 added 1 changesets with 1 changes to 1 files (+1 heads)
418 divergent bookmark @ stored as @foo
417 divergent bookmark @ stored as @foo
419 divergent bookmark X stored as X@foo
418 divergent bookmark X stored as X@foo
420 updating bookmark Z
419 updating bookmark Z
420 added 1 changesets with 1 changes to 1 files (+1 heads)
421 new changesets 0d2164f0ce0d (1 drafts)
421 new changesets 0d2164f0ce0d (1 drafts)
422 test-hook-bookmark: @foo: -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
422 test-hook-bookmark: @foo: -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
423 test-hook-bookmark: X@foo: -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
423 test-hook-bookmark: X@foo: -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
424 test-hook-bookmark: Z: 4e3505fd95835d721066b76e75dbb8cc554d7f77 -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
424 test-hook-bookmark: Z: 4e3505fd95835d721066b76e75dbb8cc554d7f77 -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
425 (run 'hg heads' to see heads, 'hg merge' to merge)
425 (run 'hg heads' to see heads, 'hg merge' to merge)
426 $ hg book
426 $ hg book
427 @ 1:9b140be10808
427 @ 1:9b140be10808
428 @foo 2:0d2164f0ce0d
428 @foo 2:0d2164f0ce0d
429 X 1:9b140be10808
429 X 1:9b140be10808
430 X@foo 2:0d2164f0ce0d
430 X@foo 2:0d2164f0ce0d
431 Y 0:4e3505fd9583
431 Y 0:4e3505fd9583
432 Z 2:0d2164f0ce0d
432 Z 2:0d2164f0ce0d
433 foo -1:000000000000
433 foo -1:000000000000
434 * foobar 1:9b140be10808
434 * foobar 1:9b140be10808
435
435
436 (test that too many divergence of bookmark)
436 (test that too many divergence of bookmark)
437
437
438 $ "$PYTHON" $TESTDIR/seq.py 1 100 | while read i; do hg bookmarks -r 000000000000 "X@${i}"; done
438 $ "$PYTHON" $TESTDIR/seq.py 1 100 | while read i; do hg bookmarks -r 000000000000 "X@${i}"; done
439 $ hg pull ../a
439 $ hg pull ../a
440 pulling from ../a
440 pulling from ../a
441 searching for changes
441 searching for changes
442 no changes found
442 no changes found
443 warning: failed to assign numbered name to divergent bookmark X
443 warning: failed to assign numbered name to divergent bookmark X
444 divergent bookmark @ stored as @1
444 divergent bookmark @ stored as @1
445 $ hg bookmarks | grep '^ X' | grep -v ':000000000000'
445 $ hg bookmarks | grep '^ X' | grep -v ':000000000000'
446 X 1:9b140be10808
446 X 1:9b140be10808
447 X@foo 2:0d2164f0ce0d
447 X@foo 2:0d2164f0ce0d
448
448
449 (test that remotely diverged bookmarks are reused if they aren't changed)
449 (test that remotely diverged bookmarks are reused if they aren't changed)
450
450
451 $ hg bookmarks | grep '^ @'
451 $ hg bookmarks | grep '^ @'
452 @ 1:9b140be10808
452 @ 1:9b140be10808
453 @1 2:0d2164f0ce0d
453 @1 2:0d2164f0ce0d
454 @foo 2:0d2164f0ce0d
454 @foo 2:0d2164f0ce0d
455 $ hg pull ../a
455 $ hg pull ../a
456 pulling from ../a
456 pulling from ../a
457 searching for changes
457 searching for changes
458 no changes found
458 no changes found
459 warning: failed to assign numbered name to divergent bookmark X
459 warning: failed to assign numbered name to divergent bookmark X
460 divergent bookmark @ stored as @1
460 divergent bookmark @ stored as @1
461 $ hg bookmarks | grep '^ @'
461 $ hg bookmarks | grep '^ @'
462 @ 1:9b140be10808
462 @ 1:9b140be10808
463 @1 2:0d2164f0ce0d
463 @1 2:0d2164f0ce0d
464 @foo 2:0d2164f0ce0d
464 @foo 2:0d2164f0ce0d
465
465
466 $ "$PYTHON" $TESTDIR/seq.py 1 100 | while read i; do hg bookmarks -d "X@${i}"; done
466 $ "$PYTHON" $TESTDIR/seq.py 1 100 | while read i; do hg bookmarks -d "X@${i}"; done
467 $ hg bookmarks -d "@1"
467 $ hg bookmarks -d "@1"
468
468
469 $ hg push -f ../a
469 $ hg push -f ../a
470 pushing to ../a
470 pushing to ../a
471 searching for changes
471 searching for changes
472 adding changesets
472 adding changesets
473 adding manifests
473 adding manifests
474 adding file changes
474 adding file changes
475 added 1 changesets with 1 changes to 1 files (+1 heads)
475 added 1 changesets with 1 changes to 1 files (+1 heads)
476 $ hg -R ../a book
476 $ hg -R ../a book
477 @ 1:0d2164f0ce0d
477 @ 1:0d2164f0ce0d
478 * X 1:0d2164f0ce0d
478 * X 1:0d2164f0ce0d
479 Y 0:4e3505fd9583
479 Y 0:4e3505fd9583
480 Z 1:0d2164f0ce0d
480 Z 1:0d2164f0ce0d
481
481
482 explicit pull should overwrite the local version (issue4439)
482 explicit pull should overwrite the local version (issue4439)
483
483
484 $ hg update -r X
484 $ hg update -r X
485 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
485 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
486 (activating bookmark X)
486 (activating bookmark X)
487 $ hg pull --config paths.foo=../a foo -B . --config "$TESTHOOK"
487 $ hg pull --config paths.foo=../a foo -B . --config "$TESTHOOK"
488 pulling from $TESTTMP/a
488 pulling from $TESTTMP/a
489 no changes found
489 no changes found
490 divergent bookmark @ stored as @foo
490 divergent bookmark @ stored as @foo
491 importing bookmark X
491 importing bookmark X
492 test-hook-bookmark: @foo: 0d2164f0ce0d8f1d6f94351eba04b794909be66c -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
492 test-hook-bookmark: @foo: 0d2164f0ce0d8f1d6f94351eba04b794909be66c -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
493 test-hook-bookmark: X: 9b140be1080824d768c5a4691a564088eede71f9 -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
493 test-hook-bookmark: X: 9b140be1080824d768c5a4691a564088eede71f9 -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
494
494
495 reinstall state for further testing:
495 reinstall state for further testing:
496
496
497 $ hg book -fr 9b140be10808 X
497 $ hg book -fr 9b140be10808 X
498
498
499 revsets should not ignore divergent bookmarks
499 revsets should not ignore divergent bookmarks
500
500
501 $ hg bookmark -fr 1 Z
501 $ hg bookmark -fr 1 Z
502 $ hg log -r 'bookmark()' --template '{rev}:{node|short} {bookmarks}\n'
502 $ hg log -r 'bookmark()' --template '{rev}:{node|short} {bookmarks}\n'
503 0:4e3505fd9583 Y
503 0:4e3505fd9583 Y
504 1:9b140be10808 @ X Z foobar
504 1:9b140be10808 @ X Z foobar
505 2:0d2164f0ce0d @foo X@foo
505 2:0d2164f0ce0d @foo X@foo
506 $ hg log -r 'bookmark("X@foo")' --template '{rev}:{node|short} {bookmarks}\n'
506 $ hg log -r 'bookmark("X@foo")' --template '{rev}:{node|short} {bookmarks}\n'
507 2:0d2164f0ce0d @foo X@foo
507 2:0d2164f0ce0d @foo X@foo
508 $ hg log -r 'bookmark("re:X@foo")' --template '{rev}:{node|short} {bookmarks}\n'
508 $ hg log -r 'bookmark("re:X@foo")' --template '{rev}:{node|short} {bookmarks}\n'
509 2:0d2164f0ce0d @foo X@foo
509 2:0d2164f0ce0d @foo X@foo
510
510
511 update a remote bookmark from a non-head to a head
511 update a remote bookmark from a non-head to a head
512
512
513 $ hg up -q Y
513 $ hg up -q Y
514 $ echo c3 > f2
514 $ echo c3 > f2
515 $ hg ci -Am3
515 $ hg ci -Am3
516 adding f2
516 adding f2
517 created new head
517 created new head
518 $ hg push ../a --config "$TESTHOOK"
518 $ hg push ../a --config "$TESTHOOK"
519 pushing to ../a
519 pushing to ../a
520 searching for changes
520 searching for changes
521 adding changesets
521 adding changesets
522 adding manifests
522 adding manifests
523 adding file changes
523 adding file changes
524 added 1 changesets with 1 changes to 1 files (+1 heads)
524 added 1 changesets with 1 changes to 1 files (+1 heads)
525 test-hook-bookmark: Y: 4e3505fd95835d721066b76e75dbb8cc554d7f77 -> f6fc62dde3c0771e29704af56ba4d8af77abcc2f
525 test-hook-bookmark: Y: 4e3505fd95835d721066b76e75dbb8cc554d7f77 -> f6fc62dde3c0771e29704af56ba4d8af77abcc2f
526 updating bookmark Y
526 updating bookmark Y
527 $ hg -R ../a book
527 $ hg -R ../a book
528 @ 1:0d2164f0ce0d
528 @ 1:0d2164f0ce0d
529 * X 1:0d2164f0ce0d
529 * X 1:0d2164f0ce0d
530 Y 3:f6fc62dde3c0
530 Y 3:f6fc62dde3c0
531 Z 1:0d2164f0ce0d
531 Z 1:0d2164f0ce0d
532
532
533 update a bookmark in the middle of a client pulling changes
533 update a bookmark in the middle of a client pulling changes
534
534
535 $ cd ..
535 $ cd ..
536 $ hg clone -q a pull-race
536 $ hg clone -q a pull-race
537
537
538 We want to use http because it is stateless and therefore more susceptible to
538 We want to use http because it is stateless and therefore more susceptible to
539 race conditions
539 race conditions
540
540
541 $ hg serve -R pull-race -p $HGPORT -d --pid-file=pull-race.pid -E main-error.log
541 $ hg serve -R pull-race -p $HGPORT -d --pid-file=pull-race.pid -E main-error.log
542 $ cat pull-race.pid >> $DAEMON_PIDS
542 $ cat pull-race.pid >> $DAEMON_PIDS
543
543
544 $ cat <<EOF > $TESTTMP/out_makecommit.sh
544 $ cat <<EOF > $TESTTMP/out_makecommit.sh
545 > #!/bin/sh
545 > #!/bin/sh
546 > hg ci -Am5
546 > hg ci -Am5
547 > echo committed in pull-race
547 > echo committed in pull-race
548 > EOF
548 > EOF
549
549
550 $ hg clone -q http://localhost:$HGPORT/ pull-race2 --config "$TESTHOOK"
550 $ hg clone -q http://localhost:$HGPORT/ pull-race2 --config "$TESTHOOK"
551 test-hook-bookmark: @: -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
551 test-hook-bookmark: @: -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
552 test-hook-bookmark: X: -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
552 test-hook-bookmark: X: -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
553 test-hook-bookmark: Y: -> f6fc62dde3c0771e29704af56ba4d8af77abcc2f
553 test-hook-bookmark: Y: -> f6fc62dde3c0771e29704af56ba4d8af77abcc2f
554 test-hook-bookmark: Z: -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
554 test-hook-bookmark: Z: -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
555 $ cd pull-race
555 $ cd pull-race
556 $ hg up -q Y
556 $ hg up -q Y
557 $ echo c4 > f2
557 $ echo c4 > f2
558 $ hg ci -Am4
558 $ hg ci -Am4
559 $ echo c5 > f3
559 $ echo c5 > f3
560 $ cat <<EOF > .hg/hgrc
560 $ cat <<EOF > .hg/hgrc
561 > [hooks]
561 > [hooks]
562 > outgoing.makecommit = sh $TESTTMP/out_makecommit.sh
562 > outgoing.makecommit = sh $TESTTMP/out_makecommit.sh
563 > EOF
563 > EOF
564
564
565 (new config needs a server restart)
565 (new config needs a server restart)
566
566
567 $ cd ..
567 $ cd ..
568 $ killdaemons.py
568 $ killdaemons.py
569 $ hg serve -R pull-race -p $HGPORT -d --pid-file=pull-race.pid -E main-error.log
569 $ hg serve -R pull-race -p $HGPORT -d --pid-file=pull-race.pid -E main-error.log
570 $ cat pull-race.pid >> $DAEMON_PIDS
570 $ cat pull-race.pid >> $DAEMON_PIDS
571 $ cd pull-race2
571 $ cd pull-race2
572 $ hg -R $TESTTMP/pull-race book
572 $ hg -R $TESTTMP/pull-race book
573 @ 1:0d2164f0ce0d
573 @ 1:0d2164f0ce0d
574 X 1:0d2164f0ce0d
574 X 1:0d2164f0ce0d
575 * Y 4:b0a5eff05604
575 * Y 4:b0a5eff05604
576 Z 1:0d2164f0ce0d
576 Z 1:0d2164f0ce0d
577 $ hg pull
577 $ hg pull
578 pulling from http://localhost:$HGPORT/
578 pulling from http://localhost:$HGPORT/
579 searching for changes
579 searching for changes
580 adding changesets
580 adding changesets
581 adding manifests
581 adding manifests
582 adding file changes
582 adding file changes
583 updating bookmark Y
583 added 1 changesets with 1 changes to 1 files
584 added 1 changesets with 1 changes to 1 files
584 updating bookmark Y
585 new changesets b0a5eff05604 (1 drafts)
585 new changesets b0a5eff05604 (1 drafts)
586 (run 'hg update' to get a working copy)
586 (run 'hg update' to get a working copy)
587 $ hg book
587 $ hg book
588 * @ 1:0d2164f0ce0d
588 * @ 1:0d2164f0ce0d
589 X 1:0d2164f0ce0d
589 X 1:0d2164f0ce0d
590 Y 4:b0a5eff05604
590 Y 4:b0a5eff05604
591 Z 1:0d2164f0ce0d
591 Z 1:0d2164f0ce0d
592
592
593 Update a bookmark right after the initial lookup -B (issue4689)
593 Update a bookmark right after the initial lookup -B (issue4689)
594
594
595 $ echo c6 > ../pull-race/f3 # to be committed during the race
595 $ echo c6 > ../pull-race/f3 # to be committed during the race
596 $ cat <<EOF > $TESTTMP/listkeys_makecommit.sh
596 $ cat <<EOF > $TESTTMP/listkeys_makecommit.sh
597 > #!/bin/sh
597 > #!/bin/sh
598 > if hg st | grep -q M; then
598 > if hg st | grep -q M; then
599 > hg commit -m race
599 > hg commit -m race
600 > echo committed in pull-race
600 > echo committed in pull-race
601 > else
601 > else
602 > exit 0
602 > exit 0
603 > fi
603 > fi
604 > EOF
604 > EOF
605 $ cat <<EOF > ../pull-race/.hg/hgrc
605 $ cat <<EOF > ../pull-race/.hg/hgrc
606 > [hooks]
606 > [hooks]
607 > # If anything to commit, commit it right after the first key listing used
607 > # If anything to commit, commit it right after the first key listing used
608 > # during lookup. This makes the commit appear before the actual getbundle
608 > # during lookup. This makes the commit appear before the actual getbundle
609 > # call.
609 > # call.
610 > listkeys.makecommit= sh $TESTTMP/listkeys_makecommit.sh
610 > listkeys.makecommit= sh $TESTTMP/listkeys_makecommit.sh
611 > EOF
611 > EOF
612 $ restart_server() {
612 $ restart_server() {
613 > "$TESTDIR/killdaemons.py" $DAEMON_PIDS
613 > "$TESTDIR/killdaemons.py" $DAEMON_PIDS
614 > hg serve -R ../pull-race -p $HGPORT -d --pid-file=../pull-race.pid -E main-error.log
614 > hg serve -R ../pull-race -p $HGPORT -d --pid-file=../pull-race.pid -E main-error.log
615 > cat ../pull-race.pid >> $DAEMON_PIDS
615 > cat ../pull-race.pid >> $DAEMON_PIDS
616 > }
616 > }
617 $ restart_server # new config need server restart
617 $ restart_server # new config need server restart
618 $ hg -R $TESTTMP/pull-race book
618 $ hg -R $TESTTMP/pull-race book
619 @ 1:0d2164f0ce0d
619 @ 1:0d2164f0ce0d
620 X 1:0d2164f0ce0d
620 X 1:0d2164f0ce0d
621 * Y 5:35d1ef0a8d1b
621 * Y 5:35d1ef0a8d1b
622 Z 1:0d2164f0ce0d
622 Z 1:0d2164f0ce0d
623 $ hg update -r Y
623 $ hg update -r Y
624 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
624 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
625 (activating bookmark Y)
625 (activating bookmark Y)
626 $ hg pull -B .
626 $ hg pull -B .
627 pulling from http://localhost:$HGPORT/
627 pulling from http://localhost:$HGPORT/
628 searching for changes
628 searching for changes
629 adding changesets
629 adding changesets
630 adding manifests
630 adding manifests
631 adding file changes
631 adding file changes
632 updating bookmark Y
632 added 1 changesets with 1 changes to 1 files
633 added 1 changesets with 1 changes to 1 files
633 updating bookmark Y
634 new changesets 35d1ef0a8d1b (1 drafts)
634 new changesets 35d1ef0a8d1b (1 drafts)
635 (run 'hg update' to get a working copy)
635 (run 'hg update' to get a working copy)
636 $ hg book
636 $ hg book
637 @ 1:0d2164f0ce0d
637 @ 1:0d2164f0ce0d
638 X 1:0d2164f0ce0d
638 X 1:0d2164f0ce0d
639 * Y 5:35d1ef0a8d1b
639 * Y 5:35d1ef0a8d1b
640 Z 1:0d2164f0ce0d
640 Z 1:0d2164f0ce0d
641
641
642 Update a bookmark right after the initial lookup -r (issue4700)
642 Update a bookmark right after the initial lookup -r (issue4700)
643
643
644 $ echo c7 > ../pull-race/f3 # to be committed during the race
644 $ echo c7 > ../pull-race/f3 # to be committed during the race
645 $ cat <<EOF > ../lookuphook.py
645 $ cat <<EOF > ../lookuphook.py
646 > """small extensions adding a hook after wireprotocol lookup to test race"""
646 > """small extensions adding a hook after wireprotocol lookup to test race"""
647 > import functools
647 > import functools
648 > from mercurial import wireprotov1server, wireprotov2server
648 > from mercurial import wireprotov1server, wireprotov2server
649 >
649 >
650 > def wrappedlookup(orig, repo, *args, **kwargs):
650 > def wrappedlookup(orig, repo, *args, **kwargs):
651 > ret = orig(repo, *args, **kwargs)
651 > ret = orig(repo, *args, **kwargs)
652 > repo.hook(b'lookup')
652 > repo.hook(b'lookup')
653 > return ret
653 > return ret
654 > for table in [wireprotov1server.commands, wireprotov2server.COMMANDS]:
654 > for table in [wireprotov1server.commands, wireprotov2server.COMMANDS]:
655 > table[b'lookup'].func = functools.partial(wrappedlookup, table[b'lookup'].func)
655 > table[b'lookup'].func = functools.partial(wrappedlookup, table[b'lookup'].func)
656 > EOF
656 > EOF
657 $ cat <<EOF > ../pull-race/.hg/hgrc
657 $ cat <<EOF > ../pull-race/.hg/hgrc
658 > [extensions]
658 > [extensions]
659 > lookuphook=$TESTTMP/lookuphook.py
659 > lookuphook=$TESTTMP/lookuphook.py
660 > [hooks]
660 > [hooks]
661 > lookup.makecommit= sh $TESTTMP/listkeys_makecommit.sh
661 > lookup.makecommit= sh $TESTTMP/listkeys_makecommit.sh
662 > EOF
662 > EOF
663 $ restart_server # new config need server restart
663 $ restart_server # new config need server restart
664 $ hg -R $TESTTMP/pull-race book
664 $ hg -R $TESTTMP/pull-race book
665 @ 1:0d2164f0ce0d
665 @ 1:0d2164f0ce0d
666 X 1:0d2164f0ce0d
666 X 1:0d2164f0ce0d
667 * Y 6:0d60821d2197
667 * Y 6:0d60821d2197
668 Z 1:0d2164f0ce0d
668 Z 1:0d2164f0ce0d
669 $ hg pull -r Y
669 $ hg pull -r Y
670 pulling from http://localhost:$HGPORT/
670 pulling from http://localhost:$HGPORT/
671 searching for changes
671 searching for changes
672 adding changesets
672 adding changesets
673 adding manifests
673 adding manifests
674 adding file changes
674 adding file changes
675 updating bookmark Y
675 added 1 changesets with 1 changes to 1 files
676 added 1 changesets with 1 changes to 1 files
676 updating bookmark Y
677 new changesets 0d60821d2197 (1 drafts)
677 new changesets 0d60821d2197 (1 drafts)
678 (run 'hg update' to get a working copy)
678 (run 'hg update' to get a working copy)
679 $ hg book
679 $ hg book
680 @ 1:0d2164f0ce0d
680 @ 1:0d2164f0ce0d
681 X 1:0d2164f0ce0d
681 X 1:0d2164f0ce0d
682 * Y 6:0d60821d2197
682 * Y 6:0d60821d2197
683 Z 1:0d2164f0ce0d
683 Z 1:0d2164f0ce0d
684 $ hg -R $TESTTMP/pull-race book
684 $ hg -R $TESTTMP/pull-race book
685 @ 1:0d2164f0ce0d
685 @ 1:0d2164f0ce0d
686 X 1:0d2164f0ce0d
686 X 1:0d2164f0ce0d
687 * Y 7:714424d9e8b8
687 * Y 7:714424d9e8b8
688 Z 1:0d2164f0ce0d
688 Z 1:0d2164f0ce0d
689
689
690 (done with this section of the test)
690 (done with this section of the test)
691
691
692 $ killdaemons.py
692 $ killdaemons.py
693 $ cd ../b
693 $ cd ../b
694
694
695 diverging a remote bookmark fails
695 diverging a remote bookmark fails
696
696
697 $ hg up -q 4e3505fd9583
697 $ hg up -q 4e3505fd9583
698 $ echo c4 > f2
698 $ echo c4 > f2
699 $ hg ci -Am4
699 $ hg ci -Am4
700 adding f2
700 adding f2
701 created new head
701 created new head
702 $ echo c5 > f2
702 $ echo c5 > f2
703 $ hg ci -Am5
703 $ hg ci -Am5
704 $ hg log -G
704 $ hg log -G
705 @ 5:c922c0139ca0 5
705 @ 5:c922c0139ca0 5
706 |
706 |
707 o 4:4efff6d98829 4
707 o 4:4efff6d98829 4
708 |
708 |
709 | o 3:f6fc62dde3c0 3
709 | o 3:f6fc62dde3c0 3
710 |/
710 |/
711 | o 2:0d2164f0ce0d 1
711 | o 2:0d2164f0ce0d 1
712 |/
712 |/
713 | o 1:9b140be10808 2
713 | o 1:9b140be10808 2
714 |/
714 |/
715 o 0:4e3505fd9583 test
715 o 0:4e3505fd9583 test
716
716
717
717
718 $ hg book -f Y
718 $ hg book -f Y
719
719
720 $ cat <<EOF > ../a/.hg/hgrc
720 $ cat <<EOF > ../a/.hg/hgrc
721 > [web]
721 > [web]
722 > push_ssl = false
722 > push_ssl = false
723 > allow_push = *
723 > allow_push = *
724 > EOF
724 > EOF
725
725
726 $ hg serve -R ../a -p $HGPORT2 -d --pid-file=../hg2.pid
726 $ hg serve -R ../a -p $HGPORT2 -d --pid-file=../hg2.pid
727 $ cat ../hg2.pid >> $DAEMON_PIDS
727 $ cat ../hg2.pid >> $DAEMON_PIDS
728
728
729 $ hg push http://localhost:$HGPORT2/
729 $ hg push http://localhost:$HGPORT2/
730 pushing to http://localhost:$HGPORT2/
730 pushing to http://localhost:$HGPORT2/
731 searching for changes
731 searching for changes
732 abort: push creates new remote head c922c0139ca0 with bookmark 'Y'!
732 abort: push creates new remote head c922c0139ca0 with bookmark 'Y'!
733 (merge or see 'hg help push' for details about pushing new heads)
733 (merge or see 'hg help push' for details about pushing new heads)
734 [255]
734 [255]
735 $ hg -R ../a book
735 $ hg -R ../a book
736 @ 1:0d2164f0ce0d
736 @ 1:0d2164f0ce0d
737 * X 1:0d2164f0ce0d
737 * X 1:0d2164f0ce0d
738 Y 3:f6fc62dde3c0
738 Y 3:f6fc62dde3c0
739 Z 1:0d2164f0ce0d
739 Z 1:0d2164f0ce0d
740
740
741
741
742 Unrelated marker does not alter the decision
742 Unrelated marker does not alter the decision
743
743
744 $ hg debugobsolete aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
744 $ hg debugobsolete aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
745 1 new obsolescence markers
745 1 new obsolescence markers
746 $ hg push http://localhost:$HGPORT2/
746 $ hg push http://localhost:$HGPORT2/
747 pushing to http://localhost:$HGPORT2/
747 pushing to http://localhost:$HGPORT2/
748 searching for changes
748 searching for changes
749 abort: push creates new remote head c922c0139ca0 with bookmark 'Y'!
749 abort: push creates new remote head c922c0139ca0 with bookmark 'Y'!
750 (merge or see 'hg help push' for details about pushing new heads)
750 (merge or see 'hg help push' for details about pushing new heads)
751 [255]
751 [255]
752 $ hg -R ../a book
752 $ hg -R ../a book
753 @ 1:0d2164f0ce0d
753 @ 1:0d2164f0ce0d
754 * X 1:0d2164f0ce0d
754 * X 1:0d2164f0ce0d
755 Y 3:f6fc62dde3c0
755 Y 3:f6fc62dde3c0
756 Z 1:0d2164f0ce0d
756 Z 1:0d2164f0ce0d
757
757
758 Update to a successor works
758 Update to a successor works
759
759
760 $ hg id --debug -r 3
760 $ hg id --debug -r 3
761 f6fc62dde3c0771e29704af56ba4d8af77abcc2f
761 f6fc62dde3c0771e29704af56ba4d8af77abcc2f
762 $ hg id --debug -r 4
762 $ hg id --debug -r 4
763 4efff6d98829d9c824c621afd6e3f01865f5439f
763 4efff6d98829d9c824c621afd6e3f01865f5439f
764 $ hg id --debug -r 5
764 $ hg id --debug -r 5
765 c922c0139ca03858f655e4a2af4dd02796a63969 tip Y
765 c922c0139ca03858f655e4a2af4dd02796a63969 tip Y
766 $ hg debugobsolete f6fc62dde3c0771e29704af56ba4d8af77abcc2f cccccccccccccccccccccccccccccccccccccccc
766 $ hg debugobsolete f6fc62dde3c0771e29704af56ba4d8af77abcc2f cccccccccccccccccccccccccccccccccccccccc
767 1 new obsolescence markers
767 1 new obsolescence markers
768 obsoleted 1 changesets
768 obsoleted 1 changesets
769 $ hg debugobsolete cccccccccccccccccccccccccccccccccccccccc 4efff6d98829d9c824c621afd6e3f01865f5439f
769 $ hg debugobsolete cccccccccccccccccccccccccccccccccccccccc 4efff6d98829d9c824c621afd6e3f01865f5439f
770 1 new obsolescence markers
770 1 new obsolescence markers
771 $ hg push http://localhost:$HGPORT2/
771 $ hg push http://localhost:$HGPORT2/
772 pushing to http://localhost:$HGPORT2/
772 pushing to http://localhost:$HGPORT2/
773 searching for changes
773 searching for changes
774 remote: adding changesets
774 remote: adding changesets
775 remote: adding manifests
775 remote: adding manifests
776 remote: adding file changes
776 remote: adding file changes
777 remote: added 2 changesets with 2 changes to 1 files (+1 heads)
777 remote: added 2 changesets with 2 changes to 1 files (+1 heads)
778 remote: 2 new obsolescence markers
778 remote: 2 new obsolescence markers
779 remote: obsoleted 1 changesets
779 remote: obsoleted 1 changesets
780 updating bookmark Y
780 updating bookmark Y
781 $ hg -R ../a book
781 $ hg -R ../a book
782 @ 1:0d2164f0ce0d
782 @ 1:0d2164f0ce0d
783 * X 1:0d2164f0ce0d
783 * X 1:0d2164f0ce0d
784 Y 5:c922c0139ca0
784 Y 5:c922c0139ca0
785 Z 1:0d2164f0ce0d
785 Z 1:0d2164f0ce0d
786
786
787 hgweb
787 hgweb
788
788
789 $ cat <<EOF > .hg/hgrc
789 $ cat <<EOF > .hg/hgrc
790 > [web]
790 > [web]
791 > push_ssl = false
791 > push_ssl = false
792 > allow_push = *
792 > allow_push = *
793 > EOF
793 > EOF
794
794
795 $ hg serve -p $HGPORT -d --pid-file=../hg.pid -E errors.log
795 $ hg serve -p $HGPORT -d --pid-file=../hg.pid -E errors.log
796 $ cat ../hg.pid >> $DAEMON_PIDS
796 $ cat ../hg.pid >> $DAEMON_PIDS
797 $ cd ../a
797 $ cd ../a
798
798
799 $ hg debugpushkey http://localhost:$HGPORT/ namespaces
799 $ hg debugpushkey http://localhost:$HGPORT/ namespaces
800 bookmarks
800 bookmarks
801 namespaces
801 namespaces
802 obsolete
802 obsolete
803 phases
803 phases
804 $ hg debugpushkey http://localhost:$HGPORT/ bookmarks
804 $ hg debugpushkey http://localhost:$HGPORT/ bookmarks
805 @ 9b140be1080824d768c5a4691a564088eede71f9
805 @ 9b140be1080824d768c5a4691a564088eede71f9
806 X 9b140be1080824d768c5a4691a564088eede71f9
806 X 9b140be1080824d768c5a4691a564088eede71f9
807 Y c922c0139ca03858f655e4a2af4dd02796a63969
807 Y c922c0139ca03858f655e4a2af4dd02796a63969
808 Z 9b140be1080824d768c5a4691a564088eede71f9
808 Z 9b140be1080824d768c5a4691a564088eede71f9
809 foo 0000000000000000000000000000000000000000
809 foo 0000000000000000000000000000000000000000
810 foobar 9b140be1080824d768c5a4691a564088eede71f9
810 foobar 9b140be1080824d768c5a4691a564088eede71f9
811 $ hg out -B http://localhost:$HGPORT/
811 $ hg out -B http://localhost:$HGPORT/
812 comparing with http://localhost:$HGPORT/
812 comparing with http://localhost:$HGPORT/
813 searching for changed bookmarks
813 searching for changed bookmarks
814 @ 0d2164f0ce0d
814 @ 0d2164f0ce0d
815 X 0d2164f0ce0d
815 X 0d2164f0ce0d
816 Z 0d2164f0ce0d
816 Z 0d2164f0ce0d
817 foo
817 foo
818 foobar
818 foobar
819 $ hg push -B Z http://localhost:$HGPORT/
819 $ hg push -B Z http://localhost:$HGPORT/
820 pushing to http://localhost:$HGPORT/
820 pushing to http://localhost:$HGPORT/
821 searching for changes
821 searching for changes
822 no changes found
822 no changes found
823 updating bookmark Z
823 updating bookmark Z
824 [1]
824 [1]
825 $ hg book -d Z
825 $ hg book -d Z
826 $ hg in -B http://localhost:$HGPORT/
826 $ hg in -B http://localhost:$HGPORT/
827 comparing with http://localhost:$HGPORT/
827 comparing with http://localhost:$HGPORT/
828 searching for changed bookmarks
828 searching for changed bookmarks
829 @ 9b140be10808
829 @ 9b140be10808
830 X 9b140be10808
830 X 9b140be10808
831 Z 0d2164f0ce0d
831 Z 0d2164f0ce0d
832 foo 000000000000
832 foo 000000000000
833 foobar 9b140be10808
833 foobar 9b140be10808
834 $ hg pull -B Z http://localhost:$HGPORT/
834 $ hg pull -B Z http://localhost:$HGPORT/
835 pulling from http://localhost:$HGPORT/
835 pulling from http://localhost:$HGPORT/
836 no changes found
836 no changes found
837 divergent bookmark @ stored as @1
837 divergent bookmark @ stored as @1
838 divergent bookmark X stored as X@1
838 divergent bookmark X stored as X@1
839 adding remote bookmark Z
839 adding remote bookmark Z
840 adding remote bookmark foo
840 adding remote bookmark foo
841 adding remote bookmark foobar
841 adding remote bookmark foobar
842 $ hg clone http://localhost:$HGPORT/ cloned-bookmarks
842 $ hg clone http://localhost:$HGPORT/ cloned-bookmarks
843 requesting all changes
843 requesting all changes
844 adding changesets
844 adding changesets
845 adding manifests
845 adding manifests
846 adding file changes
846 adding file changes
847 added 5 changesets with 5 changes to 3 files (+2 heads)
847 added 5 changesets with 5 changes to 3 files (+2 heads)
848 2 new obsolescence markers
848 2 new obsolescence markers
849 new changesets 4e3505fd9583:c922c0139ca0 (5 drafts)
849 new changesets 4e3505fd9583:c922c0139ca0 (5 drafts)
850 updating to bookmark @
850 updating to bookmark @
851 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
851 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
852 $ hg -R cloned-bookmarks bookmarks
852 $ hg -R cloned-bookmarks bookmarks
853 * @ 1:9b140be10808
853 * @ 1:9b140be10808
854 X 1:9b140be10808
854 X 1:9b140be10808
855 Y 4:c922c0139ca0
855 Y 4:c922c0139ca0
856 Z 2:0d2164f0ce0d
856 Z 2:0d2164f0ce0d
857 foo -1:000000000000
857 foo -1:000000000000
858 foobar 1:9b140be10808
858 foobar 1:9b140be10808
859
859
860 $ cd ..
860 $ cd ..
861
861
862 Test to show result of bookmarks comparison
862 Test to show result of bookmarks comparison
863
863
864 $ mkdir bmcomparison
864 $ mkdir bmcomparison
865 $ cd bmcomparison
865 $ cd bmcomparison
866
866
867 $ hg init source
867 $ hg init source
868 $ hg -R source debugbuilddag '+2*2*3*4'
868 $ hg -R source debugbuilddag '+2*2*3*4'
869 $ hg -R source log -G --template '{rev}:{node|short}'
869 $ hg -R source log -G --template '{rev}:{node|short}'
870 o 4:e7bd5218ca15
870 o 4:e7bd5218ca15
871 |
871 |
872 | o 3:6100d3090acf
872 | o 3:6100d3090acf
873 |/
873 |/
874 | o 2:fa942426a6fd
874 | o 2:fa942426a6fd
875 |/
875 |/
876 | o 1:66f7d451a68b
876 | o 1:66f7d451a68b
877 |/
877 |/
878 o 0:1ea73414a91b
878 o 0:1ea73414a91b
879
879
880 $ hg -R source bookmarks -r 0 SAME
880 $ hg -R source bookmarks -r 0 SAME
881 $ hg -R source bookmarks -r 0 ADV_ON_REPO1
881 $ hg -R source bookmarks -r 0 ADV_ON_REPO1
882 $ hg -R source bookmarks -r 0 ADV_ON_REPO2
882 $ hg -R source bookmarks -r 0 ADV_ON_REPO2
883 $ hg -R source bookmarks -r 0 DIFF_ADV_ON_REPO1
883 $ hg -R source bookmarks -r 0 DIFF_ADV_ON_REPO1
884 $ hg -R source bookmarks -r 0 DIFF_ADV_ON_REPO2
884 $ hg -R source bookmarks -r 0 DIFF_ADV_ON_REPO2
885 $ hg -R source bookmarks -r 1 DIVERGED
885 $ hg -R source bookmarks -r 1 DIVERGED
886
886
887 $ hg clone -U source repo1
887 $ hg clone -U source repo1
888
888
889 (test that incoming/outgoing exit with 1, if there is no bookmark to
889 (test that incoming/outgoing exit with 1, if there is no bookmark to
890 be exchanged)
890 be exchanged)
891
891
892 $ hg -R repo1 incoming -B
892 $ hg -R repo1 incoming -B
893 comparing with $TESTTMP/bmcomparison/source
893 comparing with $TESTTMP/bmcomparison/source
894 searching for changed bookmarks
894 searching for changed bookmarks
895 no changed bookmarks found
895 no changed bookmarks found
896 [1]
896 [1]
897 $ hg -R repo1 outgoing -B
897 $ hg -R repo1 outgoing -B
898 comparing with $TESTTMP/bmcomparison/source
898 comparing with $TESTTMP/bmcomparison/source
899 searching for changed bookmarks
899 searching for changed bookmarks
900 no changed bookmarks found
900 no changed bookmarks found
901 [1]
901 [1]
902
902
903 $ hg -R repo1 bookmarks -f -r 1 ADD_ON_REPO1
903 $ hg -R repo1 bookmarks -f -r 1 ADD_ON_REPO1
904 $ hg -R repo1 bookmarks -f -r 2 ADV_ON_REPO1
904 $ hg -R repo1 bookmarks -f -r 2 ADV_ON_REPO1
905 $ hg -R repo1 bookmarks -f -r 3 DIFF_ADV_ON_REPO1
905 $ hg -R repo1 bookmarks -f -r 3 DIFF_ADV_ON_REPO1
906 $ hg -R repo1 bookmarks -f -r 3 DIFF_DIVERGED
906 $ hg -R repo1 bookmarks -f -r 3 DIFF_DIVERGED
907 $ hg -R repo1 -q --config extensions.mq= strip 4
907 $ hg -R repo1 -q --config extensions.mq= strip 4
908 $ hg -R repo1 log -G --template '{node|short} ({bookmarks})'
908 $ hg -R repo1 log -G --template '{node|short} ({bookmarks})'
909 o 6100d3090acf (DIFF_ADV_ON_REPO1 DIFF_DIVERGED)
909 o 6100d3090acf (DIFF_ADV_ON_REPO1 DIFF_DIVERGED)
910 |
910 |
911 | o fa942426a6fd (ADV_ON_REPO1)
911 | o fa942426a6fd (ADV_ON_REPO1)
912 |/
912 |/
913 | o 66f7d451a68b (ADD_ON_REPO1 DIVERGED)
913 | o 66f7d451a68b (ADD_ON_REPO1 DIVERGED)
914 |/
914 |/
915 o 1ea73414a91b (ADV_ON_REPO2 DIFF_ADV_ON_REPO2 SAME)
915 o 1ea73414a91b (ADV_ON_REPO2 DIFF_ADV_ON_REPO2 SAME)
916
916
917
917
918 $ hg clone -U source repo2
918 $ hg clone -U source repo2
919 $ hg -R repo2 bookmarks -f -r 1 ADD_ON_REPO2
919 $ hg -R repo2 bookmarks -f -r 1 ADD_ON_REPO2
920 $ hg -R repo2 bookmarks -f -r 1 ADV_ON_REPO2
920 $ hg -R repo2 bookmarks -f -r 1 ADV_ON_REPO2
921 $ hg -R repo2 bookmarks -f -r 2 DIVERGED
921 $ hg -R repo2 bookmarks -f -r 2 DIVERGED
922 $ hg -R repo2 bookmarks -f -r 4 DIFF_ADV_ON_REPO2
922 $ hg -R repo2 bookmarks -f -r 4 DIFF_ADV_ON_REPO2
923 $ hg -R repo2 bookmarks -f -r 4 DIFF_DIVERGED
923 $ hg -R repo2 bookmarks -f -r 4 DIFF_DIVERGED
924 $ hg -R repo2 -q --config extensions.mq= strip 3
924 $ hg -R repo2 -q --config extensions.mq= strip 3
925 $ hg -R repo2 log -G --template '{node|short} ({bookmarks})'
925 $ hg -R repo2 log -G --template '{node|short} ({bookmarks})'
926 o e7bd5218ca15 (DIFF_ADV_ON_REPO2 DIFF_DIVERGED)
926 o e7bd5218ca15 (DIFF_ADV_ON_REPO2 DIFF_DIVERGED)
927 |
927 |
928 | o fa942426a6fd (DIVERGED)
928 | o fa942426a6fd (DIVERGED)
929 |/
929 |/
930 | o 66f7d451a68b (ADD_ON_REPO2 ADV_ON_REPO2)
930 | o 66f7d451a68b (ADD_ON_REPO2 ADV_ON_REPO2)
931 |/
931 |/
932 o 1ea73414a91b (ADV_ON_REPO1 DIFF_ADV_ON_REPO1 SAME)
932 o 1ea73414a91b (ADV_ON_REPO1 DIFF_ADV_ON_REPO1 SAME)
933
933
934
934
935 (test that difference of bookmarks between repositories are fully shown)
935 (test that difference of bookmarks between repositories are fully shown)
936
936
937 $ hg -R repo1 incoming -B repo2 -v
937 $ hg -R repo1 incoming -B repo2 -v
938 comparing with repo2
938 comparing with repo2
939 searching for changed bookmarks
939 searching for changed bookmarks
940 ADD_ON_REPO2 66f7d451a68b added
940 ADD_ON_REPO2 66f7d451a68b added
941 ADV_ON_REPO2 66f7d451a68b advanced
941 ADV_ON_REPO2 66f7d451a68b advanced
942 DIFF_ADV_ON_REPO2 e7bd5218ca15 changed
942 DIFF_ADV_ON_REPO2 e7bd5218ca15 changed
943 DIFF_DIVERGED e7bd5218ca15 changed
943 DIFF_DIVERGED e7bd5218ca15 changed
944 DIVERGED fa942426a6fd diverged
944 DIVERGED fa942426a6fd diverged
945 $ hg -R repo1 outgoing -B repo2 -v
945 $ hg -R repo1 outgoing -B repo2 -v
946 comparing with repo2
946 comparing with repo2
947 searching for changed bookmarks
947 searching for changed bookmarks
948 ADD_ON_REPO1 66f7d451a68b added
948 ADD_ON_REPO1 66f7d451a68b added
949 ADD_ON_REPO2 deleted
949 ADD_ON_REPO2 deleted
950 ADV_ON_REPO1 fa942426a6fd advanced
950 ADV_ON_REPO1 fa942426a6fd advanced
951 DIFF_ADV_ON_REPO1 6100d3090acf advanced
951 DIFF_ADV_ON_REPO1 6100d3090acf advanced
952 DIFF_ADV_ON_REPO2 1ea73414a91b changed
952 DIFF_ADV_ON_REPO2 1ea73414a91b changed
953 DIFF_DIVERGED 6100d3090acf changed
953 DIFF_DIVERGED 6100d3090acf changed
954 DIVERGED 66f7d451a68b diverged
954 DIVERGED 66f7d451a68b diverged
955
955
956 $ hg -R repo2 incoming -B repo1 -v
956 $ hg -R repo2 incoming -B repo1 -v
957 comparing with repo1
957 comparing with repo1
958 searching for changed bookmarks
958 searching for changed bookmarks
959 ADD_ON_REPO1 66f7d451a68b added
959 ADD_ON_REPO1 66f7d451a68b added
960 ADV_ON_REPO1 fa942426a6fd advanced
960 ADV_ON_REPO1 fa942426a6fd advanced
961 DIFF_ADV_ON_REPO1 6100d3090acf changed
961 DIFF_ADV_ON_REPO1 6100d3090acf changed
962 DIFF_DIVERGED 6100d3090acf changed
962 DIFF_DIVERGED 6100d3090acf changed
963 DIVERGED 66f7d451a68b diverged
963 DIVERGED 66f7d451a68b diverged
964 $ hg -R repo2 outgoing -B repo1 -v
964 $ hg -R repo2 outgoing -B repo1 -v
965 comparing with repo1
965 comparing with repo1
966 searching for changed bookmarks
966 searching for changed bookmarks
967 ADD_ON_REPO1 deleted
967 ADD_ON_REPO1 deleted
968 ADD_ON_REPO2 66f7d451a68b added
968 ADD_ON_REPO2 66f7d451a68b added
969 ADV_ON_REPO2 66f7d451a68b advanced
969 ADV_ON_REPO2 66f7d451a68b advanced
970 DIFF_ADV_ON_REPO1 1ea73414a91b changed
970 DIFF_ADV_ON_REPO1 1ea73414a91b changed
971 DIFF_ADV_ON_REPO2 e7bd5218ca15 advanced
971 DIFF_ADV_ON_REPO2 e7bd5218ca15 advanced
972 DIFF_DIVERGED e7bd5218ca15 changed
972 DIFF_DIVERGED e7bd5218ca15 changed
973 DIVERGED fa942426a6fd diverged
973 DIVERGED fa942426a6fd diverged
974
974
975 $ cd ..
975 $ cd ..
976
976
977 Pushing a bookmark should only push the changes required by that
977 Pushing a bookmark should only push the changes required by that
978 bookmark, not all outgoing changes:
978 bookmark, not all outgoing changes:
979 $ hg clone http://localhost:$HGPORT/ addmarks
979 $ hg clone http://localhost:$HGPORT/ addmarks
980 requesting all changes
980 requesting all changes
981 adding changesets
981 adding changesets
982 adding manifests
982 adding manifests
983 adding file changes
983 adding file changes
984 added 5 changesets with 5 changes to 3 files (+2 heads)
984 added 5 changesets with 5 changes to 3 files (+2 heads)
985 2 new obsolescence markers
985 2 new obsolescence markers
986 new changesets 4e3505fd9583:c922c0139ca0 (5 drafts)
986 new changesets 4e3505fd9583:c922c0139ca0 (5 drafts)
987 updating to bookmark @
987 updating to bookmark @
988 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
988 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
989 $ cd addmarks
989 $ cd addmarks
990 $ echo foo > foo
990 $ echo foo > foo
991 $ hg add foo
991 $ hg add foo
992 $ hg commit -m 'add foo'
992 $ hg commit -m 'add foo'
993 $ echo bar > bar
993 $ echo bar > bar
994 $ hg add bar
994 $ hg add bar
995 $ hg commit -m 'add bar'
995 $ hg commit -m 'add bar'
996 $ hg co "tip^"
996 $ hg co "tip^"
997 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
997 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
998 (leaving bookmark @)
998 (leaving bookmark @)
999 $ hg book add-foo
999 $ hg book add-foo
1000 $ hg book -r tip add-bar
1000 $ hg book -r tip add-bar
1001 Note: this push *must* push only a single changeset, as that's the point
1001 Note: this push *must* push only a single changeset, as that's the point
1002 of this test.
1002 of this test.
1003 $ hg push -B add-foo --traceback
1003 $ hg push -B add-foo --traceback
1004 pushing to http://localhost:$HGPORT/
1004 pushing to http://localhost:$HGPORT/
1005 searching for changes
1005 searching for changes
1006 remote: adding changesets
1006 remote: adding changesets
1007 remote: adding manifests
1007 remote: adding manifests
1008 remote: adding file changes
1008 remote: adding file changes
1009 remote: added 1 changesets with 1 changes to 1 files
1009 remote: added 1 changesets with 1 changes to 1 files
1010 exporting bookmark add-foo
1010 exporting bookmark add-foo
1011
1011
1012 pushing a new bookmark on a new head does not require -f if -B is specified
1012 pushing a new bookmark on a new head does not require -f if -B is specified
1013
1013
1014 $ hg up -q X
1014 $ hg up -q X
1015 $ hg book W
1015 $ hg book W
1016 $ echo c5 > f2
1016 $ echo c5 > f2
1017 $ hg ci -Am5
1017 $ hg ci -Am5
1018 created new head
1018 created new head
1019 $ hg push -B .
1019 $ hg push -B .
1020 pushing to http://localhost:$HGPORT/
1020 pushing to http://localhost:$HGPORT/
1021 searching for changes
1021 searching for changes
1022 remote: adding changesets
1022 remote: adding changesets
1023 remote: adding manifests
1023 remote: adding manifests
1024 remote: adding file changes
1024 remote: adding file changes
1025 remote: added 1 changesets with 1 changes to 1 files (+1 heads)
1025 remote: added 1 changesets with 1 changes to 1 files (+1 heads)
1026 exporting bookmark W
1026 exporting bookmark W
1027 $ hg -R ../b id -r W
1027 $ hg -R ../b id -r W
1028 cc978a373a53 tip W
1028 cc978a373a53 tip W
1029
1029
1030 pushing an existing but divergent bookmark with -B still requires -f
1030 pushing an existing but divergent bookmark with -B still requires -f
1031
1031
1032 $ hg clone -q . ../r
1032 $ hg clone -q . ../r
1033 $ hg up -q X
1033 $ hg up -q X
1034 $ echo 1 > f2
1034 $ echo 1 > f2
1035 $ hg ci -qAml
1035 $ hg ci -qAml
1036
1036
1037 $ cd ../r
1037 $ cd ../r
1038 $ hg up -q X
1038 $ hg up -q X
1039 $ echo 2 > f2
1039 $ echo 2 > f2
1040 $ hg ci -qAmr
1040 $ hg ci -qAmr
1041 $ hg push -B X
1041 $ hg push -B X
1042 pushing to $TESTTMP/addmarks
1042 pushing to $TESTTMP/addmarks
1043 searching for changes
1043 searching for changes
1044 remote has heads on branch 'default' that are not known locally: a2a606d9ff1b
1044 remote has heads on branch 'default' that are not known locally: a2a606d9ff1b
1045 abort: push creates new remote head 54694f811df9 with bookmark 'X'!
1045 abort: push creates new remote head 54694f811df9 with bookmark 'X'!
1046 (pull and merge or see 'hg help push' for details about pushing new heads)
1046 (pull and merge or see 'hg help push' for details about pushing new heads)
1047 [255]
1047 [255]
1048 $ cd ../addmarks
1048 $ cd ../addmarks
1049
1049
1050 Check summary output for incoming/outgoing bookmarks
1050 Check summary output for incoming/outgoing bookmarks
1051
1051
1052 $ hg bookmarks -d X
1052 $ hg bookmarks -d X
1053 $ hg bookmarks -d Y
1053 $ hg bookmarks -d Y
1054 $ hg summary --remote | grep '^remote:'
1054 $ hg summary --remote | grep '^remote:'
1055 remote: *, 2 incoming bookmarks, 1 outgoing bookmarks (glob)
1055 remote: *, 2 incoming bookmarks, 1 outgoing bookmarks (glob)
1056
1056
1057 $ cd ..
1057 $ cd ..
1058
1058
1059 pushing an unchanged bookmark should result in no changes
1059 pushing an unchanged bookmark should result in no changes
1060
1060
1061 $ hg init unchanged-a
1061 $ hg init unchanged-a
1062 $ hg init unchanged-b
1062 $ hg init unchanged-b
1063 $ cd unchanged-a
1063 $ cd unchanged-a
1064 $ echo initial > foo
1064 $ echo initial > foo
1065 $ hg commit -A -m initial
1065 $ hg commit -A -m initial
1066 adding foo
1066 adding foo
1067 $ hg bookmark @
1067 $ hg bookmark @
1068 $ hg push -B @ ../unchanged-b
1068 $ hg push -B @ ../unchanged-b
1069 pushing to ../unchanged-b
1069 pushing to ../unchanged-b
1070 searching for changes
1070 searching for changes
1071 adding changesets
1071 adding changesets
1072 adding manifests
1072 adding manifests
1073 adding file changes
1073 adding file changes
1074 added 1 changesets with 1 changes to 1 files
1074 added 1 changesets with 1 changes to 1 files
1075 exporting bookmark @
1075 exporting bookmark @
1076
1076
1077 $ hg push -B @ ../unchanged-b
1077 $ hg push -B @ ../unchanged-b
1078 pushing to ../unchanged-b
1078 pushing to ../unchanged-b
1079 searching for changes
1079 searching for changes
1080 no changes found
1080 no changes found
1081 [1]
1081 [1]
1082
1082
1083 Pushing a really long bookmark should work fine (issue5165)
1083 Pushing a really long bookmark should work fine (issue5165)
1084 ===============================================
1084 ===============================================
1085
1085
1086 #if b2-binary
1086 #if b2-binary
1087 >>> with open('longname', 'w') as f:
1087 >>> with open('longname', 'w') as f:
1088 ... f.write('wat' * 100) and None
1088 ... f.write('wat' * 100) and None
1089 $ hg book `cat longname`
1089 $ hg book `cat longname`
1090 $ hg push -B `cat longname` ../unchanged-b
1090 $ hg push -B `cat longname` ../unchanged-b
1091 pushing to ../unchanged-b
1091 pushing to ../unchanged-b
1092 searching for changes
1092 searching for changes
1093 no changes found
1093 no changes found
1094 exporting bookmark (wat){100} (re)
1094 exporting bookmark (wat){100} (re)
1095 [1]
1095 [1]
1096 $ hg -R ../unchanged-b book --delete `cat longname`
1096 $ hg -R ../unchanged-b book --delete `cat longname`
1097
1097
1098 Test again but forcing bundle2 exchange to make sure that doesn't regress.
1098 Test again but forcing bundle2 exchange to make sure that doesn't regress.
1099
1099
1100 $ hg push -B `cat longname` ../unchanged-b --config devel.legacy.exchange=bundle1
1100 $ hg push -B `cat longname` ../unchanged-b --config devel.legacy.exchange=bundle1
1101 pushing to ../unchanged-b
1101 pushing to ../unchanged-b
1102 searching for changes
1102 searching for changes
1103 no changes found
1103 no changes found
1104 exporting bookmark (wat){100} (re)
1104 exporting bookmark (wat){100} (re)
1105 [1]
1105 [1]
1106 $ hg -R ../unchanged-b book --delete `cat longname`
1106 $ hg -R ../unchanged-b book --delete `cat longname`
1107 $ hg book --delete `cat longname`
1107 $ hg book --delete `cat longname`
1108 $ hg co @
1108 $ hg co @
1109 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1109 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1110 (activating bookmark @)
1110 (activating bookmark @)
1111 #endif
1111 #endif
1112
1112
1113 Check hook preventing push (issue4455)
1113 Check hook preventing push (issue4455)
1114 ======================================
1114 ======================================
1115
1115
1116 $ hg bookmarks
1116 $ hg bookmarks
1117 * @ 0:55482a6fb4b1
1117 * @ 0:55482a6fb4b1
1118 $ hg log -G
1118 $ hg log -G
1119 @ 0:55482a6fb4b1 initial
1119 @ 0:55482a6fb4b1 initial
1120
1120
1121 $ hg init ../issue4455-dest
1121 $ hg init ../issue4455-dest
1122 $ hg push ../issue4455-dest # changesets only
1122 $ hg push ../issue4455-dest # changesets only
1123 pushing to ../issue4455-dest
1123 pushing to ../issue4455-dest
1124 searching for changes
1124 searching for changes
1125 adding changesets
1125 adding changesets
1126 adding manifests
1126 adding manifests
1127 adding file changes
1127 adding file changes
1128 added 1 changesets with 1 changes to 1 files
1128 added 1 changesets with 1 changes to 1 files
1129 $ cat >> .hg/hgrc << EOF
1129 $ cat >> .hg/hgrc << EOF
1130 > [paths]
1130 > [paths]
1131 > local=../issue4455-dest/
1131 > local=../issue4455-dest/
1132 > ssh=ssh://user@dummy/issue4455-dest
1132 > ssh=ssh://user@dummy/issue4455-dest
1133 > http=http://localhost:$HGPORT/
1133 > http=http://localhost:$HGPORT/
1134 > [ui]
1134 > [ui]
1135 > ssh="$PYTHON" "$TESTDIR/dummyssh"
1135 > ssh="$PYTHON" "$TESTDIR/dummyssh"
1136 > EOF
1136 > EOF
1137 $ cat >> ../issue4455-dest/.hg/hgrc << EOF
1137 $ cat >> ../issue4455-dest/.hg/hgrc << EOF
1138 > [hooks]
1138 > [hooks]
1139 > prepushkey=false
1139 > prepushkey=false
1140 > [web]
1140 > [web]
1141 > push_ssl = false
1141 > push_ssl = false
1142 > allow_push = *
1142 > allow_push = *
1143 > EOF
1143 > EOF
1144 $ killdaemons.py
1144 $ killdaemons.py
1145 $ hg serve -R ../issue4455-dest -p $HGPORT -d --pid-file=../issue4455.pid -E ../issue4455-error.log
1145 $ hg serve -R ../issue4455-dest -p $HGPORT -d --pid-file=../issue4455.pid -E ../issue4455-error.log
1146 $ cat ../issue4455.pid >> $DAEMON_PIDS
1146 $ cat ../issue4455.pid >> $DAEMON_PIDS
1147
1147
1148 Local push
1148 Local push
1149 ----------
1149 ----------
1150
1150
1151 #if b2-pushkey
1151 #if b2-pushkey
1152
1152
1153 $ hg push -B @ local
1153 $ hg push -B @ local
1154 pushing to $TESTTMP/issue4455-dest
1154 pushing to $TESTTMP/issue4455-dest
1155 searching for changes
1155 searching for changes
1156 no changes found
1156 no changes found
1157 pushkey-abort: prepushkey hook exited with status 1
1157 pushkey-abort: prepushkey hook exited with status 1
1158 abort: exporting bookmark @ failed!
1158 abort: exporting bookmark @ failed!
1159 [255]
1159 [255]
1160
1160
1161 #endif
1161 #endif
1162 #if b2-binary
1162 #if b2-binary
1163
1163
1164 $ hg push -B @ local
1164 $ hg push -B @ local
1165 pushing to $TESTTMP/issue4455-dest
1165 pushing to $TESTTMP/issue4455-dest
1166 searching for changes
1166 searching for changes
1167 no changes found
1167 no changes found
1168 abort: prepushkey hook exited with status 1
1168 abort: prepushkey hook exited with status 1
1169 [255]
1169 [255]
1170
1170
1171 #endif
1171 #endif
1172
1172
1173 $ hg -R ../issue4455-dest/ bookmarks
1173 $ hg -R ../issue4455-dest/ bookmarks
1174 no bookmarks set
1174 no bookmarks set
1175
1175
1176 Using ssh
1176 Using ssh
1177 ---------
1177 ---------
1178
1178
1179 #if b2-pushkey
1179 #if b2-pushkey
1180
1180
1181 $ hg push -B @ ssh # bundle2+
1181 $ hg push -B @ ssh # bundle2+
1182 pushing to ssh://user@dummy/issue4455-dest
1182 pushing to ssh://user@dummy/issue4455-dest
1183 searching for changes
1183 searching for changes
1184 no changes found
1184 no changes found
1185 remote: pushkey-abort: prepushkey hook exited with status 1
1185 remote: pushkey-abort: prepushkey hook exited with status 1
1186 abort: exporting bookmark @ failed!
1186 abort: exporting bookmark @ failed!
1187 [255]
1187 [255]
1188
1188
1189 $ hg -R ../issue4455-dest/ bookmarks
1189 $ hg -R ../issue4455-dest/ bookmarks
1190 no bookmarks set
1190 no bookmarks set
1191
1191
1192 $ hg push -B @ ssh --config devel.legacy.exchange=bundle1
1192 $ hg push -B @ ssh --config devel.legacy.exchange=bundle1
1193 pushing to ssh://user@dummy/issue4455-dest
1193 pushing to ssh://user@dummy/issue4455-dest
1194 searching for changes
1194 searching for changes
1195 no changes found
1195 no changes found
1196 remote: pushkey-abort: prepushkey hook exited with status 1
1196 remote: pushkey-abort: prepushkey hook exited with status 1
1197 exporting bookmark @ failed!
1197 exporting bookmark @ failed!
1198 [1]
1198 [1]
1199
1199
1200 #endif
1200 #endif
1201 #if b2-binary
1201 #if b2-binary
1202
1202
1203 $ hg push -B @ ssh # bundle2+
1203 $ hg push -B @ ssh # bundle2+
1204 pushing to ssh://user@dummy/issue4455-dest
1204 pushing to ssh://user@dummy/issue4455-dest
1205 searching for changes
1205 searching for changes
1206 no changes found
1206 no changes found
1207 remote: prepushkey hook exited with status 1
1207 remote: prepushkey hook exited with status 1
1208 abort: push failed on remote
1208 abort: push failed on remote
1209 [255]
1209 [255]
1210
1210
1211 #endif
1211 #endif
1212
1212
1213 $ hg -R ../issue4455-dest/ bookmarks
1213 $ hg -R ../issue4455-dest/ bookmarks
1214 no bookmarks set
1214 no bookmarks set
1215
1215
1216 Using http
1216 Using http
1217 ----------
1217 ----------
1218
1218
1219 #if b2-pushkey
1219 #if b2-pushkey
1220 $ hg push -B @ http # bundle2+
1220 $ hg push -B @ http # bundle2+
1221 pushing to http://localhost:$HGPORT/
1221 pushing to http://localhost:$HGPORT/
1222 searching for changes
1222 searching for changes
1223 no changes found
1223 no changes found
1224 remote: pushkey-abort: prepushkey hook exited with status 1
1224 remote: pushkey-abort: prepushkey hook exited with status 1
1225 abort: exporting bookmark @ failed!
1225 abort: exporting bookmark @ failed!
1226 [255]
1226 [255]
1227
1227
1228 $ hg -R ../issue4455-dest/ bookmarks
1228 $ hg -R ../issue4455-dest/ bookmarks
1229 no bookmarks set
1229 no bookmarks set
1230
1230
1231 $ hg push -B @ http --config devel.legacy.exchange=bundle1
1231 $ hg push -B @ http --config devel.legacy.exchange=bundle1
1232 pushing to http://localhost:$HGPORT/
1232 pushing to http://localhost:$HGPORT/
1233 searching for changes
1233 searching for changes
1234 no changes found
1234 no changes found
1235 remote: pushkey-abort: prepushkey hook exited with status 1
1235 remote: pushkey-abort: prepushkey hook exited with status 1
1236 exporting bookmark @ failed!
1236 exporting bookmark @ failed!
1237 [1]
1237 [1]
1238
1238
1239 #endif
1239 #endif
1240
1240
1241 #if b2-binary
1241 #if b2-binary
1242
1242
1243 $ hg push -B @ ssh # bundle2+
1243 $ hg push -B @ ssh # bundle2+
1244 pushing to ssh://user@dummy/issue4455-dest
1244 pushing to ssh://user@dummy/issue4455-dest
1245 searching for changes
1245 searching for changes
1246 no changes found
1246 no changes found
1247 remote: prepushkey hook exited with status 1
1247 remote: prepushkey hook exited with status 1
1248 abort: push failed on remote
1248 abort: push failed on remote
1249 [255]
1249 [255]
1250
1250
1251 #endif
1251 #endif
1252
1252
1253 $ hg -R ../issue4455-dest/ bookmarks
1253 $ hg -R ../issue4455-dest/ bookmarks
1254 no bookmarks set
1254 no bookmarks set
1255
1255
1256 $ cd ..
1256 $ cd ..
1257
1257
1258 Test that pre-pushkey compat for bookmark works as expected (issue5777)
1258 Test that pre-pushkey compat for bookmark works as expected (issue5777)
1259
1259
1260 $ cat << EOF >> $HGRCPATH
1260 $ cat << EOF >> $HGRCPATH
1261 > [ui]
1261 > [ui]
1262 > ssh="$PYTHON" "$TESTDIR/dummyssh"
1262 > ssh="$PYTHON" "$TESTDIR/dummyssh"
1263 > [server]
1263 > [server]
1264 > bookmarks-pushkey-compat = yes
1264 > bookmarks-pushkey-compat = yes
1265 > EOF
1265 > EOF
1266
1266
1267 $ hg init server
1267 $ hg init server
1268 $ echo foo > server/a
1268 $ echo foo > server/a
1269 $ hg -R server book foo
1269 $ hg -R server book foo
1270 $ hg -R server commit -Am a
1270 $ hg -R server commit -Am a
1271 adding a
1271 adding a
1272 $ hg clone ssh://user@dummy/server client
1272 $ hg clone ssh://user@dummy/server client
1273 requesting all changes
1273 requesting all changes
1274 adding changesets
1274 adding changesets
1275 adding manifests
1275 adding manifests
1276 adding file changes
1276 adding file changes
1277 added 1 changesets with 1 changes to 1 files
1277 added 1 changesets with 1 changes to 1 files
1278 new changesets 79513d0d7716 (1 drafts)
1278 new changesets 79513d0d7716 (1 drafts)
1279 updating to branch default
1279 updating to branch default
1280 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1280 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1281
1281
1282 Forbid bookmark move on the server
1282 Forbid bookmark move on the server
1283
1283
1284 $ cat << EOF >> $TESTTMP/no-bm-move.sh
1284 $ cat << EOF >> $TESTTMP/no-bm-move.sh
1285 > #!/bin/sh
1285 > #!/bin/sh
1286 > echo \$HG_NAMESPACE | grep -v bookmarks
1286 > echo \$HG_NAMESPACE | grep -v bookmarks
1287 > EOF
1287 > EOF
1288 $ cat << EOF >> server/.hg/hgrc
1288 $ cat << EOF >> server/.hg/hgrc
1289 > [hooks]
1289 > [hooks]
1290 > prepushkey.no-bm-move= sh $TESTTMP/no-bm-move.sh
1290 > prepushkey.no-bm-move= sh $TESTTMP/no-bm-move.sh
1291 > EOF
1291 > EOF
1292
1292
1293 pushing changeset is okay
1293 pushing changeset is okay
1294
1294
1295 $ echo bar >> client/a
1295 $ echo bar >> client/a
1296 $ hg -R client commit -m b
1296 $ hg -R client commit -m b
1297 $ hg -R client push
1297 $ hg -R client push
1298 pushing to ssh://user@dummy/server
1298 pushing to ssh://user@dummy/server
1299 searching for changes
1299 searching for changes
1300 remote: adding changesets
1300 remote: adding changesets
1301 remote: adding manifests
1301 remote: adding manifests
1302 remote: adding file changes
1302 remote: adding file changes
1303 remote: added 1 changesets with 1 changes to 1 files
1303 remote: added 1 changesets with 1 changes to 1 files
1304
1304
1305 attempt to move the bookmark is rejected
1305 attempt to move the bookmark is rejected
1306
1306
1307 $ hg -R client book foo -r .
1307 $ hg -R client book foo -r .
1308 moving bookmark 'foo' forward from 79513d0d7716
1308 moving bookmark 'foo' forward from 79513d0d7716
1309
1309
1310 #if b2-pushkey
1310 #if b2-pushkey
1311 $ hg -R client push
1311 $ hg -R client push
1312 pushing to ssh://user@dummy/server
1312 pushing to ssh://user@dummy/server
1313 searching for changes
1313 searching for changes
1314 no changes found
1314 no changes found
1315 remote: pushkey-abort: prepushkey.no-bm-move hook exited with status 1
1315 remote: pushkey-abort: prepushkey.no-bm-move hook exited with status 1
1316 abort: updating bookmark foo failed!
1316 abort: updating bookmark foo failed!
1317 [255]
1317 [255]
1318 #endif
1318 #endif
1319 #if b2-binary
1319 #if b2-binary
1320 $ hg -R client push
1320 $ hg -R client push
1321 pushing to ssh://user@dummy/server
1321 pushing to ssh://user@dummy/server
1322 searching for changes
1322 searching for changes
1323 no changes found
1323 no changes found
1324 remote: prepushkey.no-bm-move hook exited with status 1
1324 remote: prepushkey.no-bm-move hook exited with status 1
1325 abort: push failed on remote
1325 abort: push failed on remote
1326 [255]
1326 [255]
1327 #endif
1327 #endif
1328
1328
1329 -- test for pushing bookmarks pointing to secret changesets
1329 -- test for pushing bookmarks pointing to secret changesets
1330
1330
1331 Set up a "remote" repo
1331 Set up a "remote" repo
1332 $ hg init issue6159remote
1332 $ hg init issue6159remote
1333 $ cd issue6159remote
1333 $ cd issue6159remote
1334 $ echo a > a
1334 $ echo a > a
1335 $ hg add a
1335 $ hg add a
1336 $ hg commit -m_
1336 $ hg commit -m_
1337 $ hg bookmark foo
1337 $ hg bookmark foo
1338 $ cd ..
1338 $ cd ..
1339
1339
1340 Clone a local repo
1340 Clone a local repo
1341 $ hg clone -q issue6159remote issue6159local
1341 $ hg clone -q issue6159remote issue6159local
1342 $ cd issue6159local
1342 $ cd issue6159local
1343 $ hg up -qr foo
1343 $ hg up -qr foo
1344 $ echo b > b
1344 $ echo b > b
1345
1345
1346 Move the bookmark "foo" to point at a secret changeset
1346 Move the bookmark "foo" to point at a secret changeset
1347 $ hg commit -qAm_ --config phases.new-commit=secret
1347 $ hg commit -qAm_ --config phases.new-commit=secret
1348
1348
1349 Pushing the bookmark "foo" now fails as it contains a secret changeset
1349 Pushing the bookmark "foo" now fails as it contains a secret changeset
1350 $ hg push -r foo
1350 $ hg push -r foo
1351 pushing to $TESTTMP/issue6159remote
1351 pushing to $TESTTMP/issue6159remote
1352 searching for changes
1352 searching for changes
1353 no changes found (ignored 1 secret changesets)
1353 no changes found (ignored 1 secret changesets)
1354 abort: cannot push bookmark foo as it points to a secret changeset
1354 abort: cannot push bookmark foo as it points to a secret changeset
1355 [255]
1355 [255]
@@ -1,1236 +1,1236 b''
1
1
2 $ hg init repo
2 $ hg init repo
3 $ cd repo
3 $ cd repo
4
4
5 $ cat > $TESTTMP/hook.sh <<'EOF'
5 $ cat > $TESTTMP/hook.sh <<'EOF'
6 > echo "test-hook-bookmark: $HG_BOOKMARK: $HG_OLDNODE -> $HG_NODE"
6 > echo "test-hook-bookmark: $HG_BOOKMARK: $HG_OLDNODE -> $HG_NODE"
7 > EOF
7 > EOF
8 $ TESTHOOK="hooks.txnclose-bookmark.test=sh $TESTTMP/hook.sh"
8 $ TESTHOOK="hooks.txnclose-bookmark.test=sh $TESTTMP/hook.sh"
9
9
10 no bookmarks
10 no bookmarks
11
11
12 $ hg bookmarks
12 $ hg bookmarks
13 no bookmarks set
13 no bookmarks set
14
14
15 $ hg bookmarks -Tjson
15 $ hg bookmarks -Tjson
16 [
16 [
17 ]
17 ]
18
18
19 bookmark rev -1
19 bookmark rev -1
20
20
21 $ hg bookmark X --config "$TESTHOOK"
21 $ hg bookmark X --config "$TESTHOOK"
22 test-hook-bookmark: X: -> 0000000000000000000000000000000000000000
22 test-hook-bookmark: X: -> 0000000000000000000000000000000000000000
23
23
24 list bookmarks
24 list bookmarks
25
25
26 $ hg bookmarks
26 $ hg bookmarks
27 * X -1:000000000000
27 * X -1:000000000000
28
28
29 list bookmarks with color
29 list bookmarks with color
30
30
31 $ hg --config extensions.color= --config color.mode=ansi \
31 $ hg --config extensions.color= --config color.mode=ansi \
32 > bookmarks --color=always
32 > bookmarks --color=always
33 \x1b[0;32m * \x1b[0m\x1b[0;32mX\x1b[0m\x1b[0;32m -1:000000000000\x1b[0m (esc)
33 \x1b[0;32m * \x1b[0m\x1b[0;32mX\x1b[0m\x1b[0;32m -1:000000000000\x1b[0m (esc)
34
34
35 $ echo a > a
35 $ echo a > a
36 $ hg add a
36 $ hg add a
37 $ hg commit -m 0 --config "$TESTHOOK"
37 $ hg commit -m 0 --config "$TESTHOOK"
38 test-hook-bookmark: X: 0000000000000000000000000000000000000000 -> f7b1eb17ad24730a1651fccd46c43826d1bbc2ac
38 test-hook-bookmark: X: 0000000000000000000000000000000000000000 -> f7b1eb17ad24730a1651fccd46c43826d1bbc2ac
39
39
40 bookmark X moved to rev 0
40 bookmark X moved to rev 0
41
41
42 $ hg bookmarks
42 $ hg bookmarks
43 * X 0:f7b1eb17ad24
43 * X 0:f7b1eb17ad24
44
44
45 look up bookmark
45 look up bookmark
46
46
47 $ hg log -r X
47 $ hg log -r X
48 changeset: 0:f7b1eb17ad24
48 changeset: 0:f7b1eb17ad24
49 bookmark: X
49 bookmark: X
50 tag: tip
50 tag: tip
51 user: test
51 user: test
52 date: Thu Jan 01 00:00:00 1970 +0000
52 date: Thu Jan 01 00:00:00 1970 +0000
53 summary: 0
53 summary: 0
54
54
55
55
56 second bookmark for rev 0, command should work even with ui.strict on
56 second bookmark for rev 0, command should work even with ui.strict on
57
57
58 $ hg --config ui.strict=1 bookmark X2 --config "$TESTHOOK"
58 $ hg --config ui.strict=1 bookmark X2 --config "$TESTHOOK"
59 test-hook-bookmark: X2: -> f7b1eb17ad24730a1651fccd46c43826d1bbc2ac
59 test-hook-bookmark: X2: -> f7b1eb17ad24730a1651fccd46c43826d1bbc2ac
60
60
61 bookmark rev -1 again
61 bookmark rev -1 again
62
62
63 $ hg bookmark -r null Y
63 $ hg bookmark -r null Y
64
64
65 list bookmarks
65 list bookmarks
66
66
67 $ hg bookmarks
67 $ hg bookmarks
68 X 0:f7b1eb17ad24
68 X 0:f7b1eb17ad24
69 * X2 0:f7b1eb17ad24
69 * X2 0:f7b1eb17ad24
70 Y -1:000000000000
70 Y -1:000000000000
71 $ hg bookmarks -l
71 $ hg bookmarks -l
72 X 0:f7b1eb17ad24
72 X 0:f7b1eb17ad24
73 * X2 0:f7b1eb17ad24
73 * X2 0:f7b1eb17ad24
74 Y -1:000000000000
74 Y -1:000000000000
75 $ hg bookmarks -l X Y
75 $ hg bookmarks -l X Y
76 X 0:f7b1eb17ad24
76 X 0:f7b1eb17ad24
77 Y -1:000000000000
77 Y -1:000000000000
78 $ hg bookmarks -l .
78 $ hg bookmarks -l .
79 * X2 0:f7b1eb17ad24
79 * X2 0:f7b1eb17ad24
80 $ hg bookmarks -l X A Y
80 $ hg bookmarks -l X A Y
81 abort: bookmark 'A' does not exist
81 abort: bookmark 'A' does not exist
82 [255]
82 [255]
83 $ hg bookmarks -l -r0
83 $ hg bookmarks -l -r0
84 abort: --rev is incompatible with --list
84 abort: --rev is incompatible with --list
85 [255]
85 [255]
86 $ hg bookmarks -l --inactive
86 $ hg bookmarks -l --inactive
87 abort: --inactive is incompatible with --list
87 abort: --inactive is incompatible with --list
88 [255]
88 [255]
89
89
90 $ hg log -T '{bookmarks % "{rev} {bookmark}\n"}'
90 $ hg log -T '{bookmarks % "{rev} {bookmark}\n"}'
91 0 X
91 0 X
92 0 X2
92 0 X2
93
93
94 $ echo b > b
94 $ echo b > b
95 $ hg add b
95 $ hg add b
96 $ hg commit -m 1 --config "$TESTHOOK"
96 $ hg commit -m 1 --config "$TESTHOOK"
97 test-hook-bookmark: X2: f7b1eb17ad24730a1651fccd46c43826d1bbc2ac -> 925d80f479bb026b0fb3deb27503780b13f74123
97 test-hook-bookmark: X2: f7b1eb17ad24730a1651fccd46c43826d1bbc2ac -> 925d80f479bb026b0fb3deb27503780b13f74123
98
98
99 $ hg bookmarks -T '{rev}:{node|shortest} {bookmark} {desc|firstline}\n'
99 $ hg bookmarks -T '{rev}:{node|shortest} {bookmark} {desc|firstline}\n'
100 0:f7b1 X 0
100 0:f7b1 X 0
101 1:925d X2 1
101 1:925d X2 1
102 -1:0000 Y
102 -1:0000 Y
103
103
104 $ hg bookmarks -Tjson
104 $ hg bookmarks -Tjson
105 [
105 [
106 {
106 {
107 "active": false,
107 "active": false,
108 "bookmark": "X",
108 "bookmark": "X",
109 "node": "f7b1eb17ad24730a1651fccd46c43826d1bbc2ac",
109 "node": "f7b1eb17ad24730a1651fccd46c43826d1bbc2ac",
110 "rev": 0
110 "rev": 0
111 },
111 },
112 {
112 {
113 "active": true,
113 "active": true,
114 "bookmark": "X2",
114 "bookmark": "X2",
115 "node": "925d80f479bb026b0fb3deb27503780b13f74123",
115 "node": "925d80f479bb026b0fb3deb27503780b13f74123",
116 "rev": 1
116 "rev": 1
117 },
117 },
118 {
118 {
119 "active": false,
119 "active": false,
120 "bookmark": "Y",
120 "bookmark": "Y",
121 "node": "0000000000000000000000000000000000000000",
121 "node": "0000000000000000000000000000000000000000",
122 "rev": -1
122 "rev": -1
123 }
123 }
124 ]
124 ]
125
125
126 bookmarks revset
126 bookmarks revset
127
127
128 $ hg log -r 'bookmark()'
128 $ hg log -r 'bookmark()'
129 changeset: 0:f7b1eb17ad24
129 changeset: 0:f7b1eb17ad24
130 bookmark: X
130 bookmark: X
131 user: test
131 user: test
132 date: Thu Jan 01 00:00:00 1970 +0000
132 date: Thu Jan 01 00:00:00 1970 +0000
133 summary: 0
133 summary: 0
134
134
135 changeset: 1:925d80f479bb
135 changeset: 1:925d80f479bb
136 bookmark: X2
136 bookmark: X2
137 tag: tip
137 tag: tip
138 user: test
138 user: test
139 date: Thu Jan 01 00:00:00 1970 +0000
139 date: Thu Jan 01 00:00:00 1970 +0000
140 summary: 1
140 summary: 1
141
141
142 $ hg log -r 'bookmark(Y)'
142 $ hg log -r 'bookmark(Y)'
143 $ hg log -r 'bookmark(X2)'
143 $ hg log -r 'bookmark(X2)'
144 changeset: 1:925d80f479bb
144 changeset: 1:925d80f479bb
145 bookmark: X2
145 bookmark: X2
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: 1
149 summary: 1
150
150
151 $ hg log -r 'bookmark("re:X")'
151 $ hg log -r 'bookmark("re:X")'
152 changeset: 0:f7b1eb17ad24
152 changeset: 0:f7b1eb17ad24
153 bookmark: X
153 bookmark: X
154 user: test
154 user: test
155 date: Thu Jan 01 00:00:00 1970 +0000
155 date: Thu Jan 01 00:00:00 1970 +0000
156 summary: 0
156 summary: 0
157
157
158 changeset: 1:925d80f479bb
158 changeset: 1:925d80f479bb
159 bookmark: X2
159 bookmark: X2
160 tag: tip
160 tag: tip
161 user: test
161 user: test
162 date: Thu Jan 01 00:00:00 1970 +0000
162 date: Thu Jan 01 00:00:00 1970 +0000
163 summary: 1
163 summary: 1
164
164
165 $ hg log -r 'bookmark("literal:X")'
165 $ hg log -r 'bookmark("literal:X")'
166 changeset: 0:f7b1eb17ad24
166 changeset: 0:f7b1eb17ad24
167 bookmark: X
167 bookmark: X
168 user: test
168 user: test
169 date: Thu Jan 01 00:00:00 1970 +0000
169 date: Thu Jan 01 00:00:00 1970 +0000
170 summary: 0
170 summary: 0
171
171
172
172
173 "." is expanded to the active bookmark:
173 "." is expanded to the active bookmark:
174
174
175 $ hg log -r 'bookmark(.)'
175 $ hg log -r 'bookmark(.)'
176 changeset: 1:925d80f479bb
176 changeset: 1:925d80f479bb
177 bookmark: X2
177 bookmark: X2
178 tag: tip
178 tag: tip
179 user: test
179 user: test
180 date: Thu Jan 01 00:00:00 1970 +0000
180 date: Thu Jan 01 00:00:00 1970 +0000
181 summary: 1
181 summary: 1
182
182
183
183
184 but "literal:." is not since "." seems not a literal bookmark:
184 but "literal:." is not since "." seems not a literal bookmark:
185
185
186 $ hg log -r 'bookmark("literal:.")'
186 $ hg log -r 'bookmark("literal:.")'
187 abort: bookmark '.' does not exist!
187 abort: bookmark '.' does not exist!
188 [255]
188 [255]
189
189
190 "." should fail if there's no active bookmark:
190 "." should fail if there's no active bookmark:
191
191
192 $ hg bookmark --inactive
192 $ hg bookmark --inactive
193 $ hg log -r 'bookmark(.)'
193 $ hg log -r 'bookmark(.)'
194 abort: no active bookmark!
194 abort: no active bookmark!
195 [255]
195 [255]
196 $ hg log -r 'present(bookmark(.))'
196 $ hg log -r 'present(bookmark(.))'
197
197
198 $ hg log -r 'bookmark(unknown)'
198 $ hg log -r 'bookmark(unknown)'
199 abort: bookmark 'unknown' does not exist!
199 abort: bookmark 'unknown' does not exist!
200 [255]
200 [255]
201 $ hg log -r 'bookmark("literal:unknown")'
201 $ hg log -r 'bookmark("literal:unknown")'
202 abort: bookmark 'unknown' does not exist!
202 abort: bookmark 'unknown' does not exist!
203 [255]
203 [255]
204 $ hg log -r 'bookmark("re:unknown")'
204 $ hg log -r 'bookmark("re:unknown")'
205 $ hg log -r 'present(bookmark("literal:unknown"))'
205 $ hg log -r 'present(bookmark("literal:unknown"))'
206 $ hg log -r 'present(bookmark("re:unknown"))'
206 $ hg log -r 'present(bookmark("re:unknown"))'
207
207
208 $ hg help revsets | grep 'bookmark('
208 $ hg help revsets | grep 'bookmark('
209 "bookmark([name])"
209 "bookmark([name])"
210
210
211 reactivate "X2"
211 reactivate "X2"
212
212
213 $ hg update X2
213 $ hg update X2
214 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
214 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
215 (activating bookmark X2)
215 (activating bookmark X2)
216
216
217 bookmarks X and X2 moved to rev 1, Y at rev -1
217 bookmarks X and X2 moved to rev 1, Y at rev -1
218
218
219 $ hg bookmarks
219 $ hg bookmarks
220 X 0:f7b1eb17ad24
220 X 0:f7b1eb17ad24
221 * X2 1:925d80f479bb
221 * X2 1:925d80f479bb
222 Y -1:000000000000
222 Y -1:000000000000
223
223
224 bookmark rev 0 again
224 bookmark rev 0 again
225
225
226 $ hg bookmark -r 0 Z
226 $ hg bookmark -r 0 Z
227
227
228 $ hg update X
228 $ hg update X
229 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
229 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
230 (activating bookmark X)
230 (activating bookmark X)
231 $ echo c > c
231 $ echo c > c
232 $ hg add c
232 $ hg add c
233 $ hg commit -m 2
233 $ hg commit -m 2
234 created new head
234 created new head
235
235
236 bookmarks X moved to rev 2, Y at rev -1, Z at rev 0
236 bookmarks X moved to rev 2, Y at rev -1, Z at rev 0
237
237
238 $ hg bookmarks
238 $ hg bookmarks
239 * X 2:db815d6d32e6
239 * X 2:db815d6d32e6
240 X2 1:925d80f479bb
240 X2 1:925d80f479bb
241 Y -1:000000000000
241 Y -1:000000000000
242 Z 0:f7b1eb17ad24
242 Z 0:f7b1eb17ad24
243
243
244 rename nonexistent bookmark
244 rename nonexistent bookmark
245
245
246 $ hg bookmark -m A B
246 $ hg bookmark -m A B
247 abort: bookmark 'A' does not exist
247 abort: bookmark 'A' does not exist
248 [255]
248 [255]
249
249
250 rename to existent bookmark
250 rename to existent bookmark
251
251
252 $ hg bookmark -m X Y
252 $ hg bookmark -m X Y
253 abort: bookmark 'Y' already exists (use -f to force)
253 abort: bookmark 'Y' already exists (use -f to force)
254 [255]
254 [255]
255
255
256 force rename to existent bookmark
256 force rename to existent bookmark
257
257
258 $ hg bookmark -f -m X Y
258 $ hg bookmark -f -m X Y
259
259
260 rename bookmark using .
260 rename bookmark using .
261
261
262 $ hg book rename-me
262 $ hg book rename-me
263 $ hg book -m . renamed --config "$TESTHOOK"
263 $ hg book -m . renamed --config "$TESTHOOK"
264 test-hook-bookmark: rename-me: db815d6d32e69058eadefc8cffbad37675707975 ->
264 test-hook-bookmark: rename-me: db815d6d32e69058eadefc8cffbad37675707975 ->
265 test-hook-bookmark: renamed: -> db815d6d32e69058eadefc8cffbad37675707975
265 test-hook-bookmark: renamed: -> db815d6d32e69058eadefc8cffbad37675707975
266 $ hg bookmark
266 $ hg bookmark
267 X2 1:925d80f479bb
267 X2 1:925d80f479bb
268 Y 2:db815d6d32e6
268 Y 2:db815d6d32e6
269 Z 0:f7b1eb17ad24
269 Z 0:f7b1eb17ad24
270 * renamed 2:db815d6d32e6
270 * renamed 2:db815d6d32e6
271 $ hg up -q Y
271 $ hg up -q Y
272 $ hg book -d renamed --config "$TESTHOOK"
272 $ hg book -d renamed --config "$TESTHOOK"
273 test-hook-bookmark: renamed: db815d6d32e69058eadefc8cffbad37675707975 ->
273 test-hook-bookmark: renamed: db815d6d32e69058eadefc8cffbad37675707975 ->
274
274
275 rename bookmark using . with no active bookmark
275 rename bookmark using . with no active bookmark
276
276
277 $ hg book rename-me
277 $ hg book rename-me
278 $ hg book -i rename-me
278 $ hg book -i rename-me
279 $ hg book -m . renamed
279 $ hg book -m . renamed
280 abort: no active bookmark!
280 abort: no active bookmark!
281 [255]
281 [255]
282 $ hg up -q Y
282 $ hg up -q Y
283 $ hg book -d rename-me
283 $ hg book -d rename-me
284
284
285 delete bookmark using .
285 delete bookmark using .
286
286
287 $ hg book delete-me
287 $ hg book delete-me
288 $ hg book -d .
288 $ hg book -d .
289 $ hg bookmark
289 $ hg bookmark
290 X2 1:925d80f479bb
290 X2 1:925d80f479bb
291 Y 2:db815d6d32e6
291 Y 2:db815d6d32e6
292 Z 0:f7b1eb17ad24
292 Z 0:f7b1eb17ad24
293 $ hg up -q Y
293 $ hg up -q Y
294
294
295 delete bookmark using . with no active bookmark
295 delete bookmark using . with no active bookmark
296
296
297 $ hg book delete-me
297 $ hg book delete-me
298 $ hg book -i delete-me
298 $ hg book -i delete-me
299 $ hg book -d .
299 $ hg book -d .
300 abort: no active bookmark!
300 abort: no active bookmark!
301 [255]
301 [255]
302 $ hg up -q Y
302 $ hg up -q Y
303 $ hg book -d delete-me
303 $ hg book -d delete-me
304
304
305 list bookmarks
305 list bookmarks
306
306
307 $ hg bookmark
307 $ hg bookmark
308 X2 1:925d80f479bb
308 X2 1:925d80f479bb
309 * Y 2:db815d6d32e6
309 * Y 2:db815d6d32e6
310 Z 0:f7b1eb17ad24
310 Z 0:f7b1eb17ad24
311
311
312 bookmarks from a revset
312 bookmarks from a revset
313 $ hg bookmark -r '.^1' REVSET
313 $ hg bookmark -r '.^1' REVSET
314 $ hg bookmark -r ':tip' TIP
314 $ hg bookmark -r ':tip' TIP
315 $ hg up -q TIP
315 $ hg up -q TIP
316 $ hg bookmarks
316 $ hg bookmarks
317 REVSET 0:f7b1eb17ad24
317 REVSET 0:f7b1eb17ad24
318 * TIP 2:db815d6d32e6
318 * TIP 2:db815d6d32e6
319 X2 1:925d80f479bb
319 X2 1:925d80f479bb
320 Y 2:db815d6d32e6
320 Y 2:db815d6d32e6
321 Z 0:f7b1eb17ad24
321 Z 0:f7b1eb17ad24
322
322
323 $ hg bookmark -d REVSET
323 $ hg bookmark -d REVSET
324 $ hg bookmark -d TIP
324 $ hg bookmark -d TIP
325
325
326 rename without new name or multiple names
326 rename without new name or multiple names
327
327
328 $ hg bookmark -m Y
328 $ hg bookmark -m Y
329 abort: new bookmark name required
329 abort: new bookmark name required
330 [255]
330 [255]
331 $ hg bookmark -m Y Y2 Y3
331 $ hg bookmark -m Y Y2 Y3
332 abort: only one new bookmark name allowed
332 abort: only one new bookmark name allowed
333 [255]
333 [255]
334
334
335 delete without name
335 delete without name
336
336
337 $ hg bookmark -d
337 $ hg bookmark -d
338 abort: bookmark name required
338 abort: bookmark name required
339 [255]
339 [255]
340
340
341 delete nonexistent bookmark
341 delete nonexistent bookmark
342
342
343 $ hg bookmark -d A
343 $ hg bookmark -d A
344 abort: bookmark 'A' does not exist
344 abort: bookmark 'A' does not exist
345 [255]
345 [255]
346
346
347 delete with --inactive
347 delete with --inactive
348
348
349 $ hg bookmark -d --inactive Y
349 $ hg bookmark -d --inactive Y
350 abort: --inactive is incompatible with --delete
350 abort: --inactive is incompatible with --delete
351 [255]
351 [255]
352
352
353 bookmark name with spaces should be stripped
353 bookmark name with spaces should be stripped
354
354
355 $ hg bookmark ' x y '
355 $ hg bookmark ' x y '
356
356
357 list bookmarks
357 list bookmarks
358
358
359 $ hg bookmarks
359 $ hg bookmarks
360 X2 1:925d80f479bb
360 X2 1:925d80f479bb
361 Y 2:db815d6d32e6
361 Y 2:db815d6d32e6
362 Z 0:f7b1eb17ad24
362 Z 0:f7b1eb17ad24
363 * x y 2:db815d6d32e6
363 * x y 2:db815d6d32e6
364 $ hg log -T '{bookmarks % "{rev} {bookmark}\n"}'
364 $ hg log -T '{bookmarks % "{rev} {bookmark}\n"}'
365 2 Y
365 2 Y
366 2 x y
366 2 x y
367 1 X2
367 1 X2
368 0 Z
368 0 Z
369
369
370 look up stripped bookmark name
370 look up stripped bookmark name
371
371
372 $ hg log -r '"x y"'
372 $ hg log -r '"x y"'
373 changeset: 2:db815d6d32e6
373 changeset: 2:db815d6d32e6
374 bookmark: Y
374 bookmark: Y
375 bookmark: x y
375 bookmark: x y
376 tag: tip
376 tag: tip
377 parent: 0:f7b1eb17ad24
377 parent: 0:f7b1eb17ad24
378 user: test
378 user: test
379 date: Thu Jan 01 00:00:00 1970 +0000
379 date: Thu Jan 01 00:00:00 1970 +0000
380 summary: 2
380 summary: 2
381
381
382
382
383 reject bookmark name with newline
383 reject bookmark name with newline
384
384
385 $ hg bookmark '
385 $ hg bookmark '
386 > '
386 > '
387 abort: bookmark names cannot consist entirely of whitespace
387 abort: bookmark names cannot consist entirely of whitespace
388 [255]
388 [255]
389
389
390 $ hg bookmark -m Z '
390 $ hg bookmark -m Z '
391 > '
391 > '
392 abort: bookmark names cannot consist entirely of whitespace
392 abort: bookmark names cannot consist entirely of whitespace
393 [255]
393 [255]
394
394
395 bookmark with reserved name
395 bookmark with reserved name
396
396
397 $ hg bookmark tip
397 $ hg bookmark tip
398 abort: the name 'tip' is reserved
398 abort: the name 'tip' is reserved
399 [255]
399 [255]
400
400
401 $ hg bookmark .
401 $ hg bookmark .
402 abort: the name '.' is reserved
402 abort: the name '.' is reserved
403 [255]
403 [255]
404
404
405 $ hg bookmark null
405 $ hg bookmark null
406 abort: the name 'null' is reserved
406 abort: the name 'null' is reserved
407 [255]
407 [255]
408
408
409
409
410 bookmark with existing name
410 bookmark with existing name
411
411
412 $ hg bookmark X2
412 $ hg bookmark X2
413 abort: bookmark 'X2' already exists (use -f to force)
413 abort: bookmark 'X2' already exists (use -f to force)
414 [255]
414 [255]
415
415
416 $ hg bookmark -m Y Z
416 $ hg bookmark -m Y Z
417 abort: bookmark 'Z' already exists (use -f to force)
417 abort: bookmark 'Z' already exists (use -f to force)
418 [255]
418 [255]
419
419
420 bookmark with name of branch
420 bookmark with name of branch
421
421
422 $ hg bookmark default
422 $ hg bookmark default
423 abort: a bookmark cannot have the name of an existing branch
423 abort: a bookmark cannot have the name of an existing branch
424 [255]
424 [255]
425
425
426 $ hg bookmark -m Y default
426 $ hg bookmark -m Y default
427 abort: a bookmark cannot have the name of an existing branch
427 abort: a bookmark cannot have the name of an existing branch
428 [255]
428 [255]
429
429
430 bookmark with integer name
430 bookmark with integer name
431
431
432 $ hg bookmark 10
432 $ hg bookmark 10
433 abort: cannot use an integer as a name
433 abort: cannot use an integer as a name
434 [255]
434 [255]
435
435
436 bookmark with a name that matches a node id
436 bookmark with a name that matches a node id
437 $ hg bookmark 925d80f479bb db815d6d32e6 --config "$TESTHOOK"
437 $ hg bookmark 925d80f479bb db815d6d32e6 --config "$TESTHOOK"
438 bookmark 925d80f479bb matches a changeset hash
438 bookmark 925d80f479bb matches a changeset hash
439 (did you leave a -r out of an 'hg bookmark' command?)
439 (did you leave a -r out of an 'hg bookmark' command?)
440 bookmark db815d6d32e6 matches a changeset hash
440 bookmark db815d6d32e6 matches a changeset hash
441 (did you leave a -r out of an 'hg bookmark' command?)
441 (did you leave a -r out of an 'hg bookmark' command?)
442 test-hook-bookmark: 925d80f479bb: -> db815d6d32e69058eadefc8cffbad37675707975
442 test-hook-bookmark: 925d80f479bb: -> db815d6d32e69058eadefc8cffbad37675707975
443 test-hook-bookmark: db815d6d32e6: -> db815d6d32e69058eadefc8cffbad37675707975
443 test-hook-bookmark: db815d6d32e6: -> db815d6d32e69058eadefc8cffbad37675707975
444 $ hg bookmark -d 925d80f479bb
444 $ hg bookmark -d 925d80f479bb
445 $ hg bookmark -d db815d6d32e6
445 $ hg bookmark -d db815d6d32e6
446
446
447 $ cd ..
447 $ cd ..
448
448
449 bookmark with a name that matches an ambiguous node id
449 bookmark with a name that matches an ambiguous node id
450
450
451 $ hg init ambiguous
451 $ hg init ambiguous
452 $ cd ambiguous
452 $ cd ambiguous
453 $ echo 0 > a
453 $ echo 0 > a
454 $ hg ci -qAm 0
454 $ hg ci -qAm 0
455 $ for i in 1057 2857 4025; do
455 $ for i in 1057 2857 4025; do
456 > hg up -q 0
456 > hg up -q 0
457 > echo $i > a
457 > echo $i > a
458 > hg ci -qm $i
458 > hg ci -qm $i
459 > done
459 > done
460 $ hg up -q null
460 $ hg up -q null
461 $ hg log -r0: -T '{rev}:{node}\n'
461 $ hg log -r0: -T '{rev}:{node}\n'
462 0:b4e73ffab476aa0ee32ed81ca51e07169844bc6a
462 0:b4e73ffab476aa0ee32ed81ca51e07169844bc6a
463 1:c56256a09cd28e5764f32e8e2810d0f01e2e357a
463 1:c56256a09cd28e5764f32e8e2810d0f01e2e357a
464 2:c5623987d205cd6d9d8389bfc40fff9dbb670b48
464 2:c5623987d205cd6d9d8389bfc40fff9dbb670b48
465 3:c562ddd9c94164376c20b86b0b4991636a3bf84f
465 3:c562ddd9c94164376c20b86b0b4991636a3bf84f
466
466
467 $ hg bookmark -r0 c562
467 $ hg bookmark -r0 c562
468 $ hg bookmarks
468 $ hg bookmarks
469 c562 0:b4e73ffab476
469 c562 0:b4e73ffab476
470
470
471 $ cd ..
471 $ cd ..
472
472
473 incompatible options
473 incompatible options
474
474
475 $ cd repo
475 $ cd repo
476
476
477 $ hg bookmark -m Y -d Z
477 $ hg bookmark -m Y -d Z
478 abort: --delete and --rename are incompatible
478 abort: --delete and --rename are incompatible
479 [255]
479 [255]
480
480
481 $ hg bookmark -r 1 -d Z
481 $ hg bookmark -r 1 -d Z
482 abort: --rev is incompatible with --delete
482 abort: --rev is incompatible with --delete
483 [255]
483 [255]
484
484
485 $ hg bookmark -r 1 -m Z Y
485 $ hg bookmark -r 1 -m Z Y
486 abort: --rev is incompatible with --rename
486 abort: --rev is incompatible with --rename
487 [255]
487 [255]
488
488
489 force bookmark with existing name
489 force bookmark with existing name
490
490
491 $ hg bookmark -f X2 --config "$TESTHOOK"
491 $ hg bookmark -f X2 --config "$TESTHOOK"
492 test-hook-bookmark: X2: 925d80f479bb026b0fb3deb27503780b13f74123 -> db815d6d32e69058eadefc8cffbad37675707975
492 test-hook-bookmark: X2: 925d80f479bb026b0fb3deb27503780b13f74123 -> db815d6d32e69058eadefc8cffbad37675707975
493
493
494 force bookmark back to where it was, should deactivate it
494 force bookmark back to where it was, should deactivate it
495
495
496 $ hg bookmark -fr1 X2
496 $ hg bookmark -fr1 X2
497 $ hg bookmarks
497 $ hg bookmarks
498 X2 1:925d80f479bb
498 X2 1:925d80f479bb
499 Y 2:db815d6d32e6
499 Y 2:db815d6d32e6
500 Z 0:f7b1eb17ad24
500 Z 0:f7b1eb17ad24
501 x y 2:db815d6d32e6
501 x y 2:db815d6d32e6
502
502
503 forward bookmark to descendant without --force
503 forward bookmark to descendant without --force
504
504
505 $ hg bookmark Z
505 $ hg bookmark Z
506 moving bookmark 'Z' forward from f7b1eb17ad24
506 moving bookmark 'Z' forward from f7b1eb17ad24
507
507
508 list bookmarks
508 list bookmarks
509
509
510 $ hg bookmark
510 $ hg bookmark
511 X2 1:925d80f479bb
511 X2 1:925d80f479bb
512 Y 2:db815d6d32e6
512 Y 2:db815d6d32e6
513 * Z 2:db815d6d32e6
513 * Z 2:db815d6d32e6
514 x y 2:db815d6d32e6
514 x y 2:db815d6d32e6
515 $ hg log -T '{bookmarks % "{rev} {bookmark}\n"}'
515 $ hg log -T '{bookmarks % "{rev} {bookmark}\n"}'
516 2 Y
516 2 Y
517 2 Z
517 2 Z
518 2 x y
518 2 x y
519 1 X2
519 1 X2
520
520
521 revision but no bookmark name
521 revision but no bookmark name
522
522
523 $ hg bookmark -r .
523 $ hg bookmark -r .
524 abort: bookmark name required
524 abort: bookmark name required
525 [255]
525 [255]
526
526
527 bookmark name with whitespace only
527 bookmark name with whitespace only
528
528
529 $ hg bookmark ' '
529 $ hg bookmark ' '
530 abort: bookmark names cannot consist entirely of whitespace
530 abort: bookmark names cannot consist entirely of whitespace
531 [255]
531 [255]
532
532
533 $ hg bookmark -m Y ' '
533 $ hg bookmark -m Y ' '
534 abort: bookmark names cannot consist entirely of whitespace
534 abort: bookmark names cannot consist entirely of whitespace
535 [255]
535 [255]
536
536
537 invalid bookmark
537 invalid bookmark
538
538
539 $ hg bookmark 'foo:bar'
539 $ hg bookmark 'foo:bar'
540 abort: ':' cannot be used in a name
540 abort: ':' cannot be used in a name
541 [255]
541 [255]
542
542
543 $ hg bookmark 'foo
543 $ hg bookmark 'foo
544 > bar'
544 > bar'
545 abort: '\n' cannot be used in a name
545 abort: '\n' cannot be used in a name
546 [255]
546 [255]
547
547
548 the bookmark extension should be ignored now that it is part of core
548 the bookmark extension should be ignored now that it is part of core
549
549
550 $ echo "[extensions]" >> $HGRCPATH
550 $ echo "[extensions]" >> $HGRCPATH
551 $ echo "bookmarks=" >> $HGRCPATH
551 $ echo "bookmarks=" >> $HGRCPATH
552 $ hg bookmarks
552 $ hg bookmarks
553 X2 1:925d80f479bb
553 X2 1:925d80f479bb
554 Y 2:db815d6d32e6
554 Y 2:db815d6d32e6
555 * Z 2:db815d6d32e6
555 * Z 2:db815d6d32e6
556 x y 2:db815d6d32e6
556 x y 2:db815d6d32e6
557
557
558 test summary
558 test summary
559
559
560 $ hg summary
560 $ hg summary
561 parent: 2:db815d6d32e6 tip
561 parent: 2:db815d6d32e6 tip
562 2
562 2
563 branch: default
563 branch: default
564 bookmarks: *Z Y x y
564 bookmarks: *Z Y x y
565 commit: (clean)
565 commit: (clean)
566 update: 1 new changesets, 2 branch heads (merge)
566 update: 1 new changesets, 2 branch heads (merge)
567 phases: 3 draft
567 phases: 3 draft
568
568
569 test id
569 test id
570
570
571 $ hg id
571 $ hg id
572 db815d6d32e6 tip Y/Z/x y
572 db815d6d32e6 tip Y/Z/x y
573
573
574 test rollback
574 test rollback
575
575
576 $ echo foo > f1
576 $ echo foo > f1
577 $ hg bookmark tmp-rollback
577 $ hg bookmark tmp-rollback
578 $ hg ci -Amr
578 $ hg ci -Amr
579 adding f1
579 adding f1
580 $ hg bookmarks
580 $ hg bookmarks
581 X2 1:925d80f479bb
581 X2 1:925d80f479bb
582 Y 2:db815d6d32e6
582 Y 2:db815d6d32e6
583 Z 2:db815d6d32e6
583 Z 2:db815d6d32e6
584 * tmp-rollback 3:2bf5cfec5864
584 * tmp-rollback 3:2bf5cfec5864
585 x y 2:db815d6d32e6
585 x y 2:db815d6d32e6
586 $ hg rollback
586 $ hg rollback
587 repository tip rolled back to revision 2 (undo commit)
587 repository tip rolled back to revision 2 (undo commit)
588 working directory now based on revision 2
588 working directory now based on revision 2
589 $ hg bookmarks
589 $ hg bookmarks
590 X2 1:925d80f479bb
590 X2 1:925d80f479bb
591 Y 2:db815d6d32e6
591 Y 2:db815d6d32e6
592 Z 2:db815d6d32e6
592 Z 2:db815d6d32e6
593 * tmp-rollback 2:db815d6d32e6
593 * tmp-rollback 2:db815d6d32e6
594 x y 2:db815d6d32e6
594 x y 2:db815d6d32e6
595 $ hg bookmark -f Z -r 1
595 $ hg bookmark -f Z -r 1
596 $ hg rollback
596 $ hg rollback
597 repository tip rolled back to revision 2 (undo bookmark)
597 repository tip rolled back to revision 2 (undo bookmark)
598 $ hg bookmarks
598 $ hg bookmarks
599 X2 1:925d80f479bb
599 X2 1:925d80f479bb
600 Y 2:db815d6d32e6
600 Y 2:db815d6d32e6
601 Z 2:db815d6d32e6
601 Z 2:db815d6d32e6
602 * tmp-rollback 2:db815d6d32e6
602 * tmp-rollback 2:db815d6d32e6
603 x y 2:db815d6d32e6
603 x y 2:db815d6d32e6
604 $ hg bookmark -d tmp-rollback
604 $ hg bookmark -d tmp-rollback
605
605
606 activate bookmark on working dir parent without --force
606 activate bookmark on working dir parent without --force
607
607
608 $ hg bookmark --inactive Z
608 $ hg bookmark --inactive Z
609 $ hg bookmark Z
609 $ hg bookmark Z
610
610
611 test clone
611 test clone
612
612
613 $ hg bookmark -r 2 -i @
613 $ hg bookmark -r 2 -i @
614 $ hg bookmark -r 2 -i a@
614 $ hg bookmark -r 2 -i a@
615 $ hg bookmarks
615 $ hg bookmarks
616 @ 2:db815d6d32e6
616 @ 2:db815d6d32e6
617 X2 1:925d80f479bb
617 X2 1:925d80f479bb
618 Y 2:db815d6d32e6
618 Y 2:db815d6d32e6
619 * Z 2:db815d6d32e6
619 * Z 2:db815d6d32e6
620 a@ 2:db815d6d32e6
620 a@ 2:db815d6d32e6
621 x y 2:db815d6d32e6
621 x y 2:db815d6d32e6
622 $ hg clone . cloned-bookmarks
622 $ hg clone . cloned-bookmarks
623 updating to bookmark @
623 updating to bookmark @
624 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
624 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
625 $ hg -R cloned-bookmarks bookmarks
625 $ hg -R cloned-bookmarks bookmarks
626 * @ 2:db815d6d32e6
626 * @ 2:db815d6d32e6
627 X2 1:925d80f479bb
627 X2 1:925d80f479bb
628 Y 2:db815d6d32e6
628 Y 2:db815d6d32e6
629 Z 2:db815d6d32e6
629 Z 2:db815d6d32e6
630 a@ 2:db815d6d32e6
630 a@ 2:db815d6d32e6
631 x y 2:db815d6d32e6
631 x y 2:db815d6d32e6
632
632
633 test clone with pull protocol
633 test clone with pull protocol
634
634
635 $ hg clone --pull . cloned-bookmarks-pull
635 $ hg clone --pull . cloned-bookmarks-pull
636 requesting all changes
636 requesting all changes
637 adding changesets
637 adding changesets
638 adding manifests
638 adding manifests
639 adding file changes
639 adding file changes
640 added 3 changesets with 3 changes to 3 files (+1 heads)
640 added 3 changesets with 3 changes to 3 files (+1 heads)
641 new changesets f7b1eb17ad24:db815d6d32e6
641 new changesets f7b1eb17ad24:db815d6d32e6
642 updating to bookmark @
642 updating to bookmark @
643 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
643 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
644 $ hg -R cloned-bookmarks-pull bookmarks
644 $ hg -R cloned-bookmarks-pull bookmarks
645 * @ 2:db815d6d32e6
645 * @ 2:db815d6d32e6
646 X2 1:925d80f479bb
646 X2 1:925d80f479bb
647 Y 2:db815d6d32e6
647 Y 2:db815d6d32e6
648 Z 2:db815d6d32e6
648 Z 2:db815d6d32e6
649 a@ 2:db815d6d32e6
649 a@ 2:db815d6d32e6
650 x y 2:db815d6d32e6
650 x y 2:db815d6d32e6
651
651
652 delete multiple bookmarks at once
652 delete multiple bookmarks at once
653
653
654 $ hg bookmark -d @ a@
654 $ hg bookmark -d @ a@
655
655
656 test clone with a bookmark named "default" (issue3677)
656 test clone with a bookmark named "default" (issue3677)
657
657
658 $ hg bookmark -r 1 -f -i default
658 $ hg bookmark -r 1 -f -i default
659 $ hg clone . cloned-bookmark-default
659 $ hg clone . cloned-bookmark-default
660 updating to branch default
660 updating to branch default
661 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
661 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
662 $ hg -R cloned-bookmark-default bookmarks
662 $ hg -R cloned-bookmark-default bookmarks
663 X2 1:925d80f479bb
663 X2 1:925d80f479bb
664 Y 2:db815d6d32e6
664 Y 2:db815d6d32e6
665 Z 2:db815d6d32e6
665 Z 2:db815d6d32e6
666 default 1:925d80f479bb
666 default 1:925d80f479bb
667 x y 2:db815d6d32e6
667 x y 2:db815d6d32e6
668 $ hg -R cloned-bookmark-default parents -q
668 $ hg -R cloned-bookmark-default parents -q
669 2:db815d6d32e6
669 2:db815d6d32e6
670 $ hg bookmark -d default
670 $ hg bookmark -d default
671
671
672 test clone with a specific revision
672 test clone with a specific revision
673
673
674 $ hg clone -r 925d80 . cloned-bookmarks-rev
674 $ hg clone -r 925d80 . cloned-bookmarks-rev
675 adding changesets
675 adding changesets
676 adding manifests
676 adding manifests
677 adding file changes
677 adding file changes
678 added 2 changesets with 2 changes to 2 files
678 added 2 changesets with 2 changes to 2 files
679 new changesets f7b1eb17ad24:925d80f479bb
679 new changesets f7b1eb17ad24:925d80f479bb
680 updating to branch default
680 updating to branch default
681 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
681 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
682 $ hg -R cloned-bookmarks-rev bookmarks
682 $ hg -R cloned-bookmarks-rev bookmarks
683 X2 1:925d80f479bb
683 X2 1:925d80f479bb
684
684
685 test clone with update to a bookmark
685 test clone with update to a bookmark
686
686
687 $ hg clone -u Z . ../cloned-bookmarks-update
687 $ hg clone -u Z . ../cloned-bookmarks-update
688 updating to branch default
688 updating to branch default
689 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
689 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
690 $ hg -R ../cloned-bookmarks-update bookmarks
690 $ hg -R ../cloned-bookmarks-update bookmarks
691 X2 1:925d80f479bb
691 X2 1:925d80f479bb
692 Y 2:db815d6d32e6
692 Y 2:db815d6d32e6
693 * Z 2:db815d6d32e6
693 * Z 2:db815d6d32e6
694 x y 2:db815d6d32e6
694 x y 2:db815d6d32e6
695
695
696 create bundle with two heads
696 create bundle with two heads
697
697
698 $ hg clone . tobundle
698 $ hg clone . tobundle
699 updating to branch default
699 updating to branch default
700 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
700 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
701 $ echo x > tobundle/x
701 $ echo x > tobundle/x
702 $ hg -R tobundle add tobundle/x
702 $ hg -R tobundle add tobundle/x
703 $ hg -R tobundle commit -m'x'
703 $ hg -R tobundle commit -m'x'
704 $ hg -R tobundle update -r -2
704 $ hg -R tobundle update -r -2
705 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
705 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
706 $ echo y > tobundle/y
706 $ echo y > tobundle/y
707 $ hg -R tobundle branch test
707 $ hg -R tobundle branch test
708 marked working directory as branch test
708 marked working directory as branch test
709 (branches are permanent and global, did you want a bookmark?)
709 (branches are permanent and global, did you want a bookmark?)
710 $ hg -R tobundle add tobundle/y
710 $ hg -R tobundle add tobundle/y
711 $ hg -R tobundle commit -m'y'
711 $ hg -R tobundle commit -m'y'
712 $ hg -R tobundle bundle tobundle.hg
712 $ hg -R tobundle bundle tobundle.hg
713 searching for changes
713 searching for changes
714 2 changesets found
714 2 changesets found
715 $ hg unbundle tobundle.hg
715 $ hg unbundle tobundle.hg
716 adding changesets
716 adding changesets
717 adding manifests
717 adding manifests
718 adding file changes
718 adding file changes
719 added 2 changesets with 2 changes to 2 files (+1 heads)
719 added 2 changesets with 2 changes to 2 files (+1 heads)
720 new changesets 125c9a1d6df6:9ba5f110a0b3 (2 drafts)
720 new changesets 125c9a1d6df6:9ba5f110a0b3 (2 drafts)
721 (run 'hg heads' to see heads, 'hg merge' to merge)
721 (run 'hg heads' to see heads, 'hg merge' to merge)
722
722
723 update to active bookmark if it's not the parent
723 update to active bookmark if it's not the parent
724
724
725 (it is known issue that fsmonitor can't handle nested repositories. In
725 (it is known issue that fsmonitor can't handle nested repositories. In
726 this test scenario, cloned-bookmark-default and tobundle exist in the
726 this test scenario, cloned-bookmark-default and tobundle exist in the
727 working directory of current repository)
727 working directory of current repository)
728
728
729 $ hg summary
729 $ hg summary
730 parent: 2:db815d6d32e6
730 parent: 2:db815d6d32e6
731 2
731 2
732 branch: default
732 branch: default
733 bookmarks: *Z Y x y
733 bookmarks: *Z Y x y
734 commit: 1 added, 1 unknown (new branch head) (no-fsmonitor !)
734 commit: 1 added, 1 unknown (new branch head) (no-fsmonitor !)
735 commit: 1 added, * unknown (new branch head) (glob) (fsmonitor !)
735 commit: 1 added, * unknown (new branch head) (glob) (fsmonitor !)
736 update: 2 new changesets (update)
736 update: 2 new changesets (update)
737 phases: 5 draft
737 phases: 5 draft
738 $ hg update
738 $ hg update
739 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
739 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
740 updating bookmark Z
740 updating bookmark Z
741 $ hg bookmarks
741 $ hg bookmarks
742 X2 1:925d80f479bb
742 X2 1:925d80f479bb
743 Y 2:db815d6d32e6
743 Y 2:db815d6d32e6
744 * Z 3:125c9a1d6df6
744 * Z 3:125c9a1d6df6
745 x y 2:db815d6d32e6
745 x y 2:db815d6d32e6
746
746
747 pull --update works the same as pull && update
747 pull --update works the same as pull && update
748
748
749 $ hg bookmark -r3 Y
749 $ hg bookmark -r3 Y
750 moving bookmark 'Y' forward from db815d6d32e6
750 moving bookmark 'Y' forward from db815d6d32e6
751 $ cp -R ../cloned-bookmarks-update ../cloned-bookmarks-manual-update
751 $ cp -R ../cloned-bookmarks-update ../cloned-bookmarks-manual-update
752 $ cp -R ../cloned-bookmarks-update ../cloned-bookmarks-manual-update-with-divergence
752 $ cp -R ../cloned-bookmarks-update ../cloned-bookmarks-manual-update-with-divergence
753
753
754 (manual version)
754 (manual version)
755
755
756 $ hg -R ../cloned-bookmarks-manual-update update Y
756 $ hg -R ../cloned-bookmarks-manual-update update Y
757 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
757 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
758 (activating bookmark Y)
758 (activating bookmark Y)
759 $ hg -R ../cloned-bookmarks-manual-update pull .
759 $ hg -R ../cloned-bookmarks-manual-update pull .
760 pulling from .
760 pulling from .
761 searching for changes
761 searching for changes
762 adding changesets
762 adding changesets
763 adding manifests
763 adding manifests
764 adding file changes
764 adding file changes
765 added 2 changesets with 2 changes to 2 files (+1 heads)
766 updating bookmark Y
765 updating bookmark Y
767 updating bookmark Z
766 updating bookmark Z
767 added 2 changesets with 2 changes to 2 files (+1 heads)
768 new changesets 125c9a1d6df6:9ba5f110a0b3
768 new changesets 125c9a1d6df6:9ba5f110a0b3
769 (run 'hg heads' to see heads, 'hg merge' to merge)
769 (run 'hg heads' to see heads, 'hg merge' to merge)
770
770
771 (# tests strange but with --date crashing when bookmark have to move)
771 (# tests strange but with --date crashing when bookmark have to move)
772
772
773 $ hg -R ../cloned-bookmarks-manual-update update -d 1986
773 $ hg -R ../cloned-bookmarks-manual-update update -d 1986
774 abort: revision matching date not found
774 abort: revision matching date not found
775 [255]
775 [255]
776 $ hg -R ../cloned-bookmarks-manual-update update
776 $ hg -R ../cloned-bookmarks-manual-update update
777 updating to active bookmark Y
777 updating to active bookmark Y
778 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
778 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
779
779
780 (all in one version)
780 (all in one version)
781
781
782 $ hg -R ../cloned-bookmarks-update update Y
782 $ hg -R ../cloned-bookmarks-update update Y
783 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
783 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
784 (activating bookmark Y)
784 (activating bookmark Y)
785 $ hg -R ../cloned-bookmarks-update pull --update .
785 $ hg -R ../cloned-bookmarks-update pull --update .
786 pulling from .
786 pulling from .
787 searching for changes
787 searching for changes
788 adding changesets
788 adding changesets
789 adding manifests
789 adding manifests
790 adding file changes
790 adding file changes
791 added 2 changesets with 2 changes to 2 files (+1 heads)
792 updating bookmark Y
791 updating bookmark Y
793 updating bookmark Z
792 updating bookmark Z
793 added 2 changesets with 2 changes to 2 files (+1 heads)
794 new changesets 125c9a1d6df6:9ba5f110a0b3
794 new changesets 125c9a1d6df6:9ba5f110a0b3
795 updating to active bookmark Y
795 updating to active bookmark Y
796 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
796 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
797
797
798 We warn about divergent during bare update to the active bookmark
798 We warn about divergent during bare update to the active bookmark
799
799
800 $ hg -R ../cloned-bookmarks-manual-update-with-divergence update Y
800 $ hg -R ../cloned-bookmarks-manual-update-with-divergence update Y
801 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
801 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
802 (activating bookmark Y)
802 (activating bookmark Y)
803 $ hg -R ../cloned-bookmarks-manual-update-with-divergence bookmarks -r X2 Y@1
803 $ hg -R ../cloned-bookmarks-manual-update-with-divergence bookmarks -r X2 Y@1
804 $ hg -R ../cloned-bookmarks-manual-update-with-divergence bookmarks
804 $ hg -R ../cloned-bookmarks-manual-update-with-divergence bookmarks
805 X2 1:925d80f479bb
805 X2 1:925d80f479bb
806 * Y 2:db815d6d32e6
806 * Y 2:db815d6d32e6
807 Y@1 1:925d80f479bb
807 Y@1 1:925d80f479bb
808 Z 2:db815d6d32e6
808 Z 2:db815d6d32e6
809 x y 2:db815d6d32e6
809 x y 2:db815d6d32e6
810 $ hg -R ../cloned-bookmarks-manual-update-with-divergence pull
810 $ hg -R ../cloned-bookmarks-manual-update-with-divergence pull
811 pulling from $TESTTMP/repo
811 pulling from $TESTTMP/repo
812 searching for changes
812 searching for changes
813 adding changesets
813 adding changesets
814 adding manifests
814 adding manifests
815 adding file changes
815 adding file changes
816 added 2 changesets with 2 changes to 2 files (+1 heads)
817 updating bookmark Y
816 updating bookmark Y
818 updating bookmark Z
817 updating bookmark Z
818 added 2 changesets with 2 changes to 2 files (+1 heads)
819 new changesets 125c9a1d6df6:9ba5f110a0b3
819 new changesets 125c9a1d6df6:9ba5f110a0b3
820 (run 'hg heads' to see heads, 'hg merge' to merge)
820 (run 'hg heads' to see heads, 'hg merge' to merge)
821 $ hg -R ../cloned-bookmarks-manual-update-with-divergence update
821 $ hg -R ../cloned-bookmarks-manual-update-with-divergence update
822 updating to active bookmark Y
822 updating to active bookmark Y
823 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
823 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
824 1 other divergent bookmarks for "Y"
824 1 other divergent bookmarks for "Y"
825
825
826 test wrongly formated bookmark
826 test wrongly formated bookmark
827
827
828 $ echo '' >> .hg/bookmarks
828 $ echo '' >> .hg/bookmarks
829 $ hg bookmarks
829 $ hg bookmarks
830 X2 1:925d80f479bb
830 X2 1:925d80f479bb
831 Y 3:125c9a1d6df6
831 Y 3:125c9a1d6df6
832 * Z 3:125c9a1d6df6
832 * Z 3:125c9a1d6df6
833 x y 2:db815d6d32e6
833 x y 2:db815d6d32e6
834 $ echo "Ican'thasformatedlines" >> .hg/bookmarks
834 $ echo "Ican'thasformatedlines" >> .hg/bookmarks
835 $ hg bookmarks
835 $ hg bookmarks
836 malformed line in .hg/bookmarks: "Ican'thasformatedlines"
836 malformed line in .hg/bookmarks: "Ican'thasformatedlines"
837 X2 1:925d80f479bb
837 X2 1:925d80f479bb
838 Y 3:125c9a1d6df6
838 Y 3:125c9a1d6df6
839 * Z 3:125c9a1d6df6
839 * Z 3:125c9a1d6df6
840 x y 2:db815d6d32e6
840 x y 2:db815d6d32e6
841
841
842 test missing revisions
842 test missing revisions
843
843
844 $ echo "925d80f479b925d80f479bc925d80f479bccabab z" > .hg/bookmarks
844 $ echo "925d80f479b925d80f479bc925d80f479bccabab z" > .hg/bookmarks
845 $ hg book
845 $ hg book
846 no bookmarks set
846 no bookmarks set
847
847
848 test stripping a non-checked-out but bookmarked revision
848 test stripping a non-checked-out but bookmarked revision
849
849
850 $ hg log --graph
850 $ hg log --graph
851 o changeset: 4:9ba5f110a0b3
851 o changeset: 4:9ba5f110a0b3
852 | branch: test
852 | branch: test
853 | tag: tip
853 | tag: tip
854 | parent: 2:db815d6d32e6
854 | parent: 2:db815d6d32e6
855 | user: test
855 | user: test
856 | date: Thu Jan 01 00:00:00 1970 +0000
856 | date: Thu Jan 01 00:00:00 1970 +0000
857 | summary: y
857 | summary: y
858 |
858 |
859 | @ changeset: 3:125c9a1d6df6
859 | @ changeset: 3:125c9a1d6df6
860 |/ user: test
860 |/ user: test
861 | date: Thu Jan 01 00:00:00 1970 +0000
861 | date: Thu Jan 01 00:00:00 1970 +0000
862 | summary: x
862 | summary: x
863 |
863 |
864 o changeset: 2:db815d6d32e6
864 o changeset: 2:db815d6d32e6
865 | parent: 0:f7b1eb17ad24
865 | parent: 0:f7b1eb17ad24
866 | user: test
866 | user: test
867 | date: Thu Jan 01 00:00:00 1970 +0000
867 | date: Thu Jan 01 00:00:00 1970 +0000
868 | summary: 2
868 | summary: 2
869 |
869 |
870 | o changeset: 1:925d80f479bb
870 | o changeset: 1:925d80f479bb
871 |/ user: test
871 |/ user: test
872 | date: Thu Jan 01 00:00:00 1970 +0000
872 | date: Thu Jan 01 00:00:00 1970 +0000
873 | summary: 1
873 | summary: 1
874 |
874 |
875 o changeset: 0:f7b1eb17ad24
875 o changeset: 0:f7b1eb17ad24
876 user: test
876 user: test
877 date: Thu Jan 01 00:00:00 1970 +0000
877 date: Thu Jan 01 00:00:00 1970 +0000
878 summary: 0
878 summary: 0
879
879
880 $ hg book should-end-on-two
880 $ hg book should-end-on-two
881 $ hg co --clean 4
881 $ hg co --clean 4
882 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
882 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
883 (leaving bookmark should-end-on-two)
883 (leaving bookmark should-end-on-two)
884 $ hg book four
884 $ hg book four
885 $ hg --config extensions.mq= strip 3
885 $ hg --config extensions.mq= strip 3
886 saved backup bundle to * (glob)
886 saved backup bundle to * (glob)
887 should-end-on-two should end up pointing to revision 2, as that's the
887 should-end-on-two should end up pointing to revision 2, as that's the
888 tipmost surviving ancestor of the stripped revision.
888 tipmost surviving ancestor of the stripped revision.
889 $ hg log --graph
889 $ hg log --graph
890 @ changeset: 3:9ba5f110a0b3
890 @ changeset: 3:9ba5f110a0b3
891 | branch: test
891 | branch: test
892 | bookmark: four
892 | bookmark: four
893 | tag: tip
893 | tag: tip
894 | user: test
894 | user: test
895 | date: Thu Jan 01 00:00:00 1970 +0000
895 | date: Thu Jan 01 00:00:00 1970 +0000
896 | summary: y
896 | summary: y
897 |
897 |
898 o changeset: 2:db815d6d32e6
898 o changeset: 2:db815d6d32e6
899 | bookmark: should-end-on-two
899 | bookmark: should-end-on-two
900 | parent: 0:f7b1eb17ad24
900 | parent: 0:f7b1eb17ad24
901 | user: test
901 | user: test
902 | date: Thu Jan 01 00:00:00 1970 +0000
902 | date: Thu Jan 01 00:00:00 1970 +0000
903 | summary: 2
903 | summary: 2
904 |
904 |
905 | o changeset: 1:925d80f479bb
905 | o changeset: 1:925d80f479bb
906 |/ user: test
906 |/ user: test
907 | date: Thu Jan 01 00:00:00 1970 +0000
907 | date: Thu Jan 01 00:00:00 1970 +0000
908 | summary: 1
908 | summary: 1
909 |
909 |
910 o changeset: 0:f7b1eb17ad24
910 o changeset: 0:f7b1eb17ad24
911 user: test
911 user: test
912 date: Thu Jan 01 00:00:00 1970 +0000
912 date: Thu Jan 01 00:00:00 1970 +0000
913 summary: 0
913 summary: 0
914
914
915
915
916 no-op update doesn't deactivate bookmarks
916 no-op update doesn't deactivate bookmarks
917
917
918 (it is known issue that fsmonitor can't handle nested repositories. In
918 (it is known issue that fsmonitor can't handle nested repositories. In
919 this test scenario, cloned-bookmark-default and tobundle exist in the
919 this test scenario, cloned-bookmark-default and tobundle exist in the
920 working directory of current repository)
920 working directory of current repository)
921
921
922 $ hg bookmarks
922 $ hg bookmarks
923 * four 3:9ba5f110a0b3
923 * four 3:9ba5f110a0b3
924 should-end-on-two 2:db815d6d32e6
924 should-end-on-two 2:db815d6d32e6
925 $ hg up four
925 $ hg up four
926 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
926 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
927 $ hg up
927 $ hg up
928 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
928 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
929 $ hg sum
929 $ hg sum
930 parent: 3:9ba5f110a0b3 tip
930 parent: 3:9ba5f110a0b3 tip
931 y
931 y
932 branch: test
932 branch: test
933 bookmarks: *four
933 bookmarks: *four
934 commit: 2 unknown (clean) (no-fsmonitor !)
934 commit: 2 unknown (clean) (no-fsmonitor !)
935 commit: * unknown (clean) (glob) (fsmonitor !)
935 commit: * unknown (clean) (glob) (fsmonitor !)
936 update: (current)
936 update: (current)
937 phases: 4 draft
937 phases: 4 draft
938
938
939 test clearing divergent bookmarks of linear ancestors
939 test clearing divergent bookmarks of linear ancestors
940
940
941 $ hg bookmark Z -r 0
941 $ hg bookmark Z -r 0
942 $ hg bookmark Z@1 -r 1
942 $ hg bookmark Z@1 -r 1
943 $ hg bookmark Z@2 -r 2
943 $ hg bookmark Z@2 -r 2
944 $ hg bookmark Z@3 -r 3
944 $ hg bookmark Z@3 -r 3
945 $ hg book
945 $ hg book
946 Z 0:f7b1eb17ad24
946 Z 0:f7b1eb17ad24
947 Z@1 1:925d80f479bb
947 Z@1 1:925d80f479bb
948 Z@2 2:db815d6d32e6
948 Z@2 2:db815d6d32e6
949 Z@3 3:9ba5f110a0b3
949 Z@3 3:9ba5f110a0b3
950 * four 3:9ba5f110a0b3
950 * four 3:9ba5f110a0b3
951 should-end-on-two 2:db815d6d32e6
951 should-end-on-two 2:db815d6d32e6
952 $ hg bookmark Z
952 $ hg bookmark Z
953 moving bookmark 'Z' forward from f7b1eb17ad24
953 moving bookmark 'Z' forward from f7b1eb17ad24
954 $ hg book
954 $ hg book
955 * Z 3:9ba5f110a0b3
955 * Z 3:9ba5f110a0b3
956 Z@1 1:925d80f479bb
956 Z@1 1:925d80f479bb
957 four 3:9ba5f110a0b3
957 four 3:9ba5f110a0b3
958 should-end-on-two 2:db815d6d32e6
958 should-end-on-two 2:db815d6d32e6
959
959
960 test clearing only a single divergent bookmark across branches
960 test clearing only a single divergent bookmark across branches
961
961
962 $ hg book foo -r 1
962 $ hg book foo -r 1
963 $ hg book foo@1 -r 0
963 $ hg book foo@1 -r 0
964 $ hg book foo@2 -r 2
964 $ hg book foo@2 -r 2
965 $ hg book foo@3 -r 3
965 $ hg book foo@3 -r 3
966 $ hg book foo -r foo@3
966 $ hg book foo -r foo@3
967 $ hg book
967 $ hg book
968 * Z 3:9ba5f110a0b3
968 * Z 3:9ba5f110a0b3
969 Z@1 1:925d80f479bb
969 Z@1 1:925d80f479bb
970 foo 3:9ba5f110a0b3
970 foo 3:9ba5f110a0b3
971 foo@1 0:f7b1eb17ad24
971 foo@1 0:f7b1eb17ad24
972 foo@2 2:db815d6d32e6
972 foo@2 2:db815d6d32e6
973 four 3:9ba5f110a0b3
973 four 3:9ba5f110a0b3
974 should-end-on-two 2:db815d6d32e6
974 should-end-on-two 2:db815d6d32e6
975
975
976 pull --update works the same as pull && update (case #2)
976 pull --update works the same as pull && update (case #2)
977
977
978 It is assumed that "hg pull" itself doesn't update current active
978 It is assumed that "hg pull" itself doesn't update current active
979 bookmark ('Y' in tests below).
979 bookmark ('Y' in tests below).
980
980
981 $ hg pull -q ../cloned-bookmarks-update
981 $ hg pull -q ../cloned-bookmarks-update
982 divergent bookmark Z stored as Z@2
982 divergent bookmark Z stored as Z@2
983
983
984 (pulling revision on another named branch with --update updates
984 (pulling revision on another named branch with --update updates
985 neither the working directory nor current active bookmark: "no-op"
985 neither the working directory nor current active bookmark: "no-op"
986 case)
986 case)
987
987
988 $ echo yy >> y
988 $ echo yy >> y
989 $ hg commit -m yy
989 $ hg commit -m yy
990
990
991 $ hg -R ../cloned-bookmarks-update bookmarks | grep ' Y '
991 $ hg -R ../cloned-bookmarks-update bookmarks | grep ' Y '
992 * Y 3:125c9a1d6df6
992 * Y 3:125c9a1d6df6
993 $ hg -R ../cloned-bookmarks-update pull . --update
993 $ hg -R ../cloned-bookmarks-update pull . --update
994 pulling from .
994 pulling from .
995 searching for changes
995 searching for changes
996 adding changesets
996 adding changesets
997 adding manifests
997 adding manifests
998 adding file changes
998 adding file changes
999 added 1 changesets with 1 changes to 1 files
1000 divergent bookmark Z stored as Z@default
999 divergent bookmark Z stored as Z@default
1001 adding remote bookmark foo
1000 adding remote bookmark foo
1002 adding remote bookmark four
1001 adding remote bookmark four
1003 adding remote bookmark should-end-on-two
1002 adding remote bookmark should-end-on-two
1003 added 1 changesets with 1 changes to 1 files
1004 new changesets 5fb12f0f2d51
1004 new changesets 5fb12f0f2d51
1005 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1005 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1006 $ hg -R ../cloned-bookmarks-update parents -T "{rev}:{node|short}\n"
1006 $ hg -R ../cloned-bookmarks-update parents -T "{rev}:{node|short}\n"
1007 3:125c9a1d6df6
1007 3:125c9a1d6df6
1008 $ hg -R ../cloned-bookmarks-update bookmarks | grep ' Y '
1008 $ hg -R ../cloned-bookmarks-update bookmarks | grep ' Y '
1009 * Y 3:125c9a1d6df6
1009 * Y 3:125c9a1d6df6
1010
1010
1011 (pulling revision on current named/topological branch with --update
1011 (pulling revision on current named/topological branch with --update
1012 updates the working directory and current active bookmark)
1012 updates the working directory and current active bookmark)
1013
1013
1014 $ hg update -C -q 125c9a1d6df6
1014 $ hg update -C -q 125c9a1d6df6
1015 $ echo xx >> x
1015 $ echo xx >> x
1016 $ hg commit -m xx
1016 $ hg commit -m xx
1017
1017
1018 $ hg -R ../cloned-bookmarks-update bookmarks | grep ' Y '
1018 $ hg -R ../cloned-bookmarks-update bookmarks | grep ' Y '
1019 * Y 3:125c9a1d6df6
1019 * Y 3:125c9a1d6df6
1020 $ hg -R ../cloned-bookmarks-update pull . --update
1020 $ hg -R ../cloned-bookmarks-update pull . --update
1021 pulling from .
1021 pulling from .
1022 searching for changes
1022 searching for changes
1023 adding changesets
1023 adding changesets
1024 adding manifests
1024 adding manifests
1025 adding file changes
1025 adding file changes
1026 divergent bookmark Z stored as Z@default
1026 added 1 changesets with 1 changes to 1 files
1027 added 1 changesets with 1 changes to 1 files
1027 divergent bookmark Z stored as Z@default
1028 new changesets 81dcce76aa0b
1028 new changesets 81dcce76aa0b
1029 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1029 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1030 updating bookmark Y
1030 updating bookmark Y
1031 $ hg -R ../cloned-bookmarks-update parents -T "{rev}:{node|short}\n"
1031 $ hg -R ../cloned-bookmarks-update parents -T "{rev}:{node|short}\n"
1032 6:81dcce76aa0b
1032 6:81dcce76aa0b
1033 $ hg -R ../cloned-bookmarks-update bookmarks | grep ' Y '
1033 $ hg -R ../cloned-bookmarks-update bookmarks | grep ' Y '
1034 * Y 6:81dcce76aa0b
1034 * Y 6:81dcce76aa0b
1035
1035
1036 $ cd ..
1036 $ cd ..
1037
1037
1038 ensure changelog is written before bookmarks
1038 ensure changelog is written before bookmarks
1039 $ hg init orderrepo
1039 $ hg init orderrepo
1040 $ cd orderrepo
1040 $ cd orderrepo
1041 $ touch a
1041 $ touch a
1042 $ hg commit -Aqm one
1042 $ hg commit -Aqm one
1043 $ hg book mybook
1043 $ hg book mybook
1044 $ echo a > a
1044 $ echo a > a
1045
1045
1046 $ cat > $TESTTMP/pausefinalize.py <<EOF
1046 $ cat > $TESTTMP/pausefinalize.py <<EOF
1047 > from __future__ import absolute_import
1047 > from __future__ import absolute_import
1048 > import os
1048 > import os
1049 > import time
1049 > import time
1050 > from mercurial import extensions, localrepo
1050 > from mercurial import extensions, localrepo
1051 > def transaction(orig, self, desc, report=None):
1051 > def transaction(orig, self, desc, report=None):
1052 > tr = orig(self, desc, report)
1052 > tr = orig(self, desc, report)
1053 > def sleep(*args, **kwargs):
1053 > def sleep(*args, **kwargs):
1054 > retry = 20
1054 > retry = 20
1055 > while retry > 0 and not os.path.exists(b"$TESTTMP/unpause"):
1055 > while retry > 0 and not os.path.exists(b"$TESTTMP/unpause"):
1056 > retry -= 1
1056 > retry -= 1
1057 > time.sleep(0.5)
1057 > time.sleep(0.5)
1058 > if os.path.exists(b"$TESTTMP/unpause"):
1058 > if os.path.exists(b"$TESTTMP/unpause"):
1059 > os.remove(b"$TESTTMP/unpause")
1059 > os.remove(b"$TESTTMP/unpause")
1060 > # It is important that this finalizer start with 'a', so it runs before
1060 > # It is important that this finalizer start with 'a', so it runs before
1061 > # the changelog finalizer appends to the changelog.
1061 > # the changelog finalizer appends to the changelog.
1062 > tr.addfinalize(b'a-sleep', sleep)
1062 > tr.addfinalize(b'a-sleep', sleep)
1063 > return tr
1063 > return tr
1064 >
1064 >
1065 > def extsetup(ui):
1065 > def extsetup(ui):
1066 > # This extension inserts an artifical pause during the transaction
1066 > # This extension inserts an artifical pause during the transaction
1067 > # finalizer, so we can run commands mid-transaction-close.
1067 > # finalizer, so we can run commands mid-transaction-close.
1068 > extensions.wrapfunction(localrepo.localrepository, 'transaction',
1068 > extensions.wrapfunction(localrepo.localrepository, 'transaction',
1069 > transaction)
1069 > transaction)
1070 > EOF
1070 > EOF
1071 $ hg commit -qm two --config extensions.pausefinalize=$TESTTMP/pausefinalize.py &
1071 $ hg commit -qm two --config extensions.pausefinalize=$TESTTMP/pausefinalize.py &
1072 $ sleep 2
1072 $ sleep 2
1073 $ hg log -r .
1073 $ hg log -r .
1074 changeset: 0:867bc5792c8c
1074 changeset: 0:867bc5792c8c
1075 bookmark: mybook
1075 bookmark: mybook
1076 tag: tip
1076 tag: tip
1077 user: test
1077 user: test
1078 date: Thu Jan 01 00:00:00 1970 +0000
1078 date: Thu Jan 01 00:00:00 1970 +0000
1079 summary: one
1079 summary: one
1080
1080
1081 $ hg bookmarks
1081 $ hg bookmarks
1082 * mybook 0:867bc5792c8c
1082 * mybook 0:867bc5792c8c
1083 $ touch $TESTTMP/unpause
1083 $ touch $TESTTMP/unpause
1084
1084
1085 $ cd ..
1085 $ cd ..
1086
1086
1087 check whether HG_PENDING makes pending changes only in related
1087 check whether HG_PENDING makes pending changes only in related
1088 repositories visible to an external hook.
1088 repositories visible to an external hook.
1089
1089
1090 (emulate a transaction running concurrently by copied
1090 (emulate a transaction running concurrently by copied
1091 .hg/bookmarks.pending in subsequent test)
1091 .hg/bookmarks.pending in subsequent test)
1092
1092
1093 $ cat > $TESTTMP/savepending.sh <<EOF
1093 $ cat > $TESTTMP/savepending.sh <<EOF
1094 > cp .hg/bookmarks.pending .hg/bookmarks.pending.saved
1094 > cp .hg/bookmarks.pending .hg/bookmarks.pending.saved
1095 > exit 1 # to avoid adding new bookmark for subsequent tests
1095 > exit 1 # to avoid adding new bookmark for subsequent tests
1096 > EOF
1096 > EOF
1097
1097
1098 $ hg init unrelated
1098 $ hg init unrelated
1099 $ cd unrelated
1099 $ cd unrelated
1100 $ echo a > a
1100 $ echo a > a
1101 $ hg add a
1101 $ hg add a
1102 $ hg commit -m '#0'
1102 $ hg commit -m '#0'
1103 $ hg --config hooks.pretxnclose="sh $TESTTMP/savepending.sh" bookmarks INVISIBLE
1103 $ hg --config hooks.pretxnclose="sh $TESTTMP/savepending.sh" bookmarks INVISIBLE
1104 transaction abort!
1104 transaction abort!
1105 rollback completed
1105 rollback completed
1106 abort: pretxnclose hook exited with status 1
1106 abort: pretxnclose hook exited with status 1
1107 [255]
1107 [255]
1108 $ cp .hg/bookmarks.pending.saved .hg/bookmarks.pending
1108 $ cp .hg/bookmarks.pending.saved .hg/bookmarks.pending
1109
1109
1110 (check visible bookmarks while transaction running in repo)
1110 (check visible bookmarks while transaction running in repo)
1111
1111
1112 $ cat > $TESTTMP/checkpending.sh <<EOF
1112 $ cat > $TESTTMP/checkpending.sh <<EOF
1113 > echo "@repo"
1113 > echo "@repo"
1114 > hg -R "$TESTTMP/repo" bookmarks
1114 > hg -R "$TESTTMP/repo" bookmarks
1115 > echo "@unrelated"
1115 > echo "@unrelated"
1116 > hg -R "$TESTTMP/unrelated" bookmarks
1116 > hg -R "$TESTTMP/unrelated" bookmarks
1117 > exit 1 # to avoid adding new bookmark for subsequent tests
1117 > exit 1 # to avoid adding new bookmark for subsequent tests
1118 > EOF
1118 > EOF
1119
1119
1120 $ cd ../repo
1120 $ cd ../repo
1121 $ hg --config hooks.pretxnclose="sh $TESTTMP/checkpending.sh" bookmarks NEW
1121 $ hg --config hooks.pretxnclose="sh $TESTTMP/checkpending.sh" bookmarks NEW
1122 @repo
1122 @repo
1123 * NEW 6:81dcce76aa0b
1123 * NEW 6:81dcce76aa0b
1124 X2 1:925d80f479bb
1124 X2 1:925d80f479bb
1125 Y 4:125c9a1d6df6
1125 Y 4:125c9a1d6df6
1126 Z 5:5fb12f0f2d51
1126 Z 5:5fb12f0f2d51
1127 Z@1 1:925d80f479bb
1127 Z@1 1:925d80f479bb
1128 Z@2 4:125c9a1d6df6
1128 Z@2 4:125c9a1d6df6
1129 foo 3:9ba5f110a0b3
1129 foo 3:9ba5f110a0b3
1130 foo@1 0:f7b1eb17ad24
1130 foo@1 0:f7b1eb17ad24
1131 foo@2 2:db815d6d32e6
1131 foo@2 2:db815d6d32e6
1132 four 3:9ba5f110a0b3
1132 four 3:9ba5f110a0b3
1133 should-end-on-two 2:db815d6d32e6
1133 should-end-on-two 2:db815d6d32e6
1134 x y 2:db815d6d32e6
1134 x y 2:db815d6d32e6
1135 @unrelated
1135 @unrelated
1136 no bookmarks set
1136 no bookmarks set
1137 transaction abort!
1137 transaction abort!
1138 rollback completed
1138 rollback completed
1139 abort: pretxnclose hook exited with status 1
1139 abort: pretxnclose hook exited with status 1
1140 [255]
1140 [255]
1141
1141
1142 Check pretxnclose-bookmark can abort a transaction
1142 Check pretxnclose-bookmark can abort a transaction
1143 --------------------------------------------------
1143 --------------------------------------------------
1144
1144
1145 add hooks:
1145 add hooks:
1146
1146
1147 * to prevent NEW bookmark on a non-public changeset
1147 * to prevent NEW bookmark on a non-public changeset
1148 * to prevent non-forward move of NEW bookmark
1148 * to prevent non-forward move of NEW bookmark
1149
1149
1150 $ cat << EOF >> .hg/hgrc
1150 $ cat << EOF >> .hg/hgrc
1151 > [hooks]
1151 > [hooks]
1152 > pretxnclose-bookmark.force-public = sh -c "(echo \$HG_BOOKMARK| grep -v NEW > /dev/null) || [ -z \"\$HG_NODE\" ] || (hg log -r \"\$HG_NODE\" -T '{phase}' | grep public > /dev/null)"
1152 > pretxnclose-bookmark.force-public = sh -c "(echo \$HG_BOOKMARK| grep -v NEW > /dev/null) || [ -z \"\$HG_NODE\" ] || (hg log -r \"\$HG_NODE\" -T '{phase}' | grep public > /dev/null)"
1153 > pretxnclose-bookmark.force-forward = sh -c "(echo \$HG_BOOKMARK| grep -v NEW > /dev/null) || [ -z \"\$HG_NODE\" ] || (hg log -r \"max(\$HG_OLDNODE::\$HG_NODE)\" -T 'MATCH' | grep MATCH > /dev/null)"
1153 > pretxnclose-bookmark.force-forward = sh -c "(echo \$HG_BOOKMARK| grep -v NEW > /dev/null) || [ -z \"\$HG_NODE\" ] || (hg log -r \"max(\$HG_OLDNODE::\$HG_NODE)\" -T 'MATCH' | grep MATCH > /dev/null)"
1154 > EOF
1154 > EOF
1155
1155
1156 $ hg log -G -T phases
1156 $ hg log -G -T phases
1157 @ changeset: 6:81dcce76aa0b
1157 @ changeset: 6:81dcce76aa0b
1158 | tag: tip
1158 | tag: tip
1159 | phase: draft
1159 | phase: draft
1160 | parent: 4:125c9a1d6df6
1160 | parent: 4:125c9a1d6df6
1161 | user: test
1161 | user: test
1162 | date: Thu Jan 01 00:00:00 1970 +0000
1162 | date: Thu Jan 01 00:00:00 1970 +0000
1163 | summary: xx
1163 | summary: xx
1164 |
1164 |
1165 | o changeset: 5:5fb12f0f2d51
1165 | o changeset: 5:5fb12f0f2d51
1166 | | branch: test
1166 | | branch: test
1167 | | bookmark: Z
1167 | | bookmark: Z
1168 | | phase: draft
1168 | | phase: draft
1169 | | parent: 3:9ba5f110a0b3
1169 | | parent: 3:9ba5f110a0b3
1170 | | user: test
1170 | | user: test
1171 | | date: Thu Jan 01 00:00:00 1970 +0000
1171 | | date: Thu Jan 01 00:00:00 1970 +0000
1172 | | summary: yy
1172 | | summary: yy
1173 | |
1173 | |
1174 o | changeset: 4:125c9a1d6df6
1174 o | changeset: 4:125c9a1d6df6
1175 | | bookmark: Y
1175 | | bookmark: Y
1176 | | bookmark: Z@2
1176 | | bookmark: Z@2
1177 | | phase: public
1177 | | phase: public
1178 | | parent: 2:db815d6d32e6
1178 | | parent: 2:db815d6d32e6
1179 | | user: test
1179 | | user: test
1180 | | date: Thu Jan 01 00:00:00 1970 +0000
1180 | | date: Thu Jan 01 00:00:00 1970 +0000
1181 | | summary: x
1181 | | summary: x
1182 | |
1182 | |
1183 | o changeset: 3:9ba5f110a0b3
1183 | o changeset: 3:9ba5f110a0b3
1184 |/ branch: test
1184 |/ branch: test
1185 | bookmark: foo
1185 | bookmark: foo
1186 | bookmark: four
1186 | bookmark: four
1187 | phase: public
1187 | phase: public
1188 | user: test
1188 | user: test
1189 | date: Thu Jan 01 00:00:00 1970 +0000
1189 | date: Thu Jan 01 00:00:00 1970 +0000
1190 | summary: y
1190 | summary: y
1191 |
1191 |
1192 o changeset: 2:db815d6d32e6
1192 o changeset: 2:db815d6d32e6
1193 | bookmark: foo@2
1193 | bookmark: foo@2
1194 | bookmark: should-end-on-two
1194 | bookmark: should-end-on-two
1195 | bookmark: x y
1195 | bookmark: x y
1196 | phase: public
1196 | phase: public
1197 | parent: 0:f7b1eb17ad24
1197 | parent: 0:f7b1eb17ad24
1198 | user: test
1198 | user: test
1199 | date: Thu Jan 01 00:00:00 1970 +0000
1199 | date: Thu Jan 01 00:00:00 1970 +0000
1200 | summary: 2
1200 | summary: 2
1201 |
1201 |
1202 | o changeset: 1:925d80f479bb
1202 | o changeset: 1:925d80f479bb
1203 |/ bookmark: X2
1203 |/ bookmark: X2
1204 | bookmark: Z@1
1204 | bookmark: Z@1
1205 | phase: public
1205 | phase: public
1206 | user: test
1206 | user: test
1207 | date: Thu Jan 01 00:00:00 1970 +0000
1207 | date: Thu Jan 01 00:00:00 1970 +0000
1208 | summary: 1
1208 | summary: 1
1209 |
1209 |
1210 o changeset: 0:f7b1eb17ad24
1210 o changeset: 0:f7b1eb17ad24
1211 bookmark: foo@1
1211 bookmark: foo@1
1212 phase: public
1212 phase: public
1213 user: test
1213 user: test
1214 date: Thu Jan 01 00:00:00 1970 +0000
1214 date: Thu Jan 01 00:00:00 1970 +0000
1215 summary: 0
1215 summary: 0
1216
1216
1217
1217
1218 attempt to create on a default changeset
1218 attempt to create on a default changeset
1219
1219
1220 $ hg bookmark -r 81dcce76aa0b NEW
1220 $ hg bookmark -r 81dcce76aa0b NEW
1221 transaction abort!
1221 transaction abort!
1222 rollback completed
1222 rollback completed
1223 abort: pretxnclose-bookmark.force-public hook exited with status 1
1223 abort: pretxnclose-bookmark.force-public hook exited with status 1
1224 [255]
1224 [255]
1225
1225
1226 create on a public changeset
1226 create on a public changeset
1227
1227
1228 $ hg bookmark -r 9ba5f110a0b3 NEW
1228 $ hg bookmark -r 9ba5f110a0b3 NEW
1229
1229
1230 move to the other branch
1230 move to the other branch
1231
1231
1232 $ hg bookmark -f -r 125c9a1d6df6 NEW
1232 $ hg bookmark -f -r 125c9a1d6df6 NEW
1233 transaction abort!
1233 transaction abort!
1234 rollback completed
1234 rollback completed
1235 abort: pretxnclose-bookmark.force-forward hook exited with status 1
1235 abort: pretxnclose-bookmark.force-forward hook exited with status 1
1236 [255]
1236 [255]
@@ -1,1166 +1,1151 b''
1 #testcases sshv1 sshv2
1 #testcases sshv1 sshv2
2
2
3 #if sshv2
3 #if sshv2
4 $ cat >> $HGRCPATH << EOF
4 $ cat >> $HGRCPATH << EOF
5 > [experimental]
5 > [experimental]
6 > sshpeer.advertise-v2 = true
6 > sshpeer.advertise-v2 = true
7 > sshserver.support-v2 = true
7 > sshserver.support-v2 = true
8 > EOF
8 > EOF
9 #endif
9 #endif
10
10
11 Test exchange of common information using bundle2
11 Test exchange of common information using bundle2
12
12
13
13
14 $ getmainid() {
14 $ getmainid() {
15 > hg -R main log --template '{node}\n' --rev "$1"
15 > hg -R main log --template '{node}\n' --rev "$1"
16 > }
16 > }
17
17
18 enable obsolescence
18 enable obsolescence
19
19
20 $ cp $HGRCPATH $TESTTMP/hgrc.orig
20 $ cp $HGRCPATH $TESTTMP/hgrc.orig
21 $ cat > $TESTTMP/bundle2-pushkey-hook.sh << EOF
21 $ cat > $TESTTMP/bundle2-pushkey-hook.sh << EOF
22 > echo pushkey: lock state after \"\$HG_NAMESPACE\"
22 > echo pushkey: lock state after \"\$HG_NAMESPACE\"
23 > hg debuglock
23 > hg debuglock
24 > EOF
24 > EOF
25
25
26 $ cat >> $HGRCPATH << EOF
26 $ cat >> $HGRCPATH << EOF
27 > [experimental]
27 > [experimental]
28 > evolution.createmarkers=True
28 > evolution.createmarkers=True
29 > evolution.exchange=True
29 > evolution.exchange=True
30 > bundle2-output-capture=True
30 > bundle2-output-capture=True
31 > [ui]
31 > [ui]
32 > ssh="$PYTHON" "$TESTDIR/dummyssh"
32 > ssh="$PYTHON" "$TESTDIR/dummyssh"
33 > logtemplate={rev}:{node|short} {phase} {author} {bookmarks} {desc|firstline}
33 > logtemplate={rev}:{node|short} {phase} {author} {bookmarks} {desc|firstline}
34 > [web]
34 > [web]
35 > push_ssl = false
35 > push_ssl = false
36 > allow_push = *
36 > allow_push = *
37 > [phases]
37 > [phases]
38 > publish=False
38 > publish=False
39 > [hooks]
39 > [hooks]
40 > pretxnclose.tip = hg log -r tip -T "pre-close-tip:{node|short} {phase} {bookmarks}\n"
40 > pretxnclose.tip = hg log -r tip -T "pre-close-tip:{node|short} {phase} {bookmarks}\n"
41 > txnclose.tip = hg log -r tip -T "postclose-tip:{node|short} {phase} {bookmarks}\n"
41 > txnclose.tip = hg log -r tip -T "postclose-tip:{node|short} {phase} {bookmarks}\n"
42 > txnclose.env = sh -c "HG_LOCAL= printenv.py txnclose"
42 > txnclose.env = sh -c "HG_LOCAL= printenv.py txnclose"
43 > pushkey= sh "$TESTTMP/bundle2-pushkey-hook.sh"
43 > pushkey= sh "$TESTTMP/bundle2-pushkey-hook.sh"
44 > EOF
44 > EOF
45
45
46 The extension requires a repo (currently unused)
46 The extension requires a repo (currently unused)
47
47
48 $ hg init main
48 $ hg init main
49 $ cd main
49 $ cd main
50 $ touch a
50 $ touch a
51 $ hg add a
51 $ hg add a
52 $ hg commit -m 'a'
52 $ hg commit -m 'a'
53 pre-close-tip:3903775176ed draft
53 pre-close-tip:3903775176ed draft
54 postclose-tip:3903775176ed draft
54 postclose-tip:3903775176ed draft
55 txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_PHASES_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
55 txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_PHASES_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
56
56
57 $ hg unbundle $TESTDIR/bundles/rebase.hg
57 $ hg unbundle $TESTDIR/bundles/rebase.hg
58 adding changesets
58 adding changesets
59 adding manifests
59 adding manifests
60 adding file changes
60 adding file changes
61 pre-close-tip:02de42196ebe draft
61 added 8 changesets with 7 changes to 7 files (+3 heads)
62 added 8 changesets with 7 changes to 7 files (+3 heads)
62 pre-close-tip:02de42196ebe draft
63 new changesets cd010b8cd998:02de42196ebe (8 drafts)
63 new changesets cd010b8cd998:02de42196ebe (8 drafts)
64 postclose-tip:02de42196ebe draft
64 postclose-tip:02de42196ebe draft
65 txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NODE=cd010b8cd998f3981a5a8115f94f8da4ab506089 HG_NODE_LAST=02de42196ebee42ef284b6780a87cdc96e8eaab6 HG_PHASES_MOVED=1 HG_SOURCE=unbundle HG_TXNID=TXN:$ID$ HG_TXNNAME=unbundle
65 txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NODE=cd010b8cd998f3981a5a8115f94f8da4ab506089 HG_NODE_LAST=02de42196ebee42ef284b6780a87cdc96e8eaab6 HG_PHASES_MOVED=1 HG_SOURCE=unbundle HG_TXNID=TXN:$ID$ HG_TXNNAME=unbundle
66 bundle:*/tests/bundles/rebase.hg HG_URL=bundle:*/tests/bundles/rebase.hg (glob)
66 bundle:*/tests/bundles/rebase.hg HG_URL=bundle:*/tests/bundles/rebase.hg (glob)
67 (run 'hg heads' to see heads, 'hg merge' to merge)
67 (run 'hg heads' to see heads, 'hg merge' to merge)
68
68
69 $ cd ..
69 $ cd ..
70
70
71 Real world exchange
71 Real world exchange
72 =====================
72 =====================
73
73
74 Add more obsolescence information
74 Add more obsolescence information
75
75
76 $ hg -R main debugobsolete -d '0 0' 1111111111111111111111111111111111111111 `getmainid 9520eea781bc`
76 $ hg -R main debugobsolete -d '0 0' 1111111111111111111111111111111111111111 `getmainid 9520eea781bc`
77 pre-close-tip:02de42196ebe draft
77 pre-close-tip:02de42196ebe draft
78 1 new obsolescence markers
78 1 new obsolescence markers
79 postclose-tip:02de42196ebe draft
79 postclose-tip:02de42196ebe draft
80 txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=debugobsolete
80 txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=debugobsolete
81 $ hg -R main debugobsolete -d '0 0' 2222222222222222222222222222222222222222 `getmainid 24b6387c8c8c`
81 $ hg -R main debugobsolete -d '0 0' 2222222222222222222222222222222222222222 `getmainid 24b6387c8c8c`
82 pre-close-tip:02de42196ebe draft
82 pre-close-tip:02de42196ebe draft
83 1 new obsolescence markers
83 1 new obsolescence markers
84 postclose-tip:02de42196ebe draft
84 postclose-tip:02de42196ebe draft
85 txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=debugobsolete
85 txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=debugobsolete
86
86
87 clone --pull
87 clone --pull
88
88
89 $ hg -R main phase --public cd010b8cd998
89 $ hg -R main phase --public cd010b8cd998
90 pre-close-tip:02de42196ebe draft
90 pre-close-tip:02de42196ebe draft
91 postclose-tip:02de42196ebe draft
91 postclose-tip:02de42196ebe draft
92 txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_PHASES_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=phase
92 txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_PHASES_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=phase
93 $ hg clone main other --pull --rev 9520eea781bc
93 $ hg clone main other --pull --rev 9520eea781bc
94 adding changesets
94 adding changesets
95 adding manifests
95 adding manifests
96 adding file changes
96 adding file changes
97 pre-close-tip:9520eea781bc draft
97 added 2 changesets with 2 changes to 2 files
98 added 2 changesets with 2 changes to 2 files
98 pre-close-tip:9520eea781bc draft
99 1 new obsolescence markers
99 1 new obsolescence markers
100 new changesets cd010b8cd998:9520eea781bc (1 drafts)
100 new changesets cd010b8cd998:9520eea781bc (1 drafts)
101 postclose-tip:9520eea781bc draft
101 postclose-tip:9520eea781bc draft
102 txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_NODE=cd010b8cd998f3981a5a8115f94f8da4ab506089 HG_NODE_LAST=9520eea781bcca16c1e15acc0ba14335a0e8e5ba HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_TXNNAME=pull
102 txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_NODE=cd010b8cd998f3981a5a8115f94f8da4ab506089 HG_NODE_LAST=9520eea781bcca16c1e15acc0ba14335a0e8e5ba HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_TXNNAME=pull
103 file:/*/$TESTTMP/main HG_URL=file:$TESTTMP/main (glob)
103 file:/*/$TESTTMP/main HG_URL=file:$TESTTMP/main (glob)
104 updating to branch default
104 updating to branch default
105 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
105 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
106 $ hg -R other log -G
106 $ hg -R other log -G
107 @ 1:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
107 @ 1:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
108 |
108 |
109 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
109 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
110
110
111 $ hg -R other debugobsolete
111 $ hg -R other debugobsolete
112 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
112 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
113
113
114 pull
114 pull
115
115
116 $ hg -R main phase --public 9520eea781bc
116 $ hg -R main phase --public 9520eea781bc
117 pre-close-tip:02de42196ebe draft
117 pre-close-tip:02de42196ebe draft
118 postclose-tip:02de42196ebe draft
118 postclose-tip:02de42196ebe draft
119 txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_PHASES_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=phase
119 txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_PHASES_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=phase
120 $ hg -R other pull -r 24b6387c8c8c
120 $ hg -R other pull -r 24b6387c8c8c
121 pulling from $TESTTMP/main
121 pulling from $TESTTMP/main
122 searching for changes
122 searching for changes
123 adding changesets
123 adding changesets
124 adding manifests
124 adding manifests
125 adding file changes
125 adding file changes
126 pre-close-tip:24b6387c8c8c draft
126 added 1 changesets with 1 changes to 1 files (+1 heads)
127 added 1 changesets with 1 changes to 1 files (+1 heads)
127 pre-close-tip:24b6387c8c8c draft
128 1 new obsolescence markers
128 1 new obsolescence markers
129 new changesets 24b6387c8c8c (1 drafts)
129 new changesets 24b6387c8c8c (1 drafts)
130 postclose-tip:24b6387c8c8c draft
130 postclose-tip:24b6387c8c8c draft
131 txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_NODE=24b6387c8c8cae37178880f3fa95ded3cb1cf785 HG_NODE_LAST=24b6387c8c8cae37178880f3fa95ded3cb1cf785 HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_TXNNAME=pull
131 txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_NODE=24b6387c8c8cae37178880f3fa95ded3cb1cf785 HG_NODE_LAST=24b6387c8c8cae37178880f3fa95ded3cb1cf785 HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_TXNNAME=pull
132 file:/*/$TESTTMP/main HG_URL=file:$TESTTMP/main (glob)
132 file:/*/$TESTTMP/main HG_URL=file:$TESTTMP/main (glob)
133 (run 'hg heads' to see heads, 'hg merge' to merge)
133 (run 'hg heads' to see heads, 'hg merge' to merge)
134 $ hg -R other log -G
134 $ hg -R other log -G
135 o 2:24b6387c8c8c draft Nicolas Dumazet <nicdumz.commits@gmail.com> F
135 o 2:24b6387c8c8c draft Nicolas Dumazet <nicdumz.commits@gmail.com> F
136 |
136 |
137 | @ 1:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
137 | @ 1:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
138 |/
138 |/
139 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
139 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
140
140
141 $ hg -R other debugobsolete
141 $ hg -R other debugobsolete
142 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
142 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
143 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
143 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
144
144
145 pull empty (with phase movement)
145 pull empty (with phase movement)
146
146
147 $ hg -R main phase --public 24b6387c8c8c
147 $ hg -R main phase --public 24b6387c8c8c
148 pre-close-tip:02de42196ebe draft
148 pre-close-tip:02de42196ebe draft
149 postclose-tip:02de42196ebe draft
149 postclose-tip:02de42196ebe draft
150 txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_PHASES_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=phase
150 txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_PHASES_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=phase
151 $ hg -R other pull -r 24b6387c8c8c
151 $ hg -R other pull -r 24b6387c8c8c
152 pulling from $TESTTMP/main
152 pulling from $TESTTMP/main
153 no changes found
153 no changes found
154 pre-close-tip:24b6387c8c8c public
154 pre-close-tip:24b6387c8c8c public
155 1 local changesets published
155 1 local changesets published
156 postclose-tip:24b6387c8c8c public
156 postclose-tip:24b6387c8c8c public
157 txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=0 HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_TXNNAME=pull
157 txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=0 HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_TXNNAME=pull
158 file:/*/$TESTTMP/main HG_URL=file:$TESTTMP/main (glob)
158 file:/*/$TESTTMP/main HG_URL=file:$TESTTMP/main (glob)
159 $ hg -R other log -G
159 $ hg -R other log -G
160 o 2:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
160 o 2:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
161 |
161 |
162 | @ 1:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
162 | @ 1:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
163 |/
163 |/
164 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
164 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
165
165
166 $ hg -R other debugobsolete
166 $ hg -R other debugobsolete
167 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
167 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
168 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
168 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
169
169
170 pull empty
170 pull empty
171
171
172 $ hg -R other pull -r 24b6387c8c8c
172 $ hg -R other pull -r 24b6387c8c8c
173 pulling from $TESTTMP/main
173 pulling from $TESTTMP/main
174 no changes found
174 no changes found
175 pre-close-tip:24b6387c8c8c public
175 pre-close-tip:24b6387c8c8c public
176 postclose-tip:24b6387c8c8c public
176 postclose-tip:24b6387c8c8c public
177 txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=0 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_TXNNAME=pull
177 txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=0 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_TXNNAME=pull
178 file:/*/$TESTTMP/main HG_URL=file:$TESTTMP/main (glob)
178 file:/*/$TESTTMP/main HG_URL=file:$TESTTMP/main (glob)
179 $ hg -R other log -G
179 $ hg -R other log -G
180 o 2:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
180 o 2:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
181 |
181 |
182 | @ 1:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
182 | @ 1:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
183 |/
183 |/
184 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
184 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
185
185
186 $ hg -R other debugobsolete
186 $ hg -R other debugobsolete
187 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
187 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
188 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
188 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
189
189
190 add extra data to test their exchange during push
190 add extra data to test their exchange during push
191
191
192 $ hg -R main bookmark --rev eea13746799a book_eea1
192 $ hg -R main bookmark --rev eea13746799a book_eea1
193 pre-close-tip:02de42196ebe draft
193 pre-close-tip:02de42196ebe draft
194 postclose-tip:02de42196ebe draft
194 postclose-tip:02de42196ebe draft
195 txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
195 txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
196 $ hg -R main debugobsolete -d '0 0' 3333333333333333333333333333333333333333 `getmainid eea13746799a`
196 $ hg -R main debugobsolete -d '0 0' 3333333333333333333333333333333333333333 `getmainid eea13746799a`
197 pre-close-tip:02de42196ebe draft
197 pre-close-tip:02de42196ebe draft
198 1 new obsolescence markers
198 1 new obsolescence markers
199 postclose-tip:02de42196ebe draft
199 postclose-tip:02de42196ebe draft
200 txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=debugobsolete
200 txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=debugobsolete
201 $ hg -R main bookmark --rev 02de42196ebe book_02de
201 $ hg -R main bookmark --rev 02de42196ebe book_02de
202 pre-close-tip:02de42196ebe draft book_02de
202 pre-close-tip:02de42196ebe draft book_02de
203 postclose-tip:02de42196ebe draft book_02de
203 postclose-tip:02de42196ebe draft book_02de
204 txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
204 txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
205 $ hg -R main debugobsolete -d '0 0' 4444444444444444444444444444444444444444 `getmainid 02de42196ebe`
205 $ hg -R main debugobsolete -d '0 0' 4444444444444444444444444444444444444444 `getmainid 02de42196ebe`
206 pre-close-tip:02de42196ebe draft book_02de
206 pre-close-tip:02de42196ebe draft book_02de
207 1 new obsolescence markers
207 1 new obsolescence markers
208 postclose-tip:02de42196ebe draft book_02de
208 postclose-tip:02de42196ebe draft book_02de
209 txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=debugobsolete
209 txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=debugobsolete
210 $ hg -R main bookmark --rev 42ccdea3bb16 book_42cc
210 $ hg -R main bookmark --rev 42ccdea3bb16 book_42cc
211 pre-close-tip:02de42196ebe draft book_02de
211 pre-close-tip:02de42196ebe draft book_02de
212 postclose-tip:02de42196ebe draft book_02de
212 postclose-tip:02de42196ebe draft book_02de
213 txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
213 txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
214 $ hg -R main debugobsolete -d '0 0' 5555555555555555555555555555555555555555 `getmainid 42ccdea3bb16`
214 $ hg -R main debugobsolete -d '0 0' 5555555555555555555555555555555555555555 `getmainid 42ccdea3bb16`
215 pre-close-tip:02de42196ebe draft book_02de
215 pre-close-tip:02de42196ebe draft book_02de
216 1 new obsolescence markers
216 1 new obsolescence markers
217 postclose-tip:02de42196ebe draft book_02de
217 postclose-tip:02de42196ebe draft book_02de
218 txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=debugobsolete
218 txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=debugobsolete
219 $ hg -R main bookmark --rev 5fddd98957c8 book_5fdd
219 $ hg -R main bookmark --rev 5fddd98957c8 book_5fdd
220 pre-close-tip:02de42196ebe draft book_02de
220 pre-close-tip:02de42196ebe draft book_02de
221 postclose-tip:02de42196ebe draft book_02de
221 postclose-tip:02de42196ebe draft book_02de
222 txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
222 txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
223 $ hg -R main debugobsolete -d '0 0' 6666666666666666666666666666666666666666 `getmainid 5fddd98957c8`
223 $ hg -R main debugobsolete -d '0 0' 6666666666666666666666666666666666666666 `getmainid 5fddd98957c8`
224 pre-close-tip:02de42196ebe draft book_02de
224 pre-close-tip:02de42196ebe draft book_02de
225 1 new obsolescence markers
225 1 new obsolescence markers
226 postclose-tip:02de42196ebe draft book_02de
226 postclose-tip:02de42196ebe draft book_02de
227 txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=debugobsolete
227 txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=debugobsolete
228 $ hg -R main bookmark --rev 32af7686d403 book_32af
228 $ hg -R main bookmark --rev 32af7686d403 book_32af
229 pre-close-tip:02de42196ebe draft book_02de
229 pre-close-tip:02de42196ebe draft book_02de
230 postclose-tip:02de42196ebe draft book_02de
230 postclose-tip:02de42196ebe draft book_02de
231 txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
231 txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
232 $ hg -R main debugobsolete -d '0 0' 7777777777777777777777777777777777777777 `getmainid 32af7686d403`
232 $ hg -R main debugobsolete -d '0 0' 7777777777777777777777777777777777777777 `getmainid 32af7686d403`
233 pre-close-tip:02de42196ebe draft book_02de
233 pre-close-tip:02de42196ebe draft book_02de
234 1 new obsolescence markers
234 1 new obsolescence markers
235 postclose-tip:02de42196ebe draft book_02de
235 postclose-tip:02de42196ebe draft book_02de
236 txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=debugobsolete
236 txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=debugobsolete
237
237
238 $ hg -R other bookmark --rev cd010b8cd998 book_eea1
238 $ hg -R other bookmark --rev cd010b8cd998 book_eea1
239 pre-close-tip:24b6387c8c8c public
239 pre-close-tip:24b6387c8c8c public
240 postclose-tip:24b6387c8c8c public
240 postclose-tip:24b6387c8c8c public
241 txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
241 txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
242 $ hg -R other bookmark --rev cd010b8cd998 book_02de
242 $ hg -R other bookmark --rev cd010b8cd998 book_02de
243 pre-close-tip:24b6387c8c8c public
243 pre-close-tip:24b6387c8c8c public
244 postclose-tip:24b6387c8c8c public
244 postclose-tip:24b6387c8c8c public
245 txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
245 txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
246 $ hg -R other bookmark --rev cd010b8cd998 book_42cc
246 $ hg -R other bookmark --rev cd010b8cd998 book_42cc
247 pre-close-tip:24b6387c8c8c public
247 pre-close-tip:24b6387c8c8c public
248 postclose-tip:24b6387c8c8c public
248 postclose-tip:24b6387c8c8c public
249 txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
249 txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
250 $ hg -R other bookmark --rev cd010b8cd998 book_5fdd
250 $ hg -R other bookmark --rev cd010b8cd998 book_5fdd
251 pre-close-tip:24b6387c8c8c public
251 pre-close-tip:24b6387c8c8c public
252 postclose-tip:24b6387c8c8c public
252 postclose-tip:24b6387c8c8c public
253 txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
253 txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
254 $ hg -R other bookmark --rev cd010b8cd998 book_32af
254 $ hg -R other bookmark --rev cd010b8cd998 book_32af
255 pre-close-tip:24b6387c8c8c public
255 pre-close-tip:24b6387c8c8c public
256 postclose-tip:24b6387c8c8c public
256 postclose-tip:24b6387c8c8c public
257 txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
257 txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=bookmark
258
258
259 $ hg -R main phase --public eea13746799a
259 $ hg -R main phase --public eea13746799a
260 pre-close-tip:02de42196ebe draft book_02de
260 pre-close-tip:02de42196ebe draft book_02de
261 postclose-tip:02de42196ebe draft book_02de
261 postclose-tip:02de42196ebe draft book_02de
262 txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_PHASES_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=phase
262 txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_PHASES_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=phase
263
263
264 push
264 push
265 $ hg -R main push other --rev eea13746799a --bookmark book_eea1
265 $ hg -R main push other --rev eea13746799a --bookmark book_eea1
266 pushing to other
266 pushing to other
267 searching for changes
267 searching for changes
268 remote: adding changesets
268 remote: adding changesets
269 remote: adding manifests
269 remote: adding manifests
270 remote: adding file changes
270 remote: adding file changes
271 remote: pre-close-tip:eea13746799a public book_eea1
271 remote: added 1 changesets with 0 changes to 0 files (-1 heads)
272 remote: added 1 changesets with 0 changes to 0 files (-1 heads)
272 remote: pre-close-tip:eea13746799a public book_eea1
273 remote: 1 new obsolescence markers
273 remote: 1 new obsolescence markers
274 remote: pushkey: lock state after "bookmarks"
274 remote: pushkey: lock state after "bookmarks"
275 remote: lock: free
275 remote: lock: free
276 remote: wlock: free
276 remote: wlock: free
277 remote: postclose-tip:eea13746799a public book_eea1
277 remote: postclose-tip:eea13746799a public book_eea1
278 remote: txnclose hook: HG_BOOKMARK_MOVED=1 HG_BUNDLE2=1 HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_NODE=eea13746799a9e0bfd88f29d3c2e9dc9389f524f HG_NODE_LAST=eea13746799a9e0bfd88f29d3c2e9dc9389f524f HG_PHASES_MOVED=1 HG_SOURCE=push HG_TXNID=TXN:$ID$ HG_TXNNAME=push HG_URL=file:$TESTTMP/other
278 remote: txnclose hook: HG_BOOKMARK_MOVED=1 HG_BUNDLE2=1 HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_NODE=eea13746799a9e0bfd88f29d3c2e9dc9389f524f HG_NODE_LAST=eea13746799a9e0bfd88f29d3c2e9dc9389f524f HG_PHASES_MOVED=1 HG_SOURCE=push HG_TXNID=TXN:$ID$ HG_TXNNAME=push HG_URL=file:$TESTTMP/other
279 updating bookmark book_eea1
279 updating bookmark book_eea1
280 pre-close-tip:02de42196ebe draft book_02de
280 pre-close-tip:02de42196ebe draft book_02de
281 postclose-tip:02de42196ebe draft book_02de
281 postclose-tip:02de42196ebe draft book_02de
282 txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_SOURCE=push-response HG_TXNID=TXN:$ID$ HG_TXNNAME=push-response
282 txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_SOURCE=push-response HG_TXNID=TXN:$ID$ HG_TXNNAME=push-response
283 file:/*/$TESTTMP/other HG_URL=file:$TESTTMP/other (glob)
283 file:/*/$TESTTMP/other HG_URL=file:$TESTTMP/other (glob)
284 $ hg -R other log -G
284 $ hg -R other log -G
285 o 3:eea13746799a public Nicolas Dumazet <nicdumz.commits@gmail.com> book_eea1 G
285 o 3:eea13746799a public Nicolas Dumazet <nicdumz.commits@gmail.com> book_eea1 G
286 |\
286 |\
287 | o 2:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
287 | o 2:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
288 | |
288 | |
289 @ | 1:9520eea781bc public Nicolas Dumazet <nicdumz.commits@gmail.com> E
289 @ | 1:9520eea781bc public Nicolas Dumazet <nicdumz.commits@gmail.com> E
290 |/
290 |/
291 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> book_02de book_32af book_42cc book_5fdd A
291 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> book_02de book_32af book_42cc book_5fdd A
292
292
293 $ hg -R other debugobsolete
293 $ hg -R other debugobsolete
294 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
294 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
295 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
295 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
296 3333333333333333333333333333333333333333 eea13746799a9e0bfd88f29d3c2e9dc9389f524f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
296 3333333333333333333333333333333333333333 eea13746799a9e0bfd88f29d3c2e9dc9389f524f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
297
297
298 pull over ssh
298 pull over ssh
299
299
300 $ hg -R other pull ssh://user@dummy/main -r 02de42196ebe --bookmark book_02de
300 $ hg -R other pull ssh://user@dummy/main -r 02de42196ebe --bookmark book_02de
301 pulling from ssh://user@dummy/main
301 pulling from ssh://user@dummy/main
302 searching for changes
302 searching for changes
303 adding changesets
303 adding changesets
304 adding manifests
304 adding manifests
305 adding file changes
305 adding file changes
306 added 1 changesets with 1 changes to 1 files (+1 heads)
307 updating bookmark book_02de
306 updating bookmark book_02de
308 pre-close-tip:02de42196ebe draft book_02de
307 pre-close-tip:02de42196ebe draft book_02de
308 added 1 changesets with 1 changes to 1 files (+1 heads)
309 1 new obsolescence markers
309 1 new obsolescence markers
310 new changesets 02de42196ebe (1 drafts)
310 new changesets 02de42196ebe (1 drafts)
311 postclose-tip:02de42196ebe draft book_02de
311 postclose-tip:02de42196ebe draft book_02de
312 txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_NODE=02de42196ebee42ef284b6780a87cdc96e8eaab6 HG_NODE_LAST=02de42196ebee42ef284b6780a87cdc96e8eaab6 HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_TXNNAME=pull
312 txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_NODE=02de42196ebee42ef284b6780a87cdc96e8eaab6 HG_NODE_LAST=02de42196ebee42ef284b6780a87cdc96e8eaab6 HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_TXNNAME=pull
313 ssh://user@dummy/main HG_URL=ssh://user@dummy/main
313 ssh://user@dummy/main HG_URL=ssh://user@dummy/main
314 (run 'hg heads' to see heads, 'hg merge' to merge)
314 (run 'hg heads' to see heads, 'hg merge' to merge)
315 $ hg -R other debugobsolete
315 $ hg -R other debugobsolete
316 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
316 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
317 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
317 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
318 3333333333333333333333333333333333333333 eea13746799a9e0bfd88f29d3c2e9dc9389f524f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
318 3333333333333333333333333333333333333333 eea13746799a9e0bfd88f29d3c2e9dc9389f524f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
319 4444444444444444444444444444444444444444 02de42196ebee42ef284b6780a87cdc96e8eaab6 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
319 4444444444444444444444444444444444444444 02de42196ebee42ef284b6780a87cdc96e8eaab6 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
320
320
321 pull over http
321 pull over http
322
322
323 $ hg serve -R main -p $HGPORT -d --pid-file=main.pid -E main-error.log
323 $ hg serve -R main -p $HGPORT -d --pid-file=main.pid -E main-error.log
324 $ cat main.pid >> $DAEMON_PIDS
324 $ cat main.pid >> $DAEMON_PIDS
325
325
326 $ hg -R other pull http://localhost:$HGPORT/ -r 42ccdea3bb16 --bookmark book_42cc
326 $ hg -R other pull http://localhost:$HGPORT/ -r 42ccdea3bb16 --bookmark book_42cc
327 pulling from http://localhost:$HGPORT/
327 pulling from http://localhost:$HGPORT/
328 searching for changes
328 searching for changes
329 adding changesets
329 adding changesets
330 adding manifests
330 adding manifests
331 adding file changes
331 adding file changes
332 added 1 changesets with 1 changes to 1 files (+1 heads)
333 updating bookmark book_42cc
332 updating bookmark book_42cc
334 pre-close-tip:42ccdea3bb16 draft book_42cc
333 pre-close-tip:42ccdea3bb16 draft book_42cc
334 added 1 changesets with 1 changes to 1 files (+1 heads)
335 1 new obsolescence markers
335 1 new obsolescence markers
336 new changesets 42ccdea3bb16 (1 drafts)
336 new changesets 42ccdea3bb16 (1 drafts)
337 postclose-tip:42ccdea3bb16 draft book_42cc
337 postclose-tip:42ccdea3bb16 draft book_42cc
338 txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_NODE=42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 HG_NODE_LAST=42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_TXNNAME=pull
338 txnclose hook: HG_BOOKMARK_MOVED=1 HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_NODE=42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 HG_NODE_LAST=42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 HG_PHASES_MOVED=1 HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_TXNNAME=pull
339 http://localhost:$HGPORT/ HG_URL=http://localhost:$HGPORT/
339 http://localhost:$HGPORT/ HG_URL=http://localhost:$HGPORT/
340 (run 'hg heads .' to see heads, 'hg merge' to merge)
340 (run 'hg heads .' to see heads, 'hg merge' to merge)
341 $ cat main-error.log
341 $ cat main-error.log
342 $ hg -R other debugobsolete
342 $ hg -R other debugobsolete
343 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
343 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
344 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
344 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
345 3333333333333333333333333333333333333333 eea13746799a9e0bfd88f29d3c2e9dc9389f524f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
345 3333333333333333333333333333333333333333 eea13746799a9e0bfd88f29d3c2e9dc9389f524f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
346 4444444444444444444444444444444444444444 02de42196ebee42ef284b6780a87cdc96e8eaab6 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
346 4444444444444444444444444444444444444444 02de42196ebee42ef284b6780a87cdc96e8eaab6 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
347 5555555555555555555555555555555555555555 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
347 5555555555555555555555555555555555555555 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
348
348
349 push over ssh
349 push over ssh
350
350
351 $ hg -R main push ssh://user@dummy/other -r 5fddd98957c8 --bookmark book_5fdd
351 $ hg -R main push ssh://user@dummy/other -r 5fddd98957c8 --bookmark book_5fdd
352 pushing to ssh://user@dummy/other
352 pushing to ssh://user@dummy/other
353 searching for changes
353 searching for changes
354 remote: adding changesets
354 remote: adding changesets
355 remote: adding manifests
355 remote: adding manifests
356 remote: adding file changes
356 remote: adding file changes
357 remote: pre-close-tip:5fddd98957c8 draft book_5fdd
357 remote: added 1 changesets with 1 changes to 1 files
358 remote: added 1 changesets with 1 changes to 1 files
358 remote: pre-close-tip:5fddd98957c8 draft book_5fdd
359 remote: 1 new obsolescence markers
359 remote: 1 new obsolescence markers
360 remote: pushkey: lock state after "bookmarks"
360 remote: pushkey: lock state after "bookmarks"
361 remote: lock: free
361 remote: lock: free
362 remote: wlock: free
362 remote: wlock: free
363 remote: postclose-tip:5fddd98957c8 draft book_5fdd
363 remote: postclose-tip:5fddd98957c8 draft book_5fdd
364 remote: txnclose hook: HG_BOOKMARK_MOVED=1 HG_BUNDLE2=1 HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_NODE=5fddd98957c8a54a4d436dfe1da9d87f21a1b97b HG_NODE_LAST=5fddd98957c8a54a4d436dfe1da9d87f21a1b97b HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_TXNNAME=serve HG_URL=remote:ssh:$LOCALIP
364 remote: txnclose hook: HG_BOOKMARK_MOVED=1 HG_BUNDLE2=1 HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_NODE=5fddd98957c8a54a4d436dfe1da9d87f21a1b97b HG_NODE_LAST=5fddd98957c8a54a4d436dfe1da9d87f21a1b97b HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_TXNNAME=serve HG_URL=remote:ssh:$LOCALIP
365 updating bookmark book_5fdd
365 updating bookmark book_5fdd
366 pre-close-tip:02de42196ebe draft book_02de
366 pre-close-tip:02de42196ebe draft book_02de
367 postclose-tip:02de42196ebe draft book_02de
367 postclose-tip:02de42196ebe draft book_02de
368 txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_SOURCE=push-response HG_TXNID=TXN:$ID$ HG_TXNNAME=push-response
368 txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_SOURCE=push-response HG_TXNID=TXN:$ID$ HG_TXNNAME=push-response
369 ssh://user@dummy/other HG_URL=ssh://user@dummy/other
369 ssh://user@dummy/other HG_URL=ssh://user@dummy/other
370 $ hg -R other log -G
370 $ hg -R other log -G
371 o 6:5fddd98957c8 draft Nicolas Dumazet <nicdumz.commits@gmail.com> book_5fdd C
371 o 6:5fddd98957c8 draft Nicolas Dumazet <nicdumz.commits@gmail.com> book_5fdd C
372 |
372 |
373 o 5:42ccdea3bb16 draft Nicolas Dumazet <nicdumz.commits@gmail.com> book_42cc B
373 o 5:42ccdea3bb16 draft Nicolas Dumazet <nicdumz.commits@gmail.com> book_42cc B
374 |
374 |
375 | o 4:02de42196ebe draft Nicolas Dumazet <nicdumz.commits@gmail.com> book_02de H
375 | o 4:02de42196ebe draft Nicolas Dumazet <nicdumz.commits@gmail.com> book_02de H
376 | |
376 | |
377 | | o 3:eea13746799a public Nicolas Dumazet <nicdumz.commits@gmail.com> book_eea1 G
377 | | o 3:eea13746799a public Nicolas Dumazet <nicdumz.commits@gmail.com> book_eea1 G
378 | |/|
378 | |/|
379 | o | 2:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
379 | o | 2:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
380 |/ /
380 |/ /
381 | @ 1:9520eea781bc public Nicolas Dumazet <nicdumz.commits@gmail.com> E
381 | @ 1:9520eea781bc public Nicolas Dumazet <nicdumz.commits@gmail.com> E
382 |/
382 |/
383 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> book_32af A
383 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> book_32af A
384
384
385 $ hg -R other debugobsolete
385 $ hg -R other debugobsolete
386 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
386 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
387 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
387 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
388 3333333333333333333333333333333333333333 eea13746799a9e0bfd88f29d3c2e9dc9389f524f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
388 3333333333333333333333333333333333333333 eea13746799a9e0bfd88f29d3c2e9dc9389f524f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
389 4444444444444444444444444444444444444444 02de42196ebee42ef284b6780a87cdc96e8eaab6 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
389 4444444444444444444444444444444444444444 02de42196ebee42ef284b6780a87cdc96e8eaab6 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
390 5555555555555555555555555555555555555555 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
390 5555555555555555555555555555555555555555 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
391 6666666666666666666666666666666666666666 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
391 6666666666666666666666666666666666666666 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
392
392
393 push over http
393 push over http
394
394
395 $ hg serve -R other -p $HGPORT2 -d --pid-file=other.pid -E other-error.log
395 $ hg serve -R other -p $HGPORT2 -d --pid-file=other.pid -E other-error.log
396 $ cat other.pid >> $DAEMON_PIDS
396 $ cat other.pid >> $DAEMON_PIDS
397
397
398 $ hg -R main phase --public 32af7686d403
398 $ hg -R main phase --public 32af7686d403
399 pre-close-tip:02de42196ebe draft book_02de
399 pre-close-tip:02de42196ebe draft book_02de
400 postclose-tip:02de42196ebe draft book_02de
400 postclose-tip:02de42196ebe draft book_02de
401 txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_PHASES_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=phase
401 txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_PHASES_MOVED=1 HG_TXNID=TXN:$ID$ HG_TXNNAME=phase
402 $ hg -R main push http://localhost:$HGPORT2/ -r 32af7686d403 --bookmark book_32af
402 $ hg -R main push http://localhost:$HGPORT2/ -r 32af7686d403 --bookmark book_32af
403 pushing to http://localhost:$HGPORT2/
403 pushing to http://localhost:$HGPORT2/
404 searching for changes
404 searching for changes
405 remote: adding changesets
405 remote: adding changesets
406 remote: adding manifests
406 remote: adding manifests
407 remote: adding file changes
407 remote: adding file changes
408 remote: pre-close-tip:32af7686d403 public book_32af
408 remote: added 1 changesets with 1 changes to 1 files
409 remote: added 1 changesets with 1 changes to 1 files
409 remote: pre-close-tip:32af7686d403 public book_32af
410 remote: 1 new obsolescence markers
410 remote: 1 new obsolescence markers
411 remote: pushkey: lock state after "bookmarks"
411 remote: pushkey: lock state after "bookmarks"
412 remote: lock: free
412 remote: lock: free
413 remote: wlock: free
413 remote: wlock: free
414 remote: postclose-tip:32af7686d403 public book_32af
414 remote: postclose-tip:32af7686d403 public book_32af
415 remote: txnclose hook: HG_BOOKMARK_MOVED=1 HG_BUNDLE2=1 HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_NODE=32af7686d403cf45b5d95f2d70cebea587ac806a HG_NODE_LAST=32af7686d403cf45b5d95f2d70cebea587ac806a HG_PHASES_MOVED=1 HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_TXNNAME=serve HG_URL=remote:http:$LOCALIP: (glob)
415 remote: txnclose hook: HG_BOOKMARK_MOVED=1 HG_BUNDLE2=1 HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_NEW_OBSMARKERS=1 HG_NODE=32af7686d403cf45b5d95f2d70cebea587ac806a HG_NODE_LAST=32af7686d403cf45b5d95f2d70cebea587ac806a HG_PHASES_MOVED=1 HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_TXNNAME=serve HG_URL=remote:http:$LOCALIP: (glob)
416 updating bookmark book_32af
416 updating bookmark book_32af
417 pre-close-tip:02de42196ebe draft book_02de
417 pre-close-tip:02de42196ebe draft book_02de
418 postclose-tip:02de42196ebe draft book_02de
418 postclose-tip:02de42196ebe draft book_02de
419 txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_SOURCE=push-response HG_TXNID=TXN:$ID$ HG_TXNNAME=push-response
419 txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_SOURCE=push-response HG_TXNID=TXN:$ID$ HG_TXNNAME=push-response
420 http://localhost:$HGPORT2/ HG_URL=http://localhost:$HGPORT2/
420 http://localhost:$HGPORT2/ HG_URL=http://localhost:$HGPORT2/
421 $ cat other-error.log
421 $ cat other-error.log
422
422
423 Check final content.
423 Check final content.
424
424
425 $ hg -R other log -G
425 $ hg -R other log -G
426 o 7:32af7686d403 public Nicolas Dumazet <nicdumz.commits@gmail.com> book_32af D
426 o 7:32af7686d403 public Nicolas Dumazet <nicdumz.commits@gmail.com> book_32af D
427 |
427 |
428 o 6:5fddd98957c8 public Nicolas Dumazet <nicdumz.commits@gmail.com> book_5fdd C
428 o 6:5fddd98957c8 public Nicolas Dumazet <nicdumz.commits@gmail.com> book_5fdd C
429 |
429 |
430 o 5:42ccdea3bb16 public Nicolas Dumazet <nicdumz.commits@gmail.com> book_42cc B
430 o 5:42ccdea3bb16 public Nicolas Dumazet <nicdumz.commits@gmail.com> book_42cc B
431 |
431 |
432 | o 4:02de42196ebe draft Nicolas Dumazet <nicdumz.commits@gmail.com> book_02de H
432 | o 4:02de42196ebe draft Nicolas Dumazet <nicdumz.commits@gmail.com> book_02de H
433 | |
433 | |
434 | | o 3:eea13746799a public Nicolas Dumazet <nicdumz.commits@gmail.com> book_eea1 G
434 | | o 3:eea13746799a public Nicolas Dumazet <nicdumz.commits@gmail.com> book_eea1 G
435 | |/|
435 | |/|
436 | o | 2:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
436 | o | 2:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
437 |/ /
437 |/ /
438 | @ 1:9520eea781bc public Nicolas Dumazet <nicdumz.commits@gmail.com> E
438 | @ 1:9520eea781bc public Nicolas Dumazet <nicdumz.commits@gmail.com> E
439 |/
439 |/
440 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
440 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
441
441
442 $ hg -R other debugobsolete
442 $ hg -R other debugobsolete
443 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
443 1111111111111111111111111111111111111111 9520eea781bcca16c1e15acc0ba14335a0e8e5ba 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
444 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
444 2222222222222222222222222222222222222222 24b6387c8c8cae37178880f3fa95ded3cb1cf785 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
445 3333333333333333333333333333333333333333 eea13746799a9e0bfd88f29d3c2e9dc9389f524f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
445 3333333333333333333333333333333333333333 eea13746799a9e0bfd88f29d3c2e9dc9389f524f 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
446 4444444444444444444444444444444444444444 02de42196ebee42ef284b6780a87cdc96e8eaab6 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
446 4444444444444444444444444444444444444444 02de42196ebee42ef284b6780a87cdc96e8eaab6 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
447 5555555555555555555555555555555555555555 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
447 5555555555555555555555555555555555555555 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
448 6666666666666666666666666666666666666666 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
448 6666666666666666666666666666666666666666 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
449 7777777777777777777777777777777777777777 32af7686d403cf45b5d95f2d70cebea587ac806a 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
449 7777777777777777777777777777777777777777 32af7686d403cf45b5d95f2d70cebea587ac806a 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
450
450
451 (check that no 'pending' files remain)
451 (check that no 'pending' files remain)
452
452
453 $ ls -1 other/.hg/bookmarks*
453 $ ls -1 other/.hg/bookmarks*
454 other/.hg/bookmarks
454 other/.hg/bookmarks
455 $ ls -1 other/.hg/store/phaseroots*
455 $ ls -1 other/.hg/store/phaseroots*
456 other/.hg/store/phaseroots
456 other/.hg/store/phaseroots
457 $ ls -1 other/.hg/store/00changelog.i*
457 $ ls -1 other/.hg/store/00changelog.i*
458 other/.hg/store/00changelog.i
458 other/.hg/store/00changelog.i
459
459
460 Error Handling
460 Error Handling
461 ==============
461 ==============
462
462
463 Check that errors are properly returned to the client during push.
463 Check that errors are properly returned to the client during push.
464
464
465 Setting up
465 Setting up
466
466
467 $ cat > failpush.py << EOF
467 $ cat > failpush.py << EOF
468 > """A small extension that makes push fails when using bundle2
468 > """A small extension that makes push fails when using bundle2
469 >
469 >
470 > used to test error handling in bundle2
470 > used to test error handling in bundle2
471 > """
471 > """
472 >
472 >
473 > from mercurial import error
473 > from mercurial import error
474 > from mercurial import bundle2
474 > from mercurial import bundle2
475 > from mercurial import exchange
475 > from mercurial import exchange
476 > from mercurial import extensions
476 > from mercurial import extensions
477 > from mercurial import registrar
477 > from mercurial import registrar
478 > cmdtable = {}
478 > cmdtable = {}
479 > command = registrar.command(cmdtable)
479 > command = registrar.command(cmdtable)
480 >
480 >
481 > configtable = {}
481 > configtable = {}
482 > configitem = registrar.configitem(configtable)
482 > configitem = registrar.configitem(configtable)
483 > configitem(b'failpush', b'reason',
483 > configitem(b'failpush', b'reason',
484 > default=None,
484 > default=None,
485 > )
485 > )
486 >
486 >
487 > def _pushbundle2failpart(pushop, bundler):
487 > def _pushbundle2failpart(pushop, bundler):
488 > reason = pushop.ui.config(b'failpush', b'reason')
488 > reason = pushop.ui.config(b'failpush', b'reason')
489 > part = None
489 > part = None
490 > if reason == b'abort':
490 > if reason == b'abort':
491 > bundler.newpart(b'test:abort')
491 > bundler.newpart(b'test:abort')
492 > if reason == b'unknown':
492 > if reason == b'unknown':
493 > bundler.newpart(b'test:unknown')
493 > bundler.newpart(b'test:unknown')
494 > if reason == b'race':
494 > if reason == b'race':
495 > # 20 Bytes of crap
495 > # 20 Bytes of crap
496 > bundler.newpart(b'check:heads', data=b'01234567890123456789')
496 > bundler.newpart(b'check:heads', data=b'01234567890123456789')
497 >
497 >
498 > @bundle2.parthandler(b"test:abort")
498 > @bundle2.parthandler(b"test:abort")
499 > def handleabort(op, part):
499 > def handleabort(op, part):
500 > raise error.Abort(b'Abandon ship!', hint=b"don't panic")
500 > raise error.Abort(b'Abandon ship!', hint=b"don't panic")
501 >
501 >
502 > def uisetup(ui):
502 > def uisetup(ui):
503 > exchange.b2partsgenmapping[b'failpart'] = _pushbundle2failpart
503 > exchange.b2partsgenmapping[b'failpart'] = _pushbundle2failpart
504 > exchange.b2partsgenorder.insert(0, b'failpart')
504 > exchange.b2partsgenorder.insert(0, b'failpart')
505 >
505 >
506 > EOF
506 > EOF
507
507
508 $ cd main
508 $ cd main
509 $ hg up tip
509 $ hg up tip
510 3 files updated, 0 files merged, 1 files removed, 0 files unresolved
510 3 files updated, 0 files merged, 1 files removed, 0 files unresolved
511 $ echo 'I' > I
511 $ echo 'I' > I
512 $ hg add I
512 $ hg add I
513 $ hg ci -m 'I'
513 $ hg ci -m 'I'
514 pre-close-tip:e7ec4e813ba6 draft
514 pre-close-tip:e7ec4e813ba6 draft
515 postclose-tip:e7ec4e813ba6 draft
515 postclose-tip:e7ec4e813ba6 draft
516 txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
516 txnclose hook: HG_HOOKNAME=txnclose.env HG_HOOKTYPE=txnclose HG_TXNID=TXN:$ID$ HG_TXNNAME=commit
517 $ hg id
517 $ hg id
518 e7ec4e813ba6 tip
518 e7ec4e813ba6 tip
519 $ cd ..
519 $ cd ..
520
520
521 $ cat << EOF >> $HGRCPATH
521 $ cat << EOF >> $HGRCPATH
522 > [extensions]
522 > [extensions]
523 > failpush=$TESTTMP/failpush.py
523 > failpush=$TESTTMP/failpush.py
524 > EOF
524 > EOF
525
525
526 $ killdaemons.py
526 $ killdaemons.py
527 $ hg serve -R other -p $HGPORT2 -d --pid-file=other.pid -E other-error.log
527 $ hg serve -R other -p $HGPORT2 -d --pid-file=other.pid -E other-error.log
528 $ cat other.pid >> $DAEMON_PIDS
528 $ cat other.pid >> $DAEMON_PIDS
529
529
530 Doing the actual push: Abort error
530 Doing the actual push: Abort error
531
531
532 $ cat << EOF >> $HGRCPATH
532 $ cat << EOF >> $HGRCPATH
533 > [failpush]
533 > [failpush]
534 > reason = abort
534 > reason = abort
535 > EOF
535 > EOF
536
536
537 $ hg -R main push other -r e7ec4e813ba6
537 $ hg -R main push other -r e7ec4e813ba6
538 pushing to other
538 pushing to other
539 searching for changes
539 searching for changes
540 abort: Abandon ship!
540 abort: Abandon ship!
541 (don't panic)
541 (don't panic)
542 [255]
542 [255]
543
543
544 $ hg -R main push ssh://user@dummy/other -r e7ec4e813ba6
544 $ hg -R main push ssh://user@dummy/other -r e7ec4e813ba6
545 pushing to ssh://user@dummy/other
545 pushing to ssh://user@dummy/other
546 searching for changes
546 searching for changes
547 remote: Abandon ship!
547 remote: Abandon ship!
548 remote: (don't panic)
548 remote: (don't panic)
549 abort: push failed on remote
549 abort: push failed on remote
550 [255]
550 [255]
551
551
552 $ hg -R main push http://localhost:$HGPORT2/ -r e7ec4e813ba6
552 $ hg -R main push http://localhost:$HGPORT2/ -r e7ec4e813ba6
553 pushing to http://localhost:$HGPORT2/
553 pushing to http://localhost:$HGPORT2/
554 searching for changes
554 searching for changes
555 remote: Abandon ship!
555 remote: Abandon ship!
556 remote: (don't panic)
556 remote: (don't panic)
557 abort: push failed on remote
557 abort: push failed on remote
558 [255]
558 [255]
559
559
560
560
561 Doing the actual push: unknown mandatory parts
561 Doing the actual push: unknown mandatory parts
562
562
563 $ cat << EOF >> $HGRCPATH
563 $ cat << EOF >> $HGRCPATH
564 > [failpush]
564 > [failpush]
565 > reason = unknown
565 > reason = unknown
566 > EOF
566 > EOF
567
567
568 $ hg -R main push other -r e7ec4e813ba6
568 $ hg -R main push other -r e7ec4e813ba6
569 pushing to other
569 pushing to other
570 searching for changes
570 searching for changes
571 abort: missing support for test:unknown
571 abort: missing support for test:unknown
572 [255]
572 [255]
573
573
574 $ hg -R main push ssh://user@dummy/other -r e7ec4e813ba6
574 $ hg -R main push ssh://user@dummy/other -r e7ec4e813ba6
575 pushing to ssh://user@dummy/other
575 pushing to ssh://user@dummy/other
576 searching for changes
576 searching for changes
577 abort: missing support for test:unknown
577 abort: missing support for test:unknown
578 [255]
578 [255]
579
579
580 $ hg -R main push http://localhost:$HGPORT2/ -r e7ec4e813ba6
580 $ hg -R main push http://localhost:$HGPORT2/ -r e7ec4e813ba6
581 pushing to http://localhost:$HGPORT2/
581 pushing to http://localhost:$HGPORT2/
582 searching for changes
582 searching for changes
583 abort: missing support for test:unknown
583 abort: missing support for test:unknown
584 [255]
584 [255]
585
585
586 Doing the actual push: race
586 Doing the actual push: race
587
587
588 $ cat << EOF >> $HGRCPATH
588 $ cat << EOF >> $HGRCPATH
589 > [failpush]
589 > [failpush]
590 > reason = race
590 > reason = race
591 > EOF
591 > EOF
592
592
593 $ hg -R main push other -r e7ec4e813ba6
593 $ hg -R main push other -r e7ec4e813ba6
594 pushing to other
594 pushing to other
595 searching for changes
595 searching for changes
596 abort: push failed:
596 abort: push failed:
597 'remote repository changed while pushing - please try again'
597 'remote repository changed while pushing - please try again'
598 [255]
598 [255]
599
599
600 $ hg -R main push ssh://user@dummy/other -r e7ec4e813ba6
600 $ hg -R main push ssh://user@dummy/other -r e7ec4e813ba6
601 pushing to ssh://user@dummy/other
601 pushing to ssh://user@dummy/other
602 searching for changes
602 searching for changes
603 abort: push failed:
603 abort: push failed:
604 'remote repository changed while pushing - please try again'
604 'remote repository changed while pushing - please try again'
605 [255]
605 [255]
606
606
607 $ hg -R main push http://localhost:$HGPORT2/ -r e7ec4e813ba6
607 $ hg -R main push http://localhost:$HGPORT2/ -r e7ec4e813ba6
608 pushing to http://localhost:$HGPORT2/
608 pushing to http://localhost:$HGPORT2/
609 searching for changes
609 searching for changes
610 abort: push failed:
610 abort: push failed:
611 'remote repository changed while pushing - please try again'
611 'remote repository changed while pushing - please try again'
612 [255]
612 [255]
613
613
614 Doing the actual push: hook abort
614 Doing the actual push: hook abort
615
615
616 $ cat << EOF >> $HGRCPATH
616 $ cat << EOF >> $HGRCPATH
617 > [failpush]
617 > [failpush]
618 > reason =
618 > reason =
619 > [hooks]
619 > [hooks]
620 > pretxnclose.failpush = sh -c "echo 'You shall not pass!'; false"
620 > pretxnclose.failpush = sh -c "echo 'You shall not pass!'; false"
621 > txnabort.failpush = sh -c "echo 'Cleaning up the mess...'"
621 > txnabort.failpush = sh -c "echo 'Cleaning up the mess...'"
622 > EOF
622 > EOF
623
623
624 $ killdaemons.py
624 $ killdaemons.py
625 $ hg serve -R other -p $HGPORT2 -d --pid-file=other.pid -E other-error.log
625 $ hg serve -R other -p $HGPORT2 -d --pid-file=other.pid -E other-error.log
626 $ cat other.pid >> $DAEMON_PIDS
626 $ cat other.pid >> $DAEMON_PIDS
627
627
628 $ hg -R main push other -r e7ec4e813ba6
628 $ hg -R main push other -r e7ec4e813ba6
629 pushing to other
629 pushing to other
630 searching for changes
630 searching for changes
631 remote: adding changesets
631 remote: adding changesets
632 remote: adding manifests
632 remote: adding manifests
633 remote: adding file changes
633 remote: adding file changes
634 remote: added 1 changesets with 1 changes to 1 files
635 remote: pre-close-tip:e7ec4e813ba6 draft
634 remote: pre-close-tip:e7ec4e813ba6 draft
636 remote: You shall not pass!
635 remote: You shall not pass!
637 remote: transaction abort!
636 remote: transaction abort!
638 remote: Cleaning up the mess...
637 remote: Cleaning up the mess...
639 remote: rollback completed
638 remote: rollback completed
640 abort: pretxnclose.failpush hook exited with status 1
639 abort: pretxnclose.failpush hook exited with status 1
641 [255]
640 [255]
642
641
643 $ hg -R main push ssh://user@dummy/other -r e7ec4e813ba6
642 $ hg -R main push ssh://user@dummy/other -r e7ec4e813ba6
644 pushing to ssh://user@dummy/other
643 pushing to ssh://user@dummy/other
645 searching for changes
644 searching for changes
646 remote: adding changesets
645 remote: adding changesets
647 remote: adding manifests
646 remote: adding manifests
648 remote: adding file changes
647 remote: adding file changes
649 remote: added 1 changesets with 1 changes to 1 files
650 remote: pre-close-tip:e7ec4e813ba6 draft
648 remote: pre-close-tip:e7ec4e813ba6 draft
651 remote: You shall not pass!
649 remote: You shall not pass!
652 remote: transaction abort!
650 remote: transaction abort!
653 remote: Cleaning up the mess...
651 remote: Cleaning up the mess...
654 remote: rollback completed
652 remote: rollback completed
655 remote: pretxnclose.failpush hook exited with status 1
653 remote: pretxnclose.failpush hook exited with status 1
656 abort: push failed on remote
654 abort: push failed on remote
657 [255]
655 [255]
658
656
659 $ hg -R main push http://localhost:$HGPORT2/ -r e7ec4e813ba6
657 $ hg -R main push http://localhost:$HGPORT2/ -r e7ec4e813ba6
660 pushing to http://localhost:$HGPORT2/
658 pushing to http://localhost:$HGPORT2/
661 searching for changes
659 searching for changes
662 remote: adding changesets
660 remote: adding changesets
663 remote: adding manifests
661 remote: adding manifests
664 remote: adding file changes
662 remote: adding file changes
665 remote: added 1 changesets with 1 changes to 1 files
666 remote: pre-close-tip:e7ec4e813ba6 draft
663 remote: pre-close-tip:e7ec4e813ba6 draft
667 remote: You shall not pass!
664 remote: You shall not pass!
668 remote: transaction abort!
665 remote: transaction abort!
669 remote: Cleaning up the mess...
666 remote: Cleaning up the mess...
670 remote: rollback completed
667 remote: rollback completed
671 remote: pretxnclose.failpush hook exited with status 1
668 remote: pretxnclose.failpush hook exited with status 1
672 abort: push failed on remote
669 abort: push failed on remote
673 [255]
670 [255]
674
671
675 (check that no 'pending' files remain)
672 (check that no 'pending' files remain)
676
673
677 $ ls -1 other/.hg/bookmarks*
674 $ ls -1 other/.hg/bookmarks*
678 other/.hg/bookmarks
675 other/.hg/bookmarks
679 $ ls -1 other/.hg/store/phaseroots*
676 $ ls -1 other/.hg/store/phaseroots*
680 other/.hg/store/phaseroots
677 other/.hg/store/phaseroots
681 $ ls -1 other/.hg/store/00changelog.i*
678 $ ls -1 other/.hg/store/00changelog.i*
682 other/.hg/store/00changelog.i
679 other/.hg/store/00changelog.i
683
680
684 Check error from hook during the unbundling process itself
681 Check error from hook during the unbundling process itself
685
682
686 $ cat << EOF >> $HGRCPATH
683 $ cat << EOF >> $HGRCPATH
687 > pretxnchangegroup = sh -c "echo 'Fail early!'; false"
684 > pretxnchangegroup = sh -c "echo 'Fail early!'; false"
688 > EOF
685 > EOF
689 $ killdaemons.py # reload http config
686 $ killdaemons.py # reload http config
690 $ hg serve -R other -p $HGPORT2 -d --pid-file=other.pid -E other-error.log
687 $ hg serve -R other -p $HGPORT2 -d --pid-file=other.pid -E other-error.log
691 $ cat other.pid >> $DAEMON_PIDS
688 $ cat other.pid >> $DAEMON_PIDS
692
689
693 $ hg -R main push other -r e7ec4e813ba6
690 $ hg -R main push other -r e7ec4e813ba6
694 pushing to other
691 pushing to other
695 searching for changes
692 searching for changes
696 remote: adding changesets
693 remote: adding changesets
697 remote: adding manifests
694 remote: adding manifests
698 remote: adding file changes
695 remote: adding file changes
699 remote: added 1 changesets with 1 changes to 1 files
700 remote: Fail early!
696 remote: Fail early!
701 remote: transaction abort!
697 remote: transaction abort!
702 remote: Cleaning up the mess...
698 remote: Cleaning up the mess...
703 remote: rollback completed
699 remote: rollback completed
704 abort: pretxnchangegroup hook exited with status 1
700 abort: pretxnchangegroup hook exited with status 1
705 [255]
701 [255]
706 $ hg -R main push ssh://user@dummy/other -r e7ec4e813ba6
702 $ hg -R main push ssh://user@dummy/other -r e7ec4e813ba6
707 pushing to ssh://user@dummy/other
703 pushing to ssh://user@dummy/other
708 searching for changes
704 searching for changes
709 remote: adding changesets
705 remote: adding changesets
710 remote: adding manifests
706 remote: adding manifests
711 remote: adding file changes
707 remote: adding file changes
712 remote: added 1 changesets with 1 changes to 1 files
713 remote: Fail early!
708 remote: Fail early!
714 remote: transaction abort!
709 remote: transaction abort!
715 remote: Cleaning up the mess...
710 remote: Cleaning up the mess...
716 remote: rollback completed
711 remote: rollback completed
717 remote: pretxnchangegroup hook exited with status 1
712 remote: pretxnchangegroup hook exited with status 1
718 abort: push failed on remote
713 abort: push failed on remote
719 [255]
714 [255]
720 $ hg -R main push http://localhost:$HGPORT2/ -r e7ec4e813ba6
715 $ hg -R main push http://localhost:$HGPORT2/ -r e7ec4e813ba6
721 pushing to http://localhost:$HGPORT2/
716 pushing to http://localhost:$HGPORT2/
722 searching for changes
717 searching for changes
723 remote: adding changesets
718 remote: adding changesets
724 remote: adding manifests
719 remote: adding manifests
725 remote: adding file changes
720 remote: adding file changes
726 remote: added 1 changesets with 1 changes to 1 files
727 remote: Fail early!
721 remote: Fail early!
728 remote: transaction abort!
722 remote: transaction abort!
729 remote: Cleaning up the mess...
723 remote: Cleaning up the mess...
730 remote: rollback completed
724 remote: rollback completed
731 remote: pretxnchangegroup hook exited with status 1
725 remote: pretxnchangegroup hook exited with status 1
732 abort: push failed on remote
726 abort: push failed on remote
733 [255]
727 [255]
734
728
735 Check output capture control.
729 Check output capture control.
736
730
737 (should be still forced for http, disabled for local and ssh)
731 (should be still forced for http, disabled for local and ssh)
738
732
739 $ cat >> $HGRCPATH << EOF
733 $ cat >> $HGRCPATH << EOF
740 > [experimental]
734 > [experimental]
741 > bundle2-output-capture=False
735 > bundle2-output-capture=False
742 > EOF
736 > EOF
743
737
744 $ hg -R main push other -r e7ec4e813ba6
738 $ hg -R main push other -r e7ec4e813ba6
745 pushing to other
739 pushing to other
746 searching for changes
740 searching for changes
747 adding changesets
741 adding changesets
748 adding manifests
742 adding manifests
749 adding file changes
743 adding file changes
750 added 1 changesets with 1 changes to 1 files
751 Fail early!
744 Fail early!
752 transaction abort!
745 transaction abort!
753 Cleaning up the mess...
746 Cleaning up the mess...
754 rollback completed
747 rollback completed
755 abort: pretxnchangegroup hook exited with status 1
748 abort: pretxnchangegroup hook exited with status 1
756 [255]
749 [255]
757 $ hg -R main push ssh://user@dummy/other -r e7ec4e813ba6
750 $ hg -R main push ssh://user@dummy/other -r e7ec4e813ba6
758 pushing to ssh://user@dummy/other
751 pushing to ssh://user@dummy/other
759 searching for changes
752 searching for changes
760 remote: adding changesets
753 remote: adding changesets
761 remote: adding manifests
754 remote: adding manifests
762 remote: adding file changes
755 remote: adding file changes
763 remote: added 1 changesets with 1 changes to 1 files
764 remote: Fail early!
756 remote: Fail early!
765 remote: transaction abort!
757 remote: transaction abort!
766 remote: Cleaning up the mess...
758 remote: Cleaning up the mess...
767 remote: rollback completed
759 remote: rollback completed
768 remote: pretxnchangegroup hook exited with status 1
760 remote: pretxnchangegroup hook exited with status 1
769 abort: push failed on remote
761 abort: push failed on remote
770 [255]
762 [255]
771 $ hg -R main push http://localhost:$HGPORT2/ -r e7ec4e813ba6
763 $ hg -R main push http://localhost:$HGPORT2/ -r e7ec4e813ba6
772 pushing to http://localhost:$HGPORT2/
764 pushing to http://localhost:$HGPORT2/
773 searching for changes
765 searching for changes
774 remote: adding changesets
766 remote: adding changesets
775 remote: adding manifests
767 remote: adding manifests
776 remote: adding file changes
768 remote: adding file changes
777 remote: added 1 changesets with 1 changes to 1 files
778 remote: Fail early!
769 remote: Fail early!
779 remote: transaction abort!
770 remote: transaction abort!
780 remote: Cleaning up the mess...
771 remote: Cleaning up the mess...
781 remote: rollback completed
772 remote: rollback completed
782 remote: pretxnchangegroup hook exited with status 1
773 remote: pretxnchangegroup hook exited with status 1
783 abort: push failed on remote
774 abort: push failed on remote
784 [255]
775 [255]
785
776
786 Check abort from mandatory pushkey
777 Check abort from mandatory pushkey
787
778
788 $ cat > mandatorypart.py << EOF
779 $ cat > mandatorypart.py << EOF
789 > from mercurial import exchange
780 > from mercurial import exchange
790 > from mercurial import pushkey
781 > from mercurial import pushkey
791 > from mercurial import node
782 > from mercurial import node
792 > from mercurial import error
783 > from mercurial import error
793 > @exchange.b2partsgenerator(b'failingpuskey')
784 > @exchange.b2partsgenerator(b'failingpuskey')
794 > def addfailingpushey(pushop, bundler):
785 > def addfailingpushey(pushop, bundler):
795 > enc = pushkey.encode
786 > enc = pushkey.encode
796 > part = bundler.newpart(b'pushkey')
787 > part = bundler.newpart(b'pushkey')
797 > part.addparam(b'namespace', enc(b'phases'))
788 > part.addparam(b'namespace', enc(b'phases'))
798 > part.addparam(b'key', enc(b'cd010b8cd998f3981a5a8115f94f8da4ab506089'))
789 > part.addparam(b'key', enc(b'cd010b8cd998f3981a5a8115f94f8da4ab506089'))
799 > part.addparam(b'old', enc(b'0')) # successful update
790 > part.addparam(b'old', enc(b'0')) # successful update
800 > part.addparam(b'new', enc(b'0'))
791 > part.addparam(b'new', enc(b'0'))
801 > def fail(pushop, exc):
792 > def fail(pushop, exc):
802 > raise error.Abort(b'Correct phase push failed (because hooks)')
793 > raise error.Abort(b'Correct phase push failed (because hooks)')
803 > pushop.pkfailcb[part.id] = fail
794 > pushop.pkfailcb[part.id] = fail
804 > EOF
795 > EOF
805 $ cat >> $HGRCPATH << EOF
796 $ cat >> $HGRCPATH << EOF
806 > [hooks]
797 > [hooks]
807 > pretxnchangegroup=
798 > pretxnchangegroup=
808 > pretxnclose.failpush=
799 > pretxnclose.failpush=
809 > prepushkey.failpush = sh -c "echo 'do not push the key !'; false"
800 > prepushkey.failpush = sh -c "echo 'do not push the key !'; false"
810 > [extensions]
801 > [extensions]
811 > mandatorypart=$TESTTMP/mandatorypart.py
802 > mandatorypart=$TESTTMP/mandatorypart.py
812 > EOF
803 > EOF
813 $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS # reload http config
804 $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS # reload http config
814 $ hg serve -R other -p $HGPORT2 -d --pid-file=other.pid -E other-error.log
805 $ hg serve -R other -p $HGPORT2 -d --pid-file=other.pid -E other-error.log
815 $ cat other.pid >> $DAEMON_PIDS
806 $ cat other.pid >> $DAEMON_PIDS
816
807
817 (Failure from a hook)
808 (Failure from a hook)
818
809
819 $ hg -R main push other -r e7ec4e813ba6
810 $ hg -R main push other -r e7ec4e813ba6
820 pushing to other
811 pushing to other
821 searching for changes
812 searching for changes
822 adding changesets
813 adding changesets
823 adding manifests
814 adding manifests
824 adding file changes
815 adding file changes
825 added 1 changesets with 1 changes to 1 files
826 do not push the key !
816 do not push the key !
827 pushkey-abort: prepushkey.failpush hook exited with status 1
817 pushkey-abort: prepushkey.failpush hook exited with status 1
828 transaction abort!
818 transaction abort!
829 Cleaning up the mess...
819 Cleaning up the mess...
830 rollback completed
820 rollback completed
831 abort: Correct phase push failed (because hooks)
821 abort: Correct phase push failed (because hooks)
832 [255]
822 [255]
833 $ hg -R main push ssh://user@dummy/other -r e7ec4e813ba6
823 $ hg -R main push ssh://user@dummy/other -r e7ec4e813ba6
834 pushing to ssh://user@dummy/other
824 pushing to ssh://user@dummy/other
835 searching for changes
825 searching for changes
836 remote: adding changesets
826 remote: adding changesets
837 remote: adding manifests
827 remote: adding manifests
838 remote: adding file changes
828 remote: adding file changes
839 remote: added 1 changesets with 1 changes to 1 files
840 remote: do not push the key !
829 remote: do not push the key !
841 remote: pushkey-abort: prepushkey.failpush hook exited with status 1
830 remote: pushkey-abort: prepushkey.failpush hook exited with status 1
842 remote: transaction abort!
831 remote: transaction abort!
843 remote: Cleaning up the mess...
832 remote: Cleaning up the mess...
844 remote: rollback completed
833 remote: rollback completed
845 abort: Correct phase push failed (because hooks)
834 abort: Correct phase push failed (because hooks)
846 [255]
835 [255]
847 $ hg -R main push http://localhost:$HGPORT2/ -r e7ec4e813ba6
836 $ hg -R main push http://localhost:$HGPORT2/ -r e7ec4e813ba6
848 pushing to http://localhost:$HGPORT2/
837 pushing to http://localhost:$HGPORT2/
849 searching for changes
838 searching for changes
850 remote: adding changesets
839 remote: adding changesets
851 remote: adding manifests
840 remote: adding manifests
852 remote: adding file changes
841 remote: adding file changes
853 remote: added 1 changesets with 1 changes to 1 files
854 remote: do not push the key !
842 remote: do not push the key !
855 remote: pushkey-abort: prepushkey.failpush hook exited with status 1
843 remote: pushkey-abort: prepushkey.failpush hook exited with status 1
856 remote: transaction abort!
844 remote: transaction abort!
857 remote: Cleaning up the mess...
845 remote: Cleaning up the mess...
858 remote: rollback completed
846 remote: rollback completed
859 abort: Correct phase push failed (because hooks)
847 abort: Correct phase push failed (because hooks)
860 [255]
848 [255]
861
849
862 (Failure from a the pushkey)
850 (Failure from a the pushkey)
863
851
864 $ cat > mandatorypart.py << EOF
852 $ cat > mandatorypart.py << EOF
865 > from mercurial import exchange
853 > from mercurial import exchange
866 > from mercurial import pushkey
854 > from mercurial import pushkey
867 > from mercurial import node
855 > from mercurial import node
868 > from mercurial import error
856 > from mercurial import error
869 > @exchange.b2partsgenerator(b'failingpuskey')
857 > @exchange.b2partsgenerator(b'failingpuskey')
870 > def addfailingpushey(pushop, bundler):
858 > def addfailingpushey(pushop, bundler):
871 > enc = pushkey.encode
859 > enc = pushkey.encode
872 > part = bundler.newpart(b'pushkey')
860 > part = bundler.newpart(b'pushkey')
873 > part.addparam(b'namespace', enc(b'phases'))
861 > part.addparam(b'namespace', enc(b'phases'))
874 > part.addparam(b'key', enc(b'cd010b8cd998f3981a5a8115f94f8da4ab506089'))
862 > part.addparam(b'key', enc(b'cd010b8cd998f3981a5a8115f94f8da4ab506089'))
875 > part.addparam(b'old', enc(b'4')) # will fail
863 > part.addparam(b'old', enc(b'4')) # will fail
876 > part.addparam(b'new', enc(b'3'))
864 > part.addparam(b'new', enc(b'3'))
877 > def fail(pushop, exc):
865 > def fail(pushop, exc):
878 > raise error.Abort(b'Clown phase push failed')
866 > raise error.Abort(b'Clown phase push failed')
879 > pushop.pkfailcb[part.id] = fail
867 > pushop.pkfailcb[part.id] = fail
880 > EOF
868 > EOF
881 $ cat >> $HGRCPATH << EOF
869 $ cat >> $HGRCPATH << EOF
882 > [hooks]
870 > [hooks]
883 > prepushkey.failpush =
871 > prepushkey.failpush =
884 > EOF
872 > EOF
885 $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS # reload http config
873 $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS # reload http config
886 $ hg serve -R other -p $HGPORT2 -d --pid-file=other.pid -E other-error.log
874 $ hg serve -R other -p $HGPORT2 -d --pid-file=other.pid -E other-error.log
887 $ cat other.pid >> $DAEMON_PIDS
875 $ cat other.pid >> $DAEMON_PIDS
888
876
889 $ hg -R main push other -r e7ec4e813ba6
877 $ hg -R main push other -r e7ec4e813ba6
890 pushing to other
878 pushing to other
891 searching for changes
879 searching for changes
892 adding changesets
880 adding changesets
893 adding manifests
881 adding manifests
894 adding file changes
882 adding file changes
895 added 1 changesets with 1 changes to 1 files
896 transaction abort!
883 transaction abort!
897 Cleaning up the mess...
884 Cleaning up the mess...
898 rollback completed
885 rollback completed
899 pushkey: lock state after "phases"
886 pushkey: lock state after "phases"
900 lock: free
887 lock: free
901 wlock: free
888 wlock: free
902 abort: Clown phase push failed
889 abort: Clown phase push failed
903 [255]
890 [255]
904 $ hg -R main push ssh://user@dummy/other -r e7ec4e813ba6
891 $ hg -R main push ssh://user@dummy/other -r e7ec4e813ba6
905 pushing to ssh://user@dummy/other
892 pushing to ssh://user@dummy/other
906 searching for changes
893 searching for changes
907 remote: adding changesets
894 remote: adding changesets
908 remote: adding manifests
895 remote: adding manifests
909 remote: adding file changes
896 remote: adding file changes
910 remote: added 1 changesets with 1 changes to 1 files
911 remote: transaction abort!
897 remote: transaction abort!
912 remote: Cleaning up the mess...
898 remote: Cleaning up the mess...
913 remote: rollback completed
899 remote: rollback completed
914 remote: pushkey: lock state after "phases"
900 remote: pushkey: lock state after "phases"
915 remote: lock: free
901 remote: lock: free
916 remote: wlock: free
902 remote: wlock: free
917 abort: Clown phase push failed
903 abort: Clown phase push failed
918 [255]
904 [255]
919 $ hg -R main push http://localhost:$HGPORT2/ -r e7ec4e813ba6
905 $ hg -R main push http://localhost:$HGPORT2/ -r e7ec4e813ba6
920 pushing to http://localhost:$HGPORT2/
906 pushing to http://localhost:$HGPORT2/
921 searching for changes
907 searching for changes
922 remote: adding changesets
908 remote: adding changesets
923 remote: adding manifests
909 remote: adding manifests
924 remote: adding file changes
910 remote: adding file changes
925 remote: added 1 changesets with 1 changes to 1 files
926 remote: transaction abort!
911 remote: transaction abort!
927 remote: Cleaning up the mess...
912 remote: Cleaning up the mess...
928 remote: rollback completed
913 remote: rollback completed
929 remote: pushkey: lock state after "phases"
914 remote: pushkey: lock state after "phases"
930 remote: lock: free
915 remote: lock: free
931 remote: wlock: free
916 remote: wlock: free
932 abort: Clown phase push failed
917 abort: Clown phase push failed
933 [255]
918 [255]
934
919
935 Test lazily acquiring the lock during unbundle
920 Test lazily acquiring the lock during unbundle
936 $ cp $TESTTMP/hgrc.orig $HGRCPATH
921 $ cp $TESTTMP/hgrc.orig $HGRCPATH
937 $ cat >> $HGRCPATH <<EOF
922 $ cat >> $HGRCPATH <<EOF
938 > [ui]
923 > [ui]
939 > ssh="$PYTHON" "$TESTDIR/dummyssh"
924 > ssh="$PYTHON" "$TESTDIR/dummyssh"
940 > EOF
925 > EOF
941
926
942 $ cat >> $TESTTMP/locktester.py <<EOF
927 $ cat >> $TESTTMP/locktester.py <<EOF
943 > import os
928 > import os
944 > from mercurial import bundle2, error, extensions
929 > from mercurial import bundle2, error, extensions
945 > def checklock(orig, repo, *args, **kwargs):
930 > def checklock(orig, repo, *args, **kwargs):
946 > if repo.svfs.lexists(b"lock"):
931 > if repo.svfs.lexists(b"lock"):
947 > raise error.Abort(b"Lock should not be taken")
932 > raise error.Abort(b"Lock should not be taken")
948 > return orig(repo, *args, **kwargs)
933 > return orig(repo, *args, **kwargs)
949 > def extsetup(ui):
934 > def extsetup(ui):
950 > extensions.wrapfunction(bundle2, b'processbundle', checklock)
935 > extensions.wrapfunction(bundle2, b'processbundle', checklock)
951 > EOF
936 > EOF
952
937
953 $ hg init lazylock
938 $ hg init lazylock
954 $ cat >> lazylock/.hg/hgrc <<EOF
939 $ cat >> lazylock/.hg/hgrc <<EOF
955 > [extensions]
940 > [extensions]
956 > locktester=$TESTTMP/locktester.py
941 > locktester=$TESTTMP/locktester.py
957 > EOF
942 > EOF
958
943
959 $ hg clone -q ssh://user@dummy/lazylock lazylockclient
944 $ hg clone -q ssh://user@dummy/lazylock lazylockclient
960 $ cd lazylockclient
945 $ cd lazylockclient
961 $ touch a && hg ci -Aqm a
946 $ touch a && hg ci -Aqm a
962 $ hg push
947 $ hg push
963 pushing to ssh://user@dummy/lazylock
948 pushing to ssh://user@dummy/lazylock
964 searching for changes
949 searching for changes
965 remote: Lock should not be taken
950 remote: Lock should not be taken
966 abort: push failed on remote
951 abort: push failed on remote
967 [255]
952 [255]
968
953
969 $ cat >> ../lazylock/.hg/hgrc <<EOF
954 $ cat >> ../lazylock/.hg/hgrc <<EOF
970 > [experimental]
955 > [experimental]
971 > bundle2lazylocking=True
956 > bundle2lazylocking=True
972 > EOF
957 > EOF
973 $ hg push
958 $ hg push
974 pushing to ssh://user@dummy/lazylock
959 pushing to ssh://user@dummy/lazylock
975 searching for changes
960 searching for changes
976 remote: adding changesets
961 remote: adding changesets
977 remote: adding manifests
962 remote: adding manifests
978 remote: adding file changes
963 remote: adding file changes
979 remote: added 1 changesets with 1 changes to 1 files
964 remote: added 1 changesets with 1 changes to 1 files
980
965
981 $ cd ..
966 $ cd ..
982
967
983 Servers can disable bundle1 for clone/pull operations
968 Servers can disable bundle1 for clone/pull operations
984
969
985 $ killdaemons.py
970 $ killdaemons.py
986 $ hg init bundle2onlyserver
971 $ hg init bundle2onlyserver
987 $ cd bundle2onlyserver
972 $ cd bundle2onlyserver
988 $ cat > .hg/hgrc << EOF
973 $ cat > .hg/hgrc << EOF
989 > [server]
974 > [server]
990 > bundle1.pull = false
975 > bundle1.pull = false
991 > EOF
976 > EOF
992
977
993 $ touch foo
978 $ touch foo
994 $ hg -q commit -A -m initial
979 $ hg -q commit -A -m initial
995
980
996 $ hg serve -p $HGPORT -d --pid-file=hg.pid
981 $ hg serve -p $HGPORT -d --pid-file=hg.pid
997 $ cat hg.pid >> $DAEMON_PIDS
982 $ cat hg.pid >> $DAEMON_PIDS
998
983
999 $ hg --config devel.legacy.exchange=bundle1 clone http://localhost:$HGPORT/ not-bundle2
984 $ hg --config devel.legacy.exchange=bundle1 clone http://localhost:$HGPORT/ not-bundle2
1000 requesting all changes
985 requesting all changes
1001 abort: remote error:
986 abort: remote error:
1002 incompatible Mercurial client; bundle2 required
987 incompatible Mercurial client; bundle2 required
1003 (see https://www.mercurial-scm.org/wiki/IncompatibleClient)
988 (see https://www.mercurial-scm.org/wiki/IncompatibleClient)
1004 [255]
989 [255]
1005 $ killdaemons.py
990 $ killdaemons.py
1006 $ cd ..
991 $ cd ..
1007
992
1008 bundle1 can still pull non-generaldelta repos when generaldelta bundle1 disabled
993 bundle1 can still pull non-generaldelta repos when generaldelta bundle1 disabled
1009
994
1010 $ hg --config format.usegeneraldelta=false init notgdserver
995 $ hg --config format.usegeneraldelta=false init notgdserver
1011 $ cd notgdserver
996 $ cd notgdserver
1012 $ cat > .hg/hgrc << EOF
997 $ cat > .hg/hgrc << EOF
1013 > [server]
998 > [server]
1014 > bundle1gd.pull = false
999 > bundle1gd.pull = false
1015 > EOF
1000 > EOF
1016
1001
1017 $ touch foo
1002 $ touch foo
1018 $ hg -q commit -A -m initial
1003 $ hg -q commit -A -m initial
1019 $ hg serve -p $HGPORT -d --pid-file=hg.pid
1004 $ hg serve -p $HGPORT -d --pid-file=hg.pid
1020 $ cat hg.pid >> $DAEMON_PIDS
1005 $ cat hg.pid >> $DAEMON_PIDS
1021
1006
1022 $ hg --config devel.legacy.exchange=bundle1 clone http://localhost:$HGPORT/ not-bundle2-1
1007 $ hg --config devel.legacy.exchange=bundle1 clone http://localhost:$HGPORT/ not-bundle2-1
1023 requesting all changes
1008 requesting all changes
1024 adding changesets
1009 adding changesets
1025 adding manifests
1010 adding manifests
1026 adding file changes
1011 adding file changes
1027 added 1 changesets with 1 changes to 1 files
1012 added 1 changesets with 1 changes to 1 files
1028 new changesets 96ee1d7354c4
1013 new changesets 96ee1d7354c4
1029 updating to branch default
1014 updating to branch default
1030 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1015 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1031
1016
1032 $ killdaemons.py
1017 $ killdaemons.py
1033 $ cd ../bundle2onlyserver
1018 $ cd ../bundle2onlyserver
1034
1019
1035 bundle1 pull can be disabled for generaldelta repos only
1020 bundle1 pull can be disabled for generaldelta repos only
1036
1021
1037 $ cat > .hg/hgrc << EOF
1022 $ cat > .hg/hgrc << EOF
1038 > [server]
1023 > [server]
1039 > bundle1gd.pull = false
1024 > bundle1gd.pull = false
1040 > EOF
1025 > EOF
1041
1026
1042 $ hg serve -p $HGPORT -d --pid-file=hg.pid
1027 $ hg serve -p $HGPORT -d --pid-file=hg.pid
1043 $ cat hg.pid >> $DAEMON_PIDS
1028 $ cat hg.pid >> $DAEMON_PIDS
1044 $ hg --config devel.legacy.exchange=bundle1 clone http://localhost:$HGPORT/ not-bundle2
1029 $ hg --config devel.legacy.exchange=bundle1 clone http://localhost:$HGPORT/ not-bundle2
1045 requesting all changes
1030 requesting all changes
1046 abort: remote error:
1031 abort: remote error:
1047 incompatible Mercurial client; bundle2 required
1032 incompatible Mercurial client; bundle2 required
1048 (see https://www.mercurial-scm.org/wiki/IncompatibleClient)
1033 (see https://www.mercurial-scm.org/wiki/IncompatibleClient)
1049 [255]
1034 [255]
1050
1035
1051 $ killdaemons.py
1036 $ killdaemons.py
1052
1037
1053 Verify the global server.bundle1 option works
1038 Verify the global server.bundle1 option works
1054
1039
1055 $ cd ..
1040 $ cd ..
1056 $ cat > bundle2onlyserver/.hg/hgrc << EOF
1041 $ cat > bundle2onlyserver/.hg/hgrc << EOF
1057 > [server]
1042 > [server]
1058 > bundle1 = false
1043 > bundle1 = false
1059 > EOF
1044 > EOF
1060 $ hg serve -R bundle2onlyserver -p $HGPORT -d --pid-file=hg.pid
1045 $ hg serve -R bundle2onlyserver -p $HGPORT -d --pid-file=hg.pid
1061 $ cat hg.pid >> $DAEMON_PIDS
1046 $ cat hg.pid >> $DAEMON_PIDS
1062 $ hg --config devel.legacy.exchange=bundle1 clone http://localhost:$HGPORT not-bundle2
1047 $ hg --config devel.legacy.exchange=bundle1 clone http://localhost:$HGPORT not-bundle2
1063 requesting all changes
1048 requesting all changes
1064 abort: remote error:
1049 abort: remote error:
1065 incompatible Mercurial client; bundle2 required
1050 incompatible Mercurial client; bundle2 required
1066 (see https://www.mercurial-scm.org/wiki/IncompatibleClient)
1051 (see https://www.mercurial-scm.org/wiki/IncompatibleClient)
1067 [255]
1052 [255]
1068 $ killdaemons.py
1053 $ killdaemons.py
1069
1054
1070 $ hg --config devel.legacy.exchange=bundle1 clone ssh://user@dummy/bundle2onlyserver not-bundle2-ssh
1055 $ hg --config devel.legacy.exchange=bundle1 clone ssh://user@dummy/bundle2onlyserver not-bundle2-ssh
1071 requesting all changes
1056 requesting all changes
1072 adding changesets
1057 adding changesets
1073 remote: abort: incompatible Mercurial client; bundle2 required
1058 remote: abort: incompatible Mercurial client; bundle2 required
1074 remote: (see https://www.mercurial-scm.org/wiki/IncompatibleClient)
1059 remote: (see https://www.mercurial-scm.org/wiki/IncompatibleClient)
1075 transaction abort!
1060 transaction abort!
1076 rollback completed
1061 rollback completed
1077 abort: stream ended unexpectedly (got 0 bytes, expected 4)
1062 abort: stream ended unexpectedly (got 0 bytes, expected 4)
1078 [255]
1063 [255]
1079
1064
1080 $ cat > bundle2onlyserver/.hg/hgrc << EOF
1065 $ cat > bundle2onlyserver/.hg/hgrc << EOF
1081 > [server]
1066 > [server]
1082 > bundle1gd = false
1067 > bundle1gd = false
1083 > EOF
1068 > EOF
1084 $ hg serve -R bundle2onlyserver -p $HGPORT -d --pid-file=hg.pid
1069 $ hg serve -R bundle2onlyserver -p $HGPORT -d --pid-file=hg.pid
1085 $ cat hg.pid >> $DAEMON_PIDS
1070 $ cat hg.pid >> $DAEMON_PIDS
1086
1071
1087 $ hg --config devel.legacy.exchange=bundle1 clone http://localhost:$HGPORT/ not-bundle2
1072 $ hg --config devel.legacy.exchange=bundle1 clone http://localhost:$HGPORT/ not-bundle2
1088 requesting all changes
1073 requesting all changes
1089 abort: remote error:
1074 abort: remote error:
1090 incompatible Mercurial client; bundle2 required
1075 incompatible Mercurial client; bundle2 required
1091 (see https://www.mercurial-scm.org/wiki/IncompatibleClient)
1076 (see https://www.mercurial-scm.org/wiki/IncompatibleClient)
1092 [255]
1077 [255]
1093
1078
1094 $ killdaemons.py
1079 $ killdaemons.py
1095
1080
1096 $ cd notgdserver
1081 $ cd notgdserver
1097 $ cat > .hg/hgrc << EOF
1082 $ cat > .hg/hgrc << EOF
1098 > [server]
1083 > [server]
1099 > bundle1gd = false
1084 > bundle1gd = false
1100 > EOF
1085 > EOF
1101 $ hg serve -p $HGPORT -d --pid-file=hg.pid
1086 $ hg serve -p $HGPORT -d --pid-file=hg.pid
1102 $ cat hg.pid >> $DAEMON_PIDS
1087 $ cat hg.pid >> $DAEMON_PIDS
1103
1088
1104 $ hg --config devel.legacy.exchange=bundle1 clone http://localhost:$HGPORT/ not-bundle2-2
1089 $ hg --config devel.legacy.exchange=bundle1 clone http://localhost:$HGPORT/ not-bundle2-2
1105 requesting all changes
1090 requesting all changes
1106 adding changesets
1091 adding changesets
1107 adding manifests
1092 adding manifests
1108 adding file changes
1093 adding file changes
1109 added 1 changesets with 1 changes to 1 files
1094 added 1 changesets with 1 changes to 1 files
1110 new changesets 96ee1d7354c4
1095 new changesets 96ee1d7354c4
1111 updating to branch default
1096 updating to branch default
1112 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1097 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1113
1098
1114 $ killdaemons.py
1099 $ killdaemons.py
1115 $ cd ../bundle2onlyserver
1100 $ cd ../bundle2onlyserver
1116
1101
1117 Verify bundle1 pushes can be disabled
1102 Verify bundle1 pushes can be disabled
1118
1103
1119 $ cat > .hg/hgrc << EOF
1104 $ cat > .hg/hgrc << EOF
1120 > [server]
1105 > [server]
1121 > bundle1.push = false
1106 > bundle1.push = false
1122 > [web]
1107 > [web]
1123 > allow_push = *
1108 > allow_push = *
1124 > push_ssl = false
1109 > push_ssl = false
1125 > EOF
1110 > EOF
1126
1111
1127 $ hg serve -p $HGPORT -d --pid-file=hg.pid -E error.log
1112 $ hg serve -p $HGPORT -d --pid-file=hg.pid -E error.log
1128 $ cat hg.pid >> $DAEMON_PIDS
1113 $ cat hg.pid >> $DAEMON_PIDS
1129 $ cd ..
1114 $ cd ..
1130
1115
1131 $ hg clone http://localhost:$HGPORT bundle2-only
1116 $ hg clone http://localhost:$HGPORT bundle2-only
1132 requesting all changes
1117 requesting all changes
1133 adding changesets
1118 adding changesets
1134 adding manifests
1119 adding manifests
1135 adding file changes
1120 adding file changes
1136 added 1 changesets with 1 changes to 1 files
1121 added 1 changesets with 1 changes to 1 files
1137 new changesets 96ee1d7354c4
1122 new changesets 96ee1d7354c4
1138 updating to branch default
1123 updating to branch default
1139 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1124 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1140 $ cd bundle2-only
1125 $ cd bundle2-only
1141 $ echo commit > foo
1126 $ echo commit > foo
1142 $ hg commit -m commit
1127 $ hg commit -m commit
1143 $ hg --config devel.legacy.exchange=bundle1 push
1128 $ hg --config devel.legacy.exchange=bundle1 push
1144 pushing to http://localhost:$HGPORT/
1129 pushing to http://localhost:$HGPORT/
1145 searching for changes
1130 searching for changes
1146 abort: remote error:
1131 abort: remote error:
1147 incompatible Mercurial client; bundle2 required
1132 incompatible Mercurial client; bundle2 required
1148 (see https://www.mercurial-scm.org/wiki/IncompatibleClient)
1133 (see https://www.mercurial-scm.org/wiki/IncompatibleClient)
1149 [255]
1134 [255]
1150
1135
1151 (also check with ssh)
1136 (also check with ssh)
1152
1137
1153 $ hg --config devel.legacy.exchange=bundle1 push ssh://user@dummy/bundle2onlyserver
1138 $ hg --config devel.legacy.exchange=bundle1 push ssh://user@dummy/bundle2onlyserver
1154 pushing to ssh://user@dummy/bundle2onlyserver
1139 pushing to ssh://user@dummy/bundle2onlyserver
1155 searching for changes
1140 searching for changes
1156 remote: abort: incompatible Mercurial client; bundle2 required
1141 remote: abort: incompatible Mercurial client; bundle2 required
1157 remote: (see https://www.mercurial-scm.org/wiki/IncompatibleClient)
1142 remote: (see https://www.mercurial-scm.org/wiki/IncompatibleClient)
1158 [1]
1143 [1]
1159
1144
1160 $ hg push
1145 $ hg push
1161 pushing to http://localhost:$HGPORT/
1146 pushing to http://localhost:$HGPORT/
1162 searching for changes
1147 searching for changes
1163 remote: adding changesets
1148 remote: adding changesets
1164 remote: adding manifests
1149 remote: adding manifests
1165 remote: adding file changes
1150 remote: adding file changes
1166 remote: added 1 changesets with 1 changes to 1 files
1151 remote: added 1 changesets with 1 changes to 1 files
@@ -1,1237 +1,1236 b''
1 This test is dedicated to test the bundle2 container format
1 This test is dedicated to test the bundle2 container format
2
2
3 It test multiple existing parts to test different feature of the container. You
3 It test multiple existing parts to test different feature of the container. You
4 probably do not need to touch this test unless you change the binary encoding
4 probably do not need to touch this test unless you change the binary encoding
5 of the bundle2 format itself.
5 of the bundle2 format itself.
6
6
7 Create an extension to test bundle2 API
7 Create an extension to test bundle2 API
8
8
9 $ cat > bundle2.py << EOF
9 $ cat > bundle2.py << EOF
10 > """A small extension to test bundle2 implementation
10 > """A small extension to test bundle2 implementation
11 >
11 >
12 > This extension allows detailed testing of the various bundle2 API and
12 > This extension allows detailed testing of the various bundle2 API and
13 > behaviors.
13 > behaviors.
14 > """
14 > """
15 > import gc
15 > import gc
16 > import os
16 > import os
17 > import sys
17 > import sys
18 > from mercurial import util
18 > from mercurial import util
19 > from mercurial import bundle2
19 > from mercurial import bundle2
20 > from mercurial import scmutil
20 > from mercurial import scmutil
21 > from mercurial import discovery
21 > from mercurial import discovery
22 > from mercurial import changegroup
22 > from mercurial import changegroup
23 > from mercurial import error
23 > from mercurial import error
24 > from mercurial import obsolete
24 > from mercurial import obsolete
25 > from mercurial import pycompat
25 > from mercurial import pycompat
26 > from mercurial import registrar
26 > from mercurial import registrar
27 >
27 >
28 >
28 >
29 > try:
29 > try:
30 > import msvcrt
30 > import msvcrt
31 > msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
31 > msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
32 > msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
32 > msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
33 > msvcrt.setmode(sys.stderr.fileno(), os.O_BINARY)
33 > msvcrt.setmode(sys.stderr.fileno(), os.O_BINARY)
34 > except ImportError:
34 > except ImportError:
35 > pass
35 > pass
36 >
36 >
37 > cmdtable = {}
37 > cmdtable = {}
38 > command = registrar.command(cmdtable)
38 > command = registrar.command(cmdtable)
39 >
39 >
40 > ELEPHANTSSONG = b"""Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko
40 > ELEPHANTSSONG = b"""Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko
41 > Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
41 > Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
42 > Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko."""
42 > Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko."""
43 > assert len(ELEPHANTSSONG) == 178 # future test say 178 bytes, trust it.
43 > assert len(ELEPHANTSSONG) == 178 # future test say 178 bytes, trust it.
44 >
44 >
45 > @bundle2.parthandler(b'test:song')
45 > @bundle2.parthandler(b'test:song')
46 > def songhandler(op, part):
46 > def songhandler(op, part):
47 > """handle a "test:song" bundle2 part, printing the lyrics on stdin"""
47 > """handle a "test:song" bundle2 part, printing the lyrics on stdin"""
48 > op.ui.write(b'The choir starts singing:\n')
48 > op.ui.write(b'The choir starts singing:\n')
49 > verses = 0
49 > verses = 0
50 > for line in part.read().split(b'\n'):
50 > for line in part.read().split(b'\n'):
51 > op.ui.write(b' %s\n' % line)
51 > op.ui.write(b' %s\n' % line)
52 > verses += 1
52 > verses += 1
53 > op.records.add(b'song', {b'verses': verses})
53 > op.records.add(b'song', {b'verses': verses})
54 >
54 >
55 > @bundle2.parthandler(b'test:ping')
55 > @bundle2.parthandler(b'test:ping')
56 > def pinghandler(op, part):
56 > def pinghandler(op, part):
57 > op.ui.write(b'received ping request (id %i)\n' % part.id)
57 > op.ui.write(b'received ping request (id %i)\n' % part.id)
58 > if op.reply is not None and b'ping-pong' in op.reply.capabilities:
58 > if op.reply is not None and b'ping-pong' in op.reply.capabilities:
59 > op.ui.write_err(b'replying to ping request (id %i)\n' % part.id)
59 > op.ui.write_err(b'replying to ping request (id %i)\n' % part.id)
60 > op.reply.newpart(b'test:pong', [(b'in-reply-to', b'%d' % part.id)],
60 > op.reply.newpart(b'test:pong', [(b'in-reply-to', b'%d' % part.id)],
61 > mandatory=False)
61 > mandatory=False)
62 >
62 >
63 > @bundle2.parthandler(b'test:debugreply')
63 > @bundle2.parthandler(b'test:debugreply')
64 > def debugreply(op, part):
64 > def debugreply(op, part):
65 > """print data about the capacity of the bundle reply"""
65 > """print data about the capacity of the bundle reply"""
66 > if op.reply is None:
66 > if op.reply is None:
67 > op.ui.write(b'debugreply: no reply\n')
67 > op.ui.write(b'debugreply: no reply\n')
68 > else:
68 > else:
69 > op.ui.write(b'debugreply: capabilities:\n')
69 > op.ui.write(b'debugreply: capabilities:\n')
70 > for cap in sorted(op.reply.capabilities):
70 > for cap in sorted(op.reply.capabilities):
71 > op.ui.write(b"debugreply: '%s'\n" % cap)
71 > op.ui.write(b"debugreply: '%s'\n" % cap)
72 > for val in op.reply.capabilities[cap]:
72 > for val in op.reply.capabilities[cap]:
73 > op.ui.write(b"debugreply: '%s'\n" % val)
73 > op.ui.write(b"debugreply: '%s'\n" % val)
74 >
74 >
75 > @command(b'bundle2',
75 > @command(b'bundle2',
76 > [(b'', b'param', [], b'stream level parameter'),
76 > [(b'', b'param', [], b'stream level parameter'),
77 > (b'', b'unknown', False, b'include an unknown mandatory part in the bundle'),
77 > (b'', b'unknown', False, b'include an unknown mandatory part in the bundle'),
78 > (b'', b'unknownparams', False, b'include an unknown part parameters in the bundle'),
78 > (b'', b'unknownparams', False, b'include an unknown part parameters in the bundle'),
79 > (b'', b'parts', False, b'include some arbitrary parts to the bundle'),
79 > (b'', b'parts', False, b'include some arbitrary parts to the bundle'),
80 > (b'', b'reply', False, b'produce a reply bundle'),
80 > (b'', b'reply', False, b'produce a reply bundle'),
81 > (b'', b'pushrace', False, b'includes a check:head part with unknown nodes'),
81 > (b'', b'pushrace', False, b'includes a check:head part with unknown nodes'),
82 > (b'', b'genraise', False, b'includes a part that raise an exception during generation'),
82 > (b'', b'genraise', False, b'includes a part that raise an exception during generation'),
83 > (b'', b'timeout', False, b'emulate a timeout during bundle generation'),
83 > (b'', b'timeout', False, b'emulate a timeout during bundle generation'),
84 > (b'r', b'rev', [], b'includes those changeset in the bundle'),
84 > (b'r', b'rev', [], b'includes those changeset in the bundle'),
85 > (b'', b'compress', b'', b'compress the stream'),
85 > (b'', b'compress', b'', b'compress the stream'),
86 > ],
86 > ],
87 > b'[OUTPUTFILE]')
87 > b'[OUTPUTFILE]')
88 > def cmdbundle2(ui, repo, path=None, **opts):
88 > def cmdbundle2(ui, repo, path=None, **opts):
89 > """write a bundle2 container on standard output"""
89 > """write a bundle2 container on standard output"""
90 > bundler = bundle2.bundle20(ui)
90 > bundler = bundle2.bundle20(ui)
91 > for p in opts['param']:
91 > for p in opts['param']:
92 > p = p.split(b'=', 1)
92 > p = p.split(b'=', 1)
93 > try:
93 > try:
94 > bundler.addparam(*p)
94 > bundler.addparam(*p)
95 > except error.ProgrammingError as exc:
95 > except error.ProgrammingError as exc:
96 > raise error.Abort(b'%s' % exc)
96 > raise error.Abort(b'%s' % exc)
97 >
97 >
98 > if opts['compress']:
98 > if opts['compress']:
99 > bundler.setcompression(opts['compress'])
99 > bundler.setcompression(opts['compress'])
100 >
100 >
101 > if opts['reply']:
101 > if opts['reply']:
102 > capsstring = b'ping-pong\nelephants=babar,celeste\ncity%3D%21=celeste%2Cville'
102 > capsstring = b'ping-pong\nelephants=babar,celeste\ncity%3D%21=celeste%2Cville'
103 > bundler.newpart(b'replycaps', data=capsstring)
103 > bundler.newpart(b'replycaps', data=capsstring)
104 >
104 >
105 > if opts['pushrace']:
105 > if opts['pushrace']:
106 > # also serve to test the assignement of data outside of init
106 > # also serve to test the assignement of data outside of init
107 > part = bundler.newpart(b'check:heads')
107 > part = bundler.newpart(b'check:heads')
108 > part.data = b'01234567890123456789'
108 > part.data = b'01234567890123456789'
109 >
109 >
110 > revs = opts['rev']
110 > revs = opts['rev']
111 > if 'rev' in opts:
111 > if 'rev' in opts:
112 > revs = scmutil.revrange(repo, opts['rev'])
112 > revs = scmutil.revrange(repo, opts['rev'])
113 > if revs:
113 > if revs:
114 > # very crude version of a changegroup part creation
114 > # very crude version of a changegroup part creation
115 > bundled = repo.revs('%ld::%ld', revs, revs)
115 > bundled = repo.revs('%ld::%ld', revs, revs)
116 > headmissing = [c.node() for c in repo.set('heads(%ld)', revs)]
116 > headmissing = [c.node() for c in repo.set('heads(%ld)', revs)]
117 > headcommon = [c.node() for c in repo.set('parents(%ld) - %ld', revs, revs)]
117 > headcommon = [c.node() for c in repo.set('parents(%ld) - %ld', revs, revs)]
118 > outgoing = discovery.outgoing(repo, headcommon, headmissing)
118 > outgoing = discovery.outgoing(repo, headcommon, headmissing)
119 > cg = changegroup.makechangegroup(repo, outgoing, b'01',
119 > cg = changegroup.makechangegroup(repo, outgoing, b'01',
120 > b'test:bundle2')
120 > b'test:bundle2')
121 > bundler.newpart(b'changegroup', data=cg.getchunks(),
121 > bundler.newpart(b'changegroup', data=cg.getchunks(),
122 > mandatory=False)
122 > mandatory=False)
123 >
123 >
124 > if opts['parts']:
124 > if opts['parts']:
125 > bundler.newpart(b'test:empty', mandatory=False)
125 > bundler.newpart(b'test:empty', mandatory=False)
126 > # add a second one to make sure we handle multiple parts
126 > # add a second one to make sure we handle multiple parts
127 > bundler.newpart(b'test:empty', mandatory=False)
127 > bundler.newpart(b'test:empty', mandatory=False)
128 > bundler.newpart(b'test:song', data=ELEPHANTSSONG, mandatory=False)
128 > bundler.newpart(b'test:song', data=ELEPHANTSSONG, mandatory=False)
129 > bundler.newpart(b'test:debugreply', mandatory=False)
129 > bundler.newpart(b'test:debugreply', mandatory=False)
130 > mathpart = bundler.newpart(b'test:math')
130 > mathpart = bundler.newpart(b'test:math')
131 > mathpart.addparam(b'pi', b'3.14')
131 > mathpart.addparam(b'pi', b'3.14')
132 > mathpart.addparam(b'e', b'2.72')
132 > mathpart.addparam(b'e', b'2.72')
133 > mathpart.addparam(b'cooking', b'raw', mandatory=False)
133 > mathpart.addparam(b'cooking', b'raw', mandatory=False)
134 > mathpart.data = b'42'
134 > mathpart.data = b'42'
135 > mathpart.mandatory = False
135 > mathpart.mandatory = False
136 > # advisory known part with unknown mandatory param
136 > # advisory known part with unknown mandatory param
137 > bundler.newpart(b'test:song', [(b'randomparam', b'')], mandatory=False)
137 > bundler.newpart(b'test:song', [(b'randomparam', b'')], mandatory=False)
138 > if opts['unknown']:
138 > if opts['unknown']:
139 > bundler.newpart(b'test:unknown', data=b'some random content')
139 > bundler.newpart(b'test:unknown', data=b'some random content')
140 > if opts['unknownparams']:
140 > if opts['unknownparams']:
141 > bundler.newpart(b'test:song', [(b'randomparams', b'')])
141 > bundler.newpart(b'test:song', [(b'randomparams', b'')])
142 > if opts['parts']:
142 > if opts['parts']:
143 > bundler.newpart(b'test:ping', mandatory=False)
143 > bundler.newpart(b'test:ping', mandatory=False)
144 > if opts['genraise']:
144 > if opts['genraise']:
145 > def genraise():
145 > def genraise():
146 > yield b'first line\n'
146 > yield b'first line\n'
147 > raise RuntimeError('Someone set up us the bomb!')
147 > raise RuntimeError('Someone set up us the bomb!')
148 > bundler.newpart(b'output', data=genraise(), mandatory=False)
148 > bundler.newpart(b'output', data=genraise(), mandatory=False)
149 >
149 >
150 > if path is None:
150 > if path is None:
151 > file = pycompat.stdout
151 > file = pycompat.stdout
152 > else:
152 > else:
153 > file = open(path, 'wb')
153 > file = open(path, 'wb')
154 >
154 >
155 > if opts['timeout']:
155 > if opts['timeout']:
156 > bundler.newpart(b'test:song', data=ELEPHANTSSONG, mandatory=False)
156 > bundler.newpart(b'test:song', data=ELEPHANTSSONG, mandatory=False)
157 > for idx, junk in enumerate(bundler.getchunks()):
157 > for idx, junk in enumerate(bundler.getchunks()):
158 > ui.write(b'%d chunk\n' % idx)
158 > ui.write(b'%d chunk\n' % idx)
159 > if idx > 4:
159 > if idx > 4:
160 > # This throws a GeneratorExit inside the generator, which
160 > # This throws a GeneratorExit inside the generator, which
161 > # can cause problems if the exception-recovery code is
161 > # can cause problems if the exception-recovery code is
162 > # too zealous. It's important for this test that the break
162 > # too zealous. It's important for this test that the break
163 > # occur while we're in the middle of a part.
163 > # occur while we're in the middle of a part.
164 > break
164 > break
165 > gc.collect()
165 > gc.collect()
166 > ui.write(b'fake timeout complete.\n')
166 > ui.write(b'fake timeout complete.\n')
167 > return
167 > return
168 > try:
168 > try:
169 > for chunk in bundler.getchunks():
169 > for chunk in bundler.getchunks():
170 > file.write(chunk)
170 > file.write(chunk)
171 > except RuntimeError as exc:
171 > except RuntimeError as exc:
172 > raise error.Abort(exc)
172 > raise error.Abort(exc)
173 > finally:
173 > finally:
174 > file.flush()
174 > file.flush()
175 >
175 >
176 > @command(b'unbundle2', [], b'')
176 > @command(b'unbundle2', [], b'')
177 > def cmdunbundle2(ui, repo, replypath=None):
177 > def cmdunbundle2(ui, repo, replypath=None):
178 > """process a bundle2 stream from stdin on the current repo"""
178 > """process a bundle2 stream from stdin on the current repo"""
179 > try:
179 > try:
180 > tr = None
180 > tr = None
181 > lock = repo.lock()
181 > lock = repo.lock()
182 > tr = repo.transaction(b'processbundle')
182 > tr = repo.transaction(b'processbundle')
183 > try:
183 > try:
184 > unbundler = bundle2.getunbundler(ui, pycompat.stdin)
184 > unbundler = bundle2.getunbundler(ui, pycompat.stdin)
185 > op = bundle2.processbundle(repo, unbundler, lambda: tr)
185 > op = bundle2.processbundle(repo, unbundler, lambda: tr)
186 > tr.close()
186 > tr.close()
187 > except error.BundleValueError as exc:
187 > except error.BundleValueError as exc:
188 > raise error.Abort(b'missing support for %s' % exc)
188 > raise error.Abort(b'missing support for %s' % exc)
189 > except error.PushRaced as exc:
189 > except error.PushRaced as exc:
190 > raise error.Abort(b'push race: %s' % exc)
190 > raise error.Abort(b'push race: %s' % exc)
191 > finally:
191 > finally:
192 > if tr is not None:
192 > if tr is not None:
193 > tr.release()
193 > tr.release()
194 > lock.release()
194 > lock.release()
195 > remains = pycompat.stdin.read()
195 > remains = pycompat.stdin.read()
196 > ui.write(b'%i unread bytes\n' % len(remains))
196 > ui.write(b'%i unread bytes\n' % len(remains))
197 > if op.records[b'song']:
197 > if op.records[b'song']:
198 > totalverses = sum(r[b'verses'] for r in op.records[b'song'])
198 > totalverses = sum(r[b'verses'] for r in op.records[b'song'])
199 > ui.write(b'%i total verses sung\n' % totalverses)
199 > ui.write(b'%i total verses sung\n' % totalverses)
200 > for rec in op.records[b'changegroup']:
200 > for rec in op.records[b'changegroup']:
201 > ui.write(b'addchangegroup return: %i\n' % rec[b'return'])
201 > ui.write(b'addchangegroup return: %i\n' % rec[b'return'])
202 > if op.reply is not None and replypath is not None:
202 > if op.reply is not None and replypath is not None:
203 > with open(replypath, 'wb') as file:
203 > with open(replypath, 'wb') as file:
204 > for chunk in op.reply.getchunks():
204 > for chunk in op.reply.getchunks():
205 > file.write(chunk)
205 > file.write(chunk)
206 >
206 >
207 > @command(b'statbundle2', [], b'')
207 > @command(b'statbundle2', [], b'')
208 > def cmdstatbundle2(ui, repo):
208 > def cmdstatbundle2(ui, repo):
209 > """print statistic on the bundle2 container read from stdin"""
209 > """print statistic on the bundle2 container read from stdin"""
210 > unbundler = bundle2.getunbundler(ui, pycompat.stdin)
210 > unbundler = bundle2.getunbundler(ui, pycompat.stdin)
211 > try:
211 > try:
212 > params = unbundler.params
212 > params = unbundler.params
213 > except error.BundleValueError as exc:
213 > except error.BundleValueError as exc:
214 > raise error.Abort(b'unknown parameters: %s' % exc)
214 > raise error.Abort(b'unknown parameters: %s' % exc)
215 > ui.write(b'options count: %i\n' % len(params))
215 > ui.write(b'options count: %i\n' % len(params))
216 > for key in sorted(params):
216 > for key in sorted(params):
217 > ui.write(b'- %s\n' % key)
217 > ui.write(b'- %s\n' % key)
218 > value = params[key]
218 > value = params[key]
219 > if value is not None:
219 > if value is not None:
220 > ui.write(b' %s\n' % value)
220 > ui.write(b' %s\n' % value)
221 > count = 0
221 > count = 0
222 > for p in unbundler.iterparts():
222 > for p in unbundler.iterparts():
223 > count += 1
223 > count += 1
224 > ui.write(b' :%s:\n' % p.type)
224 > ui.write(b' :%s:\n' % p.type)
225 > ui.write(b' mandatory: %i\n' % len(p.mandatoryparams))
225 > ui.write(b' mandatory: %i\n' % len(p.mandatoryparams))
226 > ui.write(b' advisory: %i\n' % len(p.advisoryparams))
226 > ui.write(b' advisory: %i\n' % len(p.advisoryparams))
227 > ui.write(b' payload: %i bytes\n' % len(p.read()))
227 > ui.write(b' payload: %i bytes\n' % len(p.read()))
228 > ui.write(b'parts count: %i\n' % count)
228 > ui.write(b'parts count: %i\n' % count)
229 > EOF
229 > EOF
230 $ cat >> $HGRCPATH << EOF
230 $ cat >> $HGRCPATH << EOF
231 > [extensions]
231 > [extensions]
232 > bundle2=$TESTTMP/bundle2.py
232 > bundle2=$TESTTMP/bundle2.py
233 > [experimental]
233 > [experimental]
234 > evolution.createmarkers=True
234 > evolution.createmarkers=True
235 > [ui]
235 > [ui]
236 > ssh="$PYTHON" "$TESTDIR/dummyssh"
236 > ssh="$PYTHON" "$TESTDIR/dummyssh"
237 > logtemplate={rev}:{node|short} {phase} {author} {bookmarks} {desc|firstline}
237 > logtemplate={rev}:{node|short} {phase} {author} {bookmarks} {desc|firstline}
238 > [web]
238 > [web]
239 > push_ssl = false
239 > push_ssl = false
240 > allow_push = *
240 > allow_push = *
241 > [phases]
241 > [phases]
242 > publish=False
242 > publish=False
243 > EOF
243 > EOF
244
244
245 The extension requires a repo (currently unused)
245 The extension requires a repo (currently unused)
246
246
247 $ hg init main
247 $ hg init main
248 $ cd main
248 $ cd main
249 $ touch a
249 $ touch a
250 $ hg add a
250 $ hg add a
251 $ hg commit -m 'a'
251 $ hg commit -m 'a'
252
252
253
253
254 Empty bundle
254 Empty bundle
255 =================
255 =================
256
256
257 - no option
257 - no option
258 - no parts
258 - no parts
259
259
260 Test bundling
260 Test bundling
261
261
262 $ hg bundle2 | f --hexdump
262 $ hg bundle2 | f --hexdump
263
263
264 0000: 48 47 32 30 00 00 00 00 00 00 00 00 |HG20........|
264 0000: 48 47 32 30 00 00 00 00 00 00 00 00 |HG20........|
265
265
266 Test timeouts during bundling
266 Test timeouts during bundling
267 $ hg bundle2 --timeout --debug --config devel.bundle2.debug=yes
267 $ hg bundle2 --timeout --debug --config devel.bundle2.debug=yes
268 bundle2-output-bundle: "HG20", 1 parts total
268 bundle2-output-bundle: "HG20", 1 parts total
269 bundle2-output: start emission of HG20 stream
269 bundle2-output: start emission of HG20 stream
270 0 chunk
270 0 chunk
271 bundle2-output: bundle parameter:
271 bundle2-output: bundle parameter:
272 1 chunk
272 1 chunk
273 bundle2-output: start of parts
273 bundle2-output: start of parts
274 bundle2-output: bundle part: "test:song"
274 bundle2-output: bundle part: "test:song"
275 bundle2-output-part: "test:song" (advisory) 178 bytes payload
275 bundle2-output-part: "test:song" (advisory) 178 bytes payload
276 bundle2-output: part 0: "test:song"
276 bundle2-output: part 0: "test:song"
277 bundle2-output: header chunk size: 16
277 bundle2-output: header chunk size: 16
278 2 chunk
278 2 chunk
279 3 chunk
279 3 chunk
280 bundle2-output: payload chunk size: 178
280 bundle2-output: payload chunk size: 178
281 4 chunk
281 4 chunk
282 5 chunk
282 5 chunk
283 bundle2-generatorexit
283 bundle2-generatorexit
284 fake timeout complete.
284 fake timeout complete.
285
285
286 Test unbundling
286 Test unbundling
287
287
288 $ hg bundle2 | hg statbundle2
288 $ hg bundle2 | hg statbundle2
289 options count: 0
289 options count: 0
290 parts count: 0
290 parts count: 0
291
291
292 Test old style bundle are detected and refused
292 Test old style bundle are detected and refused
293
293
294 $ hg bundle --all --type v1 ../bundle.hg
294 $ hg bundle --all --type v1 ../bundle.hg
295 1 changesets found
295 1 changesets found
296 $ hg statbundle2 < ../bundle.hg
296 $ hg statbundle2 < ../bundle.hg
297 abort: unknown bundle version 10
297 abort: unknown bundle version 10
298 [255]
298 [255]
299
299
300 Test parameters
300 Test parameters
301 =================
301 =================
302
302
303 - some options
303 - some options
304 - no parts
304 - no parts
305
305
306 advisory parameters, no value
306 advisory parameters, no value
307 -------------------------------
307 -------------------------------
308
308
309 Simplest possible parameters form
309 Simplest possible parameters form
310
310
311 Test generation simple option
311 Test generation simple option
312
312
313 $ hg bundle2 --param 'caution' | f --hexdump
313 $ hg bundle2 --param 'caution' | f --hexdump
314
314
315 0000: 48 47 32 30 00 00 00 07 63 61 75 74 69 6f 6e 00 |HG20....caution.|
315 0000: 48 47 32 30 00 00 00 07 63 61 75 74 69 6f 6e 00 |HG20....caution.|
316 0010: 00 00 00 |...|
316 0010: 00 00 00 |...|
317
317
318 Test unbundling
318 Test unbundling
319
319
320 $ hg bundle2 --param 'caution' | hg statbundle2
320 $ hg bundle2 --param 'caution' | hg statbundle2
321 options count: 1
321 options count: 1
322 - caution
322 - caution
323 parts count: 0
323 parts count: 0
324
324
325 Test generation multiple option
325 Test generation multiple option
326
326
327 $ hg bundle2 --param 'caution' --param 'meal' | f --hexdump
327 $ hg bundle2 --param 'caution' --param 'meal' | f --hexdump
328
328
329 0000: 48 47 32 30 00 00 00 0c 63 61 75 74 69 6f 6e 20 |HG20....caution |
329 0000: 48 47 32 30 00 00 00 0c 63 61 75 74 69 6f 6e 20 |HG20....caution |
330 0010: 6d 65 61 6c 00 00 00 00 |meal....|
330 0010: 6d 65 61 6c 00 00 00 00 |meal....|
331
331
332 Test unbundling
332 Test unbundling
333
333
334 $ hg bundle2 --param 'caution' --param 'meal' | hg statbundle2
334 $ hg bundle2 --param 'caution' --param 'meal' | hg statbundle2
335 options count: 2
335 options count: 2
336 - caution
336 - caution
337 - meal
337 - meal
338 parts count: 0
338 parts count: 0
339
339
340 advisory parameters, with value
340 advisory parameters, with value
341 -------------------------------
341 -------------------------------
342
342
343 Test generation
343 Test generation
344
344
345 $ hg bundle2 --param 'caution' --param 'meal=vegan' --param 'elephants' | f --hexdump
345 $ hg bundle2 --param 'caution' --param 'meal=vegan' --param 'elephants' | f --hexdump
346
346
347 0000: 48 47 32 30 00 00 00 1c 63 61 75 74 69 6f 6e 20 |HG20....caution |
347 0000: 48 47 32 30 00 00 00 1c 63 61 75 74 69 6f 6e 20 |HG20....caution |
348 0010: 6d 65 61 6c 3d 76 65 67 61 6e 20 65 6c 65 70 68 |meal=vegan eleph|
348 0010: 6d 65 61 6c 3d 76 65 67 61 6e 20 65 6c 65 70 68 |meal=vegan eleph|
349 0020: 61 6e 74 73 00 00 00 00 |ants....|
349 0020: 61 6e 74 73 00 00 00 00 |ants....|
350
350
351 Test unbundling
351 Test unbundling
352
352
353 $ hg bundle2 --param 'caution' --param 'meal=vegan' --param 'elephants' | hg statbundle2
353 $ hg bundle2 --param 'caution' --param 'meal=vegan' --param 'elephants' | hg statbundle2
354 options count: 3
354 options count: 3
355 - caution
355 - caution
356 - elephants
356 - elephants
357 - meal
357 - meal
358 vegan
358 vegan
359 parts count: 0
359 parts count: 0
360
360
361 parameter with special char in value
361 parameter with special char in value
362 ---------------------------------------------------
362 ---------------------------------------------------
363
363
364 Test generation
364 Test generation
365
365
366 $ hg bundle2 --param 'e|! 7/=babar%#==tutu' --param simple | f --hexdump
366 $ hg bundle2 --param 'e|! 7/=babar%#==tutu' --param simple | f --hexdump
367
367
368 0000: 48 47 32 30 00 00 00 29 65 25 37 43 25 32 31 25 |HG20...)e%7C%21%|
368 0000: 48 47 32 30 00 00 00 29 65 25 37 43 25 32 31 25 |HG20...)e%7C%21%|
369 0010: 32 30 37 2f 3d 62 61 62 61 72 25 32 35 25 32 33 |207/=babar%25%23|
369 0010: 32 30 37 2f 3d 62 61 62 61 72 25 32 35 25 32 33 |207/=babar%25%23|
370 0020: 25 33 44 25 33 44 74 75 74 75 20 73 69 6d 70 6c |%3D%3Dtutu simpl|
370 0020: 25 33 44 25 33 44 74 75 74 75 20 73 69 6d 70 6c |%3D%3Dtutu simpl|
371 0030: 65 00 00 00 00 |e....|
371 0030: 65 00 00 00 00 |e....|
372
372
373 Test unbundling
373 Test unbundling
374
374
375 $ hg bundle2 --param 'e|! 7/=babar%#==tutu' --param simple | hg statbundle2
375 $ hg bundle2 --param 'e|! 7/=babar%#==tutu' --param simple | hg statbundle2
376 options count: 2
376 options count: 2
377 - e|! 7/
377 - e|! 7/
378 babar%#==tutu
378 babar%#==tutu
379 - simple
379 - simple
380 parts count: 0
380 parts count: 0
381
381
382 Test unknown mandatory option
382 Test unknown mandatory option
383 ---------------------------------------------------
383 ---------------------------------------------------
384
384
385 $ hg bundle2 --param 'Gravity' | hg statbundle2
385 $ hg bundle2 --param 'Gravity' | hg statbundle2
386 abort: unknown parameters: Stream Parameter - Gravity
386 abort: unknown parameters: Stream Parameter - Gravity
387 [255]
387 [255]
388
388
389 Test debug output
389 Test debug output
390 ---------------------------------------------------
390 ---------------------------------------------------
391
391
392 bundling debug
392 bundling debug
393
393
394 $ hg bundle2 --debug --param 'e|! 7/=babar%#==tutu' --param simple ../out.hg2 --config progress.debug=true --config devel.bundle2.debug=true
394 $ hg bundle2 --debug --param 'e|! 7/=babar%#==tutu' --param simple ../out.hg2 --config progress.debug=true --config devel.bundle2.debug=true
395 bundle2-output-bundle: "HG20", (2 params) 0 parts total
395 bundle2-output-bundle: "HG20", (2 params) 0 parts total
396 bundle2-output: start emission of HG20 stream
396 bundle2-output: start emission of HG20 stream
397 bundle2-output: bundle parameter: e%7C%21%207/=babar%25%23%3D%3Dtutu simple
397 bundle2-output: bundle parameter: e%7C%21%207/=babar%25%23%3D%3Dtutu simple
398 bundle2-output: start of parts
398 bundle2-output: start of parts
399 bundle2-output: end of bundle
399 bundle2-output: end of bundle
400
400
401 file content is ok
401 file content is ok
402
402
403 $ f --hexdump ../out.hg2
403 $ f --hexdump ../out.hg2
404 ../out.hg2:
404 ../out.hg2:
405 0000: 48 47 32 30 00 00 00 29 65 25 37 43 25 32 31 25 |HG20...)e%7C%21%|
405 0000: 48 47 32 30 00 00 00 29 65 25 37 43 25 32 31 25 |HG20...)e%7C%21%|
406 0010: 32 30 37 2f 3d 62 61 62 61 72 25 32 35 25 32 33 |207/=babar%25%23|
406 0010: 32 30 37 2f 3d 62 61 62 61 72 25 32 35 25 32 33 |207/=babar%25%23|
407 0020: 25 33 44 25 33 44 74 75 74 75 20 73 69 6d 70 6c |%3D%3Dtutu simpl|
407 0020: 25 33 44 25 33 44 74 75 74 75 20 73 69 6d 70 6c |%3D%3Dtutu simpl|
408 0030: 65 00 00 00 00 |e....|
408 0030: 65 00 00 00 00 |e....|
409
409
410 unbundling debug
410 unbundling debug
411
411
412 $ hg statbundle2 --debug --config progress.debug=true --config devel.bundle2.debug=true < ../out.hg2
412 $ hg statbundle2 --debug --config progress.debug=true --config devel.bundle2.debug=true < ../out.hg2
413 bundle2-input: start processing of HG20 stream
413 bundle2-input: start processing of HG20 stream
414 bundle2-input: reading bundle2 stream parameters
414 bundle2-input: reading bundle2 stream parameters
415 bundle2-input: ignoring unknown parameter e|! 7/
415 bundle2-input: ignoring unknown parameter e|! 7/
416 bundle2-input: ignoring unknown parameter simple
416 bundle2-input: ignoring unknown parameter simple
417 options count: 2
417 options count: 2
418 - e|! 7/
418 - e|! 7/
419 babar%#==tutu
419 babar%#==tutu
420 - simple
420 - simple
421 bundle2-input: start extraction of bundle2 parts
421 bundle2-input: start extraction of bundle2 parts
422 bundle2-input: part header size: 0
422 bundle2-input: part header size: 0
423 bundle2-input: end of bundle2 stream
423 bundle2-input: end of bundle2 stream
424 parts count: 0
424 parts count: 0
425
425
426
426
427 Test buggy input
427 Test buggy input
428 ---------------------------------------------------
428 ---------------------------------------------------
429
429
430 empty parameter name
430 empty parameter name
431
431
432 $ hg bundle2 --param '' --quiet
432 $ hg bundle2 --param '' --quiet
433 abort: empty parameter name
433 abort: empty parameter name
434 [255]
434 [255]
435
435
436 bad parameter name
436 bad parameter name
437
437
438 $ hg bundle2 --param 42babar
438 $ hg bundle2 --param 42babar
439 abort: non letter first character: 42babar
439 abort: non letter first character: 42babar
440 [255]
440 [255]
441
441
442
442
443 Test part
443 Test part
444 =================
444 =================
445
445
446 $ hg bundle2 --parts ../parts.hg2 --debug --config progress.debug=true --config devel.bundle2.debug=true
446 $ hg bundle2 --parts ../parts.hg2 --debug --config progress.debug=true --config devel.bundle2.debug=true
447 bundle2-output-bundle: "HG20", 7 parts total
447 bundle2-output-bundle: "HG20", 7 parts total
448 bundle2-output: start emission of HG20 stream
448 bundle2-output: start emission of HG20 stream
449 bundle2-output: bundle parameter:
449 bundle2-output: bundle parameter:
450 bundle2-output: start of parts
450 bundle2-output: start of parts
451 bundle2-output: bundle part: "test:empty"
451 bundle2-output: bundle part: "test:empty"
452 bundle2-output-part: "test:empty" (advisory) empty payload
452 bundle2-output-part: "test:empty" (advisory) empty payload
453 bundle2-output: part 0: "test:empty"
453 bundle2-output: part 0: "test:empty"
454 bundle2-output: header chunk size: 17
454 bundle2-output: header chunk size: 17
455 bundle2-output: closing payload chunk
455 bundle2-output: closing payload chunk
456 bundle2-output: bundle part: "test:empty"
456 bundle2-output: bundle part: "test:empty"
457 bundle2-output-part: "test:empty" (advisory) empty payload
457 bundle2-output-part: "test:empty" (advisory) empty payload
458 bundle2-output: part 1: "test:empty"
458 bundle2-output: part 1: "test:empty"
459 bundle2-output: header chunk size: 17
459 bundle2-output: header chunk size: 17
460 bundle2-output: closing payload chunk
460 bundle2-output: closing payload chunk
461 bundle2-output: bundle part: "test:song"
461 bundle2-output: bundle part: "test:song"
462 bundle2-output-part: "test:song" (advisory) 178 bytes payload
462 bundle2-output-part: "test:song" (advisory) 178 bytes payload
463 bundle2-output: part 2: "test:song"
463 bundle2-output: part 2: "test:song"
464 bundle2-output: header chunk size: 16
464 bundle2-output: header chunk size: 16
465 bundle2-output: payload chunk size: 178
465 bundle2-output: payload chunk size: 178
466 bundle2-output: closing payload chunk
466 bundle2-output: closing payload chunk
467 bundle2-output: bundle part: "test:debugreply"
467 bundle2-output: bundle part: "test:debugreply"
468 bundle2-output-part: "test:debugreply" (advisory) empty payload
468 bundle2-output-part: "test:debugreply" (advisory) empty payload
469 bundle2-output: part 3: "test:debugreply"
469 bundle2-output: part 3: "test:debugreply"
470 bundle2-output: header chunk size: 22
470 bundle2-output: header chunk size: 22
471 bundle2-output: closing payload chunk
471 bundle2-output: closing payload chunk
472 bundle2-output: bundle part: "test:math"
472 bundle2-output: bundle part: "test:math"
473 bundle2-output-part: "test:math" (advisory) (params: 2 mandatory 2 advisory) 2 bytes payload
473 bundle2-output-part: "test:math" (advisory) (params: 2 mandatory 2 advisory) 2 bytes payload
474 bundle2-output: part 4: "test:math"
474 bundle2-output: part 4: "test:math"
475 bundle2-output: header chunk size: 43
475 bundle2-output: header chunk size: 43
476 bundle2-output: payload chunk size: 2
476 bundle2-output: payload chunk size: 2
477 bundle2-output: closing payload chunk
477 bundle2-output: closing payload chunk
478 bundle2-output: bundle part: "test:song"
478 bundle2-output: bundle part: "test:song"
479 bundle2-output-part: "test:song" (advisory) (params: 1 mandatory) empty payload
479 bundle2-output-part: "test:song" (advisory) (params: 1 mandatory) empty payload
480 bundle2-output: part 5: "test:song"
480 bundle2-output: part 5: "test:song"
481 bundle2-output: header chunk size: 29
481 bundle2-output: header chunk size: 29
482 bundle2-output: closing payload chunk
482 bundle2-output: closing payload chunk
483 bundle2-output: bundle part: "test:ping"
483 bundle2-output: bundle part: "test:ping"
484 bundle2-output-part: "test:ping" (advisory) empty payload
484 bundle2-output-part: "test:ping" (advisory) empty payload
485 bundle2-output: part 6: "test:ping"
485 bundle2-output: part 6: "test:ping"
486 bundle2-output: header chunk size: 16
486 bundle2-output: header chunk size: 16
487 bundle2-output: closing payload chunk
487 bundle2-output: closing payload chunk
488 bundle2-output: end of bundle
488 bundle2-output: end of bundle
489
489
490 $ f --hexdump ../parts.hg2
490 $ f --hexdump ../parts.hg2
491 ../parts.hg2:
491 ../parts.hg2:
492 0000: 48 47 32 30 00 00 00 00 00 00 00 11 0a 74 65 73 |HG20.........tes|
492 0000: 48 47 32 30 00 00 00 00 00 00 00 11 0a 74 65 73 |HG20.........tes|
493 0010: 74 3a 65 6d 70 74 79 00 00 00 00 00 00 00 00 00 |t:empty.........|
493 0010: 74 3a 65 6d 70 74 79 00 00 00 00 00 00 00 00 00 |t:empty.........|
494 0020: 00 00 00 00 11 0a 74 65 73 74 3a 65 6d 70 74 79 |......test:empty|
494 0020: 00 00 00 00 11 0a 74 65 73 74 3a 65 6d 70 74 79 |......test:empty|
495 0030: 00 00 00 01 00 00 00 00 00 00 00 00 00 10 09 74 |...............t|
495 0030: 00 00 00 01 00 00 00 00 00 00 00 00 00 10 09 74 |...............t|
496 0040: 65 73 74 3a 73 6f 6e 67 00 00 00 02 00 00 00 00 |est:song........|
496 0040: 65 73 74 3a 73 6f 6e 67 00 00 00 02 00 00 00 00 |est:song........|
497 0050: 00 b2 50 61 74 61 6c 69 20 44 69 72 61 70 61 74 |..Patali Dirapat|
497 0050: 00 b2 50 61 74 61 6c 69 20 44 69 72 61 70 61 74 |..Patali Dirapat|
498 0060: 61 2c 20 43 72 6f 6d 64 61 20 43 72 6f 6d 64 61 |a, Cromda Cromda|
498 0060: 61 2c 20 43 72 6f 6d 64 61 20 43 72 6f 6d 64 61 |a, Cromda Cromda|
499 0070: 20 52 69 70 61 6c 6f 2c 20 50 61 74 61 20 50 61 | Ripalo, Pata Pa|
499 0070: 20 52 69 70 61 6c 6f 2c 20 50 61 74 61 20 50 61 | Ripalo, Pata Pa|
500 0080: 74 61 2c 20 4b 6f 20 4b 6f 20 4b 6f 0a 42 6f 6b |ta, Ko Ko Ko.Bok|
500 0080: 74 61 2c 20 4b 6f 20 4b 6f 20 4b 6f 0a 42 6f 6b |ta, Ko Ko Ko.Bok|
501 0090: 6f 72 6f 20 44 69 70 6f 75 6c 69 74 6f 2c 20 52 |oro Dipoulito, R|
501 0090: 6f 72 6f 20 44 69 70 6f 75 6c 69 74 6f 2c 20 52 |oro Dipoulito, R|
502 00a0: 6f 6e 64 69 20 52 6f 6e 64 69 20 50 65 70 69 6e |ondi Rondi Pepin|
502 00a0: 6f 6e 64 69 20 52 6f 6e 64 69 20 50 65 70 69 6e |ondi Rondi Pepin|
503 00b0: 6f 2c 20 50 61 74 61 20 50 61 74 61 2c 20 4b 6f |o, Pata Pata, Ko|
503 00b0: 6f 2c 20 50 61 74 61 20 50 61 74 61 2c 20 4b 6f |o, Pata Pata, Ko|
504 00c0: 20 4b 6f 20 4b 6f 0a 45 6d 61 6e 61 20 4b 61 72 | Ko Ko.Emana Kar|
504 00c0: 20 4b 6f 20 4b 6f 0a 45 6d 61 6e 61 20 4b 61 72 | Ko Ko.Emana Kar|
505 00d0: 61 73 73 6f 6c 69 2c 20 4c 6f 75 63 72 61 20 4c |assoli, Loucra L|
505 00d0: 61 73 73 6f 6c 69 2c 20 4c 6f 75 63 72 61 20 4c |assoli, Loucra L|
506 00e0: 6f 75 63 72 61 20 50 6f 6e 70 6f 6e 74 6f 2c 20 |oucra Ponponto, |
506 00e0: 6f 75 63 72 61 20 50 6f 6e 70 6f 6e 74 6f 2c 20 |oucra Ponponto, |
507 00f0: 50 61 74 61 20 50 61 74 61 2c 20 4b 6f 20 4b 6f |Pata Pata, Ko Ko|
507 00f0: 50 61 74 61 20 50 61 74 61 2c 20 4b 6f 20 4b 6f |Pata Pata, Ko Ko|
508 0100: 20 4b 6f 2e 00 00 00 00 00 00 00 16 0f 74 65 73 | Ko..........tes|
508 0100: 20 4b 6f 2e 00 00 00 00 00 00 00 16 0f 74 65 73 | Ko..........tes|
509 0110: 74 3a 64 65 62 75 67 72 65 70 6c 79 00 00 00 03 |t:debugreply....|
509 0110: 74 3a 64 65 62 75 67 72 65 70 6c 79 00 00 00 03 |t:debugreply....|
510 0120: 00 00 00 00 00 00 00 00 00 2b 09 74 65 73 74 3a |.........+.test:|
510 0120: 00 00 00 00 00 00 00 00 00 2b 09 74 65 73 74 3a |.........+.test:|
511 0130: 6d 61 74 68 00 00 00 04 02 01 02 04 01 04 07 03 |math............|
511 0130: 6d 61 74 68 00 00 00 04 02 01 02 04 01 04 07 03 |math............|
512 0140: 70 69 33 2e 31 34 65 32 2e 37 32 63 6f 6f 6b 69 |pi3.14e2.72cooki|
512 0140: 70 69 33 2e 31 34 65 32 2e 37 32 63 6f 6f 6b 69 |pi3.14e2.72cooki|
513 0150: 6e 67 72 61 77 00 00 00 02 34 32 00 00 00 00 00 |ngraw....42.....|
513 0150: 6e 67 72 61 77 00 00 00 02 34 32 00 00 00 00 00 |ngraw....42.....|
514 0160: 00 00 1d 09 74 65 73 74 3a 73 6f 6e 67 00 00 00 |....test:song...|
514 0160: 00 00 1d 09 74 65 73 74 3a 73 6f 6e 67 00 00 00 |....test:song...|
515 0170: 05 01 00 0b 00 72 61 6e 64 6f 6d 70 61 72 61 6d |.....randomparam|
515 0170: 05 01 00 0b 00 72 61 6e 64 6f 6d 70 61 72 61 6d |.....randomparam|
516 0180: 00 00 00 00 00 00 00 10 09 74 65 73 74 3a 70 69 |.........test:pi|
516 0180: 00 00 00 00 00 00 00 10 09 74 65 73 74 3a 70 69 |.........test:pi|
517 0190: 6e 67 00 00 00 06 00 00 00 00 00 00 00 00 00 00 |ng..............|
517 0190: 6e 67 00 00 00 06 00 00 00 00 00 00 00 00 00 00 |ng..............|
518
518
519
519
520 $ hg statbundle2 < ../parts.hg2
520 $ hg statbundle2 < ../parts.hg2
521 options count: 0
521 options count: 0
522 :test:empty:
522 :test:empty:
523 mandatory: 0
523 mandatory: 0
524 advisory: 0
524 advisory: 0
525 payload: 0 bytes
525 payload: 0 bytes
526 :test:empty:
526 :test:empty:
527 mandatory: 0
527 mandatory: 0
528 advisory: 0
528 advisory: 0
529 payload: 0 bytes
529 payload: 0 bytes
530 :test:song:
530 :test:song:
531 mandatory: 0
531 mandatory: 0
532 advisory: 0
532 advisory: 0
533 payload: 178 bytes
533 payload: 178 bytes
534 :test:debugreply:
534 :test:debugreply:
535 mandatory: 0
535 mandatory: 0
536 advisory: 0
536 advisory: 0
537 payload: 0 bytes
537 payload: 0 bytes
538 :test:math:
538 :test:math:
539 mandatory: 2
539 mandatory: 2
540 advisory: 1
540 advisory: 1
541 payload: 2 bytes
541 payload: 2 bytes
542 :test:song:
542 :test:song:
543 mandatory: 1
543 mandatory: 1
544 advisory: 0
544 advisory: 0
545 payload: 0 bytes
545 payload: 0 bytes
546 :test:ping:
546 :test:ping:
547 mandatory: 0
547 mandatory: 0
548 advisory: 0
548 advisory: 0
549 payload: 0 bytes
549 payload: 0 bytes
550 parts count: 7
550 parts count: 7
551
551
552 $ hg statbundle2 --debug --config progress.debug=true --config devel.bundle2.debug=true < ../parts.hg2
552 $ hg statbundle2 --debug --config progress.debug=true --config devel.bundle2.debug=true < ../parts.hg2
553 bundle2-input: start processing of HG20 stream
553 bundle2-input: start processing of HG20 stream
554 bundle2-input: reading bundle2 stream parameters
554 bundle2-input: reading bundle2 stream parameters
555 options count: 0
555 options count: 0
556 bundle2-input: start extraction of bundle2 parts
556 bundle2-input: start extraction of bundle2 parts
557 bundle2-input: part header size: 17
557 bundle2-input: part header size: 17
558 bundle2-input: part type: "test:empty"
558 bundle2-input: part type: "test:empty"
559 bundle2-input: part id: "0"
559 bundle2-input: part id: "0"
560 bundle2-input: part parameters: 0
560 bundle2-input: part parameters: 0
561 :test:empty:
561 :test:empty:
562 mandatory: 0
562 mandatory: 0
563 advisory: 0
563 advisory: 0
564 bundle2-input: payload chunk size: 0
564 bundle2-input: payload chunk size: 0
565 payload: 0 bytes
565 payload: 0 bytes
566 bundle2-input: part header size: 17
566 bundle2-input: part header size: 17
567 bundle2-input: part type: "test:empty"
567 bundle2-input: part type: "test:empty"
568 bundle2-input: part id: "1"
568 bundle2-input: part id: "1"
569 bundle2-input: part parameters: 0
569 bundle2-input: part parameters: 0
570 :test:empty:
570 :test:empty:
571 mandatory: 0
571 mandatory: 0
572 advisory: 0
572 advisory: 0
573 bundle2-input: payload chunk size: 0
573 bundle2-input: payload chunk size: 0
574 payload: 0 bytes
574 payload: 0 bytes
575 bundle2-input: part header size: 16
575 bundle2-input: part header size: 16
576 bundle2-input: part type: "test:song"
576 bundle2-input: part type: "test:song"
577 bundle2-input: part id: "2"
577 bundle2-input: part id: "2"
578 bundle2-input: part parameters: 0
578 bundle2-input: part parameters: 0
579 :test:song:
579 :test:song:
580 mandatory: 0
580 mandatory: 0
581 advisory: 0
581 advisory: 0
582 bundle2-input: payload chunk size: 178
582 bundle2-input: payload chunk size: 178
583 bundle2-input: payload chunk size: 0
583 bundle2-input: payload chunk size: 0
584 bundle2-input-part: total payload size 178
584 bundle2-input-part: total payload size 178
585 payload: 178 bytes
585 payload: 178 bytes
586 bundle2-input: part header size: 22
586 bundle2-input: part header size: 22
587 bundle2-input: part type: "test:debugreply"
587 bundle2-input: part type: "test:debugreply"
588 bundle2-input: part id: "3"
588 bundle2-input: part id: "3"
589 bundle2-input: part parameters: 0
589 bundle2-input: part parameters: 0
590 :test:debugreply:
590 :test:debugreply:
591 mandatory: 0
591 mandatory: 0
592 advisory: 0
592 advisory: 0
593 bundle2-input: payload chunk size: 0
593 bundle2-input: payload chunk size: 0
594 payload: 0 bytes
594 payload: 0 bytes
595 bundle2-input: part header size: 43
595 bundle2-input: part header size: 43
596 bundle2-input: part type: "test:math"
596 bundle2-input: part type: "test:math"
597 bundle2-input: part id: "4"
597 bundle2-input: part id: "4"
598 bundle2-input: part parameters: 3
598 bundle2-input: part parameters: 3
599 :test:math:
599 :test:math:
600 mandatory: 2
600 mandatory: 2
601 advisory: 1
601 advisory: 1
602 bundle2-input: payload chunk size: 2
602 bundle2-input: payload chunk size: 2
603 bundle2-input: payload chunk size: 0
603 bundle2-input: payload chunk size: 0
604 bundle2-input-part: total payload size 2
604 bundle2-input-part: total payload size 2
605 payload: 2 bytes
605 payload: 2 bytes
606 bundle2-input: part header size: 29
606 bundle2-input: part header size: 29
607 bundle2-input: part type: "test:song"
607 bundle2-input: part type: "test:song"
608 bundle2-input: part id: "5"
608 bundle2-input: part id: "5"
609 bundle2-input: part parameters: 1
609 bundle2-input: part parameters: 1
610 :test:song:
610 :test:song:
611 mandatory: 1
611 mandatory: 1
612 advisory: 0
612 advisory: 0
613 bundle2-input: payload chunk size: 0
613 bundle2-input: payload chunk size: 0
614 payload: 0 bytes
614 payload: 0 bytes
615 bundle2-input: part header size: 16
615 bundle2-input: part header size: 16
616 bundle2-input: part type: "test:ping"
616 bundle2-input: part type: "test:ping"
617 bundle2-input: part id: "6"
617 bundle2-input: part id: "6"
618 bundle2-input: part parameters: 0
618 bundle2-input: part parameters: 0
619 :test:ping:
619 :test:ping:
620 mandatory: 0
620 mandatory: 0
621 advisory: 0
621 advisory: 0
622 bundle2-input: payload chunk size: 0
622 bundle2-input: payload chunk size: 0
623 payload: 0 bytes
623 payload: 0 bytes
624 bundle2-input: part header size: 0
624 bundle2-input: part header size: 0
625 bundle2-input: end of bundle2 stream
625 bundle2-input: end of bundle2 stream
626 parts count: 7
626 parts count: 7
627
627
628 Test actual unbundling of test part
628 Test actual unbundling of test part
629 =======================================
629 =======================================
630
630
631 Process the bundle
631 Process the bundle
632
632
633 $ hg unbundle2 --debug --config progress.debug=true --config devel.bundle2.debug=true < ../parts.hg2
633 $ hg unbundle2 --debug --config progress.debug=true --config devel.bundle2.debug=true < ../parts.hg2
634 bundle2-input: start processing of HG20 stream
634 bundle2-input: start processing of HG20 stream
635 bundle2-input: reading bundle2 stream parameters
635 bundle2-input: reading bundle2 stream parameters
636 bundle2-input-bundle: with-transaction
636 bundle2-input-bundle: with-transaction
637 bundle2-input: start extraction of bundle2 parts
637 bundle2-input: start extraction of bundle2 parts
638 bundle2-input: part header size: 17
638 bundle2-input: part header size: 17
639 bundle2-input: part type: "test:empty"
639 bundle2-input: part type: "test:empty"
640 bundle2-input: part id: "0"
640 bundle2-input: part id: "0"
641 bundle2-input: part parameters: 0
641 bundle2-input: part parameters: 0
642 bundle2-input: ignoring unsupported advisory part test:empty
642 bundle2-input: ignoring unsupported advisory part test:empty
643 bundle2-input-part: "test:empty" (advisory) unsupported-type
643 bundle2-input-part: "test:empty" (advisory) unsupported-type
644 bundle2-input: payload chunk size: 0
644 bundle2-input: payload chunk size: 0
645 bundle2-input: part header size: 17
645 bundle2-input: part header size: 17
646 bundle2-input: part type: "test:empty"
646 bundle2-input: part type: "test:empty"
647 bundle2-input: part id: "1"
647 bundle2-input: part id: "1"
648 bundle2-input: part parameters: 0
648 bundle2-input: part parameters: 0
649 bundle2-input: ignoring unsupported advisory part test:empty
649 bundle2-input: ignoring unsupported advisory part test:empty
650 bundle2-input-part: "test:empty" (advisory) unsupported-type
650 bundle2-input-part: "test:empty" (advisory) unsupported-type
651 bundle2-input: payload chunk size: 0
651 bundle2-input: payload chunk size: 0
652 bundle2-input: part header size: 16
652 bundle2-input: part header size: 16
653 bundle2-input: part type: "test:song"
653 bundle2-input: part type: "test:song"
654 bundle2-input: part id: "2"
654 bundle2-input: part id: "2"
655 bundle2-input: part parameters: 0
655 bundle2-input: part parameters: 0
656 bundle2-input: found a handler for part test:song
656 bundle2-input: found a handler for part test:song
657 bundle2-input-part: "test:song" (advisory) supported
657 bundle2-input-part: "test:song" (advisory) supported
658 The choir starts singing:
658 The choir starts singing:
659 bundle2-input: payload chunk size: 178
659 bundle2-input: payload chunk size: 178
660 bundle2-input: payload chunk size: 0
660 bundle2-input: payload chunk size: 0
661 bundle2-input-part: total payload size 178
661 bundle2-input-part: total payload size 178
662 Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko
662 Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko
663 Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
663 Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
664 Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko.
664 Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko.
665 bundle2-input: part header size: 22
665 bundle2-input: part header size: 22
666 bundle2-input: part type: "test:debugreply"
666 bundle2-input: part type: "test:debugreply"
667 bundle2-input: part id: "3"
667 bundle2-input: part id: "3"
668 bundle2-input: part parameters: 0
668 bundle2-input: part parameters: 0
669 bundle2-input: found a handler for part test:debugreply
669 bundle2-input: found a handler for part test:debugreply
670 bundle2-input-part: "test:debugreply" (advisory) supported
670 bundle2-input-part: "test:debugreply" (advisory) supported
671 debugreply: no reply
671 debugreply: no reply
672 bundle2-input: payload chunk size: 0
672 bundle2-input: payload chunk size: 0
673 bundle2-input: part header size: 43
673 bundle2-input: part header size: 43
674 bundle2-input: part type: "test:math"
674 bundle2-input: part type: "test:math"
675 bundle2-input: part id: "4"
675 bundle2-input: part id: "4"
676 bundle2-input: part parameters: 3
676 bundle2-input: part parameters: 3
677 bundle2-input: ignoring unsupported advisory part test:math
677 bundle2-input: ignoring unsupported advisory part test:math
678 bundle2-input-part: "test:math" (advisory) (params: 2 mandatory 2 advisory) unsupported-type
678 bundle2-input-part: "test:math" (advisory) (params: 2 mandatory 2 advisory) unsupported-type
679 bundle2-input: payload chunk size: 2
679 bundle2-input: payload chunk size: 2
680 bundle2-input: payload chunk size: 0
680 bundle2-input: payload chunk size: 0
681 bundle2-input-part: total payload size 2
681 bundle2-input-part: total payload size 2
682 bundle2-input: part header size: 29
682 bundle2-input: part header size: 29
683 bundle2-input: part type: "test:song"
683 bundle2-input: part type: "test:song"
684 bundle2-input: part id: "5"
684 bundle2-input: part id: "5"
685 bundle2-input: part parameters: 1
685 bundle2-input: part parameters: 1
686 bundle2-input: found a handler for part test:song
686 bundle2-input: found a handler for part test:song
687 bundle2-input: ignoring unsupported advisory part test:song - randomparam
687 bundle2-input: ignoring unsupported advisory part test:song - randomparam
688 bundle2-input-part: "test:song" (advisory) (params: 1 mandatory) unsupported-params (randomparam)
688 bundle2-input-part: "test:song" (advisory) (params: 1 mandatory) unsupported-params (randomparam)
689 bundle2-input: payload chunk size: 0
689 bundle2-input: payload chunk size: 0
690 bundle2-input: part header size: 16
690 bundle2-input: part header size: 16
691 bundle2-input: part type: "test:ping"
691 bundle2-input: part type: "test:ping"
692 bundle2-input: part id: "6"
692 bundle2-input: part id: "6"
693 bundle2-input: part parameters: 0
693 bundle2-input: part parameters: 0
694 bundle2-input: found a handler for part test:ping
694 bundle2-input: found a handler for part test:ping
695 bundle2-input-part: "test:ping" (advisory) supported
695 bundle2-input-part: "test:ping" (advisory) supported
696 received ping request (id 6)
696 received ping request (id 6)
697 bundle2-input: payload chunk size: 0
697 bundle2-input: payload chunk size: 0
698 bundle2-input: part header size: 0
698 bundle2-input: part header size: 0
699 bundle2-input: end of bundle2 stream
699 bundle2-input: end of bundle2 stream
700 bundle2-input-bundle: 6 parts total
700 bundle2-input-bundle: 6 parts total
701 0 unread bytes
701 0 unread bytes
702 3 total verses sung
702 3 total verses sung
703
703
704 Unbundle with an unknown mandatory part
704 Unbundle with an unknown mandatory part
705 (should abort)
705 (should abort)
706
706
707 $ hg bundle2 --parts --unknown ../unknown.hg2
707 $ hg bundle2 --parts --unknown ../unknown.hg2
708
708
709 $ hg unbundle2 < ../unknown.hg2
709 $ hg unbundle2 < ../unknown.hg2
710 The choir starts singing:
710 The choir starts singing:
711 Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko
711 Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko
712 Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
712 Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
713 Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko.
713 Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko.
714 debugreply: no reply
714 debugreply: no reply
715 0 unread bytes
715 0 unread bytes
716 abort: missing support for test:unknown
716 abort: missing support for test:unknown
717 [255]
717 [255]
718
718
719 Unbundle with an unknown mandatory part parameters
719 Unbundle with an unknown mandatory part parameters
720 (should abort)
720 (should abort)
721
721
722 $ hg bundle2 --unknownparams ../unknown.hg2
722 $ hg bundle2 --unknownparams ../unknown.hg2
723
723
724 $ hg unbundle2 < ../unknown.hg2
724 $ hg unbundle2 < ../unknown.hg2
725 0 unread bytes
725 0 unread bytes
726 abort: missing support for test:song - randomparams
726 abort: missing support for test:song - randomparams
727 [255]
727 [255]
728
728
729 unbundle with a reply
729 unbundle with a reply
730
730
731 $ hg bundle2 --parts --reply ../parts-reply.hg2
731 $ hg bundle2 --parts --reply ../parts-reply.hg2
732 $ hg unbundle2 ../reply.hg2 < ../parts-reply.hg2
732 $ hg unbundle2 ../reply.hg2 < ../parts-reply.hg2
733 0 unread bytes
733 0 unread bytes
734 3 total verses sung
734 3 total verses sung
735
735
736 The reply is a bundle
736 The reply is a bundle
737
737
738 $ f --hexdump ../reply.hg2
738 $ f --hexdump ../reply.hg2
739 ../reply.hg2:
739 ../reply.hg2:
740 0000: 48 47 32 30 00 00 00 00 00 00 00 1b 06 6f 75 74 |HG20.........out|
740 0000: 48 47 32 30 00 00 00 00 00 00 00 1b 06 6f 75 74 |HG20.........out|
741 0010: 70 75 74 00 00 00 00 00 01 0b 01 69 6e 2d 72 65 |put........in-re|
741 0010: 70 75 74 00 00 00 00 00 01 0b 01 69 6e 2d 72 65 |put........in-re|
742 0020: 70 6c 79 2d 74 6f 33 00 00 00 d9 54 68 65 20 63 |ply-to3....The c|
742 0020: 70 6c 79 2d 74 6f 33 00 00 00 d9 54 68 65 20 63 |ply-to3....The c|
743 0030: 68 6f 69 72 20 73 74 61 72 74 73 20 73 69 6e 67 |hoir starts sing|
743 0030: 68 6f 69 72 20 73 74 61 72 74 73 20 73 69 6e 67 |hoir starts sing|
744 0040: 69 6e 67 3a 0a 20 20 20 20 50 61 74 61 6c 69 20 |ing:. Patali |
744 0040: 69 6e 67 3a 0a 20 20 20 20 50 61 74 61 6c 69 20 |ing:. Patali |
745 0050: 44 69 72 61 70 61 74 61 2c 20 43 72 6f 6d 64 61 |Dirapata, Cromda|
745 0050: 44 69 72 61 70 61 74 61 2c 20 43 72 6f 6d 64 61 |Dirapata, Cromda|
746 0060: 20 43 72 6f 6d 64 61 20 52 69 70 61 6c 6f 2c 20 | Cromda Ripalo, |
746 0060: 20 43 72 6f 6d 64 61 20 52 69 70 61 6c 6f 2c 20 | Cromda Ripalo, |
747 0070: 50 61 74 61 20 50 61 74 61 2c 20 4b 6f 20 4b 6f |Pata Pata, Ko Ko|
747 0070: 50 61 74 61 20 50 61 74 61 2c 20 4b 6f 20 4b 6f |Pata Pata, Ko Ko|
748 0080: 20 4b 6f 0a 20 20 20 20 42 6f 6b 6f 72 6f 20 44 | Ko. Bokoro D|
748 0080: 20 4b 6f 0a 20 20 20 20 42 6f 6b 6f 72 6f 20 44 | Ko. Bokoro D|
749 0090: 69 70 6f 75 6c 69 74 6f 2c 20 52 6f 6e 64 69 20 |ipoulito, Rondi |
749 0090: 69 70 6f 75 6c 69 74 6f 2c 20 52 6f 6e 64 69 20 |ipoulito, Rondi |
750 00a0: 52 6f 6e 64 69 20 50 65 70 69 6e 6f 2c 20 50 61 |Rondi Pepino, Pa|
750 00a0: 52 6f 6e 64 69 20 50 65 70 69 6e 6f 2c 20 50 61 |Rondi Pepino, Pa|
751 00b0: 74 61 20 50 61 74 61 2c 20 4b 6f 20 4b 6f 20 4b |ta Pata, Ko Ko K|
751 00b0: 74 61 20 50 61 74 61 2c 20 4b 6f 20 4b 6f 20 4b |ta Pata, Ko Ko K|
752 00c0: 6f 0a 20 20 20 20 45 6d 61 6e 61 20 4b 61 72 61 |o. Emana Kara|
752 00c0: 6f 0a 20 20 20 20 45 6d 61 6e 61 20 4b 61 72 61 |o. Emana Kara|
753 00d0: 73 73 6f 6c 69 2c 20 4c 6f 75 63 72 61 20 4c 6f |ssoli, Loucra Lo|
753 00d0: 73 73 6f 6c 69 2c 20 4c 6f 75 63 72 61 20 4c 6f |ssoli, Loucra Lo|
754 00e0: 75 63 72 61 20 50 6f 6e 70 6f 6e 74 6f 2c 20 50 |ucra Ponponto, P|
754 00e0: 75 63 72 61 20 50 6f 6e 70 6f 6e 74 6f 2c 20 50 |ucra Ponponto, P|
755 00f0: 61 74 61 20 50 61 74 61 2c 20 4b 6f 20 4b 6f 20 |ata Pata, Ko Ko |
755 00f0: 61 74 61 20 50 61 74 61 2c 20 4b 6f 20 4b 6f 20 |ata Pata, Ko Ko |
756 0100: 4b 6f 2e 0a 00 00 00 00 00 00 00 1b 06 6f 75 74 |Ko...........out|
756 0100: 4b 6f 2e 0a 00 00 00 00 00 00 00 1b 06 6f 75 74 |Ko...........out|
757 0110: 70 75 74 00 00 00 01 00 01 0b 01 69 6e 2d 72 65 |put........in-re|
757 0110: 70 75 74 00 00 00 01 00 01 0b 01 69 6e 2d 72 65 |put........in-re|
758 0120: 70 6c 79 2d 74 6f 34 00 00 00 c9 64 65 62 75 67 |ply-to4....debug|
758 0120: 70 6c 79 2d 74 6f 34 00 00 00 c9 64 65 62 75 67 |ply-to4....debug|
759 0130: 72 65 70 6c 79 3a 20 63 61 70 61 62 69 6c 69 74 |reply: capabilit|
759 0130: 72 65 70 6c 79 3a 20 63 61 70 61 62 69 6c 69 74 |reply: capabilit|
760 0140: 69 65 73 3a 0a 64 65 62 75 67 72 65 70 6c 79 3a |ies:.debugreply:|
760 0140: 69 65 73 3a 0a 64 65 62 75 67 72 65 70 6c 79 3a |ies:.debugreply:|
761 0150: 20 20 20 20 20 27 63 69 74 79 3d 21 27 0a 64 65 | 'city=!'.de|
761 0150: 20 20 20 20 20 27 63 69 74 79 3d 21 27 0a 64 65 | 'city=!'.de|
762 0160: 62 75 67 72 65 70 6c 79 3a 20 20 20 20 20 20 20 |bugreply: |
762 0160: 62 75 67 72 65 70 6c 79 3a 20 20 20 20 20 20 20 |bugreply: |
763 0170: 20 20 27 63 65 6c 65 73 74 65 2c 76 69 6c 6c 65 | 'celeste,ville|
763 0170: 20 20 27 63 65 6c 65 73 74 65 2c 76 69 6c 6c 65 | 'celeste,ville|
764 0180: 27 0a 64 65 62 75 67 72 65 70 6c 79 3a 20 20 20 |'.debugreply: |
764 0180: 27 0a 64 65 62 75 67 72 65 70 6c 79 3a 20 20 20 |'.debugreply: |
765 0190: 20 20 27 65 6c 65 70 68 61 6e 74 73 27 0a 64 65 | 'elephants'.de|
765 0190: 20 20 27 65 6c 65 70 68 61 6e 74 73 27 0a 64 65 | 'elephants'.de|
766 01a0: 62 75 67 72 65 70 6c 79 3a 20 20 20 20 20 20 20 |bugreply: |
766 01a0: 62 75 67 72 65 70 6c 79 3a 20 20 20 20 20 20 20 |bugreply: |
767 01b0: 20 20 27 62 61 62 61 72 27 0a 64 65 62 75 67 72 | 'babar'.debugr|
767 01b0: 20 20 27 62 61 62 61 72 27 0a 64 65 62 75 67 72 | 'babar'.debugr|
768 01c0: 65 70 6c 79 3a 20 20 20 20 20 20 20 20 20 27 63 |eply: 'c|
768 01c0: 65 70 6c 79 3a 20 20 20 20 20 20 20 20 20 27 63 |eply: 'c|
769 01d0: 65 6c 65 73 74 65 27 0a 64 65 62 75 67 72 65 70 |eleste'.debugrep|
769 01d0: 65 6c 65 73 74 65 27 0a 64 65 62 75 67 72 65 70 |eleste'.debugrep|
770 01e0: 6c 79 3a 20 20 20 20 20 27 70 69 6e 67 2d 70 6f |ly: 'ping-po|
770 01e0: 6c 79 3a 20 20 20 20 20 27 70 69 6e 67 2d 70 6f |ly: 'ping-po|
771 01f0: 6e 67 27 0a 00 00 00 00 00 00 00 1e 09 74 65 73 |ng'..........tes|
771 01f0: 6e 67 27 0a 00 00 00 00 00 00 00 1e 09 74 65 73 |ng'..........tes|
772 0200: 74 3a 70 6f 6e 67 00 00 00 02 01 00 0b 01 69 6e |t:pong........in|
772 0200: 74 3a 70 6f 6e 67 00 00 00 02 01 00 0b 01 69 6e |t:pong........in|
773 0210: 2d 72 65 70 6c 79 2d 74 6f 37 00 00 00 00 00 00 |-reply-to7......|
773 0210: 2d 72 65 70 6c 79 2d 74 6f 37 00 00 00 00 00 00 |-reply-to7......|
774 0220: 00 1b 06 6f 75 74 70 75 74 00 00 00 03 00 01 0b |...output.......|
774 0220: 00 1b 06 6f 75 74 70 75 74 00 00 00 03 00 01 0b |...output.......|
775 0230: 01 69 6e 2d 72 65 70 6c 79 2d 74 6f 37 00 00 00 |.in-reply-to7...|
775 0230: 01 69 6e 2d 72 65 70 6c 79 2d 74 6f 37 00 00 00 |.in-reply-to7...|
776 0240: 3d 72 65 63 65 69 76 65 64 20 70 69 6e 67 20 72 |=received ping r|
776 0240: 3d 72 65 63 65 69 76 65 64 20 70 69 6e 67 20 72 |=received ping r|
777 0250: 65 71 75 65 73 74 20 28 69 64 20 37 29 0a 72 65 |equest (id 7).re|
777 0250: 65 71 75 65 73 74 20 28 69 64 20 37 29 0a 72 65 |equest (id 7).re|
778 0260: 70 6c 79 69 6e 67 20 74 6f 20 70 69 6e 67 20 72 |plying to ping r|
778 0260: 70 6c 79 69 6e 67 20 74 6f 20 70 69 6e 67 20 72 |plying to ping r|
779 0270: 65 71 75 65 73 74 20 28 69 64 20 37 29 0a 00 00 |equest (id 7)...|
779 0270: 65 71 75 65 73 74 20 28 69 64 20 37 29 0a 00 00 |equest (id 7)...|
780 0280: 00 00 00 00 00 00 |......|
780 0280: 00 00 00 00 00 00 |......|
781
781
782 The reply is valid
782 The reply is valid
783
783
784 $ hg statbundle2 < ../reply.hg2
784 $ hg statbundle2 < ../reply.hg2
785 options count: 0
785 options count: 0
786 :output:
786 :output:
787 mandatory: 0
787 mandatory: 0
788 advisory: 1
788 advisory: 1
789 payload: 217 bytes
789 payload: 217 bytes
790 :output:
790 :output:
791 mandatory: 0
791 mandatory: 0
792 advisory: 1
792 advisory: 1
793 payload: 201 bytes
793 payload: 201 bytes
794 :test:pong:
794 :test:pong:
795 mandatory: 1
795 mandatory: 1
796 advisory: 0
796 advisory: 0
797 payload: 0 bytes
797 payload: 0 bytes
798 :output:
798 :output:
799 mandatory: 0
799 mandatory: 0
800 advisory: 1
800 advisory: 1
801 payload: 61 bytes
801 payload: 61 bytes
802 parts count: 4
802 parts count: 4
803
803
804 Unbundle the reply to get the output:
804 Unbundle the reply to get the output:
805
805
806 $ hg unbundle2 < ../reply.hg2
806 $ hg unbundle2 < ../reply.hg2
807 remote: The choir starts singing:
807 remote: The choir starts singing:
808 remote: Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko
808 remote: Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko
809 remote: Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
809 remote: Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
810 remote: Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko.
810 remote: Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko.
811 remote: debugreply: capabilities:
811 remote: debugreply: capabilities:
812 remote: debugreply: 'city=!'
812 remote: debugreply: 'city=!'
813 remote: debugreply: 'celeste,ville'
813 remote: debugreply: 'celeste,ville'
814 remote: debugreply: 'elephants'
814 remote: debugreply: 'elephants'
815 remote: debugreply: 'babar'
815 remote: debugreply: 'babar'
816 remote: debugreply: 'celeste'
816 remote: debugreply: 'celeste'
817 remote: debugreply: 'ping-pong'
817 remote: debugreply: 'ping-pong'
818 remote: received ping request (id 7)
818 remote: received ping request (id 7)
819 remote: replying to ping request (id 7)
819 remote: replying to ping request (id 7)
820 0 unread bytes
820 0 unread bytes
821
821
822 Test push race detection
822 Test push race detection
823
823
824 $ hg bundle2 --pushrace ../part-race.hg2
824 $ hg bundle2 --pushrace ../part-race.hg2
825
825
826 $ hg unbundle2 < ../part-race.hg2
826 $ hg unbundle2 < ../part-race.hg2
827 0 unread bytes
827 0 unread bytes
828 abort: push race: remote repository changed while pushing - please try again
828 abort: push race: remote repository changed while pushing - please try again
829 [255]
829 [255]
830
830
831 Support for changegroup
831 Support for changegroup
832 ===================================
832 ===================================
833
833
834 $ hg unbundle $TESTDIR/bundles/rebase.hg
834 $ hg unbundle $TESTDIR/bundles/rebase.hg
835 adding changesets
835 adding changesets
836 adding manifests
836 adding manifests
837 adding file changes
837 adding file changes
838 added 8 changesets with 7 changes to 7 files (+3 heads)
838 added 8 changesets with 7 changes to 7 files (+3 heads)
839 new changesets cd010b8cd998:02de42196ebe (8 drafts)
839 new changesets cd010b8cd998:02de42196ebe (8 drafts)
840 (run 'hg heads' to see heads, 'hg merge' to merge)
840 (run 'hg heads' to see heads, 'hg merge' to merge)
841
841
842 $ hg log -G
842 $ hg log -G
843 o 8:02de42196ebe draft Nicolas Dumazet <nicdumz.commits@gmail.com> H
843 o 8:02de42196ebe draft Nicolas Dumazet <nicdumz.commits@gmail.com> H
844 |
844 |
845 | o 7:eea13746799a draft Nicolas Dumazet <nicdumz.commits@gmail.com> G
845 | o 7:eea13746799a draft Nicolas Dumazet <nicdumz.commits@gmail.com> G
846 |/|
846 |/|
847 o | 6:24b6387c8c8c draft Nicolas Dumazet <nicdumz.commits@gmail.com> F
847 o | 6:24b6387c8c8c draft Nicolas Dumazet <nicdumz.commits@gmail.com> F
848 | |
848 | |
849 | o 5:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
849 | o 5:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
850 |/
850 |/
851 | o 4:32af7686d403 draft Nicolas Dumazet <nicdumz.commits@gmail.com> D
851 | o 4:32af7686d403 draft Nicolas Dumazet <nicdumz.commits@gmail.com> D
852 | |
852 | |
853 | o 3:5fddd98957c8 draft Nicolas Dumazet <nicdumz.commits@gmail.com> C
853 | o 3:5fddd98957c8 draft Nicolas Dumazet <nicdumz.commits@gmail.com> C
854 | |
854 | |
855 | o 2:42ccdea3bb16 draft Nicolas Dumazet <nicdumz.commits@gmail.com> B
855 | o 2:42ccdea3bb16 draft Nicolas Dumazet <nicdumz.commits@gmail.com> B
856 |/
856 |/
857 o 1:cd010b8cd998 draft Nicolas Dumazet <nicdumz.commits@gmail.com> A
857 o 1:cd010b8cd998 draft Nicolas Dumazet <nicdumz.commits@gmail.com> A
858
858
859 @ 0:3903775176ed draft test a
859 @ 0:3903775176ed draft test a
860
860
861
861
862 $ hg bundle2 --debug --config progress.debug=true --config devel.bundle2.debug=true --rev '8+7+5+4' ../rev.hg2
862 $ hg bundle2 --debug --config progress.debug=true --config devel.bundle2.debug=true --rev '8+7+5+4' ../rev.hg2
863 4 changesets found
863 4 changesets found
864 list of changesets:
864 list of changesets:
865 32af7686d403cf45b5d95f2d70cebea587ac806a
865 32af7686d403cf45b5d95f2d70cebea587ac806a
866 9520eea781bcca16c1e15acc0ba14335a0e8e5ba
866 9520eea781bcca16c1e15acc0ba14335a0e8e5ba
867 eea13746799a9e0bfd88f29d3c2e9dc9389f524f
867 eea13746799a9e0bfd88f29d3c2e9dc9389f524f
868 02de42196ebee42ef284b6780a87cdc96e8eaab6
868 02de42196ebee42ef284b6780a87cdc96e8eaab6
869 bundle2-output-bundle: "HG20", 1 parts total
869 bundle2-output-bundle: "HG20", 1 parts total
870 bundle2-output: start emission of HG20 stream
870 bundle2-output: start emission of HG20 stream
871 bundle2-output: bundle parameter:
871 bundle2-output: bundle parameter:
872 bundle2-output: start of parts
872 bundle2-output: start of parts
873 bundle2-output: bundle part: "changegroup"
873 bundle2-output: bundle part: "changegroup"
874 bundle2-output-part: "changegroup" (advisory) streamed payload
874 bundle2-output-part: "changegroup" (advisory) streamed payload
875 bundle2-output: part 0: "changegroup"
875 bundle2-output: part 0: "changegroup"
876 bundle2-output: header chunk size: 18
876 bundle2-output: header chunk size: 18
877 changesets: 1/4 chunks (25.00%)
877 changesets: 1/4 chunks (25.00%)
878 changesets: 2/4 chunks (50.00%)
878 changesets: 2/4 chunks (50.00%)
879 changesets: 3/4 chunks (75.00%)
879 changesets: 3/4 chunks (75.00%)
880 changesets: 4/4 chunks (100.00%)
880 changesets: 4/4 chunks (100.00%)
881 manifests: 1/4 chunks (25.00%)
881 manifests: 1/4 chunks (25.00%)
882 manifests: 2/4 chunks (50.00%)
882 manifests: 2/4 chunks (50.00%)
883 manifests: 3/4 chunks (75.00%)
883 manifests: 3/4 chunks (75.00%)
884 manifests: 4/4 chunks (100.00%)
884 manifests: 4/4 chunks (100.00%)
885 files: D 1/3 files (33.33%)
885 files: D 1/3 files (33.33%)
886 files: E 2/3 files (66.67%)
886 files: E 2/3 files (66.67%)
887 files: H 3/3 files (100.00%)
887 files: H 3/3 files (100.00%)
888 bundle2-output: payload chunk size: 1555
888 bundle2-output: payload chunk size: 1555
889 bundle2-output: closing payload chunk
889 bundle2-output: closing payload chunk
890 bundle2-output: end of bundle
890 bundle2-output: end of bundle
891
891
892 $ f --hexdump ../rev.hg2
892 $ f --hexdump ../rev.hg2
893 ../rev.hg2:
893 ../rev.hg2:
894 0000: 48 47 32 30 00 00 00 00 00 00 00 12 0b 63 68 61 |HG20.........cha|
894 0000: 48 47 32 30 00 00 00 00 00 00 00 12 0b 63 68 61 |HG20.........cha|
895 0010: 6e 67 65 67 72 6f 75 70 00 00 00 00 00 00 00 00 |ngegroup........|
895 0010: 6e 67 65 67 72 6f 75 70 00 00 00 00 00 00 00 00 |ngegroup........|
896 0020: 06 13 00 00 00 a4 32 af 76 86 d4 03 cf 45 b5 d9 |......2.v....E..|
896 0020: 06 13 00 00 00 a4 32 af 76 86 d4 03 cf 45 b5 d9 |......2.v....E..|
897 0030: 5f 2d 70 ce be a5 87 ac 80 6a 5f dd d9 89 57 c8 |_-p......j_...W.|
897 0030: 5f 2d 70 ce be a5 87 ac 80 6a 5f dd d9 89 57 c8 |_-p......j_...W.|
898 0040: a5 4a 4d 43 6d fe 1d a9 d8 7f 21 a1 b9 7b 00 00 |.JMCm.....!..{..|
898 0040: a5 4a 4d 43 6d fe 1d a9 d8 7f 21 a1 b9 7b 00 00 |.JMCm.....!..{..|
899 0050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
899 0050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
900 0060: 00 00 32 af 76 86 d4 03 cf 45 b5 d9 5f 2d 70 ce |..2.v....E.._-p.|
900 0060: 00 00 32 af 76 86 d4 03 cf 45 b5 d9 5f 2d 70 ce |..2.v....E.._-p.|
901 0070: be a5 87 ac 80 6a 00 00 00 00 00 00 00 29 00 00 |.....j.......)..|
901 0070: be a5 87 ac 80 6a 00 00 00 00 00 00 00 29 00 00 |.....j.......)..|
902 0080: 00 29 36 65 31 66 34 63 34 37 65 63 62 35 33 33 |.)6e1f4c47ecb533|
902 0080: 00 29 36 65 31 66 34 63 34 37 65 63 62 35 33 33 |.)6e1f4c47ecb533|
903 0090: 66 66 64 30 63 38 65 35 32 63 64 63 38 38 61 66 |ffd0c8e52cdc88af|
903 0090: 66 66 64 30 63 38 65 35 32 63 64 63 38 38 61 66 |ffd0c8e52cdc88af|
904 00a0: 62 36 63 64 33 39 65 32 30 63 0a 00 00 00 66 00 |b6cd39e20c....f.|
904 00a0: 62 36 63 64 33 39 65 32 30 63 0a 00 00 00 66 00 |b6cd39e20c....f.|
905 00b0: 00 00 68 00 00 00 02 44 0a 00 00 00 69 00 00 00 |..h....D....i...|
905 00b0: 00 00 68 00 00 00 02 44 0a 00 00 00 69 00 00 00 |..h....D....i...|
906 00c0: 6a 00 00 00 01 44 00 00 00 a4 95 20 ee a7 81 bc |j....D..... ....|
906 00c0: 6a 00 00 00 01 44 00 00 00 a4 95 20 ee a7 81 bc |j....D..... ....|
907 00d0: ca 16 c1 e1 5a cc 0b a1 43 35 a0 e8 e5 ba cd 01 |....Z...C5......|
907 00d0: ca 16 c1 e1 5a cc 0b a1 43 35 a0 e8 e5 ba cd 01 |....Z...C5......|
908 00e0: 0b 8c d9 98 f3 98 1a 5a 81 15 f9 4f 8d a4 ab 50 |.......Z...O...P|
908 00e0: 0b 8c d9 98 f3 98 1a 5a 81 15 f9 4f 8d a4 ab 50 |.......Z...O...P|
909 00f0: 60 89 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |`...............|
909 00f0: 60 89 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |`...............|
910 0100: 00 00 00 00 00 00 95 20 ee a7 81 bc ca 16 c1 e1 |....... ........|
910 0100: 00 00 00 00 00 00 95 20 ee a7 81 bc ca 16 c1 e1 |....... ........|
911 0110: 5a cc 0b a1 43 35 a0 e8 e5 ba 00 00 00 00 00 00 |Z...C5..........|
911 0110: 5a cc 0b a1 43 35 a0 e8 e5 ba 00 00 00 00 00 00 |Z...C5..........|
912 0120: 00 29 00 00 00 29 34 64 65 63 65 39 63 38 32 36 |.)...)4dece9c826|
912 0120: 00 29 00 00 00 29 34 64 65 63 65 39 63 38 32 36 |.)...)4dece9c826|
913 0130: 66 36 39 34 39 30 35 30 37 62 39 38 63 36 33 38 |f69490507b98c638|
913 0130: 66 36 39 34 39 30 35 30 37 62 39 38 63 36 33 38 |f69490507b98c638|
914 0140: 33 61 33 30 30 39 62 32 39 35 38 33 37 64 0a 00 |3a3009b295837d..|
914 0140: 33 61 33 30 30 39 62 32 39 35 38 33 37 64 0a 00 |3a3009b295837d..|
915 0150: 00 00 66 00 00 00 68 00 00 00 02 45 0a 00 00 00 |..f...h....E....|
915 0150: 00 00 66 00 00 00 68 00 00 00 02 45 0a 00 00 00 |..f...h....E....|
916 0160: 69 00 00 00 6a 00 00 00 01 45 00 00 00 a2 ee a1 |i...j....E......|
916 0160: 69 00 00 00 6a 00 00 00 01 45 00 00 00 a2 ee a1 |i...j....E......|
917 0170: 37 46 79 9a 9e 0b fd 88 f2 9d 3c 2e 9d c9 38 9f |7Fy.......<...8.|
917 0170: 37 46 79 9a 9e 0b fd 88 f2 9d 3c 2e 9d c9 38 9f |7Fy.......<...8.|
918 0180: 52 4f 24 b6 38 7c 8c 8c ae 37 17 88 80 f3 fa 95 |RO$.8|...7......|
918 0180: 52 4f 24 b6 38 7c 8c 8c ae 37 17 88 80 f3 fa 95 |RO$.8|...7......|
919 0190: de d3 cb 1c f7 85 95 20 ee a7 81 bc ca 16 c1 e1 |....... ........|
919 0190: de d3 cb 1c f7 85 95 20 ee a7 81 bc ca 16 c1 e1 |....... ........|
920 01a0: 5a cc 0b a1 43 35 a0 e8 e5 ba ee a1 37 46 79 9a |Z...C5......7Fy.|
920 01a0: 5a cc 0b a1 43 35 a0 e8 e5 ba ee a1 37 46 79 9a |Z...C5......7Fy.|
921 01b0: 9e 0b fd 88 f2 9d 3c 2e 9d c9 38 9f 52 4f 00 00 |......<...8.RO..|
921 01b0: 9e 0b fd 88 f2 9d 3c 2e 9d c9 38 9f 52 4f 00 00 |......<...8.RO..|
922 01c0: 00 00 00 00 00 29 00 00 00 29 33 36 35 62 39 33 |.....)...)365b93|
922 01c0: 00 00 00 00 00 29 00 00 00 29 33 36 35 62 39 33 |.....)...)365b93|
923 01d0: 64 35 37 66 64 66 34 38 31 34 65 32 62 35 39 31 |d57fdf4814e2b591|
923 01d0: 64 35 37 66 64 66 34 38 31 34 65 32 62 35 39 31 |d57fdf4814e2b591|
924 01e0: 31 64 36 62 61 63 66 66 32 62 31 32 30 31 34 34 |1d6bacff2b120144|
924 01e0: 31 64 36 62 61 63 66 66 32 62 31 32 30 31 34 34 |1d6bacff2b120144|
925 01f0: 34 31 0a 00 00 00 66 00 00 00 68 00 00 00 00 00 |41....f...h.....|
925 01f0: 34 31 0a 00 00 00 66 00 00 00 68 00 00 00 00 00 |41....f...h.....|
926 0200: 00 00 69 00 00 00 6a 00 00 00 01 47 00 00 00 a4 |..i...j....G....|
926 0200: 00 00 69 00 00 00 6a 00 00 00 01 47 00 00 00 a4 |..i...j....G....|
927 0210: 02 de 42 19 6e be e4 2e f2 84 b6 78 0a 87 cd c9 |..B.n......x....|
927 0210: 02 de 42 19 6e be e4 2e f2 84 b6 78 0a 87 cd c9 |..B.n......x....|
928 0220: 6e 8e aa b6 24 b6 38 7c 8c 8c ae 37 17 88 80 f3 |n...$.8|...7....|
928 0220: 6e 8e aa b6 24 b6 38 7c 8c 8c ae 37 17 88 80 f3 |n...$.8|...7....|
929 0230: fa 95 de d3 cb 1c f7 85 00 00 00 00 00 00 00 00 |................|
929 0230: fa 95 de d3 cb 1c f7 85 00 00 00 00 00 00 00 00 |................|
930 0240: 00 00 00 00 00 00 00 00 00 00 00 00 02 de 42 19 |..............B.|
930 0240: 00 00 00 00 00 00 00 00 00 00 00 00 02 de 42 19 |..............B.|
931 0250: 6e be e4 2e f2 84 b6 78 0a 87 cd c9 6e 8e aa b6 |n......x....n...|
931 0250: 6e be e4 2e f2 84 b6 78 0a 87 cd c9 6e 8e aa b6 |n......x....n...|
932 0260: 00 00 00 00 00 00 00 29 00 00 00 29 38 62 65 65 |.......)...)8bee|
932 0260: 00 00 00 00 00 00 00 29 00 00 00 29 38 62 65 65 |.......)...)8bee|
933 0270: 34 38 65 64 63 37 33 31 38 35 34 31 66 63 30 30 |48edc7318541fc00|
933 0270: 34 38 65 64 63 37 33 31 38 35 34 31 66 63 30 30 |48edc7318541fc00|
934 0280: 31 33 65 65 34 31 62 30 38 39 32 37 36 61 38 63 |13ee41b089276a8c|
934 0280: 31 33 65 65 34 31 62 30 38 39 32 37 36 61 38 63 |13ee41b089276a8c|
935 0290: 32 34 62 66 0a 00 00 00 66 00 00 00 66 00 00 00 |24bf....f...f...|
935 0290: 32 34 62 66 0a 00 00 00 66 00 00 00 66 00 00 00 |24bf....f...f...|
936 02a0: 02 48 0a 00 00 00 67 00 00 00 68 00 00 00 01 48 |.H....g...h....H|
936 02a0: 02 48 0a 00 00 00 67 00 00 00 68 00 00 00 01 48 |.H....g...h....H|
937 02b0: 00 00 00 00 00 00 00 8b 6e 1f 4c 47 ec b5 33 ff |........n.LG..3.|
937 02b0: 00 00 00 00 00 00 00 8b 6e 1f 4c 47 ec b5 33 ff |........n.LG..3.|
938 02c0: d0 c8 e5 2c dc 88 af b6 cd 39 e2 0c 66 a5 a0 18 |...,.....9..f...|
938 02c0: d0 c8 e5 2c dc 88 af b6 cd 39 e2 0c 66 a5 a0 18 |...,.....9..f...|
939 02d0: 17 fd f5 23 9c 27 38 02 b5 b7 61 8d 05 1c 89 e4 |...#.'8...a.....|
939 02d0: 17 fd f5 23 9c 27 38 02 b5 b7 61 8d 05 1c 89 e4 |...#.'8...a.....|
940 02e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
940 02e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
941 02f0: 00 00 00 00 32 af 76 86 d4 03 cf 45 b5 d9 5f 2d |....2.v....E.._-|
941 02f0: 00 00 00 00 32 af 76 86 d4 03 cf 45 b5 d9 5f 2d |....2.v....E.._-|
942 0300: 70 ce be a5 87 ac 80 6a 00 00 00 81 00 00 00 81 |p......j........|
942 0300: 70 ce be a5 87 ac 80 6a 00 00 00 81 00 00 00 81 |p......j........|
943 0310: 00 00 00 2b 44 00 63 33 66 31 63 61 32 39 32 34 |...+D.c3f1ca2924|
943 0310: 00 00 00 2b 44 00 63 33 66 31 63 61 32 39 32 34 |...+D.c3f1ca2924|
944 0320: 63 31 36 61 31 39 62 30 36 35 36 61 38 34 39 30 |c16a19b0656a8490|
944 0320: 63 31 36 61 31 39 62 30 36 35 36 61 38 34 39 30 |c16a19b0656a8490|
945 0330: 30 65 35 30 34 65 35 62 30 61 65 63 32 64 0a 00 |0e504e5b0aec2d..|
945 0330: 30 65 35 30 34 65 35 62 30 61 65 63 32 64 0a 00 |0e504e5b0aec2d..|
946 0340: 00 00 8b 4d ec e9 c8 26 f6 94 90 50 7b 98 c6 38 |...M...&...P{..8|
946 0340: 00 00 8b 4d ec e9 c8 26 f6 94 90 50 7b 98 c6 38 |...M...&...P{..8|
947 0350: 3a 30 09 b2 95 83 7d 00 7d 8c 9d 88 84 13 25 f5 |:0....}.}.....%.|
947 0350: 3a 30 09 b2 95 83 7d 00 7d 8c 9d 88 84 13 25 f5 |:0....}.}.....%.|
948 0360: c6 b0 63 71 b3 5b 4e 8a 2b 1a 83 00 00 00 00 00 |..cq.[N.+.......|
948 0360: c6 b0 63 71 b3 5b 4e 8a 2b 1a 83 00 00 00 00 00 |..cq.[N.+.......|
949 0370: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 95 |................|
949 0370: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 95 |................|
950 0380: 20 ee a7 81 bc ca 16 c1 e1 5a cc 0b a1 43 35 a0 | ........Z...C5.|
950 0380: 20 ee a7 81 bc ca 16 c1 e1 5a cc 0b a1 43 35 a0 | ........Z...C5.|
951 0390: e8 e5 ba 00 00 00 2b 00 00 00 ac 00 00 00 2b 45 |......+.......+E|
951 0390: e8 e5 ba 00 00 00 2b 00 00 00 ac 00 00 00 2b 45 |......+.......+E|
952 03a0: 00 39 63 36 66 64 30 33 35 30 61 36 63 30 64 30 |.9c6fd0350a6c0d0|
952 03a0: 00 39 63 36 66 64 30 33 35 30 61 36 63 30 64 30 |.9c6fd0350a6c0d0|
953 03b0: 63 34 39 64 34 61 39 63 35 30 31 37 63 66 30 37 |c49d4a9c5017cf07|
953 03b0: 63 34 39 64 34 61 39 63 35 30 31 37 63 66 30 37 |c49d4a9c5017cf07|
954 03c0: 30 34 33 66 35 34 65 35 38 0a 00 00 00 8b 36 5b |043f54e58.....6[|
954 03c0: 30 34 33 66 35 34 65 35 38 0a 00 00 00 8b 36 5b |043f54e58.....6[|
955 03d0: 93 d5 7f df 48 14 e2 b5 91 1d 6b ac ff 2b 12 01 |....H.....k..+..|
955 03d0: 93 d5 7f df 48 14 e2 b5 91 1d 6b ac ff 2b 12 01 |....H.....k..+..|
956 03e0: 44 41 28 a5 84 c6 5e f1 21 f8 9e b6 6a b7 d0 bc |DA(...^.!...j...|
956 03e0: 44 41 28 a5 84 c6 5e f1 21 f8 9e b6 6a b7 d0 bc |DA(...^.!...j...|
957 03f0: 15 3d 80 99 e7 ce 4d ec e9 c8 26 f6 94 90 50 7b |.=....M...&...P{|
957 03f0: 15 3d 80 99 e7 ce 4d ec e9 c8 26 f6 94 90 50 7b |.=....M...&...P{|
958 0400: 98 c6 38 3a 30 09 b2 95 83 7d ee a1 37 46 79 9a |..8:0....}..7Fy.|
958 0400: 98 c6 38 3a 30 09 b2 95 83 7d ee a1 37 46 79 9a |..8:0....}..7Fy.|
959 0410: 9e 0b fd 88 f2 9d 3c 2e 9d c9 38 9f 52 4f 00 00 |......<...8.RO..|
959 0410: 9e 0b fd 88 f2 9d 3c 2e 9d c9 38 9f 52 4f 00 00 |......<...8.RO..|
960 0420: 00 56 00 00 00 56 00 00 00 2b 46 00 32 32 62 66 |.V...V...+F.22bf|
960 0420: 00 56 00 00 00 56 00 00 00 2b 46 00 32 32 62 66 |.V...V...+F.22bf|
961 0430: 63 66 64 36 32 61 32 31 61 33 32 38 37 65 64 62 |cfd62a21a3287edb|
961 0430: 63 66 64 36 32 61 32 31 61 33 32 38 37 65 64 62 |cfd62a21a3287edb|
962 0440: 64 34 64 36 35 36 32 31 38 64 30 66 35 32 35 65 |d4d656218d0f525e|
962 0440: 64 34 64 36 35 36 32 31 38 64 30 66 35 32 35 65 |d4d656218d0f525e|
963 0450: 64 37 36 61 0a 00 00 00 97 8b ee 48 ed c7 31 85 |d76a.......H..1.|
963 0450: 64 37 36 61 0a 00 00 00 97 8b ee 48 ed c7 31 85 |d76a.......H..1.|
964 0460: 41 fc 00 13 ee 41 b0 89 27 6a 8c 24 bf 28 a5 84 |A....A..'j.$.(..|
964 0460: 41 fc 00 13 ee 41 b0 89 27 6a 8c 24 bf 28 a5 84 |A....A..'j.$.(..|
965 0470: c6 5e f1 21 f8 9e b6 6a b7 d0 bc 15 3d 80 99 e7 |.^.!...j....=...|
965 0470: c6 5e f1 21 f8 9e b6 6a b7 d0 bc 15 3d 80 99 e7 |.^.!...j....=...|
966 0480: ce 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
966 0480: ce 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
967 0490: 00 00 00 00 00 02 de 42 19 6e be e4 2e f2 84 b6 |.......B.n......|
967 0490: 00 00 00 00 00 02 de 42 19 6e be e4 2e f2 84 b6 |.......B.n......|
968 04a0: 78 0a 87 cd c9 6e 8e aa b6 00 00 00 2b 00 00 00 |x....n......+...|
968 04a0: 78 0a 87 cd c9 6e 8e aa b6 00 00 00 2b 00 00 00 |x....n......+...|
969 04b0: 56 00 00 00 00 00 00 00 81 00 00 00 81 00 00 00 |V...............|
969 04b0: 56 00 00 00 00 00 00 00 81 00 00 00 81 00 00 00 |V...............|
970 04c0: 2b 48 00 38 35 30 30 31 38 39 65 37 34 61 39 65 |+H.8500189e74a9e|
970 04c0: 2b 48 00 38 35 30 30 31 38 39 65 37 34 61 39 65 |+H.8500189e74a9e|
971 04d0: 30 34 37 35 65 38 32 32 30 39 33 62 63 37 64 62 |0475e822093bc7db|
971 04d0: 30 34 37 35 65 38 32 32 30 39 33 62 63 37 64 62 |0475e822093bc7db|
972 04e0: 30 64 36 33 31 61 65 62 30 62 34 0a 00 00 00 00 |0d631aeb0b4.....|
972 04e0: 30 64 36 33 31 61 65 62 30 62 34 0a 00 00 00 00 |0d631aeb0b4.....|
973 04f0: 00 00 00 05 44 00 00 00 62 c3 f1 ca 29 24 c1 6a |....D...b...)$.j|
973 04f0: 00 00 00 05 44 00 00 00 62 c3 f1 ca 29 24 c1 6a |....D...b...)$.j|
974 0500: 19 b0 65 6a 84 90 0e 50 4e 5b 0a ec 2d 00 00 00 |..ej...PN[..-...|
974 0500: 19 b0 65 6a 84 90 0e 50 4e 5b 0a ec 2d 00 00 00 |..ej...PN[..-...|
975 0510: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
975 0510: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
976 0520: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
976 0520: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
977 0530: 00 00 00 00 00 32 af 76 86 d4 03 cf 45 b5 d9 5f |.....2.v....E.._|
977 0530: 00 00 00 00 00 32 af 76 86 d4 03 cf 45 b5 d9 5f |.....2.v....E.._|
978 0540: 2d 70 ce be a5 87 ac 80 6a 00 00 00 00 00 00 00 |-p......j.......|
978 0540: 2d 70 ce be a5 87 ac 80 6a 00 00 00 00 00 00 00 |-p......j.......|
979 0550: 00 00 00 00 02 44 0a 00 00 00 00 00 00 00 05 45 |.....D.........E|
979 0550: 00 00 00 00 02 44 0a 00 00 00 00 00 00 00 05 45 |.....D.........E|
980 0560: 00 00 00 62 9c 6f d0 35 0a 6c 0d 0c 49 d4 a9 c5 |...b.o.5.l..I...|
980 0560: 00 00 00 62 9c 6f d0 35 0a 6c 0d 0c 49 d4 a9 c5 |...b.o.5.l..I...|
981 0570: 01 7c f0 70 43 f5 4e 58 00 00 00 00 00 00 00 00 |.|.pC.NX........|
981 0570: 01 7c f0 70 43 f5 4e 58 00 00 00 00 00 00 00 00 |.|.pC.NX........|
982 0580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
982 0580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
983 0590: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
983 0590: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
984 05a0: 95 20 ee a7 81 bc ca 16 c1 e1 5a cc 0b a1 43 35 |. ........Z...C5|
984 05a0: 95 20 ee a7 81 bc ca 16 c1 e1 5a cc 0b a1 43 35 |. ........Z...C5|
985 05b0: a0 e8 e5 ba 00 00 00 00 00 00 00 00 00 00 00 02 |................|
985 05b0: a0 e8 e5 ba 00 00 00 00 00 00 00 00 00 00 00 02 |................|
986 05c0: 45 0a 00 00 00 00 00 00 00 05 48 00 00 00 62 85 |E.........H...b.|
986 05c0: 45 0a 00 00 00 00 00 00 00 05 48 00 00 00 62 85 |E.........H...b.|
987 05d0: 00 18 9e 74 a9 e0 47 5e 82 20 93 bc 7d b0 d6 31 |...t..G^. ..}..1|
987 05d0: 00 18 9e 74 a9 e0 47 5e 82 20 93 bc 7d b0 d6 31 |...t..G^. ..}..1|
988 05e0: ae b0 b4 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
988 05e0: ae b0 b4 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
989 05f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
989 05f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
990 0600: 00 00 00 00 00 00 00 00 00 00 00 02 de 42 19 6e |.............B.n|
990 0600: 00 00 00 00 00 00 00 00 00 00 00 02 de 42 19 6e |.............B.n|
991 0610: be e4 2e f2 84 b6 78 0a 87 cd c9 6e 8e aa b6 00 |......x....n....|
991 0610: be e4 2e f2 84 b6 78 0a 87 cd c9 6e 8e aa b6 00 |......x....n....|
992 0620: 00 00 00 00 00 00 00 00 00 00 02 48 0a 00 00 00 |...........H....|
992 0620: 00 00 00 00 00 00 00 00 00 00 02 48 0a 00 00 00 |...........H....|
993 0630: 00 00 00 00 00 00 00 00 00 00 00 00 00 |.............|
993 0630: 00 00 00 00 00 00 00 00 00 00 00 00 00 |.............|
994
994
995 $ hg debugbundle ../rev.hg2
995 $ hg debugbundle ../rev.hg2
996 Stream params: {}
996 Stream params: {}
997 changegroup -- {} (mandatory: False)
997 changegroup -- {} (mandatory: False)
998 32af7686d403cf45b5d95f2d70cebea587ac806a
998 32af7686d403cf45b5d95f2d70cebea587ac806a
999 9520eea781bcca16c1e15acc0ba14335a0e8e5ba
999 9520eea781bcca16c1e15acc0ba14335a0e8e5ba
1000 eea13746799a9e0bfd88f29d3c2e9dc9389f524f
1000 eea13746799a9e0bfd88f29d3c2e9dc9389f524f
1001 02de42196ebee42ef284b6780a87cdc96e8eaab6
1001 02de42196ebee42ef284b6780a87cdc96e8eaab6
1002 $ hg unbundle ../rev.hg2
1002 $ hg unbundle ../rev.hg2
1003 adding changesets
1003 adding changesets
1004 adding manifests
1004 adding manifests
1005 adding file changes
1005 adding file changes
1006 added 0 changesets with 0 changes to 3 files
1006 added 0 changesets with 0 changes to 3 files
1007 (run 'hg update' to get a working copy)
1007 (run 'hg update' to get a working copy)
1008
1008
1009 with reply
1009 with reply
1010
1010
1011 $ hg bundle2 --rev '8+7+5+4' --reply ../rev-rr.hg2
1011 $ hg bundle2 --rev '8+7+5+4' --reply ../rev-rr.hg2
1012 $ hg unbundle2 ../rev-reply.hg2 < ../rev-rr.hg2
1012 $ hg unbundle2 ../rev-reply.hg2 < ../rev-rr.hg2
1013 added 0 changesets with 0 changes to 3 files
1013 0 unread bytes
1014 0 unread bytes
1014 addchangegroup return: 1
1015 addchangegroup return: 1
1015
1016
1016 $ f --hexdump ../rev-reply.hg2
1017 $ f --hexdump ../rev-reply.hg2
1017 ../rev-reply.hg2:
1018 ../rev-reply.hg2:
1018 0000: 48 47 32 30 00 00 00 00 00 00 00 2f 11 72 65 70 |HG20......./.rep|
1019 0000: 48 47 32 30 00 00 00 00 00 00 00 2f 11 72 65 70 |HG20......./.rep|
1019 0010: 6c 79 3a 63 68 61 6e 67 65 67 72 6f 75 70 00 00 |ly:changegroup..|
1020 0010: 6c 79 3a 63 68 61 6e 67 65 67 72 6f 75 70 00 00 |ly:changegroup..|
1020 0020: 00 00 00 02 0b 01 06 01 69 6e 2d 72 65 70 6c 79 |........in-reply|
1021 0020: 00 00 00 02 0b 01 06 01 69 6e 2d 72 65 70 6c 79 |........in-reply|
1021 0030: 2d 74 6f 31 72 65 74 75 72 6e 31 00 00 00 00 00 |-to1return1.....|
1022 0030: 2d 74 6f 31 72 65 74 75 72 6e 31 00 00 00 00 00 |-to1return1.....|
1022 0040: 00 00 1b 06 6f 75 74 70 75 74 00 00 00 01 00 01 |....output......|
1023 0040: 00 00 1b 06 6f 75 74 70 75 74 00 00 00 01 00 01 |....output......|
1023 0050: 0b 01 69 6e 2d 72 65 70 6c 79 2d 74 6f 31 00 00 |..in-reply-to1..|
1024 0050: 0b 01 69 6e 2d 72 65 70 6c 79 2d 74 6f 31 00 00 |..in-reply-to1..|
1024 0060: 00 64 61 64 64 69 6e 67 20 63 68 61 6e 67 65 73 |.dadding changes|
1025 0060: 00 37 61 64 64 69 6e 67 20 63 68 61 6e 67 65 73 |.7adding changes|
1025 0070: 65 74 73 0a 61 64 64 69 6e 67 20 6d 61 6e 69 66 |ets.adding manif|
1026 0070: 65 74 73 0a 61 64 64 69 6e 67 20 6d 61 6e 69 66 |ets.adding manif|
1026 0080: 65 73 74 73 0a 61 64 64 69 6e 67 20 66 69 6c 65 |ests.adding file|
1027 0080: 65 73 74 73 0a 61 64 64 69 6e 67 20 66 69 6c 65 |ests.adding file|
1027 0090: 20 63 68 61 6e 67 65 73 0a 61 64 64 65 64 20 30 | changes.added 0|
1028 0090: 20 63 68 61 6e 67 65 73 0a 00 00 00 00 00 00 00 | changes........|
1028 00a0: 20 63 68 61 6e 67 65 73 65 74 73 20 77 69 74 68 | changesets with|
1029 00a0: 00 |.|
1029 00b0: 20 30 20 63 68 61 6e 67 65 73 20 74 6f 20 33 20 | 0 changes to 3 |
1030 00c0: 66 69 6c 65 73 0a 00 00 00 00 00 00 00 00 |files.........|
1031
1030
1032 Check handling of exception during generation.
1031 Check handling of exception during generation.
1033 ----------------------------------------------
1032 ----------------------------------------------
1034
1033
1035 $ hg bundle2 --genraise > ../genfailed.hg2
1034 $ hg bundle2 --genraise > ../genfailed.hg2
1036 abort: Someone set up us the bomb!
1035 abort: Someone set up us the bomb!
1037 [255]
1036 [255]
1038
1037
1039 Should still be a valid bundle
1038 Should still be a valid bundle
1040
1039
1041 $ f --hexdump ../genfailed.hg2
1040 $ f --hexdump ../genfailed.hg2
1042 ../genfailed.hg2:
1041 ../genfailed.hg2:
1043 0000: 48 47 32 30 00 00 00 00 00 00 00 0d 06 6f 75 74 |HG20.........out|
1042 0000: 48 47 32 30 00 00 00 00 00 00 00 0d 06 6f 75 74 |HG20.........out|
1044 0010: 70 75 74 00 00 00 00 00 00 ff ff ff ff 00 00 00 |put.............|
1043 0010: 70 75 74 00 00 00 00 00 00 ff ff ff ff 00 00 00 |put.............|
1045 0020: 48 0b 65 72 72 6f 72 3a 61 62 6f 72 74 00 00 00 |H.error:abort...|
1044 0020: 48 0b 65 72 72 6f 72 3a 61 62 6f 72 74 00 00 00 |H.error:abort...|
1046 0030: 00 01 00 07 2d 6d 65 73 73 61 67 65 75 6e 65 78 |....-messageunex|
1045 0030: 00 01 00 07 2d 6d 65 73 73 61 67 65 75 6e 65 78 |....-messageunex|
1047 0040: 70 65 63 74 65 64 20 65 72 72 6f 72 3a 20 53 6f |pected error: So|
1046 0040: 70 65 63 74 65 64 20 65 72 72 6f 72 3a 20 53 6f |pected error: So|
1048 0050: 6d 65 6f 6e 65 20 73 65 74 20 75 70 20 75 73 20 |meone set up us |
1047 0050: 6d 65 6f 6e 65 20 73 65 74 20 75 70 20 75 73 20 |meone set up us |
1049 0060: 74 68 65 20 62 6f 6d 62 21 00 00 00 00 00 00 00 |the bomb!.......|
1048 0060: 74 68 65 20 62 6f 6d 62 21 00 00 00 00 00 00 00 |the bomb!.......|
1050 0070: 00 |.|
1049 0070: 00 |.|
1051
1050
1052 And its handling on the other size raise a clean exception
1051 And its handling on the other size raise a clean exception
1053
1052
1054 $ cat ../genfailed.hg2 | hg unbundle2
1053 $ cat ../genfailed.hg2 | hg unbundle2
1055 0 unread bytes
1054 0 unread bytes
1056 abort: unexpected error: Someone set up us the bomb!
1055 abort: unexpected error: Someone set up us the bomb!
1057 [255]
1056 [255]
1058
1057
1059 Test compression
1058 Test compression
1060 ================
1059 ================
1061
1060
1062 Simple case where it just work: GZ
1061 Simple case where it just work: GZ
1063 ----------------------------------
1062 ----------------------------------
1064
1063
1065 $ hg bundle2 --compress GZ --rev '8+7+5+4' ../rev.hg2.bz
1064 $ hg bundle2 --compress GZ --rev '8+7+5+4' ../rev.hg2.bz
1066 $ f --hexdump ../rev.hg2.bz
1065 $ f --hexdump ../rev.hg2.bz
1067 ../rev.hg2.bz:
1066 ../rev.hg2.bz:
1068 0000: 48 47 32 30 00 00 00 0e 43 6f 6d 70 72 65 73 73 |HG20....Compress|
1067 0000: 48 47 32 30 00 00 00 0e 43 6f 6d 70 72 65 73 73 |HG20....Compress|
1069 0010: 69 6f 6e 3d 47 5a 78 9c 95 94 7d 68 95 55 1c c7 |ion=GZx...}h.U..|
1068 0010: 69 6f 6e 3d 47 5a 78 9c 95 94 7d 68 95 55 1c c7 |ion=GZx...}h.U..|
1070 0020: 9f 3b 31 e8 ce fa c3 65 be a0 a4 b4 52 b9 29 e7 |.;1....e....R.).|
1069 0020: 9f 3b 31 e8 ce fa c3 65 be a0 a4 b4 52 b9 29 e7 |.;1....e....R.).|
1071 0030: f5 79 ce 89 fa 63 ed 5e 77 8b 9c c3 3f 2a 1c 68 |.y...c.^w...?*.h|
1070 0030: f5 79 ce 89 fa 63 ed 5e 77 8b 9c c3 3f 2a 1c 68 |.y...c.^w...?*.h|
1072 0040: cf 79 9b dd 6a ae b0 28 74 b8 e5 96 5b bb 86 61 |.y..j..(t...[..a|
1071 0040: cf 79 9b dd 6a ae b0 28 74 b8 e5 96 5b bb 86 61 |.y..j..(t...[..a|
1073 0050: a3 15 6e 3a 71 c8 6a e8 a5 da 95 64 28 22 ce 69 |..n:q.j....d(".i|
1072 0050: a3 15 6e 3a 71 c8 6a e8 a5 da 95 64 28 22 ce 69 |..n:q.j....d(".i|
1074 0060: cd 06 59 34 28 2b 51 2a 58 c3 17 56 2a 9a 9d 67 |..Y4(+Q*X..V*..g|
1073 0060: cd 06 59 34 28 2b 51 2a 58 c3 17 56 2a 9a 9d 67 |..Y4(+Q*X..V*..g|
1075 0070: dc c6 35 9e c4 1d f8 9e 87 f3 9c f3 3b bf 0f bf |..5.........;...|
1074 0070: dc c6 35 9e c4 1d f8 9e 87 f3 9c f3 3b bf 0f bf |..5.........;...|
1076 0080: 97 e3 38 ce f4 42 b9 d6 af ae d2 55 af ae 7b ad |..8..B.....U..{.|
1075 0080: 97 e3 38 ce f4 42 b9 d6 af ae d2 55 af ae 7b ad |..8..B.....U..{.|
1077 0090: c6 c9 8d bb 8a ec b4 07 ed 7f fd ed d3 53 be 4e |.............S.N|
1076 0090: c6 c9 8d bb 8a ec b4 07 ed 7f fd ed d3 53 be 4e |.............S.N|
1078 00a0: f4 0e af 59 52 73 ea 50 d7 96 9e ba d4 9a 1f 87 |...YRs.P........|
1077 00a0: f4 0e af 59 52 73 ea 50 d7 96 9e ba d4 9a 1f 87 |...YRs.P........|
1079 00b0: 9b 9f 1d e8 7a 6a 79 e9 cb 7f cf eb fe 7e d3 82 |....zjy......~..|
1078 00b0: 9b 9f 1d e8 7a 6a 79 e9 cb 7f cf eb fe 7e d3 82 |....zjy......~..|
1080 00c0: ce 2f 36 38 21 23 cc 36 b7 b5 38 90 ab a1 21 92 |./68!#.6..8...!.|
1079 00c0: ce 2f 36 38 21 23 cc 36 b7 b5 38 90 ab a1 21 92 |./68!#.6..8...!.|
1081 00d0: 78 5a 0a 8a b1 31 0a 48 a6 29 92 4a 32 e6 1b e1 |xZ...1.H.).J2...|
1080 00d0: 78 5a 0a 8a b1 31 0a 48 a6 29 92 4a 32 e6 1b e1 |xZ...1.H.).J2...|
1082 00e0: 4a 85 b9 46 40 46 ed 61 63 b5 d6 aa 20 1e ac 5e |J..F@F.ac... ..^|
1081 00e0: 4a 85 b9 46 40 46 ed 61 63 b5 d6 aa 20 1e ac 5e |J..F@F.ac... ..^|
1083 00f0: b0 0a ae 8a c4 03 c6 d6 f9 a3 7b eb fb 4e de 7f |..........{..N..|
1082 00f0: b0 0a ae 8a c4 03 c6 d6 f9 a3 7b eb fb 4e de 7f |..........{..N..|
1084 0100: e4 97 55 5f 15 76 96 d2 5d bf 9d 3f 38 18 29 4c |..U_.v..]..?8.)L|
1083 0100: e4 97 55 5f 15 76 96 d2 5d bf 9d 3f 38 18 29 4c |..U_.v..]..?8.)L|
1085 0110: 0f b7 5d 6e 9b b3 aa 7e c6 d5 15 5b f7 7c 52 f1 |..]n...~...[.|R.|
1084 0110: 0f b7 5d 6e 9b b3 aa 7e c6 d5 15 5b f7 7c 52 f1 |..]n...~...[.|R.|
1086 0120: 7c 73 18 63 98 6d 3e 23 51 5a 6a 2e 19 72 8d cb ||s.c.m>#QZj..r..|
1085 0120: 7c 73 18 63 98 6d 3e 23 51 5a 6a 2e 19 72 8d cb ||s.c.m>#QZj..r..|
1087 0130: 09 07 14 78 82 33 e9 62 86 7d 0c 00 17 88 53 86 |...x.3.b.}....S.|
1086 0130: 09 07 14 78 82 33 e9 62 86 7d 0c 00 17 88 53 86 |...x.3.b.}....S.|
1088 0140: 3d 75 0b 63 e2 16 c6 84 9d 76 8f 76 7a cb de fc |=u.c.....v.vz...|
1087 0140: 3d 75 0b 63 e2 16 c6 84 9d 76 8f 76 7a cb de fc |=u.c.....v.vz...|
1089 0150: a8 a3 f0 46 d3 a5 f6 c7 96 b6 9f 60 3b 57 ae 28 |...F.......`;W.(|
1088 0150: a8 a3 f0 46 d3 a5 f6 c7 96 b6 9f 60 3b 57 ae 28 |...F.......`;W.(|
1090 0160: ce b2 8d e9 f4 3e 6f 66 53 dd e5 6b ad 67 be f9 |.....>ofS..k.g..|
1089 0160: ce b2 8d e9 f4 3e 6f 66 53 dd e5 6b ad 67 be f9 |.....>ofS..k.g..|
1091 0170: 72 ee 5f 8d 61 3c 61 b6 f9 8c d8 a5 82 63 45 3d |r._.a<a......cE=|
1090 0170: 72 ee 5f 8d 61 3c 61 b6 f9 8c d8 a5 82 63 45 3d |r._.a<a......cE=|
1092 0180: a3 0c 61 90 68 24 28 87 50 b9 c2 97 c6 20 01 11 |..a.h$(.P.... ..|
1091 0180: a3 0c 61 90 68 24 28 87 50 b9 c2 97 c6 20 01 11 |..a.h$(.P.... ..|
1093 0190: 80 84 10 98 cf e8 e4 13 96 05 51 2c 38 f3 c4 ec |..........Q,8...|
1092 0190: 80 84 10 98 cf e8 e4 13 96 05 51 2c 38 f3 c4 ec |..........Q,8...|
1094 01a0: ea 43 e7 96 5e 6a c8 be 11 dd 32 78 a2 fa dd 8f |.C..^j....2x....|
1093 01a0: ea 43 e7 96 5e 6a c8 be 11 dd 32 78 a2 fa dd 8f |.C..^j....2x....|
1095 01b0: b3 61 84 61 51 0c b3 cd 27 64 42 6b c2 b4 92 1e |.a.aQ...'dBk....|
1094 01b0: b3 61 84 61 51 0c b3 cd 27 64 42 6b c2 b4 92 1e |.a.aQ...'dBk....|
1096 01c0: 86 8c 12 68 24 00 10 db 7f 50 00 c6 91 e7 fa 4c |...h$....P.....L|
1095 01c0: 86 8c 12 68 24 00 10 db 7f 50 00 c6 91 e7 fa 4c |...h$....P.....L|
1097 01d0: 22 22 cc bf 84 81 0a 92 c1 aa 2a c7 1b 49 e6 ee |""........*..I..|
1096 01d0: 22 22 cc bf 84 81 0a 92 c1 aa 2a c7 1b 49 e6 ee |""........*..I..|
1098 01e0: 6b a9 7e e0 e9 b2 91 5e 7c 73 68 e0 fc 23 3f 34 |k.~....^|sh..#?4|
1097 01e0: 6b a9 7e e0 e9 b2 91 5e 7c 73 68 e0 fc 23 3f 34 |k.~....^|sh..#?4|
1099 01f0: ed cf 0e f2 b3 d3 4c d7 ae 59 33 6f 8c 3d b8 63 |......L..Y3o.=.c|
1098 01f0: ed cf 0e f2 b3 d3 4c d7 ae 59 33 6f 8c 3d b8 63 |......L..Y3o.=.c|
1100 0200: 21 2b e8 3d e0 6f 9d 3a b7 f9 dc 24 2a b2 3e a7 |!+.=.o.:...$*.>.|
1099 0200: 21 2b e8 3d e0 6f 9d 3a b7 f9 dc 24 2a b2 3e a7 |!+.=.o.:...$*.>.|
1101 0210: 58 dc 91 d8 40 e9 23 8e 88 84 ae 0f b9 00 2e b5 |X...@.#.........|
1100 0210: 58 dc 91 d8 40 e9 23 8e 88 84 ae 0f b9 00 2e b5 |X...@.#.........|
1102 0220: 74 36 f3 40 53 40 34 15 c0 d7 12 8d e7 bb 65 f9 |t6.@S@4.......e.|
1101 0220: 74 36 f3 40 53 40 34 15 c0 d7 12 8d e7 bb 65 f9 |t6.@S@4.......e.|
1103 0230: c8 ef 03 0f ff f9 fe b6 8a 0d 6d fd ec 51 70 f7 |..........m..Qp.|
1102 0230: c8 ef 03 0f ff f9 fe b6 8a 0d 6d fd ec 51 70 f7 |..........m..Qp.|
1104 0240: a7 ad 9b 6b 9d da 74 7b 53 43 d1 43 63 fd 19 f9 |...k..t{SC.Cc...|
1103 0240: a7 ad 9b 6b 9d da 74 7b 53 43 d1 43 63 fd 19 f9 |...k..t{SC.Cc...|
1105 0250: ca 67 95 e5 ef c4 e6 6c 9e 44 e1 c5 ac 7a 82 6f |.g.....l.D...z.o|
1104 0250: ca 67 95 e5 ef c4 e6 6c 9e 44 e1 c5 ac 7a 82 6f |.g.....l.D...z.o|
1106 0260: c2 e1 d2 b5 2d 81 29 f0 5d 09 6c 6f 10 ae 88 cf |....-.).].lo....|
1105 0260: c2 e1 d2 b5 2d 81 29 f0 5d 09 6c 6f 10 ae 88 cf |....-.).].lo....|
1107 0270: 25 05 d0 93 06 78 80 60 43 2d 10 1b 47 71 2b b7 |%....x.`C-..Gq+.|
1106 0270: 25 05 d0 93 06 78 80 60 43 2d 10 1b 47 71 2b b7 |%....x.`C-..Gq+.|
1108 0280: 7f bb e9 a7 e4 7d 67 7b df 9b f7 62 cf cd d8 f4 |.....}g{...b....|
1107 0280: 7f bb e9 a7 e4 7d 67 7b df 9b f7 62 cf cd d8 f4 |.....}g{...b....|
1109 0290: 48 bc 64 51 57 43 ff ea 8b 0b ae 74 64 53 07 86 |H.dQWC.....tdS..|
1108 0290: 48 bc 64 51 57 43 ff ea 8b 0b ae 74 64 53 07 86 |H.dQWC.....tdS..|
1110 02a0: fa 66 3c 5e f7 e1 af a7 c2 90 ff a7 be 9e c9 29 |.f<^...........)|
1109 02a0: fa 66 3c 5e f7 e1 af a7 c2 90 ff a7 be 9e c9 29 |.f<^...........)|
1111 02b0: b6 cc 41 48 18 69 94 8b 7c 04 7d 8c 98 a7 95 50 |..AH.i..|.}....P|
1110 02b0: b6 cc 41 48 18 69 94 8b 7c 04 7d 8c 98 a7 95 50 |..AH.i..|.}....P|
1112 02c0: 44 d9 d0 20 c8 14 30 14 51 ad 6c 16 03 94 0f 5a |D.. ..0.Q.l....Z|
1111 02c0: 44 d9 d0 20 c8 14 30 14 51 ad 6c 16 03 94 0f 5a |D.. ..0.Q.l....Z|
1113 02d0: 46 93 7f 1c 87 8d 25 d7 9d a2 d1 92 4c f3 c2 54 |F.....%.....L..T|
1112 02d0: 46 93 7f 1c 87 8d 25 d7 9d a2 d1 92 4c f3 c2 54 |F.....%.....L..T|
1114 02e0: ba f8 70 18 ca 24 0a 29 96 43 71 f2 93 95 74 18 |..p..$.).Cq...t.|
1113 02e0: ba f8 70 18 ca 24 0a 29 96 43 71 f2 93 95 74 18 |..p..$.).Cq...t.|
1115 02f0: b5 65 c4 b8 f6 6c 5c 34 20 1e d5 0c 21 c0 b1 90 |.e...l\4 ...!...|
1114 02f0: b5 65 c4 b8 f6 6c 5c 34 20 1e d5 0c 21 c0 b1 90 |.e...l\4 ...!...|
1116 0300: 9e 12 40 b9 18 fa 5a 00 41 a2 39 d3 a9 c1 73 21 |..@...Z.A.9...s!|
1115 0300: 9e 12 40 b9 18 fa 5a 00 41 a2 39 d3 a9 c1 73 21 |..@...Z.A.9...s!|
1117 0310: 8e 5e 3c b9 b8 f8 48 6a 76 46 a7 1a b6 dd 5b 51 |.^<...HjvF....[Q|
1116 0310: 8e 5e 3c b9 b8 f8 48 6a 76 46 a7 1a b6 dd 5b 51 |.^<...HjvF....[Q|
1118 0320: 5e 19 1d 59 12 c6 32 89 02 9a c0 8f 4f b8 0a ba |^..Y..2.....O...|
1117 0320: 5e 19 1d 59 12 c6 32 89 02 9a c0 8f 4f b8 0a ba |^..Y..2.....O...|
1119 0330: 5e ec 58 37 44 a3 2f dd 33 ed c9 d3 dd c7 22 1b |^.X7D./.3.....".|
1118 0330: 5e ec 58 37 44 a3 2f dd 33 ed c9 d3 dd c7 22 1b |^.X7D./.3.....".|
1120 0340: 2f d4 94 8e 95 3f 77 a7 ae 6e f3 32 8d bb 4a 4c |/....?w..n.2..JL|
1119 0340: 2f d4 94 8e 95 3f 77 a7 ae 6e f3 32 8d bb 4a 4c |/....?w..n.2..JL|
1121 0350: b8 0a 5a 43 34 3a b3 3a d6 77 ff 5c b6 fa ad f9 |..ZC4:.:.w.\....|
1120 0350: b8 0a 5a 43 34 3a b3 3a d6 77 ff 5c b6 fa ad f9 |..ZC4:.:.w.\....|
1122 0360: db fb 6a 33 df c1 7d 99 cf ef d4 d5 6d da 77 7c |..j3..}.....m.w||
1121 0360: db fb 6a 33 df c1 7d 99 cf ef d4 d5 6d da 77 7c |..j3..}.....m.w||
1123 0370: 3b 19 fd af c5 3f f1 60 c3 17 |;....?.`..|
1122 0370: 3b 19 fd af c5 3f f1 60 c3 17 |;....?.`..|
1124 $ hg debugbundle ../rev.hg2.bz
1123 $ hg debugbundle ../rev.hg2.bz
1125 Stream params: {Compression: GZ}
1124 Stream params: {Compression: GZ}
1126 changegroup -- {} (mandatory: False)
1125 changegroup -- {} (mandatory: False)
1127 32af7686d403cf45b5d95f2d70cebea587ac806a
1126 32af7686d403cf45b5d95f2d70cebea587ac806a
1128 9520eea781bcca16c1e15acc0ba14335a0e8e5ba
1127 9520eea781bcca16c1e15acc0ba14335a0e8e5ba
1129 eea13746799a9e0bfd88f29d3c2e9dc9389f524f
1128 eea13746799a9e0bfd88f29d3c2e9dc9389f524f
1130 02de42196ebee42ef284b6780a87cdc96e8eaab6
1129 02de42196ebee42ef284b6780a87cdc96e8eaab6
1131 $ hg unbundle ../rev.hg2.bz
1130 $ hg unbundle ../rev.hg2.bz
1132 adding changesets
1131 adding changesets
1133 adding manifests
1132 adding manifests
1134 adding file changes
1133 adding file changes
1135 added 0 changesets with 0 changes to 3 files
1134 added 0 changesets with 0 changes to 3 files
1136 (run 'hg update' to get a working copy)
1135 (run 'hg update' to get a working copy)
1137 Simple case where it just work: BZ
1136 Simple case where it just work: BZ
1138 ----------------------------------
1137 ----------------------------------
1139
1138
1140 $ hg bundle2 --compress BZ --rev '8+7+5+4' ../rev.hg2.bz
1139 $ hg bundle2 --compress BZ --rev '8+7+5+4' ../rev.hg2.bz
1141 $ f --hexdump ../rev.hg2.bz
1140 $ f --hexdump ../rev.hg2.bz
1142 ../rev.hg2.bz:
1141 ../rev.hg2.bz:
1143 0000: 48 47 32 30 00 00 00 0e 43 6f 6d 70 72 65 73 73 |HG20....Compress|
1142 0000: 48 47 32 30 00 00 00 0e 43 6f 6d 70 72 65 73 73 |HG20....Compress|
1144 0010: 69 6f 6e 3d 42 5a 42 5a 68 39 31 41 59 26 53 59 |ion=BZBZh91AY&SY|
1143 0010: 69 6f 6e 3d 42 5a 42 5a 68 39 31 41 59 26 53 59 |ion=BZBZh91AY&SY|
1145 0020: a3 4b 18 3d 00 00 1a 7f ff ff bf 5f f6 ef ef 7f |.K.=......._....|
1144 0020: a3 4b 18 3d 00 00 1a 7f ff ff bf 5f f6 ef ef 7f |.K.=......._....|
1146 0030: f6 3f f7 d1 d9 ff ff f7 6e ff ff 6e f7 f6 bd df |.?......n..n....|
1145 0030: f6 3f f7 d1 d9 ff ff f7 6e ff ff 6e f7 f6 bd df |.?......n..n....|
1147 0040: b5 ab ff cf 67 f6 e7 7b f7 c0 02 d7 33 82 8b 51 |....g..{....3..Q|
1146 0040: b5 ab ff cf 67 f6 e7 7b f7 c0 02 d7 33 82 8b 51 |....g..{....3..Q|
1148 0050: 04 a5 53 d5 3d 27 a0 99 18 4d 0d 34 00 d1 a1 e8 |..S.='...M.4....|
1147 0050: 04 a5 53 d5 3d 27 a0 99 18 4d 0d 34 00 d1 a1 e8 |..S.='...M.4....|
1149 0060: 80 c8 7a 87 a9 a3 43 6a 3d 46 86 26 80 34 3d 40 |..z...Cj=F.&.4=@|
1148 0060: 80 c8 7a 87 a9 a3 43 6a 3d 46 86 26 80 34 3d 40 |..z...Cj=F.&.4=@|
1150 0070: c8 c9 b5 34 f4 8f 48 0f 51 ea 34 34 fd 4d aa 19 |...4..H.Q.44.M..|
1149 0070: c8 c9 b5 34 f4 8f 48 0f 51 ea 34 34 fd 4d aa 19 |...4..H.Q.44.M..|
1151 0080: 03 40 0c 08 da 86 43 d4 f5 0f 42 1e a0 f3 54 33 |.@....C...B...T3|
1150 0080: 03 40 0c 08 da 86 43 d4 f5 0f 42 1e a0 f3 54 33 |.@....C...B...T3|
1152 0090: 54 d3 13 4d 03 40 32 00 00 32 03 26 80 0d 00 0d |T..M.@2..2.&....|
1151 0090: 54 d3 13 4d 03 40 32 00 00 32 03 26 80 0d 00 0d |T..M.@2..2.&....|
1153 00a0: 00 68 c8 c8 03 20 32 30 98 8c 80 00 00 03 4d 00 |.h... 20......M.|
1152 00a0: 00 68 c8 c8 03 20 32 30 98 8c 80 00 00 03 4d 00 |.h... 20......M.|
1154 00b0: c8 00 00 0d 00 00 22 99 a1 34 c2 64 a6 d5 34 1a |......"..4.d..4.|
1153 00b0: c8 00 00 0d 00 00 22 99 a1 34 c2 64 a6 d5 34 1a |......"..4.d..4.|
1155 00c0: 00 00 06 86 83 4d 07 a8 d1 a0 68 01 a0 00 00 00 |.....M....h.....|
1154 00c0: 00 00 06 86 83 4d 07 a8 d1 a0 68 01 a0 00 00 00 |.....M....h.....|
1156 00d0: 00 0d 06 80 00 00 00 0d 00 03 40 00 00 04 a4 a1 |..........@.....|
1155 00d0: 00 0d 06 80 00 00 00 0d 00 03 40 00 00 04 a4 a1 |..........@.....|
1157 00e0: 4d a9 89 89 b4 9a 32 0c 43 46 86 87 a9 8d 41 9a |M.....2.CF....A.|
1156 00e0: 4d a9 89 89 b4 9a 32 0c 43 46 86 87 a9 8d 41 9a |M.....2.CF....A.|
1158 00f0: 98 46 9a 0d 31 32 1a 34 0d 0c 8d a2 0c 98 4d 06 |.F..12.4......M.|
1157 00f0: 98 46 9a 0d 31 32 1a 34 0d 0c 8d a2 0c 98 4d 06 |.F..12.4......M.|
1159 0100: 8c 40 c2 60 8d 0d 0c 20 c9 89 fa a0 d0 d3 21 a1 |.@.`... ......!.|
1158 0100: 8c 40 c2 60 8d 0d 0c 20 c9 89 fa a0 d0 d3 21 a1 |.@.`... ......!.|
1160 0110: ea 34 d3 68 9e a6 d1 74 05 33 cb 66 96 93 28 64 |.4.h...t.3.f..(d|
1159 0110: ea 34 d3 68 9e a6 d1 74 05 33 cb 66 96 93 28 64 |.4.h...t.3.f..(d|
1161 0120: 40 91 22 ac 55 9b ea 40 7b 38 94 e2 f8 06 00 cb |@.".U..@{8......|
1160 0120: 40 91 22 ac 55 9b ea 40 7b 38 94 e2 f8 06 00 cb |@.".U..@{8......|
1162 0130: 28 02 00 4d ab 40 24 10 43 18 cf 64 b4 06 83 0c |(..M.@$.C..d....|
1161 0130: 28 02 00 4d ab 40 24 10 43 18 cf 64 b4 06 83 0c |(..M.@$.C..d....|
1163 0140: 34 6c b4 a3 d4 0a 0a e4 a8 5c 4e 23 c0 c9 7a 31 |4l.......\N#..z1|
1162 0140: 34 6c b4 a3 d4 0a 0a e4 a8 5c 4e 23 c0 c9 7a 31 |4l.......\N#..z1|
1164 0150: 97 87 77 7a 64 88 80 8e 60 97 20 93 0f 8e eb c4 |..wzd...`. .....|
1163 0150: 97 87 77 7a 64 88 80 8e 60 97 20 93 0f 8e eb c4 |..wzd...`. .....|
1165 0160: 62 a4 44 a3 52 20 b2 99 a9 2e e1 d7 29 4a 54 ac |b.D.R ......)JT.|
1164 0160: 62 a4 44 a3 52 20 b2 99 a9 2e e1 d7 29 4a 54 ac |b.D.R ......)JT.|
1166 0170: 44 7a bb cc 04 3d e0 aa bd 6a 33 5e 9b a2 57 36 |Dz...=...j3^..W6|
1165 0170: 44 7a bb cc 04 3d e0 aa bd 6a 33 5e 9b a2 57 36 |Dz...=...j3^..W6|
1167 0180: fa cb 45 bb 6d 3e c1 d9 d9 f5 83 69 8a d0 e0 e2 |..E.m>.....i....|
1166 0180: fa cb 45 bb 6d 3e c1 d9 d9 f5 83 69 8a d0 e0 e2 |..E.m>.....i....|
1168 0190: e7 ae 90 55 24 da 3f ab 78 c0 4c b4 56 a3 9e a4 |...U$.?.x.L.V...|
1167 0190: e7 ae 90 55 24 da 3f ab 78 c0 4c b4 56 a3 9e a4 |...U$.?.x.L.V...|
1169 01a0: af 9c 65 74 86 ec 6d dc 62 dc 33 ca c8 50 dd 9d |..et..m.b.3..P..|
1168 01a0: af 9c 65 74 86 ec 6d dc 62 dc 33 ca c8 50 dd 9d |..et..m.b.3..P..|
1170 01b0: 98 8e 9e 59 20 f3 f0 42 91 4a 09 f5 75 8d 3d a5 |...Y ..B.J..u.=.|
1169 01b0: 98 8e 9e 59 20 f3 f0 42 91 4a 09 f5 75 8d 3d a5 |...Y ..B.J..u.=.|
1171 01c0: a5 15 cb 8d 10 63 b0 c2 2e b2 81 f7 c1 76 0e 53 |.....c.......v.S|
1170 01c0: a5 15 cb 8d 10 63 b0 c2 2e b2 81 f7 c1 76 0e 53 |.....c.......v.S|
1172 01d0: 6c 0e 46 73 b5 ae 67 f9 4c 0b 45 6b a8 32 2a 2f |l.Fs..g.L.Ek.2*/|
1171 01d0: 6c 0e 46 73 b5 ae 67 f9 4c 0b 45 6b a8 32 2a 2f |l.Fs..g.L.Ek.2*/|
1173 01e0: a2 54 a4 44 05 20 a1 38 d1 a4 c6 09 a8 2b 08 99 |.T.D. .8.....+..|
1172 01e0: a2 54 a4 44 05 20 a1 38 d1 a4 c6 09 a8 2b 08 99 |.T.D. .8.....+..|
1174 01f0: a4 14 ae 8d a3 e3 aa 34 27 d8 44 ca c3 5d 21 8b |.......4'.D..]!.|
1173 01f0: a4 14 ae 8d a3 e3 aa 34 27 d8 44 ca c3 5d 21 8b |.......4'.D..]!.|
1175 0200: 1a 1e 97 29 71 2b 09 4a 4a 55 55 94 58 65 b2 bc |...)q+.JJUU.Xe..|
1174 0200: 1a 1e 97 29 71 2b 09 4a 4a 55 55 94 58 65 b2 bc |...)q+.JJUU.Xe..|
1176 0210: f3 a5 90 26 36 76 67 7a 51 98 d6 8a 4a 99 50 b5 |...&6vgzQ...J.P.|
1175 0210: f3 a5 90 26 36 76 67 7a 51 98 d6 8a 4a 99 50 b5 |...&6vgzQ...J.P.|
1177 0220: 99 8f 94 21 17 a9 8b f3 ad 4c 33 d4 2e 40 c8 0c |...!.....L3..@..|
1176 0220: 99 8f 94 21 17 a9 8b f3 ad 4c 33 d4 2e 40 c8 0c |...!.....L3..@..|
1178 0230: 3b 90 53 39 db 48 02 34 83 48 d6 b3 99 13 d2 58 |;.S9.H.4.H.....X|
1177 0230: 3b 90 53 39 db 48 02 34 83 48 d6 b3 99 13 d2 58 |;.S9.H.4.H.....X|
1179 0240: 65 8e 71 ac a9 06 95 f2 c4 8e b4 08 6b d3 0c ae |e.q.........k...|
1178 0240: 65 8e 71 ac a9 06 95 f2 c4 8e b4 08 6b d3 0c ae |e.q.........k...|
1180 0250: d9 90 56 71 43 a7 a2 62 16 3e 50 63 d3 57 3c 2d |..VqC..b.>Pc.W<-|
1179 0250: d9 90 56 71 43 a7 a2 62 16 3e 50 63 d3 57 3c 2d |..VqC..b.>Pc.W<-|
1181 0260: 9f 0f 34 05 08 d8 a6 4b 59 31 54 66 3a 45 0c 8a |..4....KY1Tf:E..|
1180 0260: 9f 0f 34 05 08 d8 a6 4b 59 31 54 66 3a 45 0c 8a |..4....KY1Tf:E..|
1182 0270: c7 90 3a f0 6a 83 1b f5 ca fb 80 2b 50 06 fb 51 |..:.j......+P..Q|
1181 0270: c7 90 3a f0 6a 83 1b f5 ca fb 80 2b 50 06 fb 51 |..:.j......+P..Q|
1183 0280: 7e a6 a4 d4 81 44 82 21 54 00 5b 1a 30 83 62 a3 |~....D.!T.[.0.b.|
1182 0280: 7e a6 a4 d4 81 44 82 21 54 00 5b 1a 30 83 62 a3 |~....D.!T.[.0.b.|
1184 0290: 18 b6 24 19 1e 45 df 4d 5c db a6 af 5b ac 90 fa |..$..E.M\...[...|
1183 0290: 18 b6 24 19 1e 45 df 4d 5c db a6 af 5b ac 90 fa |..$..E.M\...[...|
1185 02a0: 3e ed f9 ec 4c ba 36 ee d8 60 20 a7 c7 3b cb d1 |>...L.6..` ..;..|
1184 02a0: 3e ed f9 ec 4c ba 36 ee d8 60 20 a7 c7 3b cb d1 |>...L.6..` ..;..|
1186 02b0: 90 43 7d 27 16 50 5d ad f4 14 07 0b 90 5c cc 6b |.C}'.P]......\.k|
1185 02b0: 90 43 7d 27 16 50 5d ad f4 14 07 0b 90 5c cc 6b |.C}'.P]......\.k|
1187 02c0: 8d 3f a6 88 f4 34 37 a8 cf 14 63 36 19 f7 3e 28 |.?...47...c6..>(|
1186 02c0: 8d 3f a6 88 f4 34 37 a8 cf 14 63 36 19 f7 3e 28 |.?...47...c6..>(|
1188 02d0: de 99 e8 16 a4 9d 0d 40 a1 a7 24 52 14 a6 72 62 |.......@..$R..rb|
1187 02d0: de 99 e8 16 a4 9d 0d 40 a1 a7 24 52 14 a6 72 62 |.......@..$R..rb|
1189 02e0: 59 5a ca 2d e5 51 90 78 88 d9 c6 c7 21 d0 f7 46 |YZ.-.Q.x....!..F|
1188 02e0: 59 5a ca 2d e5 51 90 78 88 d9 c6 c7 21 d0 f7 46 |YZ.-.Q.x....!..F|
1190 02f0: b2 04 46 44 4e 20 9c 12 b1 03 4e 25 e0 a9 0c 58 |..FDN ....N%...X|
1189 02f0: b2 04 46 44 4e 20 9c 12 b1 03 4e 25 e0 a9 0c 58 |..FDN ....N%...X|
1191 0300: 5b 1d 3c 93 20 01 51 de a9 1c 69 23 32 46 14 b4 |[.<. .Q...i#2F..|
1190 0300: 5b 1d 3c 93 20 01 51 de a9 1c 69 23 32 46 14 b4 |[.<. .Q...i#2F..|
1192 0310: 90 db 17 98 98 50 03 90 29 aa 40 b0 13 d8 43 d2 |.....P..).@...C.|
1191 0310: 90 db 17 98 98 50 03 90 29 aa 40 b0 13 d8 43 d2 |.....P..).@...C.|
1193 0320: 5f c5 9d eb f3 f2 ad 41 e8 7a a9 ed a1 58 84 a6 |_......A.z...X..|
1192 0320: 5f c5 9d eb f3 f2 ad 41 e8 7a a9 ed a1 58 84 a6 |_......A.z...X..|
1194 0330: 42 bf d6 fc 24 82 c1 20 32 26 4a 15 a6 1d 29 7f |B...$.. 2&J...).|
1193 0330: 42 bf d6 fc 24 82 c1 20 32 26 4a 15 a6 1d 29 7f |B...$.. 2&J...).|
1195 0340: 7e f4 3d 07 bc 62 9a 5b ec 44 3d 72 1d 41 8b 5c |~.=..b.[.D=r.A.\|
1194 0340: 7e f4 3d 07 bc 62 9a 5b ec 44 3d 72 1d 41 8b 5c |~.=..b.[.D=r.A.\|
1196 0350: 80 de 0e 62 9a 2e f8 83 00 d5 07 a0 9c c6 74 98 |...b..........t.|
1195 0350: 80 de 0e 62 9a 2e f8 83 00 d5 07 a0 9c c6 74 98 |...b..........t.|
1197 0360: 11 b2 5e a9 38 02 03 ee fd 86 5c f4 86 b3 ae da |..^.8.....\.....|
1196 0360: 11 b2 5e a9 38 02 03 ee fd 86 5c f4 86 b3 ae da |..^.8.....\.....|
1198 0370: 05 94 01 c5 c6 ea 18 e6 ba 2a ba b3 04 5c 96 89 |.........*...\..|
1197 0370: 05 94 01 c5 c6 ea 18 e6 ba 2a ba b3 04 5c 96 89 |.........*...\..|
1199 0380: 72 63 5b 10 11 f6 67 34 98 cb e4 c0 4e fa e6 99 |rc[...g4....N...|
1198 0380: 72 63 5b 10 11 f6 67 34 98 cb e4 c0 4e fa e6 99 |rc[...g4....N...|
1200 0390: 19 6e 50 e8 26 8d 0c 17 e0 be ef e1 8e 02 6f 32 |.nP.&.........o2|
1199 0390: 19 6e 50 e8 26 8d 0c 17 e0 be ef e1 8e 02 6f 32 |.nP.&.........o2|
1201 03a0: 82 dc 26 f8 a1 08 f3 8a 0d f3 c4 75 00 48 73 b8 |..&........u.Hs.|
1200 03a0: 82 dc 26 f8 a1 08 f3 8a 0d f3 c4 75 00 48 73 b8 |..&........u.Hs.|
1202 03b0: be 3b 0d 7f d0 fd c7 78 96 ec e0 03 80 68 4d 8d |.;.....x.....hM.|
1201 03b0: be 3b 0d 7f d0 fd c7 78 96 ec e0 03 80 68 4d 8d |.;.....x.....hM.|
1203 03c0: 43 8c d7 68 58 f9 50 f0 18 cb 21 58 1b 60 cd 1f |C..hX.P...!X.`..|
1202 03c0: 43 8c d7 68 58 f9 50 f0 18 cb 21 58 1b 60 cd 1f |C..hX.P...!X.`..|
1204 03d0: 84 36 2e 16 1f 0a f7 4e 8f eb df 01 2d c2 79 0b |.6.....N....-.y.|
1203 03d0: 84 36 2e 16 1f 0a f7 4e 8f eb df 01 2d c2 79 0b |.6.....N....-.y.|
1205 03e0: f7 24 ea 0d e8 59 86 51 6e 1c 30 a3 ad 2f ee 8c |.$...Y.Qn.0../..|
1204 03e0: f7 24 ea 0d e8 59 86 51 6e 1c 30 a3 ad 2f ee 8c |.$...Y.Qn.0../..|
1206 03f0: 90 c8 84 d5 e8 34 c1 95 b2 c9 f6 4d 87 1c 7d 19 |.....4.....M..}.|
1205 03f0: 90 c8 84 d5 e8 34 c1 95 b2 c9 f6 4d 87 1c 7d 19 |.....4.....M..}.|
1207 0400: d6 41 58 56 7a e0 6c ba 10 c7 e8 33 39 36 96 e7 |.AXVz.l....396..|
1206 0400: d6 41 58 56 7a e0 6c ba 10 c7 e8 33 39 36 96 e7 |.AXVz.l....396..|
1208 0410: d2 f9 59 9a 08 95 48 38 e7 0b b7 0a 24 67 c4 39 |..Y...H8....$g.9|
1207 0410: d2 f9 59 9a 08 95 48 38 e7 0b b7 0a 24 67 c4 39 |..Y...H8....$g.9|
1209 0420: 8b 43 88 57 9c 01 f5 61 b5 e1 27 41 7e af 83 fe |.C.W...a..'A~...|
1208 0420: 8b 43 88 57 9c 01 f5 61 b5 e1 27 41 7e af 83 fe |.C.W...a..'A~...|
1210 0430: 2e e4 8a 70 a1 21 46 96 30 7a |...p.!F.0z|
1209 0430: 2e e4 8a 70 a1 21 46 96 30 7a |...p.!F.0z|
1211 $ hg debugbundle ../rev.hg2.bz
1210 $ hg debugbundle ../rev.hg2.bz
1212 Stream params: {Compression: BZ}
1211 Stream params: {Compression: BZ}
1213 changegroup -- {} (mandatory: False)
1212 changegroup -- {} (mandatory: False)
1214 32af7686d403cf45b5d95f2d70cebea587ac806a
1213 32af7686d403cf45b5d95f2d70cebea587ac806a
1215 9520eea781bcca16c1e15acc0ba14335a0e8e5ba
1214 9520eea781bcca16c1e15acc0ba14335a0e8e5ba
1216 eea13746799a9e0bfd88f29d3c2e9dc9389f524f
1215 eea13746799a9e0bfd88f29d3c2e9dc9389f524f
1217 02de42196ebee42ef284b6780a87cdc96e8eaab6
1216 02de42196ebee42ef284b6780a87cdc96e8eaab6
1218 $ hg unbundle ../rev.hg2.bz
1217 $ hg unbundle ../rev.hg2.bz
1219 adding changesets
1218 adding changesets
1220 adding manifests
1219 adding manifests
1221 adding file changes
1220 adding file changes
1222 added 0 changesets with 0 changes to 3 files
1221 added 0 changesets with 0 changes to 3 files
1223 (run 'hg update' to get a working copy)
1222 (run 'hg update' to get a working copy)
1224
1223
1225 unknown compression while unbundling
1224 unknown compression while unbundling
1226 -----------------------------
1225 -----------------------------
1227
1226
1228 $ hg bundle2 --param Compression=FooBarUnknown --rev '8+7+5+4' ../rev.hg2.bz
1227 $ hg bundle2 --param Compression=FooBarUnknown --rev '8+7+5+4' ../rev.hg2.bz
1229 $ cat ../rev.hg2.bz | hg statbundle2
1228 $ cat ../rev.hg2.bz | hg statbundle2
1230 abort: unknown parameters: Stream Parameter - Compression='FooBarUnknown'
1229 abort: unknown parameters: Stream Parameter - Compression='FooBarUnknown'
1231 [255]
1230 [255]
1232 $ hg unbundle ../rev.hg2.bz
1231 $ hg unbundle ../rev.hg2.bz
1233 abort: ../rev.hg2.bz: unknown bundle feature, Stream Parameter - Compression='FooBarUnknown'
1232 abort: ../rev.hg2.bz: unknown bundle feature, Stream Parameter - Compression='FooBarUnknown'
1234 (see https://mercurial-scm.org/wiki/BundleFeature for more information)
1233 (see https://mercurial-scm.org/wiki/BundleFeature for more information)
1235 [255]
1234 [255]
1236
1235
1237 $ cd ..
1236 $ cd ..
@@ -1,460 +1,457 b''
1 Create an extension to test bundle2 with multiple changegroups
1 Create an extension to test bundle2 with multiple changegroups
2
2
3 $ cat > bundle2.py <<EOF
3 $ cat > bundle2.py <<EOF
4 > """
4 > """
5 > """
5 > """
6 > from mercurial import changegroup, discovery, exchange
6 > from mercurial import changegroup, discovery, exchange
7 >
7 >
8 > def _getbundlechangegrouppart(bundler, repo, source, bundlecaps=None,
8 > def _getbundlechangegrouppart(bundler, repo, source, bundlecaps=None,
9 > b2caps=None, heads=None, common=None,
9 > b2caps=None, heads=None, common=None,
10 > **kwargs):
10 > **kwargs):
11 > # Create two changegroups given the common changesets and heads for the
11 > # Create two changegroups given the common changesets and heads for the
12 > # changegroup part we are being requested. Use the parent of each head
12 > # changegroup part we are being requested. Use the parent of each head
13 > # in 'heads' as intermediate heads for the first changegroup.
13 > # in 'heads' as intermediate heads for the first changegroup.
14 > intermediates = [repo[r].p1().node() for r in heads]
14 > intermediates = [repo[r].p1().node() for r in heads]
15 > outgoing = discovery.outgoing(repo, common, intermediates)
15 > outgoing = discovery.outgoing(repo, common, intermediates)
16 > cg = changegroup.makechangegroup(repo, outgoing, b'01',
16 > cg = changegroup.makechangegroup(repo, outgoing, b'01',
17 > source, bundlecaps=bundlecaps)
17 > source, bundlecaps=bundlecaps)
18 > bundler.newpart(b'output', data=b'changegroup1')
18 > bundler.newpart(b'output', data=b'changegroup1')
19 > bundler.newpart(b'changegroup', data=cg.getchunks())
19 > bundler.newpart(b'changegroup', data=cg.getchunks())
20 > outgoing = discovery.outgoing(repo, common + intermediates, heads)
20 > outgoing = discovery.outgoing(repo, common + intermediates, heads)
21 > cg = changegroup.makechangegroup(repo, outgoing, b'01',
21 > cg = changegroup.makechangegroup(repo, outgoing, b'01',
22 > source, bundlecaps=bundlecaps)
22 > source, bundlecaps=bundlecaps)
23 > bundler.newpart(b'output', data=b'changegroup2')
23 > bundler.newpart(b'output', data=b'changegroup2')
24 > bundler.newpart(b'changegroup', data=cg.getchunks())
24 > bundler.newpart(b'changegroup', data=cg.getchunks())
25 >
25 >
26 > def _pull(repo, *args, **kwargs):
26 > def _pull(repo, *args, **kwargs):
27 > pullop = _orig_pull(repo, *args, **kwargs)
27 > pullop = _orig_pull(repo, *args, **kwargs)
28 > repo.ui.write(b'pullop.cgresult is %d\n' % pullop.cgresult)
28 > repo.ui.write(b'pullop.cgresult is %d\n' % pullop.cgresult)
29 > return pullop
29 > return pullop
30 >
30 >
31 > _orig_pull = exchange.pull
31 > _orig_pull = exchange.pull
32 > exchange.pull = _pull
32 > exchange.pull = _pull
33 > exchange.getbundle2partsmapping[b'changegroup'] = _getbundlechangegrouppart
33 > exchange.getbundle2partsmapping[b'changegroup'] = _getbundlechangegrouppart
34 > EOF
34 > EOF
35
35
36 $ cat >> $HGRCPATH << EOF
36 $ cat >> $HGRCPATH << EOF
37 > [ui]
37 > [ui]
38 > logtemplate={rev}:{node|short} {phase} {author} {bookmarks} {desc|firstline}
38 > logtemplate={rev}:{node|short} {phase} {author} {bookmarks} {desc|firstline}
39 > EOF
39 > EOF
40
40
41 Start with a simple repository with a single commit
41 Start with a simple repository with a single commit
42
42
43 $ hg init repo
43 $ hg init repo
44 $ cd repo
44 $ cd repo
45 $ cat > .hg/hgrc << EOF
45 $ cat > .hg/hgrc << EOF
46 > [extensions]
46 > [extensions]
47 > bundle2=$TESTTMP/bundle2.py
47 > bundle2=$TESTTMP/bundle2.py
48 > EOF
48 > EOF
49
49
50 $ echo A > A
50 $ echo A > A
51 $ hg commit -A -m A -q
51 $ hg commit -A -m A -q
52 $ cd ..
52 $ cd ..
53
53
54 Clone
54 Clone
55
55
56 $ hg clone -q repo clone
56 $ hg clone -q repo clone
57
57
58 Add two linear commits
58 Add two linear commits
59
59
60 $ cd repo
60 $ cd repo
61 $ echo B > B
61 $ echo B > B
62 $ hg commit -A -m B -q
62 $ hg commit -A -m B -q
63 $ echo C > C
63 $ echo C > C
64 $ hg commit -A -m C -q
64 $ hg commit -A -m C -q
65
65
66 $ cd ../clone
66 $ cd ../clone
67 $ cat >> .hg/hgrc <<EOF
67 $ cat >> .hg/hgrc <<EOF
68 > [hooks]
68 > [hooks]
69 > pretxnchangegroup = sh -c "printenv.py --line pretxnchangegroup"
69 > pretxnchangegroup = sh -c "printenv.py --line pretxnchangegroup"
70 > changegroup = sh -c "printenv.py --line changegroup"
70 > changegroup = sh -c "printenv.py --line changegroup"
71 > incoming = sh -c "printenv.py --line incoming"
71 > incoming = sh -c "printenv.py --line incoming"
72 > EOF
72 > EOF
73
73
74 Pull the new commits in the clone
74 Pull the new commits in the clone
75
75
76 $ hg pull
76 $ hg pull
77 pulling from $TESTTMP/repo
77 pulling from $TESTTMP/repo
78 searching for changes
78 searching for changes
79 remote: changegroup1
79 remote: changegroup1
80 adding changesets
80 adding changesets
81 adding manifests
81 adding manifests
82 adding file changes
82 adding file changes
83 added 1 changesets with 1 changes to 1 files
84 pretxnchangegroup hook: HG_HOOKNAME=pretxnchangegroup
83 pretxnchangegroup hook: HG_HOOKNAME=pretxnchangegroup
85 HG_HOOKTYPE=pretxnchangegroup
84 HG_HOOKTYPE=pretxnchangegroup
86 HG_NODE=27547f69f25460a52fff66ad004e58da7ad3fb56
85 HG_NODE=27547f69f25460a52fff66ad004e58da7ad3fb56
87 HG_NODE_LAST=27547f69f25460a52fff66ad004e58da7ad3fb56
86 HG_NODE_LAST=27547f69f25460a52fff66ad004e58da7ad3fb56
88 HG_PENDING=$TESTTMP/clone
87 HG_PENDING=$TESTTMP/clone
89 HG_SOURCE=pull
88 HG_SOURCE=pull
90 HG_TXNID=TXN:$ID$
89 HG_TXNID=TXN:$ID$
91 HG_TXNNAME=pull
90 HG_TXNNAME=pull
92 file:/*/$TESTTMP/repo (glob)
91 file:/*/$TESTTMP/repo (glob)
93 HG_URL=file:$TESTTMP/repo
92 HG_URL=file:$TESTTMP/repo
94
93
95 remote: changegroup2
94 remote: changegroup2
96 adding changesets
95 adding changesets
97 adding manifests
96 adding manifests
98 adding file changes
97 adding file changes
99 added 1 changesets with 1 changes to 1 files
100 pretxnchangegroup hook: HG_HOOKNAME=pretxnchangegroup
98 pretxnchangegroup hook: HG_HOOKNAME=pretxnchangegroup
101 HG_HOOKTYPE=pretxnchangegroup
99 HG_HOOKTYPE=pretxnchangegroup
102 HG_NODE=f838bfaca5c7226600ebcfd84f3c3c13a28d3757
100 HG_NODE=f838bfaca5c7226600ebcfd84f3c3c13a28d3757
103 HG_NODE_LAST=f838bfaca5c7226600ebcfd84f3c3c13a28d3757
101 HG_NODE_LAST=f838bfaca5c7226600ebcfd84f3c3c13a28d3757
104 HG_PENDING=$TESTTMP/clone
102 HG_PENDING=$TESTTMP/clone
105 HG_PHASES_MOVED=1
103 HG_PHASES_MOVED=1
106 HG_SOURCE=pull
104 HG_SOURCE=pull
107 HG_TXNID=TXN:$ID$
105 HG_TXNID=TXN:$ID$
108 HG_TXNNAME=pull
106 HG_TXNNAME=pull
109 file:/*/$TESTTMP/repo (glob)
107 file:/*/$TESTTMP/repo (glob)
110 HG_URL=file:$TESTTMP/repo
108 HG_URL=file:$TESTTMP/repo
111
109
110 added 2 changesets with 2 changes to 2 files
112 new changesets 27547f69f254:f838bfaca5c7
111 new changesets 27547f69f254:f838bfaca5c7
113 changegroup hook: HG_HOOKNAME=changegroup
112 changegroup hook: HG_HOOKNAME=changegroup
114 HG_HOOKTYPE=changegroup
113 HG_HOOKTYPE=changegroup
115 HG_NODE=27547f69f25460a52fff66ad004e58da7ad3fb56
114 HG_NODE=27547f69f25460a52fff66ad004e58da7ad3fb56
116 HG_NODE_LAST=27547f69f25460a52fff66ad004e58da7ad3fb56
115 HG_NODE_LAST=27547f69f25460a52fff66ad004e58da7ad3fb56
117 HG_SOURCE=pull
116 HG_SOURCE=pull
118 HG_TXNID=TXN:$ID$
117 HG_TXNID=TXN:$ID$
119 HG_TXNNAME=pull
118 HG_TXNNAME=pull
120 file:/*/$TESTTMP/repo (glob)
119 file:/*/$TESTTMP/repo (glob)
121 HG_URL=file:$TESTTMP/repo
120 HG_URL=file:$TESTTMP/repo
122
121
123 incoming hook: HG_HOOKNAME=incoming
122 incoming hook: HG_HOOKNAME=incoming
124 HG_HOOKTYPE=incoming
123 HG_HOOKTYPE=incoming
125 HG_NODE=27547f69f25460a52fff66ad004e58da7ad3fb56
124 HG_NODE=27547f69f25460a52fff66ad004e58da7ad3fb56
126 HG_SOURCE=pull
125 HG_SOURCE=pull
127 HG_TXNID=TXN:$ID$
126 HG_TXNID=TXN:$ID$
128 HG_TXNNAME=pull
127 HG_TXNNAME=pull
129 file:/*/$TESTTMP/repo (glob)
128 file:/*/$TESTTMP/repo (glob)
130 HG_URL=file:$TESTTMP/repo
129 HG_URL=file:$TESTTMP/repo
131
130
132 changegroup hook: HG_HOOKNAME=changegroup
131 changegroup hook: HG_HOOKNAME=changegroup
133 HG_HOOKTYPE=changegroup
132 HG_HOOKTYPE=changegroup
134 HG_NODE=f838bfaca5c7226600ebcfd84f3c3c13a28d3757
133 HG_NODE=f838bfaca5c7226600ebcfd84f3c3c13a28d3757
135 HG_NODE_LAST=f838bfaca5c7226600ebcfd84f3c3c13a28d3757
134 HG_NODE_LAST=f838bfaca5c7226600ebcfd84f3c3c13a28d3757
136 HG_PHASES_MOVED=1
135 HG_PHASES_MOVED=1
137 HG_SOURCE=pull
136 HG_SOURCE=pull
138 HG_TXNID=TXN:$ID$
137 HG_TXNID=TXN:$ID$
139 HG_TXNNAME=pull
138 HG_TXNNAME=pull
140 file:/*/$TESTTMP/repo (glob)
139 file:/*/$TESTTMP/repo (glob)
141 HG_URL=file:$TESTTMP/repo
140 HG_URL=file:$TESTTMP/repo
142
141
143 incoming hook: HG_HOOKNAME=incoming
142 incoming hook: HG_HOOKNAME=incoming
144 HG_HOOKTYPE=incoming
143 HG_HOOKTYPE=incoming
145 HG_NODE=f838bfaca5c7226600ebcfd84f3c3c13a28d3757
144 HG_NODE=f838bfaca5c7226600ebcfd84f3c3c13a28d3757
146 HG_PHASES_MOVED=1
145 HG_PHASES_MOVED=1
147 HG_SOURCE=pull
146 HG_SOURCE=pull
148 HG_TXNID=TXN:$ID$
147 HG_TXNID=TXN:$ID$
149 HG_TXNNAME=pull
148 HG_TXNNAME=pull
150 file:/*/$TESTTMP/repo (glob)
149 file:/*/$TESTTMP/repo (glob)
151 HG_URL=file:$TESTTMP/repo
150 HG_URL=file:$TESTTMP/repo
152
151
153 pullop.cgresult is 1
152 pullop.cgresult is 1
154 (run 'hg update' to get a working copy)
153 (run 'hg update' to get a working copy)
155 $ hg update
154 $ hg update
156 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
155 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
157 $ hg log -G
156 $ hg log -G
158 @ 2:f838bfaca5c7 public test C
157 @ 2:f838bfaca5c7 public test C
159 |
158 |
160 o 1:27547f69f254 public test B
159 o 1:27547f69f254 public test B
161 |
160 |
162 o 0:4a2df7238c3b public test A
161 o 0:4a2df7238c3b public test A
163
162
164 Add more changesets with multiple heads to the original repository
163 Add more changesets with multiple heads to the original repository
165
164
166 $ cd ../repo
165 $ cd ../repo
167 $ echo D > D
166 $ echo D > D
168 $ hg commit -A -m D -q
167 $ hg commit -A -m D -q
169 $ hg up -r 1
168 $ hg up -r 1
170 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
169 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
171 $ echo E > E
170 $ echo E > E
172 $ hg commit -A -m E -q
171 $ hg commit -A -m E -q
173 $ echo F > F
172 $ echo F > F
174 $ hg commit -A -m F -q
173 $ hg commit -A -m F -q
175 $ hg up -r 1
174 $ hg up -r 1
176 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
175 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
177 $ echo G > G
176 $ echo G > G
178 $ hg commit -A -m G -q
177 $ hg commit -A -m G -q
179 $ hg up -r 3
178 $ hg up -r 3
180 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
179 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
181 $ echo H > H
180 $ echo H > H
182 $ hg commit -A -m H -q
181 $ hg commit -A -m H -q
183 $ hg log -G
182 $ hg log -G
184 @ 7:5cd59d311f65 draft test H
183 @ 7:5cd59d311f65 draft test H
185 |
184 |
186 | o 6:1d14c3ce6ac0 draft test G
185 | o 6:1d14c3ce6ac0 draft test G
187 | |
186 | |
188 | | o 5:7f219660301f draft test F
187 | | o 5:7f219660301f draft test F
189 | | |
188 | | |
190 | | o 4:8a5212ebc852 draft test E
189 | | o 4:8a5212ebc852 draft test E
191 | |/
190 | |/
192 o | 3:b3325c91a4d9 draft test D
191 o | 3:b3325c91a4d9 draft test D
193 | |
192 | |
194 o | 2:f838bfaca5c7 draft test C
193 o | 2:f838bfaca5c7 draft test C
195 |/
194 |/
196 o 1:27547f69f254 draft test B
195 o 1:27547f69f254 draft test B
197 |
196 |
198 o 0:4a2df7238c3b draft test A
197 o 0:4a2df7238c3b draft test A
199
198
200 New heads are reported during transfer and properly accounted for in
199 New heads are reported during transfer and properly accounted for in
201 pullop.cgresult
200 pullop.cgresult
202
201
203 $ cd ../clone
202 $ cd ../clone
204 $ hg pull
203 $ hg pull
205 pulling from $TESTTMP/repo
204 pulling from $TESTTMP/repo
206 searching for changes
205 searching for changes
207 remote: changegroup1
206 remote: changegroup1
208 adding changesets
207 adding changesets
209 adding manifests
208 adding manifests
210 adding file changes
209 adding file changes
211 added 2 changesets with 2 changes to 2 files (+1 heads)
212 pretxnchangegroup hook: HG_HOOKNAME=pretxnchangegroup
210 pretxnchangegroup hook: HG_HOOKNAME=pretxnchangegroup
213 HG_HOOKTYPE=pretxnchangegroup
211 HG_HOOKTYPE=pretxnchangegroup
214 HG_NODE=b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e
212 HG_NODE=b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e
215 HG_NODE_LAST=8a5212ebc8527f9fb821601504794e3eb11a1ed3
213 HG_NODE_LAST=8a5212ebc8527f9fb821601504794e3eb11a1ed3
216 HG_PENDING=$TESTTMP/clone
214 HG_PENDING=$TESTTMP/clone
217 HG_SOURCE=pull
215 HG_SOURCE=pull
218 HG_TXNID=TXN:$ID$
216 HG_TXNID=TXN:$ID$
219 HG_TXNNAME=pull
217 HG_TXNNAME=pull
220 file:/*/$TESTTMP/repo (glob)
218 file:/*/$TESTTMP/repo (glob)
221 HG_URL=file:$TESTTMP/repo
219 HG_URL=file:$TESTTMP/repo
222
220
223 remote: changegroup2
221 remote: changegroup2
224 adding changesets
222 adding changesets
225 adding manifests
223 adding manifests
226 adding file changes
224 adding file changes
227 added 3 changesets with 3 changes to 3 files (+1 heads)
228 pretxnchangegroup hook: HG_HOOKNAME=pretxnchangegroup
225 pretxnchangegroup hook: HG_HOOKNAME=pretxnchangegroup
229 HG_HOOKTYPE=pretxnchangegroup
226 HG_HOOKTYPE=pretxnchangegroup
230 HG_NODE=7f219660301fe4c8a116f714df5e769695cc2b46
227 HG_NODE=7f219660301fe4c8a116f714df5e769695cc2b46
231 HG_NODE_LAST=5cd59d311f6508b8e0ed28a266756c859419c9f1
228 HG_NODE_LAST=5cd59d311f6508b8e0ed28a266756c859419c9f1
232 HG_PENDING=$TESTTMP/clone
229 HG_PENDING=$TESTTMP/clone
233 HG_PHASES_MOVED=1
230 HG_PHASES_MOVED=1
234 HG_SOURCE=pull
231 HG_SOURCE=pull
235 HG_TXNID=TXN:$ID$
232 HG_TXNID=TXN:$ID$
236 HG_TXNNAME=pull
233 HG_TXNNAME=pull
237 file:/*/$TESTTMP/repo (glob)
234 file:/*/$TESTTMP/repo (glob)
238 HG_URL=file:$TESTTMP/repo
235 HG_URL=file:$TESTTMP/repo
239
236
237 added 5 changesets with 5 changes to 5 files (+2 heads)
240 new changesets b3325c91a4d9:5cd59d311f65
238 new changesets b3325c91a4d9:5cd59d311f65
241 changegroup hook: HG_HOOKNAME=changegroup
239 changegroup hook: HG_HOOKNAME=changegroup
242 HG_HOOKTYPE=changegroup
240 HG_HOOKTYPE=changegroup
243 HG_NODE=b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e
241 HG_NODE=b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e
244 HG_NODE_LAST=8a5212ebc8527f9fb821601504794e3eb11a1ed3
242 HG_NODE_LAST=8a5212ebc8527f9fb821601504794e3eb11a1ed3
245 HG_SOURCE=pull
243 HG_SOURCE=pull
246 HG_TXNID=TXN:$ID$
244 HG_TXNID=TXN:$ID$
247 HG_TXNNAME=pull
245 HG_TXNNAME=pull
248 file:/*/$TESTTMP/repo (glob)
246 file:/*/$TESTTMP/repo (glob)
249 HG_URL=file:$TESTTMP/repo
247 HG_URL=file:$TESTTMP/repo
250
248
251 incoming hook: HG_HOOKNAME=incoming
249 incoming hook: HG_HOOKNAME=incoming
252 HG_HOOKTYPE=incoming
250 HG_HOOKTYPE=incoming
253 HG_NODE=b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e
251 HG_NODE=b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e
254 HG_SOURCE=pull
252 HG_SOURCE=pull
255 HG_TXNID=TXN:$ID$
253 HG_TXNID=TXN:$ID$
256 HG_TXNNAME=pull
254 HG_TXNNAME=pull
257 file:/*/$TESTTMP/repo (glob)
255 file:/*/$TESTTMP/repo (glob)
258 HG_URL=file:$TESTTMP/repo
256 HG_URL=file:$TESTTMP/repo
259
257
260 incoming hook: HG_HOOKNAME=incoming
258 incoming hook: HG_HOOKNAME=incoming
261 HG_HOOKTYPE=incoming
259 HG_HOOKTYPE=incoming
262 HG_NODE=8a5212ebc8527f9fb821601504794e3eb11a1ed3
260 HG_NODE=8a5212ebc8527f9fb821601504794e3eb11a1ed3
263 HG_SOURCE=pull
261 HG_SOURCE=pull
264 HG_TXNID=TXN:$ID$
262 HG_TXNID=TXN:$ID$
265 HG_TXNNAME=pull
263 HG_TXNNAME=pull
266 file:/*/$TESTTMP/repo (glob)
264 file:/*/$TESTTMP/repo (glob)
267 HG_URL=file:$TESTTMP/repo
265 HG_URL=file:$TESTTMP/repo
268
266
269 changegroup hook: HG_HOOKNAME=changegroup
267 changegroup hook: HG_HOOKNAME=changegroup
270 HG_HOOKTYPE=changegroup
268 HG_HOOKTYPE=changegroup
271 HG_NODE=7f219660301fe4c8a116f714df5e769695cc2b46
269 HG_NODE=7f219660301fe4c8a116f714df5e769695cc2b46
272 HG_NODE_LAST=5cd59d311f6508b8e0ed28a266756c859419c9f1
270 HG_NODE_LAST=5cd59d311f6508b8e0ed28a266756c859419c9f1
273 HG_PHASES_MOVED=1
271 HG_PHASES_MOVED=1
274 HG_SOURCE=pull
272 HG_SOURCE=pull
275 HG_TXNID=TXN:$ID$
273 HG_TXNID=TXN:$ID$
276 HG_TXNNAME=pull
274 HG_TXNNAME=pull
277 file:/*/$TESTTMP/repo (glob)
275 file:/*/$TESTTMP/repo (glob)
278 HG_URL=file:$TESTTMP/repo
276 HG_URL=file:$TESTTMP/repo
279
277
280 incoming hook: HG_HOOKNAME=incoming
278 incoming hook: HG_HOOKNAME=incoming
281 HG_HOOKTYPE=incoming
279 HG_HOOKTYPE=incoming
282 HG_NODE=7f219660301fe4c8a116f714df5e769695cc2b46
280 HG_NODE=7f219660301fe4c8a116f714df5e769695cc2b46
283 HG_PHASES_MOVED=1
281 HG_PHASES_MOVED=1
284 HG_SOURCE=pull
282 HG_SOURCE=pull
285 HG_TXNID=TXN:$ID$
283 HG_TXNID=TXN:$ID$
286 HG_TXNNAME=pull
284 HG_TXNNAME=pull
287 file:/*/$TESTTMP/repo (glob)
285 file:/*/$TESTTMP/repo (glob)
288 HG_URL=file:$TESTTMP/repo
286 HG_URL=file:$TESTTMP/repo
289
287
290 incoming hook: HG_HOOKNAME=incoming
288 incoming hook: HG_HOOKNAME=incoming
291 HG_HOOKTYPE=incoming
289 HG_HOOKTYPE=incoming
292 HG_NODE=1d14c3ce6ac0582d2809220d33e8cd7a696e0156
290 HG_NODE=1d14c3ce6ac0582d2809220d33e8cd7a696e0156
293 HG_PHASES_MOVED=1
291 HG_PHASES_MOVED=1
294 HG_SOURCE=pull
292 HG_SOURCE=pull
295 HG_TXNID=TXN:$ID$
293 HG_TXNID=TXN:$ID$
296 HG_TXNNAME=pull
294 HG_TXNNAME=pull
297 file:/*/$TESTTMP/repo (glob)
295 file:/*/$TESTTMP/repo (glob)
298 HG_URL=file:$TESTTMP/repo
296 HG_URL=file:$TESTTMP/repo
299
297
300 incoming hook: HG_HOOKNAME=incoming
298 incoming hook: HG_HOOKNAME=incoming
301 HG_HOOKTYPE=incoming
299 HG_HOOKTYPE=incoming
302 HG_NODE=5cd59d311f6508b8e0ed28a266756c859419c9f1
300 HG_NODE=5cd59d311f6508b8e0ed28a266756c859419c9f1
303 HG_PHASES_MOVED=1
301 HG_PHASES_MOVED=1
304 HG_SOURCE=pull
302 HG_SOURCE=pull
305 HG_TXNID=TXN:$ID$
303 HG_TXNID=TXN:$ID$
306 HG_TXNNAME=pull
304 HG_TXNNAME=pull
307 file:/*/$TESTTMP/repo (glob)
305 file:/*/$TESTTMP/repo (glob)
308 HG_URL=file:$TESTTMP/repo
306 HG_URL=file:$TESTTMP/repo
309
307
310 pullop.cgresult is 3
308 pullop.cgresult is 3
311 (run 'hg heads' to see heads, 'hg merge' to merge)
309 (run 'hg heads' to see heads, 'hg merge' to merge)
312 $ hg log -G
310 $ hg log -G
313 o 7:5cd59d311f65 public test H
311 o 7:5cd59d311f65 public test H
314 |
312 |
315 | o 6:1d14c3ce6ac0 public test G
313 | o 6:1d14c3ce6ac0 public test G
316 | |
314 | |
317 | | o 5:7f219660301f public test F
315 | | o 5:7f219660301f public test F
318 | | |
316 | | |
319 | | o 4:8a5212ebc852 public test E
317 | | o 4:8a5212ebc852 public test E
320 | |/
318 | |/
321 o | 3:b3325c91a4d9 public test D
319 o | 3:b3325c91a4d9 public test D
322 | |
320 | |
323 @ | 2:f838bfaca5c7 public test C
321 @ | 2:f838bfaca5c7 public test C
324 |/
322 |/
325 o 1:27547f69f254 public test B
323 o 1:27547f69f254 public test B
326 |
324 |
327 o 0:4a2df7238c3b public test A
325 o 0:4a2df7238c3b public test A
328
326
329 Removing a head from the original repository by merging it
327 Removing a head from the original repository by merging it
330
328
331 $ cd ../repo
329 $ cd ../repo
332 $ hg merge -r 6 -q
330 $ hg merge -r 6 -q
333 $ hg commit -m Merge
331 $ hg commit -m Merge
334 $ echo I > I
332 $ echo I > I
335 $ hg commit -A -m H -q
333 $ hg commit -A -m H -q
336 $ hg log -G
334 $ hg log -G
337 @ 9:9d18e5bd9ab0 draft test H
335 @ 9:9d18e5bd9ab0 draft test H
338 |
336 |
339 o 8:71bd7b46de72 draft test Merge
337 o 8:71bd7b46de72 draft test Merge
340 |\
338 |\
341 | o 7:5cd59d311f65 draft test H
339 | o 7:5cd59d311f65 draft test H
342 | |
340 | |
343 o | 6:1d14c3ce6ac0 draft test G
341 o | 6:1d14c3ce6ac0 draft test G
344 | |
342 | |
345 | | o 5:7f219660301f draft test F
343 | | o 5:7f219660301f draft test F
346 | | |
344 | | |
347 +---o 4:8a5212ebc852 draft test E
345 +---o 4:8a5212ebc852 draft test E
348 | |
346 | |
349 | o 3:b3325c91a4d9 draft test D
347 | o 3:b3325c91a4d9 draft test D
350 | |
348 | |
351 | o 2:f838bfaca5c7 draft test C
349 | o 2:f838bfaca5c7 draft test C
352 |/
350 |/
353 o 1:27547f69f254 draft test B
351 o 1:27547f69f254 draft test B
354 |
352 |
355 o 0:4a2df7238c3b draft test A
353 o 0:4a2df7238c3b draft test A
356
354
357 Removed heads are reported during transfer and properly accounted for in
355 Removed heads are reported during transfer and properly accounted for in
358 pullop.cgresult
356 pullop.cgresult
359
357
360 $ cd ../clone
358 $ cd ../clone
361 $ hg pull
359 $ hg pull
362 pulling from $TESTTMP/repo
360 pulling from $TESTTMP/repo
363 searching for changes
361 searching for changes
364 remote: changegroup1
362 remote: changegroup1
365 adding changesets
363 adding changesets
366 adding manifests
364 adding manifests
367 adding file changes
365 adding file changes
368 added 1 changesets with 0 changes to 0 files (-1 heads)
369 pretxnchangegroup hook: HG_HOOKNAME=pretxnchangegroup
366 pretxnchangegroup hook: HG_HOOKNAME=pretxnchangegroup
370 HG_HOOKTYPE=pretxnchangegroup
367 HG_HOOKTYPE=pretxnchangegroup
371 HG_NODE=71bd7b46de72e69a32455bf88d04757d542e6cf4
368 HG_NODE=71bd7b46de72e69a32455bf88d04757d542e6cf4
372 HG_NODE_LAST=71bd7b46de72e69a32455bf88d04757d542e6cf4
369 HG_NODE_LAST=71bd7b46de72e69a32455bf88d04757d542e6cf4
373 HG_PENDING=$TESTTMP/clone
370 HG_PENDING=$TESTTMP/clone
374 HG_SOURCE=pull
371 HG_SOURCE=pull
375 HG_TXNID=TXN:$ID$
372 HG_TXNID=TXN:$ID$
376 HG_TXNNAME=pull
373 HG_TXNNAME=pull
377 file:/*/$TESTTMP/repo (glob)
374 file:/*/$TESTTMP/repo (glob)
378 HG_URL=file:$TESTTMP/repo
375 HG_URL=file:$TESTTMP/repo
379
376
380 remote: changegroup2
377 remote: changegroup2
381 adding changesets
378 adding changesets
382 adding manifests
379 adding manifests
383 adding file changes
380 adding file changes
384 added 1 changesets with 1 changes to 1 files
385 pretxnchangegroup hook: HG_HOOKNAME=pretxnchangegroup
381 pretxnchangegroup hook: HG_HOOKNAME=pretxnchangegroup
386 HG_HOOKTYPE=pretxnchangegroup
382 HG_HOOKTYPE=pretxnchangegroup
387 HG_NODE=9d18e5bd9ab09337802595d49f1dad0c98df4d84
383 HG_NODE=9d18e5bd9ab09337802595d49f1dad0c98df4d84
388 HG_NODE_LAST=9d18e5bd9ab09337802595d49f1dad0c98df4d84
384 HG_NODE_LAST=9d18e5bd9ab09337802595d49f1dad0c98df4d84
389 HG_PENDING=$TESTTMP/clone
385 HG_PENDING=$TESTTMP/clone
390 HG_PHASES_MOVED=1
386 HG_PHASES_MOVED=1
391 HG_SOURCE=pull
387 HG_SOURCE=pull
392 HG_TXNID=TXN:$ID$
388 HG_TXNID=TXN:$ID$
393 HG_TXNNAME=pull
389 HG_TXNNAME=pull
394 file:/*/$TESTTMP/repo (glob)
390 file:/*/$TESTTMP/repo (glob)
395 HG_URL=file:$TESTTMP/repo
391 HG_URL=file:$TESTTMP/repo
396
392
393 added 2 changesets with 1 changes to 1 files (-1 heads)
397 new changesets 71bd7b46de72:9d18e5bd9ab0
394 new changesets 71bd7b46de72:9d18e5bd9ab0
398 changegroup hook: HG_HOOKNAME=changegroup
395 changegroup hook: HG_HOOKNAME=changegroup
399 HG_HOOKTYPE=changegroup
396 HG_HOOKTYPE=changegroup
400 HG_NODE=71bd7b46de72e69a32455bf88d04757d542e6cf4
397 HG_NODE=71bd7b46de72e69a32455bf88d04757d542e6cf4
401 HG_NODE_LAST=71bd7b46de72e69a32455bf88d04757d542e6cf4
398 HG_NODE_LAST=71bd7b46de72e69a32455bf88d04757d542e6cf4
402 HG_SOURCE=pull
399 HG_SOURCE=pull
403 HG_TXNID=TXN:$ID$
400 HG_TXNID=TXN:$ID$
404 HG_TXNNAME=pull
401 HG_TXNNAME=pull
405 file:/*/$TESTTMP/repo (glob)
402 file:/*/$TESTTMP/repo (glob)
406 HG_URL=file:$TESTTMP/repo
403 HG_URL=file:$TESTTMP/repo
407
404
408 incoming hook: HG_HOOKNAME=incoming
405 incoming hook: HG_HOOKNAME=incoming
409 HG_HOOKTYPE=incoming
406 HG_HOOKTYPE=incoming
410 HG_NODE=71bd7b46de72e69a32455bf88d04757d542e6cf4
407 HG_NODE=71bd7b46de72e69a32455bf88d04757d542e6cf4
411 HG_SOURCE=pull
408 HG_SOURCE=pull
412 HG_TXNID=TXN:$ID$
409 HG_TXNID=TXN:$ID$
413 HG_TXNNAME=pull
410 HG_TXNNAME=pull
414 file:/*/$TESTTMP/repo (glob)
411 file:/*/$TESTTMP/repo (glob)
415 HG_URL=file:$TESTTMP/repo
412 HG_URL=file:$TESTTMP/repo
416
413
417 changegroup hook: HG_HOOKNAME=changegroup
414 changegroup hook: HG_HOOKNAME=changegroup
418 HG_HOOKTYPE=changegroup
415 HG_HOOKTYPE=changegroup
419 HG_NODE=9d18e5bd9ab09337802595d49f1dad0c98df4d84
416 HG_NODE=9d18e5bd9ab09337802595d49f1dad0c98df4d84
420 HG_NODE_LAST=9d18e5bd9ab09337802595d49f1dad0c98df4d84
417 HG_NODE_LAST=9d18e5bd9ab09337802595d49f1dad0c98df4d84
421 HG_PHASES_MOVED=1
418 HG_PHASES_MOVED=1
422 HG_SOURCE=pull
419 HG_SOURCE=pull
423 HG_TXNID=TXN:$ID$
420 HG_TXNID=TXN:$ID$
424 HG_TXNNAME=pull
421 HG_TXNNAME=pull
425 file:/*/$TESTTMP/repo (glob)
422 file:/*/$TESTTMP/repo (glob)
426 HG_URL=file:$TESTTMP/repo
423 HG_URL=file:$TESTTMP/repo
427
424
428 incoming hook: HG_HOOKNAME=incoming
425 incoming hook: HG_HOOKNAME=incoming
429 HG_HOOKTYPE=incoming
426 HG_HOOKTYPE=incoming
430 HG_NODE=9d18e5bd9ab09337802595d49f1dad0c98df4d84
427 HG_NODE=9d18e5bd9ab09337802595d49f1dad0c98df4d84
431 HG_PHASES_MOVED=1
428 HG_PHASES_MOVED=1
432 HG_SOURCE=pull
429 HG_SOURCE=pull
433 HG_TXNID=TXN:$ID$
430 HG_TXNID=TXN:$ID$
434 HG_TXNNAME=pull
431 HG_TXNNAME=pull
435 file:/*/$TESTTMP/repo (glob)
432 file:/*/$TESTTMP/repo (glob)
436 HG_URL=file:$TESTTMP/repo
433 HG_URL=file:$TESTTMP/repo
437
434
438 pullop.cgresult is -2
435 pullop.cgresult is -2
439 (run 'hg update' to get a working copy)
436 (run 'hg update' to get a working copy)
440 $ hg log -G
437 $ hg log -G
441 o 9:9d18e5bd9ab0 public test H
438 o 9:9d18e5bd9ab0 public test H
442 |
439 |
443 o 8:71bd7b46de72 public test Merge
440 o 8:71bd7b46de72 public test Merge
444 |\
441 |\
445 | o 7:5cd59d311f65 public test H
442 | o 7:5cd59d311f65 public test H
446 | |
443 | |
447 o | 6:1d14c3ce6ac0 public test G
444 o | 6:1d14c3ce6ac0 public test G
448 | |
445 | |
449 | | o 5:7f219660301f public test F
446 | | o 5:7f219660301f public test F
450 | | |
447 | | |
451 +---o 4:8a5212ebc852 public test E
448 +---o 4:8a5212ebc852 public test E
452 | |
449 | |
453 | o 3:b3325c91a4d9 public test D
450 | o 3:b3325c91a4d9 public test D
454 | |
451 | |
455 | @ 2:f838bfaca5c7 public test C
452 | @ 2:f838bfaca5c7 public test C
456 |/
453 |/
457 o 1:27547f69f254 public test B
454 o 1:27547f69f254 public test B
458 |
455 |
459 o 0:4a2df7238c3b public test A
456 o 0:4a2df7238c3b public test A
460
457
@@ -1,619 +1,609 b''
1 #testcases sshv1 sshv2
1 #testcases sshv1 sshv2
2
2
3 #if sshv2
3 #if sshv2
4 $ cat >> $HGRCPATH << EOF
4 $ cat >> $HGRCPATH << EOF
5 > [experimental]
5 > [experimental]
6 > sshpeer.advertise-v2 = true
6 > sshpeer.advertise-v2 = true
7 > sshserver.support-v2 = true
7 > sshserver.support-v2 = true
8 > EOF
8 > EOF
9 #endif
9 #endif
10
10
11 Create an extension to test bundle2 remote-changegroup parts
11 Create an extension to test bundle2 remote-changegroup parts
12
12
13 $ cat > bundle2.py << EOF
13 $ cat > bundle2.py << EOF
14 > """A small extension to test bundle2 remote-changegroup parts.
14 > """A small extension to test bundle2 remote-changegroup parts.
15 >
15 >
16 > Current bundle2 implementation doesn't provide a way to generate those
16 > Current bundle2 implementation doesn't provide a way to generate those
17 > parts, so they must be created by extensions.
17 > parts, so they must be created by extensions.
18 > """
18 > """
19 > from mercurial import (
19 > from mercurial import (
20 > bundle2,
20 > bundle2,
21 > changegroup,
21 > changegroup,
22 > discovery,
22 > discovery,
23 > exchange,
23 > exchange,
24 > pycompat,
24 > pycompat,
25 > util,
25 > util,
26 > )
26 > )
27 >
27 >
28 > def _getbundlechangegrouppart(bundler, repo, source, bundlecaps=None,
28 > def _getbundlechangegrouppart(bundler, repo, source, bundlecaps=None,
29 > b2caps=None, heads=None, common=None,
29 > b2caps=None, heads=None, common=None,
30 > **kwargs):
30 > **kwargs):
31 > """this function replaces the changegroup part handler for getbundle.
31 > """this function replaces the changegroup part handler for getbundle.
32 > It allows to create a set of arbitrary parts containing changegroups
32 > It allows to create a set of arbitrary parts containing changegroups
33 > and remote-changegroups, as described in a bundle2maker file in the
33 > and remote-changegroups, as described in a bundle2maker file in the
34 > repository .hg/ directory.
34 > repository .hg/ directory.
35 >
35 >
36 > Each line of that bundle2maker file contain a description of the
36 > Each line of that bundle2maker file contain a description of the
37 > part to add:
37 > part to add:
38 > - changegroup common_revset heads_revset
38 > - changegroup common_revset heads_revset
39 > Creates a changegroup part based, using common_revset and
39 > Creates a changegroup part based, using common_revset and
40 > heads_revset for outgoing
40 > heads_revset for outgoing
41 > - remote-changegroup url file
41 > - remote-changegroup url file
42 > Creates a remote-changegroup part for a bundle at the given
42 > Creates a remote-changegroup part for a bundle at the given
43 > url. Size and digest, as required by the client, are computed
43 > url. Size and digest, as required by the client, are computed
44 > from the given file.
44 > from the given file.
45 > - raw-remote-changegroup <python expression>
45 > - raw-remote-changegroup <python expression>
46 > Creates a remote-changegroup part with the data given in the
46 > Creates a remote-changegroup part with the data given in the
47 > Python expression as parameters. The Python expression is
47 > Python expression as parameters. The Python expression is
48 > evaluated with eval, and is expected to be a dict.
48 > evaluated with eval, and is expected to be a dict.
49 > """
49 > """
50 > def newpart(name, data=b''):
50 > def newpart(name, data=b''):
51 > """wrapper around bundler.newpart adding an extra part making the
51 > """wrapper around bundler.newpart adding an extra part making the
52 > client output information about each processed part"""
52 > client output information about each processed part"""
53 > bundler.newpart(b'output', data=name)
53 > bundler.newpart(b'output', data=name)
54 > part = bundler.newpart(name, data=data)
54 > part = bundler.newpart(name, data=data)
55 > return part
55 > return part
56 >
56 >
57 > for line in open(repo.vfs.join(b'bundle2maker'), 'rb'):
57 > for line in open(repo.vfs.join(b'bundle2maker'), 'rb'):
58 > line = line.strip()
58 > line = line.strip()
59 > try:
59 > try:
60 > verb, args = line.split(None, 1)
60 > verb, args = line.split(None, 1)
61 > except ValueError:
61 > except ValueError:
62 > verb, args = line, b''
62 > verb, args = line, b''
63 > if verb == b'remote-changegroup':
63 > if verb == b'remote-changegroup':
64 > url, file = args.split()
64 > url, file = args.split()
65 > bundledata = open(file, 'rb').read()
65 > bundledata = open(file, 'rb').read()
66 > digest = util.digester.preferred(b2caps[b'digests'])
66 > digest = util.digester.preferred(b2caps[b'digests'])
67 > d = util.digester([digest], bundledata)
67 > d = util.digester([digest], bundledata)
68 > part = newpart(b'remote-changegroup')
68 > part = newpart(b'remote-changegroup')
69 > part.addparam(b'url', url)
69 > part.addparam(b'url', url)
70 > part.addparam(b'size', b'%d' % len(bundledata))
70 > part.addparam(b'size', b'%d' % len(bundledata))
71 > part.addparam(b'digests', digest)
71 > part.addparam(b'digests', digest)
72 > part.addparam(b'digest:%s' % digest, d[digest])
72 > part.addparam(b'digest:%s' % digest, d[digest])
73 > elif verb == b'raw-remote-changegroup':
73 > elif verb == b'raw-remote-changegroup':
74 > part = newpart(b'remote-changegroup')
74 > part = newpart(b'remote-changegroup')
75 > for k, v in eval(args).items():
75 > for k, v in eval(args).items():
76 > part.addparam(pycompat.sysbytes(k), pycompat.bytestr(v))
76 > part.addparam(pycompat.sysbytes(k), pycompat.bytestr(v))
77 > elif verb == b'changegroup':
77 > elif verb == b'changegroup':
78 > _common, heads = args.split()
78 > _common, heads = args.split()
79 > common.extend(repo[r].node() for r in repo.revs(_common))
79 > common.extend(repo[r].node() for r in repo.revs(_common))
80 > heads = [repo[r].node() for r in repo.revs(heads)]
80 > heads = [repo[r].node() for r in repo.revs(heads)]
81 > outgoing = discovery.outgoing(repo, common, heads)
81 > outgoing = discovery.outgoing(repo, common, heads)
82 > cg = changegroup.makechangegroup(repo, outgoing, b'01',
82 > cg = changegroup.makechangegroup(repo, outgoing, b'01',
83 > b'changegroup')
83 > b'changegroup')
84 > newpart(b'changegroup', cg.getchunks())
84 > newpart(b'changegroup', cg.getchunks())
85 > else:
85 > else:
86 > raise Exception('unknown verb')
86 > raise Exception('unknown verb')
87 >
87 >
88 > exchange.getbundle2partsmapping[b'changegroup'] = _getbundlechangegrouppart
88 > exchange.getbundle2partsmapping[b'changegroup'] = _getbundlechangegrouppart
89 > EOF
89 > EOF
90
90
91 Start a simple HTTP server to serve bundles
91 Start a simple HTTP server to serve bundles
92
92
93 $ "$PYTHON" "$TESTDIR/dumbhttp.py" -p $HGPORT --pid dumb.pid
93 $ "$PYTHON" "$TESTDIR/dumbhttp.py" -p $HGPORT --pid dumb.pid
94 $ cat dumb.pid >> $DAEMON_PIDS
94 $ cat dumb.pid >> $DAEMON_PIDS
95
95
96 $ cat >> $HGRCPATH << EOF
96 $ cat >> $HGRCPATH << EOF
97 > [ui]
97 > [ui]
98 > ssh="$PYTHON" "$TESTDIR/dummyssh"
98 > ssh="$PYTHON" "$TESTDIR/dummyssh"
99 > logtemplate={rev}:{node|short} {phase} {author} {bookmarks} {desc|firstline}
99 > logtemplate={rev}:{node|short} {phase} {author} {bookmarks} {desc|firstline}
100 > EOF
100 > EOF
101
101
102 $ hg init repo
102 $ hg init repo
103
103
104 $ hg -R repo unbundle $TESTDIR/bundles/rebase.hg
104 $ hg -R repo unbundle $TESTDIR/bundles/rebase.hg
105 adding changesets
105 adding changesets
106 adding manifests
106 adding manifests
107 adding file changes
107 adding file changes
108 added 8 changesets with 7 changes to 7 files (+2 heads)
108 added 8 changesets with 7 changes to 7 files (+2 heads)
109 new changesets cd010b8cd998:02de42196ebe (8 drafts)
109 new changesets cd010b8cd998:02de42196ebe (8 drafts)
110 (run 'hg heads' to see heads, 'hg merge' to merge)
110 (run 'hg heads' to see heads, 'hg merge' to merge)
111
111
112 $ hg -R repo log -G
112 $ hg -R repo log -G
113 o 7:02de42196ebe draft Nicolas Dumazet <nicdumz.commits@gmail.com> H
113 o 7:02de42196ebe draft Nicolas Dumazet <nicdumz.commits@gmail.com> H
114 |
114 |
115 | o 6:eea13746799a draft Nicolas Dumazet <nicdumz.commits@gmail.com> G
115 | o 6:eea13746799a draft Nicolas Dumazet <nicdumz.commits@gmail.com> G
116 |/|
116 |/|
117 o | 5:24b6387c8c8c draft Nicolas Dumazet <nicdumz.commits@gmail.com> F
117 o | 5:24b6387c8c8c draft Nicolas Dumazet <nicdumz.commits@gmail.com> F
118 | |
118 | |
119 | o 4:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
119 | o 4:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
120 |/
120 |/
121 | o 3:32af7686d403 draft Nicolas Dumazet <nicdumz.commits@gmail.com> D
121 | o 3:32af7686d403 draft Nicolas Dumazet <nicdumz.commits@gmail.com> D
122 | |
122 | |
123 | o 2:5fddd98957c8 draft Nicolas Dumazet <nicdumz.commits@gmail.com> C
123 | o 2:5fddd98957c8 draft Nicolas Dumazet <nicdumz.commits@gmail.com> C
124 | |
124 | |
125 | o 1:42ccdea3bb16 draft Nicolas Dumazet <nicdumz.commits@gmail.com> B
125 | o 1:42ccdea3bb16 draft Nicolas Dumazet <nicdumz.commits@gmail.com> B
126 |/
126 |/
127 o 0:cd010b8cd998 draft Nicolas Dumazet <nicdumz.commits@gmail.com> A
127 o 0:cd010b8cd998 draft Nicolas Dumazet <nicdumz.commits@gmail.com> A
128
128
129 $ hg clone repo orig
129 $ hg clone repo orig
130 updating to branch default
130 updating to branch default
131 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
131 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
132
132
133 $ cat > repo/.hg/hgrc << EOF
133 $ cat > repo/.hg/hgrc << EOF
134 > [extensions]
134 > [extensions]
135 > bundle2=$TESTTMP/bundle2.py
135 > bundle2=$TESTTMP/bundle2.py
136 > EOF
136 > EOF
137
137
138 Test a pull with an remote-changegroup
138 Test a pull with an remote-changegroup
139
139
140 $ hg bundle -R repo --type v1 --base '0:4' -r '5:7' bundle.hg
140 $ hg bundle -R repo --type v1 --base '0:4' -r '5:7' bundle.hg
141 3 changesets found
141 3 changesets found
142 $ cat > repo/.hg/bundle2maker << EOF
142 $ cat > repo/.hg/bundle2maker << EOF
143 > remote-changegroup http://localhost:$HGPORT/bundle.hg bundle.hg
143 > remote-changegroup http://localhost:$HGPORT/bundle.hg bundle.hg
144 > EOF
144 > EOF
145 $ hg clone orig clone -r 3 -r 4
145 $ hg clone orig clone -r 3 -r 4
146 adding changesets
146 adding changesets
147 adding manifests
147 adding manifests
148 adding file changes
148 adding file changes
149 added 5 changesets with 5 changes to 5 files (+1 heads)
149 added 5 changesets with 5 changes to 5 files (+1 heads)
150 new changesets cd010b8cd998:9520eea781bc
150 new changesets cd010b8cd998:9520eea781bc
151 updating to branch default
151 updating to branch default
152 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
152 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
153 $ hg pull -R clone ssh://user@dummy/repo
153 $ hg pull -R clone ssh://user@dummy/repo
154 pulling from ssh://user@dummy/repo
154 pulling from ssh://user@dummy/repo
155 searching for changes
155 searching for changes
156 remote: remote-changegroup
156 remote: remote-changegroup
157 adding changesets
157 adding changesets
158 adding manifests
158 adding manifests
159 adding file changes
159 adding file changes
160 added 3 changesets with 2 changes to 2 files (+1 heads)
160 added 3 changesets with 2 changes to 2 files (+1 heads)
161 new changesets 24b6387c8c8c:02de42196ebe
161 new changesets 24b6387c8c8c:02de42196ebe
162 (run 'hg heads .' to see heads, 'hg merge' to merge)
162 (run 'hg heads .' to see heads, 'hg merge' to merge)
163 $ hg -R clone log -G
163 $ hg -R clone log -G
164 o 7:02de42196ebe public Nicolas Dumazet <nicdumz.commits@gmail.com> H
164 o 7:02de42196ebe public Nicolas Dumazet <nicdumz.commits@gmail.com> H
165 |
165 |
166 | o 6:eea13746799a public Nicolas Dumazet <nicdumz.commits@gmail.com> G
166 | o 6:eea13746799a public Nicolas Dumazet <nicdumz.commits@gmail.com> G
167 |/|
167 |/|
168 o | 5:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
168 o | 5:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
169 | |
169 | |
170 | o 4:9520eea781bc public Nicolas Dumazet <nicdumz.commits@gmail.com> E
170 | o 4:9520eea781bc public Nicolas Dumazet <nicdumz.commits@gmail.com> E
171 |/
171 |/
172 | @ 3:32af7686d403 public Nicolas Dumazet <nicdumz.commits@gmail.com> D
172 | @ 3:32af7686d403 public Nicolas Dumazet <nicdumz.commits@gmail.com> D
173 | |
173 | |
174 | o 2:5fddd98957c8 public Nicolas Dumazet <nicdumz.commits@gmail.com> C
174 | o 2:5fddd98957c8 public Nicolas Dumazet <nicdumz.commits@gmail.com> C
175 | |
175 | |
176 | o 1:42ccdea3bb16 public Nicolas Dumazet <nicdumz.commits@gmail.com> B
176 | o 1:42ccdea3bb16 public Nicolas Dumazet <nicdumz.commits@gmail.com> B
177 |/
177 |/
178 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
178 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
179
179
180 $ rm -rf clone
180 $ rm -rf clone
181
181
182 Test a pull with an remote-changegroup and a following changegroup
182 Test a pull with an remote-changegroup and a following changegroup
183
183
184 $ hg bundle -R repo --type v1 --base 2 -r '3:4' bundle2.hg
184 $ hg bundle -R repo --type v1 --base 2 -r '3:4' bundle2.hg
185 2 changesets found
185 2 changesets found
186 $ cat > repo/.hg/bundle2maker << EOF
186 $ cat > repo/.hg/bundle2maker << EOF
187 > remote-changegroup http://localhost:$HGPORT/bundle2.hg bundle2.hg
187 > remote-changegroup http://localhost:$HGPORT/bundle2.hg bundle2.hg
188 > changegroup 0:4 5:7
188 > changegroup 0:4 5:7
189 > EOF
189 > EOF
190 $ hg clone orig clone -r 2
190 $ hg clone orig clone -r 2
191 adding changesets
191 adding changesets
192 adding manifests
192 adding manifests
193 adding file changes
193 adding file changes
194 added 3 changesets with 3 changes to 3 files
194 added 3 changesets with 3 changes to 3 files
195 new changesets cd010b8cd998:5fddd98957c8
195 new changesets cd010b8cd998:5fddd98957c8
196 updating to branch default
196 updating to branch default
197 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
197 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
198 $ hg pull -R clone ssh://user@dummy/repo
198 $ hg pull -R clone ssh://user@dummy/repo
199 pulling from ssh://user@dummy/repo
199 pulling from ssh://user@dummy/repo
200 searching for changes
200 searching for changes
201 remote: remote-changegroup
201 remote: remote-changegroup
202 adding changesets
202 adding changesets
203 adding manifests
203 adding manifests
204 adding file changes
204 adding file changes
205 added 2 changesets with 2 changes to 2 files (+1 heads)
206 remote: changegroup
205 remote: changegroup
207 adding changesets
206 adding changesets
208 adding manifests
207 adding manifests
209 adding file changes
208 adding file changes
210 added 3 changesets with 2 changes to 2 files (+1 heads)
209 added 5 changesets with 4 changes to 4 files (+2 heads)
211 new changesets 32af7686d403:02de42196ebe
210 new changesets 32af7686d403:02de42196ebe
212 (run 'hg heads' to see heads, 'hg merge' to merge)
211 (run 'hg heads' to see heads, 'hg merge' to merge)
213 $ hg -R clone log -G
212 $ hg -R clone log -G
214 o 7:02de42196ebe public Nicolas Dumazet <nicdumz.commits@gmail.com> H
213 o 7:02de42196ebe public Nicolas Dumazet <nicdumz.commits@gmail.com> H
215 |
214 |
216 | o 6:eea13746799a public Nicolas Dumazet <nicdumz.commits@gmail.com> G
215 | o 6:eea13746799a public Nicolas Dumazet <nicdumz.commits@gmail.com> G
217 |/|
216 |/|
218 o | 5:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
217 o | 5:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
219 | |
218 | |
220 | o 4:9520eea781bc public Nicolas Dumazet <nicdumz.commits@gmail.com> E
219 | o 4:9520eea781bc public Nicolas Dumazet <nicdumz.commits@gmail.com> E
221 |/
220 |/
222 | o 3:32af7686d403 public Nicolas Dumazet <nicdumz.commits@gmail.com> D
221 | o 3:32af7686d403 public Nicolas Dumazet <nicdumz.commits@gmail.com> D
223 | |
222 | |
224 | @ 2:5fddd98957c8 public Nicolas Dumazet <nicdumz.commits@gmail.com> C
223 | @ 2:5fddd98957c8 public Nicolas Dumazet <nicdumz.commits@gmail.com> C
225 | |
224 | |
226 | o 1:42ccdea3bb16 public Nicolas Dumazet <nicdumz.commits@gmail.com> B
225 | o 1:42ccdea3bb16 public Nicolas Dumazet <nicdumz.commits@gmail.com> B
227 |/
226 |/
228 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
227 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
229
228
230 $ rm -rf clone
229 $ rm -rf clone
231
230
232 Test a pull with a changegroup followed by an remote-changegroup
231 Test a pull with a changegroup followed by an remote-changegroup
233
232
234 $ hg bundle -R repo --type v1 --base '0:4' -r '5:7' bundle3.hg
233 $ hg bundle -R repo --type v1 --base '0:4' -r '5:7' bundle3.hg
235 3 changesets found
234 3 changesets found
236 $ cat > repo/.hg/bundle2maker << EOF
235 $ cat > repo/.hg/bundle2maker << EOF
237 > changegroup 000000000000 :4
236 > changegroup 000000000000 :4
238 > remote-changegroup http://localhost:$HGPORT/bundle3.hg bundle3.hg
237 > remote-changegroup http://localhost:$HGPORT/bundle3.hg bundle3.hg
239 > EOF
238 > EOF
240 $ hg clone orig clone -r 2
239 $ hg clone orig clone -r 2
241 adding changesets
240 adding changesets
242 adding manifests
241 adding manifests
243 adding file changes
242 adding file changes
244 added 3 changesets with 3 changes to 3 files
243 added 3 changesets with 3 changes to 3 files
245 new changesets cd010b8cd998:5fddd98957c8
244 new changesets cd010b8cd998:5fddd98957c8
246 updating to branch default
245 updating to branch default
247 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
246 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
248 $ hg pull -R clone ssh://user@dummy/repo
247 $ hg pull -R clone ssh://user@dummy/repo
249 pulling from ssh://user@dummy/repo
248 pulling from ssh://user@dummy/repo
250 searching for changes
249 searching for changes
251 remote: changegroup
250 remote: changegroup
252 adding changesets
251 adding changesets
253 adding manifests
252 adding manifests
254 adding file changes
253 adding file changes
255 added 2 changesets with 2 changes to 2 files (+1 heads)
256 remote: remote-changegroup
254 remote: remote-changegroup
257 adding changesets
255 adding changesets
258 adding manifests
256 adding manifests
259 adding file changes
257 adding file changes
260 added 3 changesets with 2 changes to 2 files (+1 heads)
258 added 5 changesets with 4 changes to 4 files (+2 heads)
261 new changesets 32af7686d403:02de42196ebe
259 new changesets 32af7686d403:02de42196ebe
262 (run 'hg heads' to see heads, 'hg merge' to merge)
260 (run 'hg heads' to see heads, 'hg merge' to merge)
263 $ hg -R clone log -G
261 $ hg -R clone log -G
264 o 7:02de42196ebe public Nicolas Dumazet <nicdumz.commits@gmail.com> H
262 o 7:02de42196ebe public Nicolas Dumazet <nicdumz.commits@gmail.com> H
265 |
263 |
266 | o 6:eea13746799a public Nicolas Dumazet <nicdumz.commits@gmail.com> G
264 | o 6:eea13746799a public Nicolas Dumazet <nicdumz.commits@gmail.com> G
267 |/|
265 |/|
268 o | 5:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
266 o | 5:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
269 | |
267 | |
270 | o 4:9520eea781bc public Nicolas Dumazet <nicdumz.commits@gmail.com> E
268 | o 4:9520eea781bc public Nicolas Dumazet <nicdumz.commits@gmail.com> E
271 |/
269 |/
272 | o 3:32af7686d403 public Nicolas Dumazet <nicdumz.commits@gmail.com> D
270 | o 3:32af7686d403 public Nicolas Dumazet <nicdumz.commits@gmail.com> D
273 | |
271 | |
274 | @ 2:5fddd98957c8 public Nicolas Dumazet <nicdumz.commits@gmail.com> C
272 | @ 2:5fddd98957c8 public Nicolas Dumazet <nicdumz.commits@gmail.com> C
275 | |
273 | |
276 | o 1:42ccdea3bb16 public Nicolas Dumazet <nicdumz.commits@gmail.com> B
274 | o 1:42ccdea3bb16 public Nicolas Dumazet <nicdumz.commits@gmail.com> B
277 |/
275 |/
278 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
276 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
279
277
280 $ rm -rf clone
278 $ rm -rf clone
281
279
282 Test a pull with two remote-changegroups and a changegroup
280 Test a pull with two remote-changegroups and a changegroup
283
281
284 $ hg bundle -R repo --type v1 --base 2 -r '3:4' bundle4.hg
282 $ hg bundle -R repo --type v1 --base 2 -r '3:4' bundle4.hg
285 2 changesets found
283 2 changesets found
286 $ hg bundle -R repo --type v1 --base '3:4' -r '5:6' bundle5.hg
284 $ hg bundle -R repo --type v1 --base '3:4' -r '5:6' bundle5.hg
287 2 changesets found
285 2 changesets found
288 $ cat > repo/.hg/bundle2maker << EOF
286 $ cat > repo/.hg/bundle2maker << EOF
289 > remote-changegroup http://localhost:$HGPORT/bundle4.hg bundle4.hg
287 > remote-changegroup http://localhost:$HGPORT/bundle4.hg bundle4.hg
290 > remote-changegroup http://localhost:$HGPORT/bundle5.hg bundle5.hg
288 > remote-changegroup http://localhost:$HGPORT/bundle5.hg bundle5.hg
291 > changegroup 0:6 7
289 > changegroup 0:6 7
292 > EOF
290 > EOF
293 $ hg clone orig clone -r 2
291 $ hg clone orig clone -r 2
294 adding changesets
292 adding changesets
295 adding manifests
293 adding manifests
296 adding file changes
294 adding file changes
297 added 3 changesets with 3 changes to 3 files
295 added 3 changesets with 3 changes to 3 files
298 new changesets cd010b8cd998:5fddd98957c8
296 new changesets cd010b8cd998:5fddd98957c8
299 updating to branch default
297 updating to branch default
300 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
298 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
301 $ hg pull -R clone ssh://user@dummy/repo
299 $ hg pull -R clone ssh://user@dummy/repo
302 pulling from ssh://user@dummy/repo
300 pulling from ssh://user@dummy/repo
303 searching for changes
301 searching for changes
304 remote: remote-changegroup
302 remote: remote-changegroup
305 adding changesets
303 adding changesets
306 adding manifests
304 adding manifests
307 adding file changes
305 adding file changes
308 added 2 changesets with 2 changes to 2 files (+1 heads)
309 remote: remote-changegroup
306 remote: remote-changegroup
310 adding changesets
307 adding changesets
311 adding manifests
308 adding manifests
312 adding file changes
309 adding file changes
313 added 2 changesets with 1 changes to 1 files
314 remote: changegroup
310 remote: changegroup
315 adding changesets
311 adding changesets
316 adding manifests
312 adding manifests
317 adding file changes
313 adding file changes
318 added 1 changesets with 1 changes to 1 files (+1 heads)
314 added 5 changesets with 4 changes to 4 files (+2 heads)
319 new changesets 32af7686d403:02de42196ebe
315 new changesets 32af7686d403:02de42196ebe
320 (run 'hg heads' to see heads, 'hg merge' to merge)
316 (run 'hg heads' to see heads, 'hg merge' to merge)
321 $ hg -R clone log -G
317 $ hg -R clone log -G
322 o 7:02de42196ebe public Nicolas Dumazet <nicdumz.commits@gmail.com> H
318 o 7:02de42196ebe public Nicolas Dumazet <nicdumz.commits@gmail.com> H
323 |
319 |
324 | o 6:eea13746799a public Nicolas Dumazet <nicdumz.commits@gmail.com> G
320 | o 6:eea13746799a public Nicolas Dumazet <nicdumz.commits@gmail.com> G
325 |/|
321 |/|
326 o | 5:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
322 o | 5:24b6387c8c8c public Nicolas Dumazet <nicdumz.commits@gmail.com> F
327 | |
323 | |
328 | o 4:9520eea781bc public Nicolas Dumazet <nicdumz.commits@gmail.com> E
324 | o 4:9520eea781bc public Nicolas Dumazet <nicdumz.commits@gmail.com> E
329 |/
325 |/
330 | o 3:32af7686d403 public Nicolas Dumazet <nicdumz.commits@gmail.com> D
326 | o 3:32af7686d403 public Nicolas Dumazet <nicdumz.commits@gmail.com> D
331 | |
327 | |
332 | @ 2:5fddd98957c8 public Nicolas Dumazet <nicdumz.commits@gmail.com> C
328 | @ 2:5fddd98957c8 public Nicolas Dumazet <nicdumz.commits@gmail.com> C
333 | |
329 | |
334 | o 1:42ccdea3bb16 public Nicolas Dumazet <nicdumz.commits@gmail.com> B
330 | o 1:42ccdea3bb16 public Nicolas Dumazet <nicdumz.commits@gmail.com> B
335 |/
331 |/
336 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
332 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
337
333
338 $ rm -rf clone
334 $ rm -rf clone
339
335
340 Hash digest tests
336 Hash digest tests
341
337
342 $ hg bundle -R repo --type v1 -a bundle6.hg
338 $ hg bundle -R repo --type v1 -a bundle6.hg
343 8 changesets found
339 8 changesets found
344
340
345 $ cat > repo/.hg/bundle2maker << EOF
341 $ cat > repo/.hg/bundle2maker << EOF
346 > raw-remote-changegroup {'url': 'http://localhost:$HGPORT/bundle6.hg', 'size': 1663, 'digests': 'sha1', 'digest:sha1': '2c880cfec23cff7d8f80c2f12958d1563cbdaba6'}
342 > raw-remote-changegroup {'url': 'http://localhost:$HGPORT/bundle6.hg', 'size': 1663, 'digests': 'sha1', 'digest:sha1': '2c880cfec23cff7d8f80c2f12958d1563cbdaba6'}
347 > EOF
343 > EOF
348 $ hg clone ssh://user@dummy/repo clone
344 $ hg clone ssh://user@dummy/repo clone
349 requesting all changes
345 requesting all changes
350 remote: remote-changegroup
346 remote: remote-changegroup
351 adding changesets
347 adding changesets
352 adding manifests
348 adding manifests
353 adding file changes
349 adding file changes
354 added 8 changesets with 7 changes to 7 files (+2 heads)
350 added 8 changesets with 7 changes to 7 files (+2 heads)
355 new changesets cd010b8cd998:02de42196ebe
351 new changesets cd010b8cd998:02de42196ebe
356 updating to branch default
352 updating to branch default
357 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
353 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
358 $ rm -rf clone
354 $ rm -rf clone
359
355
360 $ cat > repo/.hg/bundle2maker << EOF
356 $ cat > repo/.hg/bundle2maker << EOF
361 > raw-remote-changegroup {'url': 'http://localhost:$HGPORT/bundle6.hg', 'size': 1663, 'digests': 'md5', 'digest:md5': 'e22172c2907ef88794b7bea6642c2394'}
357 > raw-remote-changegroup {'url': 'http://localhost:$HGPORT/bundle6.hg', 'size': 1663, 'digests': 'md5', 'digest:md5': 'e22172c2907ef88794b7bea6642c2394'}
362 > EOF
358 > EOF
363 $ hg clone ssh://user@dummy/repo clone
359 $ hg clone ssh://user@dummy/repo clone
364 requesting all changes
360 requesting all changes
365 remote: remote-changegroup
361 remote: remote-changegroup
366 adding changesets
362 adding changesets
367 adding manifests
363 adding manifests
368 adding file changes
364 adding file changes
369 added 8 changesets with 7 changes to 7 files (+2 heads)
365 added 8 changesets with 7 changes to 7 files (+2 heads)
370 new changesets cd010b8cd998:02de42196ebe
366 new changesets cd010b8cd998:02de42196ebe
371 updating to branch default
367 updating to branch default
372 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
368 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
373 $ rm -rf clone
369 $ rm -rf clone
374
370
375 Hash digest mismatch throws an error
371 Hash digest mismatch throws an error
376
372
377 $ cat > repo/.hg/bundle2maker << EOF
373 $ cat > repo/.hg/bundle2maker << EOF
378 > raw-remote-changegroup {'url': 'http://localhost:$HGPORT/bundle6.hg', 'size': 1663, 'digests': 'sha1', 'digest:sha1': '0' * 40}
374 > raw-remote-changegroup {'url': 'http://localhost:$HGPORT/bundle6.hg', 'size': 1663, 'digests': 'sha1', 'digest:sha1': '0' * 40}
379 > EOF
375 > EOF
380 $ hg clone ssh://user@dummy/repo clone
376 $ hg clone ssh://user@dummy/repo clone
381 requesting all changes
377 requesting all changes
382 remote: remote-changegroup
378 remote: remote-changegroup
383 adding changesets
379 adding changesets
384 adding manifests
380 adding manifests
385 adding file changes
381 adding file changes
386 added 8 changesets with 7 changes to 7 files (+2 heads)
387 transaction abort!
382 transaction abort!
388 rollback completed
383 rollback completed
389 abort: bundle at http://localhost:$HGPORT/bundle6.hg is corrupted:
384 abort: bundle at http://localhost:$HGPORT/bundle6.hg is corrupted:
390 sha1 mismatch: expected 0000000000000000000000000000000000000000, got 2c880cfec23cff7d8f80c2f12958d1563cbdaba6
385 sha1 mismatch: expected 0000000000000000000000000000000000000000, got 2c880cfec23cff7d8f80c2f12958d1563cbdaba6
391 [255]
386 [255]
392
387
393 Multiple hash digests can be given
388 Multiple hash digests can be given
394
389
395 $ cat > repo/.hg/bundle2maker << EOF
390 $ cat > repo/.hg/bundle2maker << EOF
396 > raw-remote-changegroup {'url': 'http://localhost:$HGPORT/bundle6.hg', 'size': 1663, 'digests': 'md5 sha1', 'digest:md5': 'e22172c2907ef88794b7bea6642c2394', 'digest:sha1': '2c880cfec23cff7d8f80c2f12958d1563cbdaba6'}
391 > raw-remote-changegroup {'url': 'http://localhost:$HGPORT/bundle6.hg', 'size': 1663, 'digests': 'md5 sha1', 'digest:md5': 'e22172c2907ef88794b7bea6642c2394', 'digest:sha1': '2c880cfec23cff7d8f80c2f12958d1563cbdaba6'}
397 > EOF
392 > EOF
398 $ hg clone ssh://user@dummy/repo clone
393 $ hg clone ssh://user@dummy/repo clone
399 requesting all changes
394 requesting all changes
400 remote: remote-changegroup
395 remote: remote-changegroup
401 adding changesets
396 adding changesets
402 adding manifests
397 adding manifests
403 adding file changes
398 adding file changes
404 added 8 changesets with 7 changes to 7 files (+2 heads)
399 added 8 changesets with 7 changes to 7 files (+2 heads)
405 new changesets cd010b8cd998:02de42196ebe
400 new changesets cd010b8cd998:02de42196ebe
406 updating to branch default
401 updating to branch default
407 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
402 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
408 $ rm -rf clone
403 $ rm -rf clone
409
404
410 If either of the multiple hash digests mismatches, an error is thrown
405 If either of the multiple hash digests mismatches, an error is thrown
411
406
412 $ cat > repo/.hg/bundle2maker << EOF
407 $ cat > repo/.hg/bundle2maker << EOF
413 > raw-remote-changegroup {'url': 'http://localhost:$HGPORT/bundle6.hg', 'size': 1663, 'digests': 'md5 sha1', 'digest:md5': '0' * 32, 'digest:sha1': '2c880cfec23cff7d8f80c2f12958d1563cbdaba6'}
408 > raw-remote-changegroup {'url': 'http://localhost:$HGPORT/bundle6.hg', 'size': 1663, 'digests': 'md5 sha1', 'digest:md5': '0' * 32, 'digest:sha1': '2c880cfec23cff7d8f80c2f12958d1563cbdaba6'}
414 > EOF
409 > EOF
415 $ hg clone ssh://user@dummy/repo clone
410 $ hg clone ssh://user@dummy/repo clone
416 requesting all changes
411 requesting all changes
417 remote: remote-changegroup
412 remote: remote-changegroup
418 adding changesets
413 adding changesets
419 adding manifests
414 adding manifests
420 adding file changes
415 adding file changes
421 added 8 changesets with 7 changes to 7 files (+2 heads)
422 transaction abort!
416 transaction abort!
423 rollback completed
417 rollback completed
424 abort: bundle at http://localhost:$HGPORT/bundle6.hg is corrupted:
418 abort: bundle at http://localhost:$HGPORT/bundle6.hg is corrupted:
425 md5 mismatch: expected 00000000000000000000000000000000, got e22172c2907ef88794b7bea6642c2394
419 md5 mismatch: expected 00000000000000000000000000000000, got e22172c2907ef88794b7bea6642c2394
426 [255]
420 [255]
427
421
428 $ cat > repo/.hg/bundle2maker << EOF
422 $ cat > repo/.hg/bundle2maker << EOF
429 > raw-remote-changegroup {'url': 'http://localhost:$HGPORT/bundle6.hg', 'size': 1663, 'digests': 'md5 sha1', 'digest:md5': 'e22172c2907ef88794b7bea6642c2394', 'digest:sha1': '0' * 40}
423 > raw-remote-changegroup {'url': 'http://localhost:$HGPORT/bundle6.hg', 'size': 1663, 'digests': 'md5 sha1', 'digest:md5': 'e22172c2907ef88794b7bea6642c2394', 'digest:sha1': '0' * 40}
430 > EOF
424 > EOF
431 $ hg clone ssh://user@dummy/repo clone
425 $ hg clone ssh://user@dummy/repo clone
432 requesting all changes
426 requesting all changes
433 remote: remote-changegroup
427 remote: remote-changegroup
434 adding changesets
428 adding changesets
435 adding manifests
429 adding manifests
436 adding file changes
430 adding file changes
437 added 8 changesets with 7 changes to 7 files (+2 heads)
438 transaction abort!
431 transaction abort!
439 rollback completed
432 rollback completed
440 abort: bundle at http://localhost:$HGPORT/bundle6.hg is corrupted:
433 abort: bundle at http://localhost:$HGPORT/bundle6.hg is corrupted:
441 sha1 mismatch: expected 0000000000000000000000000000000000000000, got 2c880cfec23cff7d8f80c2f12958d1563cbdaba6
434 sha1 mismatch: expected 0000000000000000000000000000000000000000, got 2c880cfec23cff7d8f80c2f12958d1563cbdaba6
442 [255]
435 [255]
443
436
444 Corruption tests
437 Corruption tests
445
438
446 $ hg clone orig clone -r 2
439 $ hg clone orig clone -r 2
447 adding changesets
440 adding changesets
448 adding manifests
441 adding manifests
449 adding file changes
442 adding file changes
450 added 3 changesets with 3 changes to 3 files
443 added 3 changesets with 3 changes to 3 files
451 new changesets cd010b8cd998:5fddd98957c8
444 new changesets cd010b8cd998:5fddd98957c8
452 updating to branch default
445 updating to branch default
453 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
446 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
454
447
455 $ cat > repo/.hg/bundle2maker << EOF
448 $ cat > repo/.hg/bundle2maker << EOF
456 > remote-changegroup http://localhost:$HGPORT/bundle4.hg bundle4.hg
449 > remote-changegroup http://localhost:$HGPORT/bundle4.hg bundle4.hg
457 > raw-remote-changegroup {'url': 'http://localhost:$HGPORT/bundle5.hg', 'size': 578, 'digests': 'sha1', 'digest:sha1': '0' * 40}
450 > raw-remote-changegroup {'url': 'http://localhost:$HGPORT/bundle5.hg', 'size': 578, 'digests': 'sha1', 'digest:sha1': '0' * 40}
458 > changegroup 0:6 7
451 > changegroup 0:6 7
459 > EOF
452 > EOF
460 $ hg pull -R clone ssh://user@dummy/repo
453 $ hg pull -R clone ssh://user@dummy/repo
461 pulling from ssh://user@dummy/repo
454 pulling from ssh://user@dummy/repo
462 searching for changes
455 searching for changes
463 remote: remote-changegroup
456 remote: remote-changegroup
464 adding changesets
457 adding changesets
465 adding manifests
458 adding manifests
466 adding file changes
459 adding file changes
467 added 2 changesets with 2 changes to 2 files (+1 heads)
468 remote: remote-changegroup
460 remote: remote-changegroup
469 adding changesets
461 adding changesets
470 adding manifests
462 adding manifests
471 adding file changes
463 adding file changes
472 added 2 changesets with 1 changes to 1 files
473 transaction abort!
464 transaction abort!
474 rollback completed
465 rollback completed
475 abort: bundle at http://localhost:$HGPORT/bundle5.hg is corrupted:
466 abort: bundle at http://localhost:$HGPORT/bundle5.hg is corrupted:
476 sha1 mismatch: expected 0000000000000000000000000000000000000000, got f29485d6bfd37db99983cfc95ecb52f8ca396106
467 sha1 mismatch: expected 0000000000000000000000000000000000000000, got f29485d6bfd37db99983cfc95ecb52f8ca396106
477 [255]
468 [255]
478
469
479 The entire transaction has been rolled back in the pull above
470 The entire transaction has been rolled back in the pull above
480
471
481 $ hg -R clone log -G
472 $ hg -R clone log -G
482 @ 2:5fddd98957c8 public Nicolas Dumazet <nicdumz.commits@gmail.com> C
473 @ 2:5fddd98957c8 public Nicolas Dumazet <nicdumz.commits@gmail.com> C
483 |
474 |
484 o 1:42ccdea3bb16 public Nicolas Dumazet <nicdumz.commits@gmail.com> B
475 o 1:42ccdea3bb16 public Nicolas Dumazet <nicdumz.commits@gmail.com> B
485 |
476 |
486 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
477 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
487
478
488
479
489 No params
480 No params
490
481
491 $ cat > repo/.hg/bundle2maker << EOF
482 $ cat > repo/.hg/bundle2maker << EOF
492 > raw-remote-changegroup {}
483 > raw-remote-changegroup {}
493 > EOF
484 > EOF
494 $ hg pull -R clone ssh://user@dummy/repo
485 $ hg pull -R clone ssh://user@dummy/repo
495 pulling from ssh://user@dummy/repo
486 pulling from ssh://user@dummy/repo
496 searching for changes
487 searching for changes
497 remote: remote-changegroup
488 remote: remote-changegroup
498 abort: remote-changegroup: missing "url" param
489 abort: remote-changegroup: missing "url" param
499 [255]
490 [255]
500
491
501 Missing size
492 Missing size
502
493
503 $ cat > repo/.hg/bundle2maker << EOF
494 $ cat > repo/.hg/bundle2maker << EOF
504 > raw-remote-changegroup {'url': 'http://localhost:$HGPORT/bundle4.hg'}
495 > raw-remote-changegroup {'url': 'http://localhost:$HGPORT/bundle4.hg'}
505 > EOF
496 > EOF
506 $ hg pull -R clone ssh://user@dummy/repo
497 $ hg pull -R clone ssh://user@dummy/repo
507 pulling from ssh://user@dummy/repo
498 pulling from ssh://user@dummy/repo
508 searching for changes
499 searching for changes
509 remote: remote-changegroup
500 remote: remote-changegroup
510 abort: remote-changegroup: missing "size" param
501 abort: remote-changegroup: missing "size" param
511 [255]
502 [255]
512
503
513 Invalid size
504 Invalid size
514
505
515 $ cat > repo/.hg/bundle2maker << EOF
506 $ cat > repo/.hg/bundle2maker << EOF
516 > raw-remote-changegroup {'url': 'http://localhost:$HGPORT/bundle4.hg', 'size': 'foo'}
507 > raw-remote-changegroup {'url': 'http://localhost:$HGPORT/bundle4.hg', 'size': 'foo'}
517 > EOF
508 > EOF
518 $ hg pull -R clone ssh://user@dummy/repo
509 $ hg pull -R clone ssh://user@dummy/repo
519 pulling from ssh://user@dummy/repo
510 pulling from ssh://user@dummy/repo
520 searching for changes
511 searching for changes
521 remote: remote-changegroup
512 remote: remote-changegroup
522 abort: remote-changegroup: invalid value for param "size"
513 abort: remote-changegroup: invalid value for param "size"
523 [255]
514 [255]
524
515
525 Size mismatch
516 Size mismatch
526
517
527 $ cat > repo/.hg/bundle2maker << EOF
518 $ cat > repo/.hg/bundle2maker << EOF
528 > raw-remote-changegroup {'url': 'http://localhost:$HGPORT/bundle4.hg', 'size': 42}
519 > raw-remote-changegroup {'url': 'http://localhost:$HGPORT/bundle4.hg', 'size': 42}
529 > EOF
520 > EOF
530 $ hg pull -R clone ssh://user@dummy/repo
521 $ hg pull -R clone ssh://user@dummy/repo
531 pulling from ssh://user@dummy/repo
522 pulling from ssh://user@dummy/repo
532 searching for changes
523 searching for changes
533 remote: remote-changegroup
524 remote: remote-changegroup
534 adding changesets
525 adding changesets
535 adding manifests
526 adding manifests
536 adding file changes
527 adding file changes
537 added 2 changesets with 2 changes to 2 files (+1 heads)
538 transaction abort!
528 transaction abort!
539 rollback completed
529 rollback completed
540 abort: bundle at http://localhost:$HGPORT/bundle4.hg is corrupted:
530 abort: bundle at http://localhost:$HGPORT/bundle4.hg is corrupted:
541 size mismatch: expected 42, got 581
531 size mismatch: expected 42, got 581
542 [255]
532 [255]
543
533
544 Unknown digest
534 Unknown digest
545
535
546 $ cat > repo/.hg/bundle2maker << EOF
536 $ cat > repo/.hg/bundle2maker << EOF
547 > raw-remote-changegroup {'url': 'http://localhost:$HGPORT/bundle4.hg', 'size': 581, 'digests': 'foo', 'digest:foo': 'bar'}
537 > raw-remote-changegroup {'url': 'http://localhost:$HGPORT/bundle4.hg', 'size': 581, 'digests': 'foo', 'digest:foo': 'bar'}
548 > EOF
538 > EOF
549 $ hg pull -R clone ssh://user@dummy/repo
539 $ hg pull -R clone ssh://user@dummy/repo
550 pulling from ssh://user@dummy/repo
540 pulling from ssh://user@dummy/repo
551 searching for changes
541 searching for changes
552 remote: remote-changegroup
542 remote: remote-changegroup
553 abort: missing support for remote-changegroup - digest:foo
543 abort: missing support for remote-changegroup - digest:foo
554 [255]
544 [255]
555
545
556 Missing digest
546 Missing digest
557
547
558 $ cat > repo/.hg/bundle2maker << EOF
548 $ cat > repo/.hg/bundle2maker << EOF
559 > raw-remote-changegroup {'url': 'http://localhost:$HGPORT/bundle4.hg', 'size': 581, 'digests': 'sha1'}
549 > raw-remote-changegroup {'url': 'http://localhost:$HGPORT/bundle4.hg', 'size': 581, 'digests': 'sha1'}
560 > EOF
550 > EOF
561 $ hg pull -R clone ssh://user@dummy/repo
551 $ hg pull -R clone ssh://user@dummy/repo
562 pulling from ssh://user@dummy/repo
552 pulling from ssh://user@dummy/repo
563 searching for changes
553 searching for changes
564 remote: remote-changegroup
554 remote: remote-changegroup
565 abort: remote-changegroup: missing "digest:sha1" param
555 abort: remote-changegroup: missing "digest:sha1" param
566 [255]
556 [255]
567
557
568 Not an HTTP url
558 Not an HTTP url
569
559
570 $ cat > repo/.hg/bundle2maker << EOF
560 $ cat > repo/.hg/bundle2maker << EOF
571 > raw-remote-changegroup {'url': 'ssh://localhost:$HGPORT/bundle4.hg', 'size': 581}
561 > raw-remote-changegroup {'url': 'ssh://localhost:$HGPORT/bundle4.hg', 'size': 581}
572 > EOF
562 > EOF
573 $ hg pull -R clone ssh://user@dummy/repo
563 $ hg pull -R clone ssh://user@dummy/repo
574 pulling from ssh://user@dummy/repo
564 pulling from ssh://user@dummy/repo
575 searching for changes
565 searching for changes
576 remote: remote-changegroup
566 remote: remote-changegroup
577 abort: remote-changegroup does not support ssh urls
567 abort: remote-changegroup does not support ssh urls
578 [255]
568 [255]
579
569
580 Not a bundle
570 Not a bundle
581
571
582 $ cat > notbundle.hg << EOF
572 $ cat > notbundle.hg << EOF
583 > foo
573 > foo
584 > EOF
574 > EOF
585 $ cat > repo/.hg/bundle2maker << EOF
575 $ cat > repo/.hg/bundle2maker << EOF
586 > remote-changegroup http://localhost:$HGPORT/notbundle.hg notbundle.hg
576 > remote-changegroup http://localhost:$HGPORT/notbundle.hg notbundle.hg
587 > EOF
577 > EOF
588 $ hg pull -R clone ssh://user@dummy/repo
578 $ hg pull -R clone ssh://user@dummy/repo
589 pulling from ssh://user@dummy/repo
579 pulling from ssh://user@dummy/repo
590 searching for changes
580 searching for changes
591 remote: remote-changegroup
581 remote: remote-changegroup
592 abort: http://localhost:$HGPORT/notbundle.hg: not a Mercurial bundle
582 abort: http://localhost:$HGPORT/notbundle.hg: not a Mercurial bundle
593 [255]
583 [255]
594
584
595 Not a bundle 1.0
585 Not a bundle 1.0
596
586
597 $ cat > notbundle10.hg << EOF
587 $ cat > notbundle10.hg << EOF
598 > HG20
588 > HG20
599 > EOF
589 > EOF
600 $ cat > repo/.hg/bundle2maker << EOF
590 $ cat > repo/.hg/bundle2maker << EOF
601 > remote-changegroup http://localhost:$HGPORT/notbundle10.hg notbundle10.hg
591 > remote-changegroup http://localhost:$HGPORT/notbundle10.hg notbundle10.hg
602 > EOF
592 > EOF
603 $ hg pull -R clone ssh://user@dummy/repo
593 $ hg pull -R clone ssh://user@dummy/repo
604 pulling from ssh://user@dummy/repo
594 pulling from ssh://user@dummy/repo
605 searching for changes
595 searching for changes
606 remote: remote-changegroup
596 remote: remote-changegroup
607 abort: http://localhost:$HGPORT/notbundle10.hg: not a bundle version 1.0
597 abort: http://localhost:$HGPORT/notbundle10.hg: not a bundle version 1.0
608 [255]
598 [255]
609
599
610 $ hg -R clone log -G
600 $ hg -R clone log -G
611 @ 2:5fddd98957c8 public Nicolas Dumazet <nicdumz.commits@gmail.com> C
601 @ 2:5fddd98957c8 public Nicolas Dumazet <nicdumz.commits@gmail.com> C
612 |
602 |
613 o 1:42ccdea3bb16 public Nicolas Dumazet <nicdumz.commits@gmail.com> B
603 o 1:42ccdea3bb16 public Nicolas Dumazet <nicdumz.commits@gmail.com> B
614 |
604 |
615 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
605 o 0:cd010b8cd998 public Nicolas Dumazet <nicdumz.commits@gmail.com> A
616
606
617 $ rm -rf clone
607 $ rm -rf clone
618
608
619 $ killdaemons.py
609 $ killdaemons.py
@@ -1,1301 +1,1301 b''
1 #testcases sshv1 sshv2
1 #testcases sshv1 sshv2
2
2
3 #if sshv2
3 #if sshv2
4 $ cat >> $HGRCPATH << EOF
4 $ cat >> $HGRCPATH << EOF
5 > [experimental]
5 > [experimental]
6 > sshpeer.advertise-v2 = true
6 > sshpeer.advertise-v2 = true
7 > sshserver.support-v2 = true
7 > sshserver.support-v2 = true
8 > EOF
8 > EOF
9 #endif
9 #endif
10
10
11 Prepare repo a:
11 Prepare repo a:
12
12
13 $ hg init a
13 $ hg init a
14 $ cd a
14 $ cd a
15 $ echo a > a
15 $ echo a > a
16 $ hg add a
16 $ hg add a
17 $ hg commit -m test
17 $ hg commit -m test
18 $ echo first line > b
18 $ echo first line > b
19 $ hg add b
19 $ hg add b
20
20
21 Create a non-inlined filelog:
21 Create a non-inlined filelog:
22
22
23 $ "$PYTHON" -c 'open("data1", "wb").write(b"".join(b"%d\n" % x for x in range(10000)))'
23 $ "$PYTHON" -c 'open("data1", "wb").write(b"".join(b"%d\n" % x for x in range(10000)))'
24 $ for j in 0 1 2 3 4 5 6 7 8 9; do
24 $ for j in 0 1 2 3 4 5 6 7 8 9; do
25 > cat data1 >> b
25 > cat data1 >> b
26 > hg commit -m test
26 > hg commit -m test
27 > done
27 > done
28
28
29 List files in store/data (should show a 'b.d'):
29 List files in store/data (should show a 'b.d'):
30
30
31 #if reporevlogstore
31 #if reporevlogstore
32 $ for i in .hg/store/data/*; do
32 $ for i in .hg/store/data/*; do
33 > echo $i
33 > echo $i
34 > done
34 > done
35 .hg/store/data/a.i
35 .hg/store/data/a.i
36 .hg/store/data/b.d
36 .hg/store/data/b.d
37 .hg/store/data/b.i
37 .hg/store/data/b.i
38 #endif
38 #endif
39
39
40 Trigger branchcache creation:
40 Trigger branchcache creation:
41
41
42 $ hg branches
42 $ hg branches
43 default 10:a7949464abda
43 default 10:a7949464abda
44 $ ls .hg/cache
44 $ ls .hg/cache
45 branch2-served
45 branch2-served
46 rbc-names-v1
46 rbc-names-v1
47 rbc-revs-v1
47 rbc-revs-v1
48
48
49 Default operation:
49 Default operation:
50
50
51 $ hg clone . ../b
51 $ hg clone . ../b
52 updating to branch default
52 updating to branch default
53 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
53 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
54 $ cd ../b
54 $ cd ../b
55
55
56 Ensure branchcache got copied over:
56 Ensure branchcache got copied over:
57
57
58 $ ls .hg/cache
58 $ ls .hg/cache
59 branch2-served
59 branch2-served
60 rbc-names-v1
60 rbc-names-v1
61 rbc-revs-v1
61 rbc-revs-v1
62
62
63 $ cat a
63 $ cat a
64 a
64 a
65 $ hg verify
65 $ hg verify
66 checking changesets
66 checking changesets
67 checking manifests
67 checking manifests
68 crosschecking files in changesets and manifests
68 crosschecking files in changesets and manifests
69 checking files
69 checking files
70 checked 11 changesets with 11 changes to 2 files
70 checked 11 changesets with 11 changes to 2 files
71
71
72 Invalid dest '' must abort:
72 Invalid dest '' must abort:
73
73
74 $ hg clone . ''
74 $ hg clone . ''
75 abort: empty destination path is not valid
75 abort: empty destination path is not valid
76 [255]
76 [255]
77
77
78 No update, with debug option:
78 No update, with debug option:
79
79
80 #if hardlink
80 #if hardlink
81 $ hg --debug clone -U . ../c --config progress.debug=true
81 $ hg --debug clone -U . ../c --config progress.debug=true
82 linking: 1 files
82 linking: 1 files
83 linking: 2 files
83 linking: 2 files
84 linking: 3 files
84 linking: 3 files
85 linking: 4 files
85 linking: 4 files
86 linking: 5 files
86 linking: 5 files
87 linking: 6 files
87 linking: 6 files
88 linking: 7 files
88 linking: 7 files
89 linking: 8 files
89 linking: 8 files
90 linked 8 files (reporevlogstore !)
90 linked 8 files (reporevlogstore !)
91 linking: 9 files (reposimplestore !)
91 linking: 9 files (reposimplestore !)
92 linking: 10 files (reposimplestore !)
92 linking: 10 files (reposimplestore !)
93 linking: 11 files (reposimplestore !)
93 linking: 11 files (reposimplestore !)
94 linking: 12 files (reposimplestore !)
94 linking: 12 files (reposimplestore !)
95 linking: 13 files (reposimplestore !)
95 linking: 13 files (reposimplestore !)
96 linking: 14 files (reposimplestore !)
96 linking: 14 files (reposimplestore !)
97 linking: 15 files (reposimplestore !)
97 linking: 15 files (reposimplestore !)
98 linking: 16 files (reposimplestore !)
98 linking: 16 files (reposimplestore !)
99 linking: 17 files (reposimplestore !)
99 linking: 17 files (reposimplestore !)
100 linking: 18 files (reposimplestore !)
100 linking: 18 files (reposimplestore !)
101 linked 18 files (reposimplestore !)
101 linked 18 files (reposimplestore !)
102 #else
102 #else
103 $ hg --debug clone -U . ../c --config progress.debug=true
103 $ hg --debug clone -U . ../c --config progress.debug=true
104 linking: 1 files
104 linking: 1 files
105 copying: 2 files
105 copying: 2 files
106 copying: 3 files
106 copying: 3 files
107 copying: 4 files
107 copying: 4 files
108 copying: 5 files
108 copying: 5 files
109 copying: 6 files
109 copying: 6 files
110 copying: 7 files
110 copying: 7 files
111 copying: 8 files
111 copying: 8 files
112 copied 8 files (reporevlogstore !)
112 copied 8 files (reporevlogstore !)
113 copying: 9 files (reposimplestore !)
113 copying: 9 files (reposimplestore !)
114 copying: 10 files (reposimplestore !)
114 copying: 10 files (reposimplestore !)
115 copying: 11 files (reposimplestore !)
115 copying: 11 files (reposimplestore !)
116 copying: 12 files (reposimplestore !)
116 copying: 12 files (reposimplestore !)
117 copying: 13 files (reposimplestore !)
117 copying: 13 files (reposimplestore !)
118 copying: 14 files (reposimplestore !)
118 copying: 14 files (reposimplestore !)
119 copying: 15 files (reposimplestore !)
119 copying: 15 files (reposimplestore !)
120 copying: 16 files (reposimplestore !)
120 copying: 16 files (reposimplestore !)
121 copying: 17 files (reposimplestore !)
121 copying: 17 files (reposimplestore !)
122 copying: 18 files (reposimplestore !)
122 copying: 18 files (reposimplestore !)
123 copied 18 files (reposimplestore !)
123 copied 18 files (reposimplestore !)
124 #endif
124 #endif
125 $ cd ../c
125 $ cd ../c
126
126
127 Ensure branchcache got copied over:
127 Ensure branchcache got copied over:
128
128
129 $ ls .hg/cache
129 $ ls .hg/cache
130 branch2-served
130 branch2-served
131 rbc-names-v1
131 rbc-names-v1
132 rbc-revs-v1
132 rbc-revs-v1
133
133
134 $ cat a 2>/dev/null || echo "a not present"
134 $ cat a 2>/dev/null || echo "a not present"
135 a not present
135 a not present
136 $ hg verify
136 $ hg verify
137 checking changesets
137 checking changesets
138 checking manifests
138 checking manifests
139 crosschecking files in changesets and manifests
139 crosschecking files in changesets and manifests
140 checking files
140 checking files
141 checked 11 changesets with 11 changes to 2 files
141 checked 11 changesets with 11 changes to 2 files
142
142
143 Default destination:
143 Default destination:
144
144
145 $ mkdir ../d
145 $ mkdir ../d
146 $ cd ../d
146 $ cd ../d
147 $ hg clone ../a
147 $ hg clone ../a
148 destination directory: a
148 destination directory: a
149 updating to branch default
149 updating to branch default
150 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
150 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
151 $ cd a
151 $ cd a
152 $ hg cat a
152 $ hg cat a
153 a
153 a
154 $ cd ../..
154 $ cd ../..
155
155
156 Check that we drop the 'file:' from the path before writing the .hgrc:
156 Check that we drop the 'file:' from the path before writing the .hgrc:
157
157
158 $ hg clone file:a e
158 $ hg clone file:a e
159 updating to branch default
159 updating to branch default
160 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
160 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
161 $ grep 'file:' e/.hg/hgrc
161 $ grep 'file:' e/.hg/hgrc
162 [1]
162 [1]
163
163
164 Check that path aliases are expanded:
164 Check that path aliases are expanded:
165
165
166 $ hg clone -q -U --config 'paths.foobar=a#0' foobar f
166 $ hg clone -q -U --config 'paths.foobar=a#0' foobar f
167 $ hg -R f showconfig paths.default
167 $ hg -R f showconfig paths.default
168 $TESTTMP/a#0
168 $TESTTMP/a#0
169
169
170 Use --pull:
170 Use --pull:
171
171
172 $ hg clone --pull a g
172 $ hg clone --pull a g
173 requesting all changes
173 requesting all changes
174 adding changesets
174 adding changesets
175 adding manifests
175 adding manifests
176 adding file changes
176 adding file changes
177 added 11 changesets with 11 changes to 2 files
177 added 11 changesets with 11 changes to 2 files
178 new changesets acb14030fe0a:a7949464abda
178 new changesets acb14030fe0a:a7949464abda
179 updating to branch default
179 updating to branch default
180 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
180 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
181 $ hg -R g verify
181 $ hg -R g verify
182 checking changesets
182 checking changesets
183 checking manifests
183 checking manifests
184 crosschecking files in changesets and manifests
184 crosschecking files in changesets and manifests
185 checking files
185 checking files
186 checked 11 changesets with 11 changes to 2 files
186 checked 11 changesets with 11 changes to 2 files
187
187
188 Invalid dest '' with --pull must abort (issue2528):
188 Invalid dest '' with --pull must abort (issue2528):
189
189
190 $ hg clone --pull a ''
190 $ hg clone --pull a ''
191 abort: empty destination path is not valid
191 abort: empty destination path is not valid
192 [255]
192 [255]
193
193
194 Clone to '.':
194 Clone to '.':
195
195
196 $ mkdir h
196 $ mkdir h
197 $ cd h
197 $ cd h
198 $ hg clone ../a .
198 $ hg clone ../a .
199 updating to branch default
199 updating to branch default
200 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
200 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
201 $ cd ..
201 $ cd ..
202
202
203
203
204 *** Tests for option -u ***
204 *** Tests for option -u ***
205
205
206 Adding some more history to repo a:
206 Adding some more history to repo a:
207
207
208 $ cd a
208 $ cd a
209 $ hg tag ref1
209 $ hg tag ref1
210 $ echo the quick brown fox >a
210 $ echo the quick brown fox >a
211 $ hg ci -m "hacked default"
211 $ hg ci -m "hacked default"
212 $ hg up ref1
212 $ hg up ref1
213 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
213 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
214 $ hg branch stable
214 $ hg branch stable
215 marked working directory as branch stable
215 marked working directory as branch stable
216 (branches are permanent and global, did you want a bookmark?)
216 (branches are permanent and global, did you want a bookmark?)
217 $ echo some text >a
217 $ echo some text >a
218 $ hg ci -m "starting branch stable"
218 $ hg ci -m "starting branch stable"
219 $ hg tag ref2
219 $ hg tag ref2
220 $ echo some more text >a
220 $ echo some more text >a
221 $ hg ci -m "another change for branch stable"
221 $ hg ci -m "another change for branch stable"
222 $ hg up ref2
222 $ hg up ref2
223 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
223 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
224 $ hg parents
224 $ hg parents
225 changeset: 13:e8ece76546a6
225 changeset: 13:e8ece76546a6
226 branch: stable
226 branch: stable
227 tag: ref2
227 tag: ref2
228 parent: 10:a7949464abda
228 parent: 10:a7949464abda
229 user: test
229 user: test
230 date: Thu Jan 01 00:00:00 1970 +0000
230 date: Thu Jan 01 00:00:00 1970 +0000
231 summary: starting branch stable
231 summary: starting branch stable
232
232
233
233
234 Repo a has two heads:
234 Repo a has two heads:
235
235
236 $ hg heads
236 $ hg heads
237 changeset: 15:0aae7cf88f0d
237 changeset: 15:0aae7cf88f0d
238 branch: stable
238 branch: stable
239 tag: tip
239 tag: tip
240 user: test
240 user: test
241 date: Thu Jan 01 00:00:00 1970 +0000
241 date: Thu Jan 01 00:00:00 1970 +0000
242 summary: another change for branch stable
242 summary: another change for branch stable
243
243
244 changeset: 12:f21241060d6a
244 changeset: 12:f21241060d6a
245 user: test
245 user: test
246 date: Thu Jan 01 00:00:00 1970 +0000
246 date: Thu Jan 01 00:00:00 1970 +0000
247 summary: hacked default
247 summary: hacked default
248
248
249
249
250 $ cd ..
250 $ cd ..
251
251
252
252
253 Testing --noupdate with --updaterev (must abort):
253 Testing --noupdate with --updaterev (must abort):
254
254
255 $ hg clone --noupdate --updaterev 1 a ua
255 $ hg clone --noupdate --updaterev 1 a ua
256 abort: cannot specify both --noupdate and --updaterev
256 abort: cannot specify both --noupdate and --updaterev
257 [255]
257 [255]
258
258
259
259
260 Testing clone -u:
260 Testing clone -u:
261
261
262 $ hg clone -u . a ua
262 $ hg clone -u . a ua
263 updating to branch stable
263 updating to branch stable
264 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
264 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
265
265
266 Repo ua has both heads:
266 Repo ua has both heads:
267
267
268 $ hg -R ua heads
268 $ hg -R ua heads
269 changeset: 15:0aae7cf88f0d
269 changeset: 15:0aae7cf88f0d
270 branch: stable
270 branch: stable
271 tag: tip
271 tag: tip
272 user: test
272 user: test
273 date: Thu Jan 01 00:00:00 1970 +0000
273 date: Thu Jan 01 00:00:00 1970 +0000
274 summary: another change for branch stable
274 summary: another change for branch stable
275
275
276 changeset: 12:f21241060d6a
276 changeset: 12:f21241060d6a
277 user: test
277 user: test
278 date: Thu Jan 01 00:00:00 1970 +0000
278 date: Thu Jan 01 00:00:00 1970 +0000
279 summary: hacked default
279 summary: hacked default
280
280
281
281
282 Same revision checked out in repo a and ua:
282 Same revision checked out in repo a and ua:
283
283
284 $ hg -R a parents --template "{node|short}\n"
284 $ hg -R a parents --template "{node|short}\n"
285 e8ece76546a6
285 e8ece76546a6
286 $ hg -R ua parents --template "{node|short}\n"
286 $ hg -R ua parents --template "{node|short}\n"
287 e8ece76546a6
287 e8ece76546a6
288
288
289 $ rm -r ua
289 $ rm -r ua
290
290
291
291
292 Testing clone --pull -u:
292 Testing clone --pull -u:
293
293
294 $ hg clone --pull -u . a ua
294 $ hg clone --pull -u . a ua
295 requesting all changes
295 requesting all changes
296 adding changesets
296 adding changesets
297 adding manifests
297 adding manifests
298 adding file changes
298 adding file changes
299 added 16 changesets with 16 changes to 3 files (+1 heads)
299 added 16 changesets with 16 changes to 3 files (+1 heads)
300 new changesets acb14030fe0a:0aae7cf88f0d
300 new changesets acb14030fe0a:0aae7cf88f0d
301 updating to branch stable
301 updating to branch stable
302 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
302 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
303
303
304 Repo ua has both heads:
304 Repo ua has both heads:
305
305
306 $ hg -R ua heads
306 $ hg -R ua heads
307 changeset: 15:0aae7cf88f0d
307 changeset: 15:0aae7cf88f0d
308 branch: stable
308 branch: stable
309 tag: tip
309 tag: tip
310 user: test
310 user: test
311 date: Thu Jan 01 00:00:00 1970 +0000
311 date: Thu Jan 01 00:00:00 1970 +0000
312 summary: another change for branch stable
312 summary: another change for branch stable
313
313
314 changeset: 12:f21241060d6a
314 changeset: 12:f21241060d6a
315 user: test
315 user: test
316 date: Thu Jan 01 00:00:00 1970 +0000
316 date: Thu Jan 01 00:00:00 1970 +0000
317 summary: hacked default
317 summary: hacked default
318
318
319
319
320 Same revision checked out in repo a and ua:
320 Same revision checked out in repo a and ua:
321
321
322 $ hg -R a parents --template "{node|short}\n"
322 $ hg -R a parents --template "{node|short}\n"
323 e8ece76546a6
323 e8ece76546a6
324 $ hg -R ua parents --template "{node|short}\n"
324 $ hg -R ua parents --template "{node|short}\n"
325 e8ece76546a6
325 e8ece76546a6
326
326
327 $ rm -r ua
327 $ rm -r ua
328
328
329
329
330 Testing clone -u <branch>:
330 Testing clone -u <branch>:
331
331
332 $ hg clone -u stable a ua
332 $ hg clone -u stable a ua
333 updating to branch stable
333 updating to branch stable
334 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
334 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
335
335
336 Repo ua has both heads:
336 Repo ua has both heads:
337
337
338 $ hg -R ua heads
338 $ hg -R ua heads
339 changeset: 15:0aae7cf88f0d
339 changeset: 15:0aae7cf88f0d
340 branch: stable
340 branch: stable
341 tag: tip
341 tag: tip
342 user: test
342 user: test
343 date: Thu Jan 01 00:00:00 1970 +0000
343 date: Thu Jan 01 00:00:00 1970 +0000
344 summary: another change for branch stable
344 summary: another change for branch stable
345
345
346 changeset: 12:f21241060d6a
346 changeset: 12:f21241060d6a
347 user: test
347 user: test
348 date: Thu Jan 01 00:00:00 1970 +0000
348 date: Thu Jan 01 00:00:00 1970 +0000
349 summary: hacked default
349 summary: hacked default
350
350
351
351
352 Branch 'stable' is checked out:
352 Branch 'stable' is checked out:
353
353
354 $ hg -R ua parents
354 $ hg -R ua parents
355 changeset: 15:0aae7cf88f0d
355 changeset: 15:0aae7cf88f0d
356 branch: stable
356 branch: stable
357 tag: tip
357 tag: tip
358 user: test
358 user: test
359 date: Thu Jan 01 00:00:00 1970 +0000
359 date: Thu Jan 01 00:00:00 1970 +0000
360 summary: another change for branch stable
360 summary: another change for branch stable
361
361
362
362
363 $ rm -r ua
363 $ rm -r ua
364
364
365
365
366 Testing default checkout:
366 Testing default checkout:
367
367
368 $ hg clone a ua
368 $ hg clone a ua
369 updating to branch default
369 updating to branch default
370 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
370 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
371
371
372 Repo ua has both heads:
372 Repo ua has both heads:
373
373
374 $ hg -R ua heads
374 $ hg -R ua heads
375 changeset: 15:0aae7cf88f0d
375 changeset: 15:0aae7cf88f0d
376 branch: stable
376 branch: stable
377 tag: tip
377 tag: tip
378 user: test
378 user: test
379 date: Thu Jan 01 00:00:00 1970 +0000
379 date: Thu Jan 01 00:00:00 1970 +0000
380 summary: another change for branch stable
380 summary: another change for branch stable
381
381
382 changeset: 12:f21241060d6a
382 changeset: 12:f21241060d6a
383 user: test
383 user: test
384 date: Thu Jan 01 00:00:00 1970 +0000
384 date: Thu Jan 01 00:00:00 1970 +0000
385 summary: hacked default
385 summary: hacked default
386
386
387
387
388 Branch 'default' is checked out:
388 Branch 'default' is checked out:
389
389
390 $ hg -R ua parents
390 $ hg -R ua parents
391 changeset: 12:f21241060d6a
391 changeset: 12:f21241060d6a
392 user: test
392 user: test
393 date: Thu Jan 01 00:00:00 1970 +0000
393 date: Thu Jan 01 00:00:00 1970 +0000
394 summary: hacked default
394 summary: hacked default
395
395
396 Test clone with a branch named "@" (issue3677)
396 Test clone with a branch named "@" (issue3677)
397
397
398 $ hg -R ua branch @
398 $ hg -R ua branch @
399 marked working directory as branch @
399 marked working directory as branch @
400 $ hg -R ua commit -m 'created branch @'
400 $ hg -R ua commit -m 'created branch @'
401 $ hg clone ua atbranch
401 $ hg clone ua atbranch
402 updating to branch default
402 updating to branch default
403 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
403 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
404 $ hg -R atbranch heads
404 $ hg -R atbranch heads
405 changeset: 16:798b6d97153e
405 changeset: 16:798b6d97153e
406 branch: @
406 branch: @
407 tag: tip
407 tag: tip
408 parent: 12:f21241060d6a
408 parent: 12:f21241060d6a
409 user: test
409 user: test
410 date: Thu Jan 01 00:00:00 1970 +0000
410 date: Thu Jan 01 00:00:00 1970 +0000
411 summary: created branch @
411 summary: created branch @
412
412
413 changeset: 15:0aae7cf88f0d
413 changeset: 15:0aae7cf88f0d
414 branch: stable
414 branch: stable
415 user: test
415 user: test
416 date: Thu Jan 01 00:00:00 1970 +0000
416 date: Thu Jan 01 00:00:00 1970 +0000
417 summary: another change for branch stable
417 summary: another change for branch stable
418
418
419 changeset: 12:f21241060d6a
419 changeset: 12:f21241060d6a
420 user: test
420 user: test
421 date: Thu Jan 01 00:00:00 1970 +0000
421 date: Thu Jan 01 00:00:00 1970 +0000
422 summary: hacked default
422 summary: hacked default
423
423
424 $ hg -R atbranch parents
424 $ hg -R atbranch parents
425 changeset: 12:f21241060d6a
425 changeset: 12:f21241060d6a
426 user: test
426 user: test
427 date: Thu Jan 01 00:00:00 1970 +0000
427 date: Thu Jan 01 00:00:00 1970 +0000
428 summary: hacked default
428 summary: hacked default
429
429
430
430
431 $ rm -r ua atbranch
431 $ rm -r ua atbranch
432
432
433
433
434 Testing #<branch>:
434 Testing #<branch>:
435
435
436 $ hg clone -u . a#stable ua
436 $ hg clone -u . a#stable ua
437 adding changesets
437 adding changesets
438 adding manifests
438 adding manifests
439 adding file changes
439 adding file changes
440 added 14 changesets with 14 changes to 3 files
440 added 14 changesets with 14 changes to 3 files
441 new changesets acb14030fe0a:0aae7cf88f0d
441 new changesets acb14030fe0a:0aae7cf88f0d
442 updating to branch stable
442 updating to branch stable
443 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
443 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
444
444
445 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
445 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
446
446
447 $ hg -R ua heads
447 $ hg -R ua heads
448 changeset: 13:0aae7cf88f0d
448 changeset: 13:0aae7cf88f0d
449 branch: stable
449 branch: stable
450 tag: tip
450 tag: tip
451 user: test
451 user: test
452 date: Thu Jan 01 00:00:00 1970 +0000
452 date: Thu Jan 01 00:00:00 1970 +0000
453 summary: another change for branch stable
453 summary: another change for branch stable
454
454
455 changeset: 10:a7949464abda
455 changeset: 10:a7949464abda
456 user: test
456 user: test
457 date: Thu Jan 01 00:00:00 1970 +0000
457 date: Thu Jan 01 00:00:00 1970 +0000
458 summary: test
458 summary: test
459
459
460
460
461 Same revision checked out in repo a and ua:
461 Same revision checked out in repo a and ua:
462
462
463 $ hg -R a parents --template "{node|short}\n"
463 $ hg -R a parents --template "{node|short}\n"
464 e8ece76546a6
464 e8ece76546a6
465 $ hg -R ua parents --template "{node|short}\n"
465 $ hg -R ua parents --template "{node|short}\n"
466 e8ece76546a6
466 e8ece76546a6
467
467
468 $ rm -r ua
468 $ rm -r ua
469
469
470
470
471 Testing -u -r <branch>:
471 Testing -u -r <branch>:
472
472
473 $ hg clone -u . -r stable a ua
473 $ hg clone -u . -r stable a ua
474 adding changesets
474 adding changesets
475 adding manifests
475 adding manifests
476 adding file changes
476 adding file changes
477 added 14 changesets with 14 changes to 3 files
477 added 14 changesets with 14 changes to 3 files
478 new changesets acb14030fe0a:0aae7cf88f0d
478 new changesets acb14030fe0a:0aae7cf88f0d
479 updating to branch stable
479 updating to branch stable
480 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
480 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
481
481
482 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
482 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
483
483
484 $ hg -R ua heads
484 $ hg -R ua heads
485 changeset: 13:0aae7cf88f0d
485 changeset: 13:0aae7cf88f0d
486 branch: stable
486 branch: stable
487 tag: tip
487 tag: tip
488 user: test
488 user: test
489 date: Thu Jan 01 00:00:00 1970 +0000
489 date: Thu Jan 01 00:00:00 1970 +0000
490 summary: another change for branch stable
490 summary: another change for branch stable
491
491
492 changeset: 10:a7949464abda
492 changeset: 10:a7949464abda
493 user: test
493 user: test
494 date: Thu Jan 01 00:00:00 1970 +0000
494 date: Thu Jan 01 00:00:00 1970 +0000
495 summary: test
495 summary: test
496
496
497
497
498 Same revision checked out in repo a and ua:
498 Same revision checked out in repo a and ua:
499
499
500 $ hg -R a parents --template "{node|short}\n"
500 $ hg -R a parents --template "{node|short}\n"
501 e8ece76546a6
501 e8ece76546a6
502 $ hg -R ua parents --template "{node|short}\n"
502 $ hg -R ua parents --template "{node|short}\n"
503 e8ece76546a6
503 e8ece76546a6
504
504
505 $ rm -r ua
505 $ rm -r ua
506
506
507
507
508 Testing -r <branch>:
508 Testing -r <branch>:
509
509
510 $ hg clone -r stable a ua
510 $ hg clone -r stable a ua
511 adding changesets
511 adding changesets
512 adding manifests
512 adding manifests
513 adding file changes
513 adding file changes
514 added 14 changesets with 14 changes to 3 files
514 added 14 changesets with 14 changes to 3 files
515 new changesets acb14030fe0a:0aae7cf88f0d
515 new changesets acb14030fe0a:0aae7cf88f0d
516 updating to branch stable
516 updating to branch stable
517 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
517 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
518
518
519 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
519 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
520
520
521 $ hg -R ua heads
521 $ hg -R ua heads
522 changeset: 13:0aae7cf88f0d
522 changeset: 13:0aae7cf88f0d
523 branch: stable
523 branch: stable
524 tag: tip
524 tag: tip
525 user: test
525 user: test
526 date: Thu Jan 01 00:00:00 1970 +0000
526 date: Thu Jan 01 00:00:00 1970 +0000
527 summary: another change for branch stable
527 summary: another change for branch stable
528
528
529 changeset: 10:a7949464abda
529 changeset: 10:a7949464abda
530 user: test
530 user: test
531 date: Thu Jan 01 00:00:00 1970 +0000
531 date: Thu Jan 01 00:00:00 1970 +0000
532 summary: test
532 summary: test
533
533
534
534
535 Branch 'stable' is checked out:
535 Branch 'stable' is checked out:
536
536
537 $ hg -R ua parents
537 $ hg -R ua parents
538 changeset: 13:0aae7cf88f0d
538 changeset: 13:0aae7cf88f0d
539 branch: stable
539 branch: stable
540 tag: tip
540 tag: tip
541 user: test
541 user: test
542 date: Thu Jan 01 00:00:00 1970 +0000
542 date: Thu Jan 01 00:00:00 1970 +0000
543 summary: another change for branch stable
543 summary: another change for branch stable
544
544
545
545
546 $ rm -r ua
546 $ rm -r ua
547
547
548
548
549 Issue2267: Error in 1.6 hg.py: TypeError: 'NoneType' object is not
549 Issue2267: Error in 1.6 hg.py: TypeError: 'NoneType' object is not
550 iterable in addbranchrevs()
550 iterable in addbranchrevs()
551
551
552 $ cat <<EOF > simpleclone.py
552 $ cat <<EOF > simpleclone.py
553 > from mercurial import hg, ui as uimod
553 > from mercurial import hg, ui as uimod
554 > myui = uimod.ui.load()
554 > myui = uimod.ui.load()
555 > repo = hg.repository(myui, b'a')
555 > repo = hg.repository(myui, b'a')
556 > hg.clone(myui, {}, repo, dest=b"ua")
556 > hg.clone(myui, {}, repo, dest=b"ua")
557 > EOF
557 > EOF
558
558
559 $ "$PYTHON" simpleclone.py
559 $ "$PYTHON" simpleclone.py
560 updating to branch default
560 updating to branch default
561 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
561 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
562
562
563 $ rm -r ua
563 $ rm -r ua
564
564
565 $ cat <<EOF > branchclone.py
565 $ cat <<EOF > branchclone.py
566 > from mercurial import extensions, hg, ui as uimod
566 > from mercurial import extensions, hg, ui as uimod
567 > myui = uimod.ui.load()
567 > myui = uimod.ui.load()
568 > extensions.loadall(myui)
568 > extensions.loadall(myui)
569 > extensions.populateui(myui)
569 > extensions.populateui(myui)
570 > repo = hg.repository(myui, b'a')
570 > repo = hg.repository(myui, b'a')
571 > hg.clone(myui, {}, repo, dest=b"ua", branch=[b"stable"])
571 > hg.clone(myui, {}, repo, dest=b"ua", branch=[b"stable"])
572 > EOF
572 > EOF
573
573
574 $ "$PYTHON" branchclone.py
574 $ "$PYTHON" branchclone.py
575 adding changesets
575 adding changesets
576 adding manifests
576 adding manifests
577 adding file changes
577 adding file changes
578 added 14 changesets with 14 changes to 3 files
578 added 14 changesets with 14 changes to 3 files
579 new changesets acb14030fe0a:0aae7cf88f0d
579 new changesets acb14030fe0a:0aae7cf88f0d
580 updating to branch stable
580 updating to branch stable
581 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
581 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
582 $ rm -r ua
582 $ rm -r ua
583
583
584
584
585 Test clone with special '@' bookmark:
585 Test clone with special '@' bookmark:
586 $ cd a
586 $ cd a
587 $ hg bookmark -r a7949464abda @ # branch point of stable from default
587 $ hg bookmark -r a7949464abda @ # branch point of stable from default
588 $ hg clone . ../i
588 $ hg clone . ../i
589 updating to bookmark @
589 updating to bookmark @
590 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
590 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
591 $ hg id -i ../i
591 $ hg id -i ../i
592 a7949464abda
592 a7949464abda
593 $ rm -r ../i
593 $ rm -r ../i
594
594
595 $ hg bookmark -f -r stable @
595 $ hg bookmark -f -r stable @
596 $ hg bookmarks
596 $ hg bookmarks
597 @ 15:0aae7cf88f0d
597 @ 15:0aae7cf88f0d
598 $ hg clone . ../i
598 $ hg clone . ../i
599 updating to bookmark @ on branch stable
599 updating to bookmark @ on branch stable
600 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
600 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
601 $ hg id -i ../i
601 $ hg id -i ../i
602 0aae7cf88f0d
602 0aae7cf88f0d
603 $ cd "$TESTTMP"
603 $ cd "$TESTTMP"
604
604
605
605
606 Testing failures:
606 Testing failures:
607
607
608 $ mkdir fail
608 $ mkdir fail
609 $ cd fail
609 $ cd fail
610
610
611 No local source
611 No local source
612
612
613 $ hg clone a b
613 $ hg clone a b
614 abort: repository a not found!
614 abort: repository a not found!
615 [255]
615 [255]
616
616
617 No remote source
617 No remote source
618
618
619 #if windows
619 #if windows
620 $ hg clone http://$LOCALIP:3121/a b
620 $ hg clone http://$LOCALIP:3121/a b
621 abort: error: * (glob)
621 abort: error: * (glob)
622 [255]
622 [255]
623 #else
623 #else
624 $ hg clone http://$LOCALIP:3121/a b
624 $ hg clone http://$LOCALIP:3121/a b
625 abort: error: *refused* (glob)
625 abort: error: *refused* (glob)
626 [255]
626 [255]
627 #endif
627 #endif
628 $ rm -rf b # work around bug with http clone
628 $ rm -rf b # work around bug with http clone
629
629
630
630
631 #if unix-permissions no-root
631 #if unix-permissions no-root
632
632
633 Inaccessible source
633 Inaccessible source
634
634
635 $ mkdir a
635 $ mkdir a
636 $ chmod 000 a
636 $ chmod 000 a
637 $ hg clone a b
637 $ hg clone a b
638 abort: Permission denied: *$TESTTMP/fail/a/.hg* (glob)
638 abort: Permission denied: *$TESTTMP/fail/a/.hg* (glob)
639 [255]
639 [255]
640
640
641 Inaccessible destination
641 Inaccessible destination
642
642
643 $ hg init b
643 $ hg init b
644 $ cd b
644 $ cd b
645 $ hg clone . ../a
645 $ hg clone . ../a
646 abort: Permission denied: *../a* (glob)
646 abort: Permission denied: *../a* (glob)
647 [255]
647 [255]
648 $ cd ..
648 $ cd ..
649 $ chmod 700 a
649 $ chmod 700 a
650 $ rm -r a b
650 $ rm -r a b
651
651
652 #endif
652 #endif
653
653
654
654
655 #if fifo
655 #if fifo
656
656
657 Source of wrong type
657 Source of wrong type
658
658
659 $ mkfifo a
659 $ mkfifo a
660 $ hg clone a b
660 $ hg clone a b
661 abort: $ENOTDIR$: *$TESTTMP/fail/a/.hg* (glob)
661 abort: $ENOTDIR$: *$TESTTMP/fail/a/.hg* (glob)
662 [255]
662 [255]
663 $ rm a
663 $ rm a
664
664
665 #endif
665 #endif
666
666
667 Default destination, same directory
667 Default destination, same directory
668
668
669 $ hg init q
669 $ hg init q
670 $ hg clone q
670 $ hg clone q
671 destination directory: q
671 destination directory: q
672 abort: destination 'q' is not empty
672 abort: destination 'q' is not empty
673 [255]
673 [255]
674
674
675 destination directory not empty
675 destination directory not empty
676
676
677 $ mkdir a
677 $ mkdir a
678 $ echo stuff > a/a
678 $ echo stuff > a/a
679 $ hg clone q a
679 $ hg clone q a
680 abort: destination 'a' is not empty
680 abort: destination 'a' is not empty
681 [255]
681 [255]
682
682
683
683
684 #if unix-permissions no-root
684 #if unix-permissions no-root
685
685
686 leave existing directory in place after clone failure
686 leave existing directory in place after clone failure
687
687
688 $ hg init c
688 $ hg init c
689 $ cd c
689 $ cd c
690 $ echo c > c
690 $ echo c > c
691 $ hg commit -A -m test
691 $ hg commit -A -m test
692 adding c
692 adding c
693 $ chmod -rx .hg/store/data
693 $ chmod -rx .hg/store/data
694 $ cd ..
694 $ cd ..
695 $ mkdir d
695 $ mkdir d
696 $ hg clone c d 2> err
696 $ hg clone c d 2> err
697 [255]
697 [255]
698 $ test -d d
698 $ test -d d
699 $ test -d d/.hg
699 $ test -d d/.hg
700 [1]
700 [1]
701
701
702 re-enable perm to allow deletion
702 re-enable perm to allow deletion
703
703
704 $ chmod +rx c/.hg/store/data
704 $ chmod +rx c/.hg/store/data
705
705
706 #endif
706 #endif
707
707
708 $ cd ..
708 $ cd ..
709
709
710 Test clone from the repository in (emulated) revlog format 0 (issue4203):
710 Test clone from the repository in (emulated) revlog format 0 (issue4203):
711
711
712 $ mkdir issue4203
712 $ mkdir issue4203
713 $ mkdir -p src/.hg
713 $ mkdir -p src/.hg
714 $ echo foo > src/foo
714 $ echo foo > src/foo
715 $ hg -R src add src/foo
715 $ hg -R src add src/foo
716 $ hg -R src commit -m '#0'
716 $ hg -R src commit -m '#0'
717 $ hg -R src log -q
717 $ hg -R src log -q
718 0:e1bab28bca43
718 0:e1bab28bca43
719 $ hg -R src debugrevlog -c | egrep 'format|flags'
719 $ hg -R src debugrevlog -c | egrep 'format|flags'
720 format : 0
720 format : 0
721 flags : (none)
721 flags : (none)
722 $ hg root -R src -T json | sed 's|\\\\|\\|g'
722 $ hg root -R src -T json | sed 's|\\\\|\\|g'
723 [
723 [
724 {
724 {
725 "hgpath": "$TESTTMP/src/.hg",
725 "hgpath": "$TESTTMP/src/.hg",
726 "reporoot": "$TESTTMP/src",
726 "reporoot": "$TESTTMP/src",
727 "storepath": "$TESTTMP/src/.hg"
727 "storepath": "$TESTTMP/src/.hg"
728 }
728 }
729 ]
729 ]
730 $ hg clone -U -q src dst
730 $ hg clone -U -q src dst
731 $ hg -R dst log -q
731 $ hg -R dst log -q
732 0:e1bab28bca43
732 0:e1bab28bca43
733
733
734 Create repositories to test auto sharing functionality
734 Create repositories to test auto sharing functionality
735
735
736 $ cat >> $HGRCPATH << EOF
736 $ cat >> $HGRCPATH << EOF
737 > [extensions]
737 > [extensions]
738 > share=
738 > share=
739 > EOF
739 > EOF
740
740
741 $ hg init empty
741 $ hg init empty
742 $ hg init source1a
742 $ hg init source1a
743 $ cd source1a
743 $ cd source1a
744 $ echo initial1 > foo
744 $ echo initial1 > foo
745 $ hg -q commit -A -m initial
745 $ hg -q commit -A -m initial
746 $ echo second > foo
746 $ echo second > foo
747 $ hg commit -m second
747 $ hg commit -m second
748 $ cd ..
748 $ cd ..
749
749
750 $ hg init filteredrev0
750 $ hg init filteredrev0
751 $ cd filteredrev0
751 $ cd filteredrev0
752 $ cat >> .hg/hgrc << EOF
752 $ cat >> .hg/hgrc << EOF
753 > [experimental]
753 > [experimental]
754 > evolution.createmarkers=True
754 > evolution.createmarkers=True
755 > EOF
755 > EOF
756 $ echo initial1 > foo
756 $ echo initial1 > foo
757 $ hg -q commit -A -m initial0
757 $ hg -q commit -A -m initial0
758 $ hg -q up -r null
758 $ hg -q up -r null
759 $ echo initial2 > foo
759 $ echo initial2 > foo
760 $ hg -q commit -A -m initial1
760 $ hg -q commit -A -m initial1
761 $ hg debugobsolete c05d5c47a5cf81401869999f3d05f7d699d2b29a e082c1832e09a7d1e78b7fd49a592d372de854c8
761 $ hg debugobsolete c05d5c47a5cf81401869999f3d05f7d699d2b29a e082c1832e09a7d1e78b7fd49a592d372de854c8
762 1 new obsolescence markers
762 1 new obsolescence markers
763 obsoleted 1 changesets
763 obsoleted 1 changesets
764 $ cd ..
764 $ cd ..
765
765
766 $ hg -q clone --pull source1a source1b
766 $ hg -q clone --pull source1a source1b
767 $ cd source1a
767 $ cd source1a
768 $ hg bookmark bookA
768 $ hg bookmark bookA
769 $ echo 1a > foo
769 $ echo 1a > foo
770 $ hg commit -m 1a
770 $ hg commit -m 1a
771 $ cd ../source1b
771 $ cd ../source1b
772 $ hg -q up -r 0
772 $ hg -q up -r 0
773 $ echo head1 > foo
773 $ echo head1 > foo
774 $ hg commit -m head1
774 $ hg commit -m head1
775 created new head
775 created new head
776 $ hg bookmark head1
776 $ hg bookmark head1
777 $ hg -q up -r 0
777 $ hg -q up -r 0
778 $ echo head2 > foo
778 $ echo head2 > foo
779 $ hg commit -m head2
779 $ hg commit -m head2
780 created new head
780 created new head
781 $ hg bookmark head2
781 $ hg bookmark head2
782 $ hg -q up -r 0
782 $ hg -q up -r 0
783 $ hg branch branch1
783 $ hg branch branch1
784 marked working directory as branch branch1
784 marked working directory as branch branch1
785 (branches are permanent and global, did you want a bookmark?)
785 (branches are permanent and global, did you want a bookmark?)
786 $ echo branch1 > foo
786 $ echo branch1 > foo
787 $ hg commit -m branch1
787 $ hg commit -m branch1
788 $ hg -q up -r 0
788 $ hg -q up -r 0
789 $ hg branch branch2
789 $ hg branch branch2
790 marked working directory as branch branch2
790 marked working directory as branch branch2
791 $ echo branch2 > foo
791 $ echo branch2 > foo
792 $ hg commit -m branch2
792 $ hg commit -m branch2
793 $ cd ..
793 $ cd ..
794 $ hg init source2
794 $ hg init source2
795 $ cd source2
795 $ cd source2
796 $ echo initial2 > foo
796 $ echo initial2 > foo
797 $ hg -q commit -A -m initial2
797 $ hg -q commit -A -m initial2
798 $ echo second > foo
798 $ echo second > foo
799 $ hg commit -m second
799 $ hg commit -m second
800 $ cd ..
800 $ cd ..
801
801
802 Clone with auto share from an empty repo should not result in share
802 Clone with auto share from an empty repo should not result in share
803
803
804 $ mkdir share
804 $ mkdir share
805 $ hg --config share.pool=share clone empty share-empty
805 $ hg --config share.pool=share clone empty share-empty
806 (not using pooled storage: remote appears to be empty)
806 (not using pooled storage: remote appears to be empty)
807 updating to branch default
807 updating to branch default
808 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
808 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
809 $ ls share
809 $ ls share
810 $ test -d share-empty/.hg/store
810 $ test -d share-empty/.hg/store
811 $ test -f share-empty/.hg/sharedpath
811 $ test -f share-empty/.hg/sharedpath
812 [1]
812 [1]
813
813
814 Clone with auto share from a repo with filtered revision 0 should not result in share
814 Clone with auto share from a repo with filtered revision 0 should not result in share
815
815
816 $ hg --config share.pool=share clone filteredrev0 share-filtered
816 $ hg --config share.pool=share clone filteredrev0 share-filtered
817 (not using pooled storage: unable to resolve identity of remote)
817 (not using pooled storage: unable to resolve identity of remote)
818 requesting all changes
818 requesting all changes
819 adding changesets
819 adding changesets
820 adding manifests
820 adding manifests
821 adding file changes
821 adding file changes
822 added 1 changesets with 1 changes to 1 files
822 added 1 changesets with 1 changes to 1 files
823 new changesets e082c1832e09
823 new changesets e082c1832e09
824 updating to branch default
824 updating to branch default
825 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
825 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
826
826
827 Clone from repo with content should result in shared store being created
827 Clone from repo with content should result in shared store being created
828
828
829 $ hg --config share.pool=share clone source1a share-dest1a
829 $ hg --config share.pool=share clone source1a share-dest1a
830 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
830 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
831 requesting all changes
831 requesting all changes
832 adding changesets
832 adding changesets
833 adding manifests
833 adding manifests
834 adding file changes
834 adding file changes
835 added 3 changesets with 3 changes to 1 files
835 added 3 changesets with 3 changes to 1 files
836 new changesets b5f04eac9d8f:e5bfe23c0b47
836 new changesets b5f04eac9d8f:e5bfe23c0b47
837 searching for changes
837 searching for changes
838 no changes found
838 no changes found
839 adding remote bookmark bookA
839 adding remote bookmark bookA
840 updating working directory
840 updating working directory
841 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
841 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
842
842
843 The shared repo should have been created
843 The shared repo should have been created
844
844
845 $ ls share
845 $ ls share
846 b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1
846 b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1
847
847
848 The destination should point to it
848 The destination should point to it
849
849
850 $ cat share-dest1a/.hg/sharedpath; echo
850 $ cat share-dest1a/.hg/sharedpath; echo
851 $TESTTMP/share/b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1/.hg
851 $TESTTMP/share/b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1/.hg
852
852
853 The destination should have bookmarks
853 The destination should have bookmarks
854
854
855 $ hg -R share-dest1a bookmarks
855 $ hg -R share-dest1a bookmarks
856 bookA 2:e5bfe23c0b47
856 bookA 2:e5bfe23c0b47
857
857
858 The default path should be the remote, not the share
858 The default path should be the remote, not the share
859
859
860 $ hg -R share-dest1a config paths.default
860 $ hg -R share-dest1a config paths.default
861 $TESTTMP/source1a
861 $TESTTMP/source1a
862
862
863 Clone with existing share dir should result in pull + share
863 Clone with existing share dir should result in pull + share
864
864
865 $ hg --config share.pool=share clone source1b share-dest1b
865 $ hg --config share.pool=share clone source1b share-dest1b
866 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
866 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
867 searching for changes
867 searching for changes
868 adding changesets
868 adding changesets
869 adding manifests
869 adding manifests
870 adding file changes
870 adding file changes
871 added 4 changesets with 4 changes to 1 files (+4 heads)
872 adding remote bookmark head1
871 adding remote bookmark head1
873 adding remote bookmark head2
872 adding remote bookmark head2
873 added 4 changesets with 4 changes to 1 files (+4 heads)
874 new changesets 4a8dc1ab4c13:6bacf4683960
874 new changesets 4a8dc1ab4c13:6bacf4683960
875 updating working directory
875 updating working directory
876 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
876 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
877
877
878 $ ls share
878 $ ls share
879 b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1
879 b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1
880
880
881 $ cat share-dest1b/.hg/sharedpath; echo
881 $ cat share-dest1b/.hg/sharedpath; echo
882 $TESTTMP/share/b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1/.hg
882 $TESTTMP/share/b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1/.hg
883
883
884 We only get bookmarks from the remote, not everything in the share
884 We only get bookmarks from the remote, not everything in the share
885
885
886 $ hg -R share-dest1b bookmarks
886 $ hg -R share-dest1b bookmarks
887 head1 3:4a8dc1ab4c13
887 head1 3:4a8dc1ab4c13
888 head2 4:99f71071f117
888 head2 4:99f71071f117
889
889
890 Default path should be source, not share.
890 Default path should be source, not share.
891
891
892 $ hg -R share-dest1b config paths.default
892 $ hg -R share-dest1b config paths.default
893 $TESTTMP/source1b
893 $TESTTMP/source1b
894
894
895 Checked out revision should be head of default branch
895 Checked out revision should be head of default branch
896
896
897 $ hg -R share-dest1b log -r .
897 $ hg -R share-dest1b log -r .
898 changeset: 4:99f71071f117
898 changeset: 4:99f71071f117
899 bookmark: head2
899 bookmark: head2
900 parent: 0:b5f04eac9d8f
900 parent: 0:b5f04eac9d8f
901 user: test
901 user: test
902 date: Thu Jan 01 00:00:00 1970 +0000
902 date: Thu Jan 01 00:00:00 1970 +0000
903 summary: head2
903 summary: head2
904
904
905
905
906 Clone from unrelated repo should result in new share
906 Clone from unrelated repo should result in new share
907
907
908 $ hg --config share.pool=share clone source2 share-dest2
908 $ hg --config share.pool=share clone source2 share-dest2
909 (sharing from new pooled repository 22aeff664783fd44c6d9b435618173c118c3448e)
909 (sharing from new pooled repository 22aeff664783fd44c6d9b435618173c118c3448e)
910 requesting all changes
910 requesting all changes
911 adding changesets
911 adding changesets
912 adding manifests
912 adding manifests
913 adding file changes
913 adding file changes
914 added 2 changesets with 2 changes to 1 files
914 added 2 changesets with 2 changes to 1 files
915 new changesets 22aeff664783:63cf6c3dba4a
915 new changesets 22aeff664783:63cf6c3dba4a
916 searching for changes
916 searching for changes
917 no changes found
917 no changes found
918 updating working directory
918 updating working directory
919 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
919 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
920
920
921 $ ls share
921 $ ls share
922 22aeff664783fd44c6d9b435618173c118c3448e
922 22aeff664783fd44c6d9b435618173c118c3448e
923 b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1
923 b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1
924
924
925 remote naming mode works as advertised
925 remote naming mode works as advertised
926
926
927 $ hg --config share.pool=shareremote --config share.poolnaming=remote clone source1a share-remote1a
927 $ hg --config share.pool=shareremote --config share.poolnaming=remote clone source1a share-remote1a
928 (sharing from new pooled repository 195bb1fcdb595c14a6c13e0269129ed78f6debde)
928 (sharing from new pooled repository 195bb1fcdb595c14a6c13e0269129ed78f6debde)
929 requesting all changes
929 requesting all changes
930 adding changesets
930 adding changesets
931 adding manifests
931 adding manifests
932 adding file changes
932 adding file changes
933 added 3 changesets with 3 changes to 1 files
933 added 3 changesets with 3 changes to 1 files
934 new changesets b5f04eac9d8f:e5bfe23c0b47
934 new changesets b5f04eac9d8f:e5bfe23c0b47
935 searching for changes
935 searching for changes
936 no changes found
936 no changes found
937 adding remote bookmark bookA
937 adding remote bookmark bookA
938 updating working directory
938 updating working directory
939 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
939 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
940
940
941 $ ls shareremote
941 $ ls shareremote
942 195bb1fcdb595c14a6c13e0269129ed78f6debde
942 195bb1fcdb595c14a6c13e0269129ed78f6debde
943
943
944 $ hg --config share.pool=shareremote --config share.poolnaming=remote clone source1b share-remote1b
944 $ hg --config share.pool=shareremote --config share.poolnaming=remote clone source1b share-remote1b
945 (sharing from new pooled repository c0d4f83847ca2a873741feb7048a45085fd47c46)
945 (sharing from new pooled repository c0d4f83847ca2a873741feb7048a45085fd47c46)
946 requesting all changes
946 requesting all changes
947 adding changesets
947 adding changesets
948 adding manifests
948 adding manifests
949 adding file changes
949 adding file changes
950 added 6 changesets with 6 changes to 1 files (+4 heads)
950 added 6 changesets with 6 changes to 1 files (+4 heads)
951 new changesets b5f04eac9d8f:6bacf4683960
951 new changesets b5f04eac9d8f:6bacf4683960
952 searching for changes
952 searching for changes
953 no changes found
953 no changes found
954 adding remote bookmark head1
954 adding remote bookmark head1
955 adding remote bookmark head2
955 adding remote bookmark head2
956 updating working directory
956 updating working directory
957 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
957 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
958
958
959 $ ls shareremote
959 $ ls shareremote
960 195bb1fcdb595c14a6c13e0269129ed78f6debde
960 195bb1fcdb595c14a6c13e0269129ed78f6debde
961 c0d4f83847ca2a873741feb7048a45085fd47c46
961 c0d4f83847ca2a873741feb7048a45085fd47c46
962
962
963 request to clone a single revision is respected in sharing mode
963 request to clone a single revision is respected in sharing mode
964
964
965 $ hg --config share.pool=sharerevs clone -r 4a8dc1ab4c13 source1b share-1arev
965 $ hg --config share.pool=sharerevs clone -r 4a8dc1ab4c13 source1b share-1arev
966 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
966 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
967 adding changesets
967 adding changesets
968 adding manifests
968 adding manifests
969 adding file changes
969 adding file changes
970 added 2 changesets with 2 changes to 1 files
970 added 2 changesets with 2 changes to 1 files
971 new changesets b5f04eac9d8f:4a8dc1ab4c13
971 new changesets b5f04eac9d8f:4a8dc1ab4c13
972 no changes found
972 no changes found
973 adding remote bookmark head1
973 adding remote bookmark head1
974 updating working directory
974 updating working directory
975 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
975 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
976
976
977 $ hg -R share-1arev log -G
977 $ hg -R share-1arev log -G
978 @ changeset: 1:4a8dc1ab4c13
978 @ changeset: 1:4a8dc1ab4c13
979 | bookmark: head1
979 | bookmark: head1
980 | tag: tip
980 | tag: tip
981 | user: test
981 | user: test
982 | date: Thu Jan 01 00:00:00 1970 +0000
982 | date: Thu Jan 01 00:00:00 1970 +0000
983 | summary: head1
983 | summary: head1
984 |
984 |
985 o changeset: 0:b5f04eac9d8f
985 o changeset: 0:b5f04eac9d8f
986 user: test
986 user: test
987 date: Thu Jan 01 00:00:00 1970 +0000
987 date: Thu Jan 01 00:00:00 1970 +0000
988 summary: initial
988 summary: initial
989
989
990
990
991 making another clone should only pull down requested rev
991 making another clone should only pull down requested rev
992
992
993 $ hg --config share.pool=sharerevs clone -r 99f71071f117 source1b share-1brev
993 $ hg --config share.pool=sharerevs clone -r 99f71071f117 source1b share-1brev
994 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
994 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
995 searching for changes
995 searching for changes
996 adding changesets
996 adding changesets
997 adding manifests
997 adding manifests
998 adding file changes
998 adding file changes
999 added 1 changesets with 1 changes to 1 files (+1 heads)
1000 adding remote bookmark head1
999 adding remote bookmark head1
1001 adding remote bookmark head2
1000 adding remote bookmark head2
1001 added 1 changesets with 1 changes to 1 files (+1 heads)
1002 new changesets 99f71071f117
1002 new changesets 99f71071f117
1003 updating working directory
1003 updating working directory
1004 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1004 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1005
1005
1006 $ hg -R share-1brev log -G
1006 $ hg -R share-1brev log -G
1007 @ changeset: 2:99f71071f117
1007 @ changeset: 2:99f71071f117
1008 | bookmark: head2
1008 | bookmark: head2
1009 | tag: tip
1009 | tag: tip
1010 | parent: 0:b5f04eac9d8f
1010 | parent: 0:b5f04eac9d8f
1011 | user: test
1011 | user: test
1012 | date: Thu Jan 01 00:00:00 1970 +0000
1012 | date: Thu Jan 01 00:00:00 1970 +0000
1013 | summary: head2
1013 | summary: head2
1014 |
1014 |
1015 | o changeset: 1:4a8dc1ab4c13
1015 | o changeset: 1:4a8dc1ab4c13
1016 |/ bookmark: head1
1016 |/ bookmark: head1
1017 | user: test
1017 | user: test
1018 | date: Thu Jan 01 00:00:00 1970 +0000
1018 | date: Thu Jan 01 00:00:00 1970 +0000
1019 | summary: head1
1019 | summary: head1
1020 |
1020 |
1021 o changeset: 0:b5f04eac9d8f
1021 o changeset: 0:b5f04eac9d8f
1022 user: test
1022 user: test
1023 date: Thu Jan 01 00:00:00 1970 +0000
1023 date: Thu Jan 01 00:00:00 1970 +0000
1024 summary: initial
1024 summary: initial
1025
1025
1026
1026
1027 Request to clone a single branch is respected in sharing mode
1027 Request to clone a single branch is respected in sharing mode
1028
1028
1029 $ hg --config share.pool=sharebranch clone -b branch1 source1b share-1bbranch1
1029 $ hg --config share.pool=sharebranch clone -b branch1 source1b share-1bbranch1
1030 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1030 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1031 adding changesets
1031 adding changesets
1032 adding manifests
1032 adding manifests
1033 adding file changes
1033 adding file changes
1034 added 2 changesets with 2 changes to 1 files
1034 added 2 changesets with 2 changes to 1 files
1035 new changesets b5f04eac9d8f:5f92a6c1a1b1
1035 new changesets b5f04eac9d8f:5f92a6c1a1b1
1036 no changes found
1036 no changes found
1037 updating working directory
1037 updating working directory
1038 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1038 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1039
1039
1040 $ hg -R share-1bbranch1 log -G
1040 $ hg -R share-1bbranch1 log -G
1041 o changeset: 1:5f92a6c1a1b1
1041 o changeset: 1:5f92a6c1a1b1
1042 | branch: branch1
1042 | branch: branch1
1043 | tag: tip
1043 | tag: tip
1044 | user: test
1044 | user: test
1045 | date: Thu Jan 01 00:00:00 1970 +0000
1045 | date: Thu Jan 01 00:00:00 1970 +0000
1046 | summary: branch1
1046 | summary: branch1
1047 |
1047 |
1048 @ changeset: 0:b5f04eac9d8f
1048 @ changeset: 0:b5f04eac9d8f
1049 user: test
1049 user: test
1050 date: Thu Jan 01 00:00:00 1970 +0000
1050 date: Thu Jan 01 00:00:00 1970 +0000
1051 summary: initial
1051 summary: initial
1052
1052
1053
1053
1054 $ hg --config share.pool=sharebranch clone -b branch2 source1b share-1bbranch2
1054 $ hg --config share.pool=sharebranch clone -b branch2 source1b share-1bbranch2
1055 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1055 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1056 searching for changes
1056 searching for changes
1057 adding changesets
1057 adding changesets
1058 adding manifests
1058 adding manifests
1059 adding file changes
1059 adding file changes
1060 added 1 changesets with 1 changes to 1 files (+1 heads)
1060 added 1 changesets with 1 changes to 1 files (+1 heads)
1061 new changesets 6bacf4683960
1061 new changesets 6bacf4683960
1062 updating working directory
1062 updating working directory
1063 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1063 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1064
1064
1065 $ hg -R share-1bbranch2 log -G
1065 $ hg -R share-1bbranch2 log -G
1066 o changeset: 2:6bacf4683960
1066 o changeset: 2:6bacf4683960
1067 | branch: branch2
1067 | branch: branch2
1068 | tag: tip
1068 | tag: tip
1069 | parent: 0:b5f04eac9d8f
1069 | parent: 0:b5f04eac9d8f
1070 | user: test
1070 | user: test
1071 | date: Thu Jan 01 00:00:00 1970 +0000
1071 | date: Thu Jan 01 00:00:00 1970 +0000
1072 | summary: branch2
1072 | summary: branch2
1073 |
1073 |
1074 | o changeset: 1:5f92a6c1a1b1
1074 | o changeset: 1:5f92a6c1a1b1
1075 |/ branch: branch1
1075 |/ branch: branch1
1076 | user: test
1076 | user: test
1077 | date: Thu Jan 01 00:00:00 1970 +0000
1077 | date: Thu Jan 01 00:00:00 1970 +0000
1078 | summary: branch1
1078 | summary: branch1
1079 |
1079 |
1080 @ changeset: 0:b5f04eac9d8f
1080 @ changeset: 0:b5f04eac9d8f
1081 user: test
1081 user: test
1082 date: Thu Jan 01 00:00:00 1970 +0000
1082 date: Thu Jan 01 00:00:00 1970 +0000
1083 summary: initial
1083 summary: initial
1084
1084
1085
1085
1086 -U is respected in share clone mode
1086 -U is respected in share clone mode
1087
1087
1088 $ hg --config share.pool=share clone -U source1a share-1anowc
1088 $ hg --config share.pool=share clone -U source1a share-1anowc
1089 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1089 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1090 searching for changes
1090 searching for changes
1091 no changes found
1091 no changes found
1092 adding remote bookmark bookA
1092 adding remote bookmark bookA
1093
1093
1094 $ ls share-1anowc
1094 $ ls share-1anowc
1095
1095
1096 Test that auto sharing doesn't cause failure of "hg clone local remote"
1096 Test that auto sharing doesn't cause failure of "hg clone local remote"
1097
1097
1098 $ cd $TESTTMP
1098 $ cd $TESTTMP
1099 $ hg -R a id -r 0
1099 $ hg -R a id -r 0
1100 acb14030fe0a
1100 acb14030fe0a
1101 $ hg id -R remote -r 0
1101 $ hg id -R remote -r 0
1102 abort: repository remote not found!
1102 abort: repository remote not found!
1103 [255]
1103 [255]
1104 $ hg --config share.pool=share -q clone -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" a ssh://user@dummy/remote
1104 $ hg --config share.pool=share -q clone -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" a ssh://user@dummy/remote
1105 $ hg -R remote id -r 0
1105 $ hg -R remote id -r 0
1106 acb14030fe0a
1106 acb14030fe0a
1107
1107
1108 Cloning into pooled storage doesn't race (issue5104)
1108 Cloning into pooled storage doesn't race (issue5104)
1109
1109
1110 $ HGPOSTLOCKDELAY=2.0 hg --config share.pool=racepool --config extensions.lockdelay=$TESTDIR/lockdelay.py clone source1a share-destrace1 > race1.log 2>&1 &
1110 $ HGPOSTLOCKDELAY=2.0 hg --config share.pool=racepool --config extensions.lockdelay=$TESTDIR/lockdelay.py clone source1a share-destrace1 > race1.log 2>&1 &
1111 $ HGPRELOCKDELAY=1.0 hg --config share.pool=racepool --config extensions.lockdelay=$TESTDIR/lockdelay.py clone source1a share-destrace2 > race2.log 2>&1
1111 $ HGPRELOCKDELAY=1.0 hg --config share.pool=racepool --config extensions.lockdelay=$TESTDIR/lockdelay.py clone source1a share-destrace2 > race2.log 2>&1
1112 $ wait
1112 $ wait
1113
1113
1114 $ hg -R share-destrace1 log -r tip
1114 $ hg -R share-destrace1 log -r tip
1115 changeset: 2:e5bfe23c0b47
1115 changeset: 2:e5bfe23c0b47
1116 bookmark: bookA
1116 bookmark: bookA
1117 tag: tip
1117 tag: tip
1118 user: test
1118 user: test
1119 date: Thu Jan 01 00:00:00 1970 +0000
1119 date: Thu Jan 01 00:00:00 1970 +0000
1120 summary: 1a
1120 summary: 1a
1121
1121
1122
1122
1123 $ hg -R share-destrace2 log -r tip
1123 $ hg -R share-destrace2 log -r tip
1124 changeset: 2:e5bfe23c0b47
1124 changeset: 2:e5bfe23c0b47
1125 bookmark: bookA
1125 bookmark: bookA
1126 tag: tip
1126 tag: tip
1127 user: test
1127 user: test
1128 date: Thu Jan 01 00:00:00 1970 +0000
1128 date: Thu Jan 01 00:00:00 1970 +0000
1129 summary: 1a
1129 summary: 1a
1130
1130
1131 One repo should be new, the other should be shared from the pool. We
1131 One repo should be new, the other should be shared from the pool. We
1132 don't care which is which, so we just make sure we always print the
1132 don't care which is which, so we just make sure we always print the
1133 one containing "new pooled" first, then one one containing "existing
1133 one containing "new pooled" first, then one one containing "existing
1134 pooled".
1134 pooled".
1135
1135
1136 $ (grep 'new pooled' race1.log > /dev/null && cat race1.log || cat race2.log) | grep -v lock
1136 $ (grep 'new pooled' race1.log > /dev/null && cat race1.log || cat race2.log) | grep -v lock
1137 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1137 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1138 requesting all changes
1138 requesting all changes
1139 adding changesets
1139 adding changesets
1140 adding manifests
1140 adding manifests
1141 adding file changes
1141 adding file changes
1142 added 3 changesets with 3 changes to 1 files
1142 added 3 changesets with 3 changes to 1 files
1143 new changesets b5f04eac9d8f:e5bfe23c0b47
1143 new changesets b5f04eac9d8f:e5bfe23c0b47
1144 searching for changes
1144 searching for changes
1145 no changes found
1145 no changes found
1146 adding remote bookmark bookA
1146 adding remote bookmark bookA
1147 updating working directory
1147 updating working directory
1148 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1148 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1149
1149
1150 $ (grep 'existing pooled' race1.log > /dev/null && cat race1.log || cat race2.log) | grep -v lock
1150 $ (grep 'existing pooled' race1.log > /dev/null && cat race1.log || cat race2.log) | grep -v lock
1151 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1151 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1152 searching for changes
1152 searching for changes
1153 no changes found
1153 no changes found
1154 adding remote bookmark bookA
1154 adding remote bookmark bookA
1155 updating working directory
1155 updating working directory
1156 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1156 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1157
1157
1158 SEC: check for unsafe ssh url
1158 SEC: check for unsafe ssh url
1159
1159
1160 $ cat >> $HGRCPATH << EOF
1160 $ cat >> $HGRCPATH << EOF
1161 > [ui]
1161 > [ui]
1162 > ssh = sh -c "read l; read l; read l"
1162 > ssh = sh -c "read l; read l; read l"
1163 > EOF
1163 > EOF
1164
1164
1165 $ hg clone 'ssh://-oProxyCommand=touch${IFS}owned/path'
1165 $ hg clone 'ssh://-oProxyCommand=touch${IFS}owned/path'
1166 abort: potentially unsafe url: 'ssh://-oProxyCommand=touch${IFS}owned/path'
1166 abort: potentially unsafe url: 'ssh://-oProxyCommand=touch${IFS}owned/path'
1167 [255]
1167 [255]
1168 $ hg clone 'ssh://%2DoProxyCommand=touch${IFS}owned/path'
1168 $ hg clone 'ssh://%2DoProxyCommand=touch${IFS}owned/path'
1169 abort: potentially unsafe url: 'ssh://-oProxyCommand=touch${IFS}owned/path'
1169 abort: potentially unsafe url: 'ssh://-oProxyCommand=touch${IFS}owned/path'
1170 [255]
1170 [255]
1171 $ hg clone 'ssh://fakehost|touch%20owned/path'
1171 $ hg clone 'ssh://fakehost|touch%20owned/path'
1172 abort: no suitable response from remote hg!
1172 abort: no suitable response from remote hg!
1173 [255]
1173 [255]
1174 $ hg clone 'ssh://fakehost%7Ctouch%20owned/path'
1174 $ hg clone 'ssh://fakehost%7Ctouch%20owned/path'
1175 abort: no suitable response from remote hg!
1175 abort: no suitable response from remote hg!
1176 [255]
1176 [255]
1177
1177
1178 $ hg clone 'ssh://-oProxyCommand=touch owned%20foo@example.com/nonexistent/path'
1178 $ hg clone 'ssh://-oProxyCommand=touch owned%20foo@example.com/nonexistent/path'
1179 abort: potentially unsafe url: 'ssh://-oProxyCommand=touch owned foo@example.com/nonexistent/path'
1179 abort: potentially unsafe url: 'ssh://-oProxyCommand=touch owned foo@example.com/nonexistent/path'
1180 [255]
1180 [255]
1181
1181
1182 #if windows
1182 #if windows
1183 $ hg clone "ssh://%26touch%20owned%20/" --debug
1183 $ hg clone "ssh://%26touch%20owned%20/" --debug
1184 running sh -c "read l; read l; read l" "&touch owned " "hg -R . serve --stdio"
1184 running sh -c "read l; read l; read l" "&touch owned " "hg -R . serve --stdio"
1185 sending upgrade request: * proto=exp-ssh-v2-0003 (glob) (sshv2 !)
1185 sending upgrade request: * proto=exp-ssh-v2-0003 (glob) (sshv2 !)
1186 sending hello command
1186 sending hello command
1187 sending between command
1187 sending between command
1188 abort: no suitable response from remote hg!
1188 abort: no suitable response from remote hg!
1189 [255]
1189 [255]
1190 $ hg clone "ssh://example.com:%26touch%20owned%20/" --debug
1190 $ hg clone "ssh://example.com:%26touch%20owned%20/" --debug
1191 running sh -c "read l; read l; read l" -p "&touch owned " example.com "hg -R . serve --stdio"
1191 running sh -c "read l; read l; read l" -p "&touch owned " example.com "hg -R . serve --stdio"
1192 sending upgrade request: * proto=exp-ssh-v2-0003 (glob) (sshv2 !)
1192 sending upgrade request: * proto=exp-ssh-v2-0003 (glob) (sshv2 !)
1193 sending hello command
1193 sending hello command
1194 sending between command
1194 sending between command
1195 abort: no suitable response from remote hg!
1195 abort: no suitable response from remote hg!
1196 [255]
1196 [255]
1197 #else
1197 #else
1198 $ hg clone "ssh://%3btouch%20owned%20/" --debug
1198 $ hg clone "ssh://%3btouch%20owned%20/" --debug
1199 running sh -c "read l; read l; read l" ';touch owned ' 'hg -R . serve --stdio'
1199 running sh -c "read l; read l; read l" ';touch owned ' 'hg -R . serve --stdio'
1200 sending upgrade request: * proto=exp-ssh-v2-0003 (glob) (sshv2 !)
1200 sending upgrade request: * proto=exp-ssh-v2-0003 (glob) (sshv2 !)
1201 sending hello command
1201 sending hello command
1202 sending between command
1202 sending between command
1203 abort: no suitable response from remote hg!
1203 abort: no suitable response from remote hg!
1204 [255]
1204 [255]
1205 $ hg clone "ssh://example.com:%3btouch%20owned%20/" --debug
1205 $ hg clone "ssh://example.com:%3btouch%20owned%20/" --debug
1206 running sh -c "read l; read l; read l" -p ';touch owned ' example.com 'hg -R . serve --stdio'
1206 running sh -c "read l; read l; read l" -p ';touch owned ' example.com 'hg -R . serve --stdio'
1207 sending upgrade request: * proto=exp-ssh-v2-0003 (glob) (sshv2 !)
1207 sending upgrade request: * proto=exp-ssh-v2-0003 (glob) (sshv2 !)
1208 sending hello command
1208 sending hello command
1209 sending between command
1209 sending between command
1210 abort: no suitable response from remote hg!
1210 abort: no suitable response from remote hg!
1211 [255]
1211 [255]
1212 #endif
1212 #endif
1213
1213
1214 $ hg clone "ssh://v-alid.example.com/" --debug
1214 $ hg clone "ssh://v-alid.example.com/" --debug
1215 running sh -c "read l; read l; read l" v-alid\.example\.com ['"]hg -R \. serve --stdio['"] (re)
1215 running sh -c "read l; read l; read l" v-alid\.example\.com ['"]hg -R \. serve --stdio['"] (re)
1216 sending upgrade request: * proto=exp-ssh-v2-0003 (glob) (sshv2 !)
1216 sending upgrade request: * proto=exp-ssh-v2-0003 (glob) (sshv2 !)
1217 sending hello command
1217 sending hello command
1218 sending between command
1218 sending between command
1219 abort: no suitable response from remote hg!
1219 abort: no suitable response from remote hg!
1220 [255]
1220 [255]
1221
1221
1222 We should not have created a file named owned - if it exists, the
1222 We should not have created a file named owned - if it exists, the
1223 attack succeeded.
1223 attack succeeded.
1224 $ if test -f owned; then echo 'you got owned'; fi
1224 $ if test -f owned; then echo 'you got owned'; fi
1225
1225
1226 Cloning without fsmonitor enabled does not print a warning for small repos
1226 Cloning without fsmonitor enabled does not print a warning for small repos
1227
1227
1228 $ hg clone a fsmonitor-default
1228 $ hg clone a fsmonitor-default
1229 updating to bookmark @ on branch stable
1229 updating to bookmark @ on branch stable
1230 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1230 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1231
1231
1232 Lower the warning threshold to simulate a large repo
1232 Lower the warning threshold to simulate a large repo
1233
1233
1234 $ cat >> $HGRCPATH << EOF
1234 $ cat >> $HGRCPATH << EOF
1235 > [fsmonitor]
1235 > [fsmonitor]
1236 > warn_update_file_count = 2
1236 > warn_update_file_count = 2
1237 > EOF
1237 > EOF
1238
1238
1239 We should see a warning about no fsmonitor on supported platforms
1239 We should see a warning about no fsmonitor on supported platforms
1240
1240
1241 #if linuxormacos no-fsmonitor
1241 #if linuxormacos no-fsmonitor
1242 $ hg clone a nofsmonitor
1242 $ hg clone a nofsmonitor
1243 updating to bookmark @ on branch stable
1243 updating to bookmark @ on branch stable
1244 (warning: large working directory being used without fsmonitor enabled; enable fsmonitor to improve performance; see "hg help -e fsmonitor")
1244 (warning: large working directory being used without fsmonitor enabled; enable fsmonitor to improve performance; see "hg help -e fsmonitor")
1245 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1245 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1246 #else
1246 #else
1247 $ hg clone a nofsmonitor
1247 $ hg clone a nofsmonitor
1248 updating to bookmark @ on branch stable
1248 updating to bookmark @ on branch stable
1249 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1249 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1250 #endif
1250 #endif
1251
1251
1252 We should not see warning about fsmonitor when it is enabled
1252 We should not see warning about fsmonitor when it is enabled
1253
1253
1254 #if fsmonitor
1254 #if fsmonitor
1255 $ hg clone a fsmonitor-enabled
1255 $ hg clone a fsmonitor-enabled
1256 updating to bookmark @ on branch stable
1256 updating to bookmark @ on branch stable
1257 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1257 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1258 #endif
1258 #endif
1259
1259
1260 We can disable the fsmonitor warning
1260 We can disable the fsmonitor warning
1261
1261
1262 $ hg --config fsmonitor.warn_when_unused=false clone a fsmonitor-disable-warning
1262 $ hg --config fsmonitor.warn_when_unused=false clone a fsmonitor-disable-warning
1263 updating to bookmark @ on branch stable
1263 updating to bookmark @ on branch stable
1264 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1264 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1265
1265
1266 Loaded fsmonitor but disabled in config should still print warning
1266 Loaded fsmonitor but disabled in config should still print warning
1267
1267
1268 #if linuxormacos fsmonitor
1268 #if linuxormacos fsmonitor
1269 $ hg --config fsmonitor.mode=off clone a fsmonitor-mode-off
1269 $ hg --config fsmonitor.mode=off clone a fsmonitor-mode-off
1270 updating to bookmark @ on branch stable
1270 updating to bookmark @ on branch stable
1271 (warning: large working directory being used without fsmonitor enabled; enable fsmonitor to improve performance; see "hg help -e fsmonitor") (fsmonitor !)
1271 (warning: large working directory being used without fsmonitor enabled; enable fsmonitor to improve performance; see "hg help -e fsmonitor") (fsmonitor !)
1272 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1272 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1273 #endif
1273 #endif
1274
1274
1275 Warning not printed if working directory isn't empty
1275 Warning not printed if working directory isn't empty
1276
1276
1277 $ hg -q clone a fsmonitor-update
1277 $ hg -q clone a fsmonitor-update
1278 (warning: large working directory being used without fsmonitor enabled; enable fsmonitor to improve performance; see "hg help -e fsmonitor") (?)
1278 (warning: large working directory being used without fsmonitor enabled; enable fsmonitor to improve performance; see "hg help -e fsmonitor") (?)
1279 $ cd fsmonitor-update
1279 $ cd fsmonitor-update
1280 $ hg up acb14030fe0a
1280 $ hg up acb14030fe0a
1281 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
1281 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
1282 (leaving bookmark @)
1282 (leaving bookmark @)
1283 $ hg up cf0fe1914066
1283 $ hg up cf0fe1914066
1284 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1284 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1285
1285
1286 `hg update` from null revision also prints
1286 `hg update` from null revision also prints
1287
1287
1288 $ hg up null
1288 $ hg up null
1289 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
1289 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
1290
1290
1291 #if linuxormacos no-fsmonitor
1291 #if linuxormacos no-fsmonitor
1292 $ hg up cf0fe1914066
1292 $ hg up cf0fe1914066
1293 (warning: large working directory being used without fsmonitor enabled; enable fsmonitor to improve performance; see "hg help -e fsmonitor")
1293 (warning: large working directory being used without fsmonitor enabled; enable fsmonitor to improve performance; see "hg help -e fsmonitor")
1294 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1294 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1295 #else
1295 #else
1296 $ hg up cf0fe1914066
1296 $ hg up cf0fe1914066
1297 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1297 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1298 #endif
1298 #endif
1299
1299
1300 $ cd ..
1300 $ cd ..
1301
1301
@@ -1,218 +1,211 b''
1 Test the EOL hook
1 Test the EOL hook
2
2
3 $ hg init main
3 $ hg init main
4 $ cat > main/.hg/hgrc <<EOF
4 $ cat > main/.hg/hgrc <<EOF
5 > [hooks]
5 > [hooks]
6 > pretxnchangegroup = python:hgext.eol.hook
6 > pretxnchangegroup = python:hgext.eol.hook
7 > EOF
7 > EOF
8 $ hg clone main fork
8 $ hg clone main fork
9 updating to branch default
9 updating to branch default
10 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
10 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
11 $ cd fork
11 $ cd fork
12
12
13 Create repo
13 Create repo
14 $ cat > .hgeol <<EOF
14 $ cat > .hgeol <<EOF
15 > [patterns]
15 > [patterns]
16 > mixed.txt = BIN
16 > mixed.txt = BIN
17 > crlf.txt = CRLF
17 > crlf.txt = CRLF
18 > **.txt = native
18 > **.txt = native
19 > EOF
19 > EOF
20 $ hg add .hgeol
20 $ hg add .hgeol
21 $ hg commit -m 'Commit .hgeol'
21 $ hg commit -m 'Commit .hgeol'
22
22
23 $ printf "first\nsecond\nthird\n" > a.txt
23 $ printf "first\nsecond\nthird\n" > a.txt
24 $ hg add a.txt
24 $ hg add a.txt
25 $ hg commit -m 'LF a.txt'
25 $ hg commit -m 'LF a.txt'
26 $ hg push ../main
26 $ hg push ../main
27 pushing to ../main
27 pushing to ../main
28 searching for changes
28 searching for changes
29 adding changesets
29 adding changesets
30 adding manifests
30 adding manifests
31 adding file changes
31 adding file changes
32 added 2 changesets with 2 changes to 2 files
32 added 2 changesets with 2 changes to 2 files
33
33
34 $ printf "first\r\nsecond\r\nthird\n" > a.txt
34 $ printf "first\r\nsecond\r\nthird\n" > a.txt
35 $ hg commit -m 'CRLF a.txt'
35 $ hg commit -m 'CRLF a.txt'
36 $ hg push ../main
36 $ hg push ../main
37 pushing to ../main
37 pushing to ../main
38 searching for changes
38 searching for changes
39 adding changesets
39 adding changesets
40 adding manifests
40 adding manifests
41 adding file changes
41 adding file changes
42 added 1 changesets with 1 changes to 1 files
43 error: pretxnchangegroup hook failed: end-of-line check failed:
42 error: pretxnchangegroup hook failed: end-of-line check failed:
44 a.txt in a8ee6548cd86 should not have CRLF line endings
43 a.txt in a8ee6548cd86 should not have CRLF line endings
45 transaction abort!
44 transaction abort!
46 rollback completed
45 rollback completed
47 abort: end-of-line check failed:
46 abort: end-of-line check failed:
48 a.txt in a8ee6548cd86 should not have CRLF line endings
47 a.txt in a8ee6548cd86 should not have CRLF line endings
49 [255]
48 [255]
50
49
51 $ printf "first\nsecond\nthird\n" > a.txt
50 $ printf "first\nsecond\nthird\n" > a.txt
52 $ hg commit -m 'LF a.txt (fixed)'
51 $ hg commit -m 'LF a.txt (fixed)'
53 $ hg push ../main
52 $ hg push ../main
54 pushing to ../main
53 pushing to ../main
55 searching for changes
54 searching for changes
56 adding changesets
55 adding changesets
57 adding manifests
56 adding manifests
58 adding file changes
57 adding file changes
59 added 2 changesets with 2 changes to 1 files
58 added 2 changesets with 2 changes to 1 files
60
59
61 $ printf "first\nsecond\nthird\n" > crlf.txt
60 $ printf "first\nsecond\nthird\n" > crlf.txt
62 $ hg add crlf.txt
61 $ hg add crlf.txt
63 $ hg commit -m 'LF crlf.txt'
62 $ hg commit -m 'LF crlf.txt'
64 $ hg push ../main
63 $ hg push ../main
65 pushing to ../main
64 pushing to ../main
66 searching for changes
65 searching for changes
67 adding changesets
66 adding changesets
68 adding manifests
67 adding manifests
69 adding file changes
68 adding file changes
70 added 1 changesets with 1 changes to 1 files
71 error: pretxnchangegroup hook failed: end-of-line check failed:
69 error: pretxnchangegroup hook failed: end-of-line check failed:
72 crlf.txt in 004ba2132725 should not have LF line endings
70 crlf.txt in 004ba2132725 should not have LF line endings
73 transaction abort!
71 transaction abort!
74 rollback completed
72 rollback completed
75 abort: end-of-line check failed:
73 abort: end-of-line check failed:
76 crlf.txt in 004ba2132725 should not have LF line endings
74 crlf.txt in 004ba2132725 should not have LF line endings
77 [255]
75 [255]
78
76
79 $ printf "first\r\nsecond\r\nthird\r\n" > crlf.txt
77 $ printf "first\r\nsecond\r\nthird\r\n" > crlf.txt
80 $ hg commit -m 'CRLF crlf.txt (fixed)'
78 $ hg commit -m 'CRLF crlf.txt (fixed)'
81 $ hg push ../main
79 $ hg push ../main
82 pushing to ../main
80 pushing to ../main
83 searching for changes
81 searching for changes
84 adding changesets
82 adding changesets
85 adding manifests
83 adding manifests
86 adding file changes
84 adding file changes
87 added 2 changesets with 2 changes to 1 files
85 added 2 changesets with 2 changes to 1 files
88
86
89 $ printf "first\r\nsecond" > b.txt
87 $ printf "first\r\nsecond" > b.txt
90 $ hg add b.txt
88 $ hg add b.txt
91 $ hg commit -m 'CRLF b.txt'
89 $ hg commit -m 'CRLF b.txt'
92 $ hg push ../main
90 $ hg push ../main
93 pushing to ../main
91 pushing to ../main
94 searching for changes
92 searching for changes
95 adding changesets
93 adding changesets
96 adding manifests
94 adding manifests
97 adding file changes
95 adding file changes
98 added 1 changesets with 1 changes to 1 files
99 error: pretxnchangegroup hook failed: end-of-line check failed:
96 error: pretxnchangegroup hook failed: end-of-line check failed:
100 b.txt in fbcf9b1025f5 should not have CRLF line endings
97 b.txt in fbcf9b1025f5 should not have CRLF line endings
101 transaction abort!
98 transaction abort!
102 rollback completed
99 rollback completed
103 abort: end-of-line check failed:
100 abort: end-of-line check failed:
104 b.txt in fbcf9b1025f5 should not have CRLF line endings
101 b.txt in fbcf9b1025f5 should not have CRLF line endings
105 [255]
102 [255]
106
103
107 $ hg up -r -2
104 $ hg up -r -2
108 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
105 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
109 $ printf "some\nother\nfile" > c.txt
106 $ printf "some\nother\nfile" > c.txt
110 $ hg add c.txt
107 $ hg add c.txt
111 $ hg commit -m "LF c.txt, b.txt doesn't exist here"
108 $ hg commit -m "LF c.txt, b.txt doesn't exist here"
112 created new head
109 created new head
113 $ hg push -f ../main
110 $ hg push -f ../main
114 pushing to ../main
111 pushing to ../main
115 searching for changes
112 searching for changes
116 adding changesets
113 adding changesets
117 adding manifests
114 adding manifests
118 adding file changes
115 adding file changes
119 added 2 changesets with 2 changes to 2 files (+1 heads)
120 error: pretxnchangegroup hook failed: end-of-line check failed:
116 error: pretxnchangegroup hook failed: end-of-line check failed:
121 b.txt in fbcf9b1025f5 should not have CRLF line endings
117 b.txt in fbcf9b1025f5 should not have CRLF line endings
122 transaction abort!
118 transaction abort!
123 rollback completed
119 rollback completed
124 abort: end-of-line check failed:
120 abort: end-of-line check failed:
125 b.txt in fbcf9b1025f5 should not have CRLF line endings
121 b.txt in fbcf9b1025f5 should not have CRLF line endings
126 [255]
122 [255]
127
123
128 Test checkheadshook alias
124 Test checkheadshook alias
129
125
130 $ cat > ../main/.hg/hgrc <<EOF
126 $ cat > ../main/.hg/hgrc <<EOF
131 > [hooks]
127 > [hooks]
132 > pretxnchangegroup = python:hgext.eol.checkheadshook
128 > pretxnchangegroup = python:hgext.eol.checkheadshook
133 > EOF
129 > EOF
134 $ hg push -f ../main
130 $ hg push -f ../main
135 pushing to ../main
131 pushing to ../main
136 searching for changes
132 searching for changes
137 adding changesets
133 adding changesets
138 adding manifests
134 adding manifests
139 adding file changes
135 adding file changes
140 added 2 changesets with 2 changes to 2 files (+1 heads)
141 error: pretxnchangegroup hook failed: end-of-line check failed:
136 error: pretxnchangegroup hook failed: end-of-line check failed:
142 b.txt in fbcf9b1025f5 should not have CRLF line endings
137 b.txt in fbcf9b1025f5 should not have CRLF line endings
143 transaction abort!
138 transaction abort!
144 rollback completed
139 rollback completed
145 abort: end-of-line check failed:
140 abort: end-of-line check failed:
146 b.txt in fbcf9b1025f5 should not have CRLF line endings
141 b.txt in fbcf9b1025f5 should not have CRLF line endings
147 [255]
142 [255]
148
143
149 We can fix the head and push again
144 We can fix the head and push again
150
145
151 $ hg up 6
146 $ hg up 6
152 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
147 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
153 $ printf "first\nsecond" > b.txt
148 $ printf "first\nsecond" > b.txt
154 $ hg ci -m "remove CRLF from b.txt"
149 $ hg ci -m "remove CRLF from b.txt"
155 $ hg push -f ../main
150 $ hg push -f ../main
156 pushing to ../main
151 pushing to ../main
157 searching for changes
152 searching for changes
158 adding changesets
153 adding changesets
159 adding manifests
154 adding manifests
160 adding file changes
155 adding file changes
161 added 3 changesets with 3 changes to 2 files (+1 heads)
156 added 3 changesets with 3 changes to 2 files (+1 heads)
162 $ hg -R ../main rollback
157 $ hg -R ../main rollback
163 repository tip rolled back to revision 5 (undo push)
158 repository tip rolled back to revision 5 (undo push)
164
159
165 Test it still fails with checkallhook
160 Test it still fails with checkallhook
166
161
167 $ cat > ../main/.hg/hgrc <<EOF
162 $ cat > ../main/.hg/hgrc <<EOF
168 > [hooks]
163 > [hooks]
169 > pretxnchangegroup = python:hgext.eol.checkallhook
164 > pretxnchangegroup = python:hgext.eol.checkallhook
170 > EOF
165 > EOF
171 $ hg push -f ../main
166 $ hg push -f ../main
172 pushing to ../main
167 pushing to ../main
173 searching for changes
168 searching for changes
174 adding changesets
169 adding changesets
175 adding manifests
170 adding manifests
176 adding file changes
171 adding file changes
177 added 3 changesets with 3 changes to 2 files (+1 heads)
178 error: pretxnchangegroup hook failed: end-of-line check failed:
172 error: pretxnchangegroup hook failed: end-of-line check failed:
179 b.txt in fbcf9b1025f5 should not have CRLF line endings
173 b.txt in fbcf9b1025f5 should not have CRLF line endings
180 transaction abort!
174 transaction abort!
181 rollback completed
175 rollback completed
182 abort: end-of-line check failed:
176 abort: end-of-line check failed:
183 b.txt in fbcf9b1025f5 should not have CRLF line endings
177 b.txt in fbcf9b1025f5 should not have CRLF line endings
184 [255]
178 [255]
185
179
186 But we can push the clean head
180 But we can push the clean head
187
181
188 $ hg push -r7 -f ../main
182 $ hg push -r7 -f ../main
189 pushing to ../main
183 pushing to ../main
190 searching for changes
184 searching for changes
191 adding changesets
185 adding changesets
192 adding manifests
186 adding manifests
193 adding file changes
187 adding file changes
194 added 1 changesets with 1 changes to 1 files
188 added 1 changesets with 1 changes to 1 files
195
189
196 Test multiple files/revisions output
190 Test multiple files/revisions output
197
191
198 $ printf "another\r\nbad\r\none" > d.txt
192 $ printf "another\r\nbad\r\none" > d.txt
199 $ hg add d.txt
193 $ hg add d.txt
200 $ hg ci -m "add d.txt"
194 $ hg ci -m "add d.txt"
201 $ hg push -f ../main
195 $ hg push -f ../main
202 pushing to ../main
196 pushing to ../main
203 searching for changes
197 searching for changes
204 adding changesets
198 adding changesets
205 adding manifests
199 adding manifests
206 adding file changes
200 adding file changes
207 added 3 changesets with 3 changes to 2 files (+1 heads)
208 error: pretxnchangegroup hook failed: end-of-line check failed:
201 error: pretxnchangegroup hook failed: end-of-line check failed:
209 b.txt in fbcf9b1025f5 should not have CRLF line endings
202 b.txt in fbcf9b1025f5 should not have CRLF line endings
210 d.txt in a7040e68714f should not have CRLF line endings
203 d.txt in a7040e68714f should not have CRLF line endings
211 transaction abort!
204 transaction abort!
212 rollback completed
205 rollback completed
213 abort: end-of-line check failed:
206 abort: end-of-line check failed:
214 b.txt in fbcf9b1025f5 should not have CRLF line endings
207 b.txt in fbcf9b1025f5 should not have CRLF line endings
215 d.txt in a7040e68714f should not have CRLF line endings
208 d.txt in a7040e68714f should not have CRLF line endings
216 [255]
209 [255]
217
210
218 $ cd ..
211 $ cd ..
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now