Show More
@@ -119,6 +119,19 b' Binary format is as follow' | |||||
119 |
|
119 | |||
120 | The current implementation always produces either zero or one chunk. |
|
120 | The current implementation always produces either zero or one chunk. | |
121 | This is an implementation limitation that will ultimatly be lifted. |
|
121 | This is an implementation limitation that will ultimatly be lifted. | |
|
122 | ||||
|
123 | Bundle processing | |||
|
124 | ============================ | |||
|
125 | ||||
|
126 | Each part is processed in order using a "part handler". Handler are registered | |||
|
127 | for a certain part type. | |||
|
128 | ||||
|
129 | The matching of a part to its handler is case insensitive. The case of the | |||
|
130 | part type is used to know if a part is mandatory or advisory. If the Part type | |||
|
131 | contains any uppercase char it is considered mandatory. When no handler is | |||
|
132 | known for a Mandatory part, the process is aborted and an exception is raised. | |||
|
133 | If the part is advisory and no handler is known, the part is ignored. | |||
|
134 | ||||
122 | """ |
|
135 | """ | |
123 |
|
136 | |||
124 | import util |
|
137 | import util | |
@@ -161,8 +174,9 b' def parthandler(parttype):' | |||||
161 | ... |
|
174 | ... | |
162 | """ |
|
175 | """ | |
163 | def _decorator(func): |
|
176 | def _decorator(func): | |
164 | assert parttype not in parthandlermapping |
|
177 | lparttype = parttype.lower() # enforce lower case matching. | |
165 | parthandlermapping[parttype] = func |
|
178 | assert lparttype not in parthandlermapping | |
|
179 | parthandlermapping[lparttype] = func | |||
166 | return func |
|
180 | return func | |
167 | return _decorator |
|
181 | return _decorator | |
168 |
|
182 | |||
@@ -179,8 +193,7 b' def processbundle(repo, stream):' | |||||
179 | This is very early version of this function that will be strongly reworked |
|
193 | This is very early version of this function that will be strongly reworked | |
180 | before final usage. |
|
194 | before final usage. | |
181 |
|
195 | |||
182 | All unknown parts are currently ignored (Mandatory parts logic will comes |
|
196 | Unknown Mandatory part will abort the process. | |
183 | later). |
|
|||
184 | """ |
|
197 | """ | |
185 | ui = repo.ui |
|
198 | ui = repo.ui | |
186 | # Extraction of the unbundler object will most likely change. It may be |
|
199 | # Extraction of the unbundler object will most likely change. It may be | |
@@ -200,6 +213,11 b' def processbundle(repo, stream):' | |||||
200 | handler = parthandlermapping[key] |
|
213 | handler = parthandlermapping[key] | |
201 | ui.debug('found an handler for part %r\n' % parttype) |
|
214 | ui.debug('found an handler for part %r\n' % parttype) | |
202 | except KeyError: |
|
215 | except KeyError: | |
|
216 | if key != parttype: # mandatory parts | |||
|
217 | # todo: | |||
|
218 | # - use a more precise exception | |||
|
219 | # - consume the bundle2 stream anyway. | |||
|
220 | raise | |||
203 | ui.debug('ignoring unknown advisory part %r\n' % key) |
|
221 | ui.debug('ignoring unknown advisory part %r\n' % key) | |
204 | # todo: consume the part (once we use streamed parts) |
|
222 | # todo: consume the part (once we use streamed parts) | |
205 | continue |
|
223 | continue |
@@ -29,6 +29,7 b' Create an extension to test bundle2 API' | |||||
29 | > |
|
29 | > | |
30 | > @command('bundle2', |
|
30 | > @command('bundle2', | |
31 | > [('', 'param', [], 'stream level parameter'), |
|
31 | > [('', 'param', [], 'stream level parameter'), | |
|
32 | > ('', 'unknown', False, 'include an unknown mandatory part in the bundle'), | |||
32 | > ('', 'parts', False, 'include some arbitrary parts to the bundle'),], |
|
33 | > ('', 'parts', False, 'include some arbitrary parts to the bundle'),], | |
33 | > '[OUTPUTFILE]') |
|
34 | > '[OUTPUTFILE]') | |
34 | > def cmdbundle2(ui, repo, path=None, **opts): |
|
35 | > def cmdbundle2(ui, repo, path=None, **opts): | |
@@ -54,6 +55,10 b' Create an extension to test bundle2 API' | |||||
54 | > [('cooking', 'raw')], |
|
55 | > [('cooking', 'raw')], | |
55 | > '42') |
|
56 | > '42') | |
56 | > bundler.addpart(part) |
|
57 | > bundler.addpart(part) | |
|
58 | > if opts['unknown']: | |||
|
59 | > part = bundle2.part('test:UNKNOWN', | |||
|
60 | > data='some random content') | |||
|
61 | > bundler.addpart(part) | |||
57 | > |
|
62 | > | |
58 | > if path is None: |
|
63 | > if path is None: | |
59 | > file = sys.stdout |
|
64 | > file = sys.stdout | |
@@ -66,7 +71,10 b' Create an extension to test bundle2 API' | |||||
66 | > @command('unbundle2', [], '') |
|
71 | > @command('unbundle2', [], '') | |
67 | > def cmdunbundle2(ui, repo): |
|
72 | > def cmdunbundle2(ui, repo): | |
68 | > """process a bundle2 stream from stdin on the current repo""" |
|
73 | > """process a bundle2 stream from stdin on the current repo""" | |
69 | > bundle2.processbundle(repo, sys.stdin) |
|
74 | > try: | |
|
75 | > bundle2.processbundle(repo, sys.stdin) | |||
|
76 | > except KeyError, exc: | |||
|
77 | > raise util.Abort('missing support for %s' % exc) | |||
70 | > |
|
78 | > | |
71 | > @command('statbundle2', [], '') |
|
79 | > @command('statbundle2', [], '') | |
72 | > def cmdstatbundle2(ui, repo): |
|
80 | > def cmdstatbundle2(ui, repo): | |
@@ -377,3 +385,14 b' Process the bundle' | |||||
377 | ignoring unknown advisory part 'test:math' |
|
385 | ignoring unknown advisory part 'test:math' | |
378 | part header size: 0 |
|
386 | part header size: 0 | |
379 | end of bundle2 stream |
|
387 | end of bundle2 stream | |
|
388 | ||||
|
389 | ||||
|
390 | $ hg bundle2 --parts --unknown ../unknown.hg2 | |||
|
391 | ||||
|
392 | $ hg unbundle2 < ../unknown.hg2 | |||
|
393 | The choir start singing: | |||
|
394 | Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko | |||
|
395 | Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko | |||
|
396 | Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko. | |||
|
397 | abort: missing support for 'test:unknown' | |||
|
398 | [255] |
General Comments 0
You need to be logged in to leave comments.
Login now