##// END OF EJS Templates
wireprotov1server: use binascii.unhexlify...
Gregory Szorc -
r41506:fb28dc97 default draft
parent child Browse files
Show More
@@ -1,744 +1,745 b''
1 test-abort-checkin.t
1 test-abort-checkin.t
2 test-absorb-edit-lines.t
2 test-absorb-edit-lines.t
3 test-absorb-filefixupstate.py
3 test-absorb-filefixupstate.py
4 test-absorb-phase.t
4 test-absorb-phase.t
5 test-absorb-rename.t
5 test-absorb-rename.t
6 test-absorb-strip.t
6 test-absorb-strip.t
7 test-absorb.t
7 test-absorb.t
8 test-add.t
8 test-add.t
9 test-addremove-similar.t
9 test-addremove-similar.t
10 test-addremove.t
10 test-addremove.t
11 test-alias.t
11 test-alias.t
12 test-amend-subrepo.t
12 test-amend-subrepo.t
13 test-amend.t
13 test-amend.t
14 test-ancestor.py
14 test-ancestor.py
15 test-annotate.py
15 test-annotate.py
16 test-annotate.t
16 test-annotate.t
17 test-arbitraryfilectx.t
17 test-arbitraryfilectx.t
18 test-archive-symlinks.t
18 test-archive-symlinks.t
19 test-archive.t
19 test-archive.t
20 test-atomictempfile.py
20 test-atomictempfile.py
21 test-audit-path.t
21 test-audit-path.t
22 test-audit-subrepo.t
22 test-audit-subrepo.t
23 test-automv.t
23 test-automv.t
24 test-backout.t
24 test-backout.t
25 test-backwards-remove.t
25 test-backwards-remove.t
26 test-bad-extension.t
26 test-bad-extension.t
27 test-bad-pull.t
27 test-bad-pull.t
28 test-basic.t
28 test-basic.t
29 test-batching.py
29 test-batching.py
30 test-bdiff.py
30 test-bdiff.py
31 test-bheads.t
31 test-bheads.t
32 test-bisect.t
32 test-bisect.t
33 test-bisect2.t
33 test-bisect2.t
34 test-bisect3.t
34 test-bisect3.t
35 test-blackbox.t
35 test-blackbox.t
36 test-bookflow.t
36 test-bookflow.t
37 test-bookmarks-current.t
37 test-bookmarks-current.t
38 test-bookmarks-merge.t
38 test-bookmarks-merge.t
39 test-bookmarks-pushpull.t
39 test-bookmarks-pushpull.t
40 test-bookmarks-rebase.t
40 test-bookmarks-rebase.t
41 test-bookmarks-strip.t
41 test-bookmarks-strip.t
42 test-bookmarks.t
42 test-bookmarks.t
43 test-branch-change.t
43 test-branch-change.t
44 test-branch-option.t
44 test-branch-option.t
45 test-branch-tag-confict.t
45 test-branch-tag-confict.t
46 test-branches.t
46 test-branches.t
47 test-bugzilla.t
47 test-bugzilla.t
48 test-bundle-phases.t
48 test-bundle-phases.t
49 test-bundle-r.t
49 test-bundle-r.t
50 test-bundle-type.t
50 test-bundle-type.t
51 test-bundle-vs-outgoing.t
51 test-bundle-vs-outgoing.t
52 test-bundle.t
52 test-bundle.t
53 test-bundle2-exchange.t
53 test-bundle2-exchange.t
54 test-bundle2-format.t
54 test-bundle2-format.t
55 test-bundle2-multiple-changegroups.t
55 test-bundle2-multiple-changegroups.t
56 test-bundle2-pushback.t
56 test-bundle2-pushback.t
57 test-bundle2-remote-changegroup.t
57 test-bundle2-remote-changegroup.t
58 test-cache-abuse.t
58 test-cache-abuse.t
59 test-cappedreader.py
59 test-cappedreader.py
60 test-casecollision-merge.t
60 test-casecollision-merge.t
61 test-casecollision.t
61 test-casecollision.t
62 test-casefolding.t
62 test-casefolding.t
63 test-cat.t
63 test-cat.t
64 test-cbor.py
64 test-cbor.py
65 test-censor.t
65 test-censor.t
66 test-changelog-exec.t
66 test-changelog-exec.t
67 test-check-code.t
67 test-check-code.t
68 test-check-commit.t
68 test-check-commit.t
69 test-check-config.py
69 test-check-config.py
70 test-check-config.t
70 test-check-config.t
71 test-check-execute.t
71 test-check-execute.t
72 test-check-help.t
72 test-check-help.t
73 test-check-interfaces.py
73 test-check-interfaces.py
74 test-check-module-imports.t
74 test-check-module-imports.t
75 test-check-py3-compat.t
75 test-check-py3-compat.t
76 test-check-pyflakes.t
76 test-check-pyflakes.t
77 test-check-pylint.t
77 test-check-pylint.t
78 test-check-shbang.t
78 test-check-shbang.t
79 test-children.t
79 test-children.t
80 test-churn.t
80 test-churn.t
81 test-clone-cgi.t
81 test-clone-cgi.t
82 test-clone-pull-corruption.t
82 test-clone-pull-corruption.t
83 test-clone-r.t
83 test-clone-r.t
84 test-clone-uncompressed.t
84 test-clone-uncompressed.t
85 test-clone-update-order.t
85 test-clone-update-order.t
86 test-clone.t
86 test-clone.t
87 test-clonebundles.t
87 test-clonebundles.t
88 test-close-head.t
88 test-close-head.t
89 test-commandserver.t
89 test-commandserver.t
90 test-commit-amend.t
90 test-commit-amend.t
91 test-commit-interactive.t
91 test-commit-interactive.t
92 test-commit-multiple.t
92 test-commit-multiple.t
93 test-commit-unresolved.t
93 test-commit-unresolved.t
94 test-commit.t
94 test-commit.t
95 test-committer.t
95 test-committer.t
96 test-completion.t
96 test-completion.t
97 test-config-env.py
97 test-config-env.py
98 test-config.t
98 test-config.t
99 test-conflict.t
99 test-conflict.t
100 test-confused-revert.t
100 test-confused-revert.t
101 test-context-metadata.t
101 test-context-metadata.t
102 test-context.py
102 test-context.py
103 test-contrib-check-code.t
103 test-contrib-check-code.t
104 test-contrib-check-commit.t
104 test-contrib-check-commit.t
105 test-contrib-dumprevlog.t
105 test-contrib-dumprevlog.t
106 test-contrib-perf.t
106 test-contrib-perf.t
107 test-contrib-relnotes.t
107 test-contrib-relnotes.t
108 test-contrib-testparseutil.t
108 test-contrib-testparseutil.t
109 test-contrib.t
109 test-contrib.t
110 test-convert-authormap.t
110 test-convert-authormap.t
111 test-convert-clonebranches.t
111 test-convert-clonebranches.t
112 test-convert-cvs-branch.t
112 test-convert-cvs-branch.t
113 test-convert-cvs-detectmerge.t
113 test-convert-cvs-detectmerge.t
114 test-convert-cvs-synthetic.t
114 test-convert-cvs-synthetic.t
115 test-convert-cvs.t
115 test-convert-cvs.t
116 test-convert-cvsnt-mergepoints.t
116 test-convert-cvsnt-mergepoints.t
117 test-convert-datesort.t
117 test-convert-datesort.t
118 test-convert-filemap.t
118 test-convert-filemap.t
119 test-convert-hg-sink.t
119 test-convert-hg-sink.t
120 test-convert-hg-source.t
120 test-convert-hg-source.t
121 test-convert-hg-startrev.t
121 test-convert-hg-startrev.t
122 test-convert-splicemap.t
122 test-convert-splicemap.t
123 test-convert-svn-sink.t
123 test-convert-svn-sink.t
124 test-convert-tagsbranch-topology.t
124 test-convert-tagsbranch-topology.t
125 test-convert.t
125 test-convert.t
126 test-copy-move-merge.t
126 test-copy-move-merge.t
127 test-copy.t
127 test-copy.t
128 test-copytrace-heuristics.t
128 test-copytrace-heuristics.t
129 test-custom-filters.t
129 test-custom-filters.t
130 test-debugbuilddag.t
130 test-debugbuilddag.t
131 test-debugbundle.t
131 test-debugbundle.t
132 test-debugcommands.t
132 test-debugcommands.t
133 test-debugextensions.t
133 test-debugextensions.t
134 test-debugindexdot.t
134 test-debugindexdot.t
135 test-debugrename.t
135 test-debugrename.t
136 test-default-push.t
136 test-default-push.t
137 test-diff-antipatience.t
137 test-diff-antipatience.t
138 test-diff-binary-file.t
138 test-diff-binary-file.t
139 test-diff-change.t
139 test-diff-change.t
140 test-diff-color.t
140 test-diff-color.t
141 test-diff-copy-depth.t
141 test-diff-copy-depth.t
142 test-diff-hashes.t
142 test-diff-hashes.t
143 test-diff-ignore-whitespace.t
143 test-diff-ignore-whitespace.t
144 test-diff-indent-heuristic.t
144 test-diff-indent-heuristic.t
145 test-diff-issue2761.t
145 test-diff-issue2761.t
146 test-diff-newlines.t
146 test-diff-newlines.t
147 test-diff-reverse.t
147 test-diff-reverse.t
148 test-diff-subdir.t
148 test-diff-subdir.t
149 test-diff-unified.t
149 test-diff-unified.t
150 test-diff-upgrade.t
150 test-diff-upgrade.t
151 test-diffdir.t
151 test-diffdir.t
152 test-diffstat.t
152 test-diffstat.t
153 test-directaccess.t
153 test-directaccess.t
154 test-dirstate-backup.t
154 test-dirstate-backup.t
155 test-dirstate-nonnormalset.t
155 test-dirstate-nonnormalset.t
156 test-dirstate-race.t
156 test-dirstate-race.t
157 test-dirstate.t
157 test-dirstate.t
158 test-dispatch.py
158 test-dispatch.py
159 test-dispatch.t
159 test-dispatch.t
160 test-doctest.py
160 test-doctest.py
161 test-double-merge.t
161 test-double-merge.t
162 test-drawdag.t
162 test-drawdag.t
163 test-duplicateoptions.py
163 test-duplicateoptions.py
164 test-editor-filename.t
164 test-editor-filename.t
165 test-empty-dir.t
165 test-empty-dir.t
166 test-empty-file.t
166 test-empty-file.t
167 test-empty-group.t
167 test-empty-group.t
168 test-empty.t
168 test-empty.t
169 test-encode.t
169 test-encode.t
170 test-encoding-align.t
170 test-encoding-align.t
171 test-encoding-func.py
171 test-encoding-func.py
172 test-encoding-textwrap.t
172 test-encoding-textwrap.t
173 test-encoding.t
173 test-encoding.t
174 test-eol-add.t
174 test-eol-add.t
175 test-eol-clone.t
175 test-eol-clone.t
176 test-eol-hook.t
176 test-eol-hook.t
177 test-eol-patch.t
177 test-eol-patch.t
178 test-eol-tag.t
178 test-eol-tag.t
179 test-eol-update.t
179 test-eol-update.t
180 test-eol.t
180 test-eol.t
181 test-eolfilename.t
181 test-eolfilename.t
182 test-excessive-merge.t
182 test-excessive-merge.t
183 test-exchange-obsmarkers-case-A1.t
183 test-exchange-obsmarkers-case-A1.t
184 test-exchange-obsmarkers-case-A2.t
184 test-exchange-obsmarkers-case-A2.t
185 test-exchange-obsmarkers-case-A3.t
185 test-exchange-obsmarkers-case-A3.t
186 test-exchange-obsmarkers-case-A4.t
186 test-exchange-obsmarkers-case-A4.t
187 test-exchange-obsmarkers-case-A5.t
187 test-exchange-obsmarkers-case-A5.t
188 test-exchange-obsmarkers-case-A6.t
188 test-exchange-obsmarkers-case-A6.t
189 test-exchange-obsmarkers-case-A7.t
189 test-exchange-obsmarkers-case-A7.t
190 test-exchange-obsmarkers-case-B1.t
190 test-exchange-obsmarkers-case-B1.t
191 test-exchange-obsmarkers-case-B2.t
191 test-exchange-obsmarkers-case-B2.t
192 test-exchange-obsmarkers-case-B3.t
192 test-exchange-obsmarkers-case-B3.t
193 test-exchange-obsmarkers-case-B4.t
193 test-exchange-obsmarkers-case-B4.t
194 test-exchange-obsmarkers-case-B5.t
194 test-exchange-obsmarkers-case-B5.t
195 test-exchange-obsmarkers-case-B6.t
195 test-exchange-obsmarkers-case-B6.t
196 test-exchange-obsmarkers-case-B7.t
196 test-exchange-obsmarkers-case-B7.t
197 test-exchange-obsmarkers-case-C1.t
197 test-exchange-obsmarkers-case-C1.t
198 test-exchange-obsmarkers-case-C2.t
198 test-exchange-obsmarkers-case-C2.t
199 test-exchange-obsmarkers-case-C3.t
199 test-exchange-obsmarkers-case-C3.t
200 test-exchange-obsmarkers-case-C4.t
200 test-exchange-obsmarkers-case-C4.t
201 test-exchange-obsmarkers-case-D1.t
201 test-exchange-obsmarkers-case-D1.t
202 test-exchange-obsmarkers-case-D2.t
202 test-exchange-obsmarkers-case-D2.t
203 test-exchange-obsmarkers-case-D3.t
203 test-exchange-obsmarkers-case-D3.t
204 test-exchange-obsmarkers-case-D4.t
204 test-exchange-obsmarkers-case-D4.t
205 test-execute-bit.t
205 test-execute-bit.t
206 test-export.t
206 test-export.t
207 test-extdata.t
207 test-extdata.t
208 test-extdiff.t
208 test-extdiff.t
209 test-extension-timing.t
209 test-extension-timing.t
210 test-extensions-afterloaded.t
210 test-extensions-afterloaded.t
211 test-extensions-wrapfunction.py
211 test-extensions-wrapfunction.py
212 test-extra-filelog-entry.t
212 test-extra-filelog-entry.t
213 test-fastannotate-corrupt.t
213 test-fastannotate-corrupt.t
214 test-fastannotate-diffopts.t
214 test-fastannotate-diffopts.t
215 test-fastannotate-hg.t
215 test-fastannotate-hg.t
216 test-fastannotate-perfhack.t
216 test-fastannotate-perfhack.t
217 test-fastannotate-protocol.t
217 test-fastannotate-protocol.t
218 test-fastannotate-renames.t
218 test-fastannotate-renames.t
219 test-fastannotate-revmap.py
219 test-fastannotate-revmap.py
220 test-fastannotate.t
220 test-fastannotate.t
221 test-fetch.t
221 test-fetch.t
222 test-filebranch.t
222 test-filebranch.t
223 test-filecache.py
223 test-filecache.py
224 test-filelog.py
224 test-filelog.py
225 test-fileset-generated.t
225 test-fileset-generated.t
226 test-fileset.t
226 test-fileset.t
227 test-fix-topology.t
227 test-fix-topology.t
228 test-fix.t
228 test-fix.t
229 test-flags.t
229 test-flags.t
230 test-fncache.t
230 test-fncache.t
231 test-gendoc-da.t
231 test-gendoc-da.t
232 test-gendoc-de.t
232 test-gendoc-de.t
233 test-gendoc-el.t
233 test-gendoc-el.t
234 test-gendoc-fr.t
234 test-gendoc-fr.t
235 test-gendoc-it.t
235 test-gendoc-it.t
236 test-gendoc-ja.t
236 test-gendoc-ja.t
237 test-gendoc-pt_BR.t
237 test-gendoc-pt_BR.t
238 test-gendoc-ro.t
238 test-gendoc-ro.t
239 test-gendoc-ru.t
239 test-gendoc-ru.t
240 test-gendoc-sv.t
240 test-gendoc-sv.t
241 test-gendoc-zh_CN.t
241 test-gendoc-zh_CN.t
242 test-gendoc-zh_TW.t
242 test-gendoc-zh_TW.t
243 test-gendoc.t
243 test-gendoc.t
244 test-generaldelta.t
244 test-generaldelta.t
245 test-getbundle.t
245 test-getbundle.t
246 test-git-export.t
246 test-git-export.t
247 test-githelp.t
247 test-githelp.t
248 test-globalopts.t
248 test-globalopts.t
249 test-glog-beautifygraph.t
249 test-glog-beautifygraph.t
250 test-glog-topological.t
250 test-glog-topological.t
251 test-glog.t
251 test-glog.t
252 test-gpg.t
252 test-gpg.t
253 test-graft.t
253 test-graft.t
254 test-grep.t
254 test-grep.t
255 test-hardlinks.t
255 test-hardlinks.t
256 test-help-hide.t
256 test-help-hide.t
257 test-help.t
257 test-help.t
258 test-hg-parseurl.py
258 test-hg-parseurl.py
259 test-hghave.t
259 test-hghave.t
260 test-hgignore.t
260 test-hgignore.t
261 test-hgk.t
261 test-hgk.t
262 test-hgrc.t
262 test-hgrc.t
263 test-hgweb-annotate-whitespace.t
263 test-hgweb-annotate-whitespace.t
264 test-hgweb-auth.py
264 test-hgweb-auth.py
265 test-hgweb-bundle.t
265 test-hgweb-bundle.t
266 test-hgweb-commands.t
266 test-hgweb-commands.t
267 test-hgweb-csp.t
267 test-hgweb-csp.t
268 test-hgweb-descend-empties.t
268 test-hgweb-descend-empties.t
269 test-hgweb-diffs.t
269 test-hgweb-diffs.t
270 test-hgweb-empty.t
270 test-hgweb-empty.t
271 test-hgweb-filelog.t
271 test-hgweb-filelog.t
272 test-hgweb-no-path-info.t
272 test-hgweb-no-path-info.t
273 test-hgweb-no-request-uri.t
273 test-hgweb-no-request-uri.t
274 test-hgweb-non-interactive.t
274 test-hgweb-non-interactive.t
275 test-hgweb-raw.t
275 test-hgweb-raw.t
276 test-hgweb-removed.t
276 test-hgweb-removed.t
277 test-hgweb-symrev.t
277 test-hgweb-symrev.t
278 test-hgweb.t
278 test-hgweb.t
279 test-hgwebdir-paths.py
279 test-hgwebdir-paths.py
280 test-hgwebdir.t
280 test-hgwebdir.t
281 test-hgwebdirsym.t
281 test-hgwebdirsym.t
282 test-histedit-arguments.t
282 test-histedit-arguments.t
283 test-histedit-base.t
283 test-histedit-base.t
284 test-histedit-bookmark-motion.t
284 test-histedit-bookmark-motion.t
285 test-histedit-commute.t
285 test-histedit-commute.t
286 test-histedit-drop.t
286 test-histedit-drop.t
287 test-histedit-edit.t
287 test-histedit-edit.t
288 test-histedit-fold-non-commute.t
288 test-histedit-fold-non-commute.t
289 test-histedit-fold.t
289 test-histedit-fold.t
290 test-histedit-no-backup.t
290 test-histedit-no-backup.t
291 test-histedit-no-change.t
291 test-histedit-no-change.t
292 test-histedit-non-commute-abort.t
292 test-histedit-non-commute-abort.t
293 test-histedit-non-commute.t
293 test-histedit-non-commute.t
294 test-histedit-obsolete.t
294 test-histedit-obsolete.t
295 test-histedit-outgoing.t
295 test-histedit-outgoing.t
296 test-histedit-templates.t
296 test-histedit-templates.t
297 test-http-api-httpv2.t
297 test-http-api-httpv2.t
298 test-http-api.t
298 test-http-api.t
299 test-http-bad-server.t
299 test-http-bad-server.t
300 test-http-branchmap.t
300 test-http-branchmap.t
301 test-http-bundle1.t
301 test-http-bundle1.t
302 test-http-clone-r.t
302 test-http-clone-r.t
303 test-http-permissions.t
303 test-http-permissions.t
304 test-http-protocol.t
304 test-http-protocol.t
305 test-http.t
305 test-http.t
306 test-hybridencode.py
306 test-hybridencode.py
307 test-i18n.t
307 test-i18n.t
308 test-identify.t
308 test-identify.t
309 test-impexp-branch.t
309 test-impexp-branch.t
310 test-import-bypass.t
310 test-import-bypass.t
311 test-import-context.t
311 test-import-context.t
312 test-import-eol.t
312 test-import-eol.t
313 test-import-merge.t
313 test-import-merge.t
314 test-import-unknown.t
314 test-import-unknown.t
315 test-import.t
315 test-import.t
316 test-imports-checker.t
316 test-imports-checker.t
317 test-incoming-outgoing.t
317 test-incoming-outgoing.t
318 test-infinitepush-bundlestore.t
318 test-infinitepush-bundlestore.t
319 test-infinitepush-ci.t
319 test-infinitepush-ci.t
320 test-infinitepush.t
320 test-infinitepush.t
321 test-inherit-mode.t
321 test-inherit-mode.t
322 test-init.t
322 test-init.t
323 test-install.t
323 test-install.t
324 test-issue1089.t
324 test-issue1089.t
325 test-issue1102.t
325 test-issue1102.t
326 test-issue1175.t
326 test-issue1175.t
327 test-issue1306.t
327 test-issue1306.t
328 test-issue1438.t
328 test-issue1438.t
329 test-issue1502.t
329 test-issue1502.t
330 test-issue1802.t
330 test-issue1802.t
331 test-issue1877.t
331 test-issue1877.t
332 test-issue1993.t
332 test-issue1993.t
333 test-issue2137.t
333 test-issue2137.t
334 test-issue3084.t
334 test-issue3084.t
335 test-issue4074.t
335 test-issue4074.t
336 test-issue522.t
336 test-issue522.t
337 test-issue586.t
337 test-issue586.t
338 test-issue5979.t
338 test-issue5979.t
339 test-issue612.t
339 test-issue612.t
340 test-issue619.t
340 test-issue619.t
341 test-issue660.t
341 test-issue660.t
342 test-issue672.t
342 test-issue672.t
343 test-issue842.t
343 test-issue842.t
344 test-journal-exists.t
344 test-journal-exists.t
345 test-journal-share.t
345 test-journal-share.t
346 test-journal.t
346 test-journal.t
347 test-keyword.t
347 test-keyword.t
348 test-known.t
348 test-known.t
349 test-largefiles-cache.t
349 test-largefiles-cache.t
350 test-largefiles-misc.t
350 test-largefiles-misc.t
351 test-largefiles-small-disk.t
351 test-largefiles-small-disk.t
352 test-largefiles-update.t
352 test-largefiles-update.t
353 test-largefiles-wireproto.t
353 test-largefiles-wireproto.t
354 test-largefiles.t
354 test-largefiles.t
355 test-lfconvert.t
355 test-lfconvert.t
356 test-lfs-bundle.t
356 test-lfs-bundle.t
357 test-lfs-largefiles.t
357 test-lfs-largefiles.t
358 test-lfs-pointer.py
358 test-lfs-pointer.py
359 test-lfs-test-server.t
359 test-lfs-test-server.t
360 test-lfs.t
360 test-lfs.t
361 test-linelog.py
361 test-linelog.py
362 test-linerange.py
362 test-linerange.py
363 test-locate.t
363 test-locate.t
364 test-lock-badness.t
364 test-lock-badness.t
365 test-log-exthook.t
365 test-log-exthook.t
366 test-log-linerange.t
366 test-log-linerange.t
367 test-log.t
367 test-log.t
368 test-logexchange.t
368 test-logexchange.t
369 test-logtoprocess.t
369 test-logtoprocess.t
370 test-lrucachedict.py
370 test-lrucachedict.py
371 test-mactext.t
371 test-mactext.t
372 test-mailmap.t
372 test-mailmap.t
373 test-manifest-merging.t
373 test-manifest-merging.t
374 test-manifest.py
374 test-manifest.py
375 test-manifest.t
375 test-manifest.t
376 test-match.py
376 test-match.py
377 test-mdiff.py
377 test-mdiff.py
378 test-merge-changedelete.t
378 test-merge-changedelete.t
379 test-merge-closedheads.t
379 test-merge-closedheads.t
380 test-merge-commit.t
380 test-merge-commit.t
381 test-merge-criss-cross.t
381 test-merge-criss-cross.t
382 test-merge-default.t
382 test-merge-default.t
383 test-merge-force.t
383 test-merge-force.t
384 test-merge-halt.t
384 test-merge-halt.t
385 test-merge-internal-tools-pattern.t
385 test-merge-internal-tools-pattern.t
386 test-merge-local.t
386 test-merge-local.t
387 test-merge-no-file-change.t
387 test-merge-no-file-change.t
388 test-merge-remove.t
388 test-merge-remove.t
389 test-merge-revert.t
389 test-merge-revert.t
390 test-merge-revert2.t
390 test-merge-revert2.t
391 test-merge-subrepos.t
391 test-merge-subrepos.t
392 test-merge-symlinks.t
392 test-merge-symlinks.t
393 test-merge-tools.t
393 test-merge-tools.t
394 test-merge-types.t
394 test-merge-types.t
395 test-merge1.t
395 test-merge1.t
396 test-merge10.t
396 test-merge10.t
397 test-merge2.t
397 test-merge2.t
398 test-merge4.t
398 test-merge4.t
399 test-merge5.t
399 test-merge5.t
400 test-merge6.t
400 test-merge6.t
401 test-merge7.t
401 test-merge7.t
402 test-merge8.t
402 test-merge8.t
403 test-merge9.t
403 test-merge9.t
404 test-minifileset.py
404 test-minifileset.py
405 test-minirst.py
405 test-minirst.py
406 test-missing-capability.t
406 test-missing-capability.t
407 test-mq-eol.t
407 test-mq-eol.t
408 test-mq-git.t
408 test-mq-git.t
409 test-mq-guards.t
409 test-mq-guards.t
410 test-mq-header-date.t
410 test-mq-header-date.t
411 test-mq-header-from.t
411 test-mq-header-from.t
412 test-mq-merge.t
412 test-mq-merge.t
413 test-mq-missingfiles.t
413 test-mq-missingfiles.t
414 test-mq-pull-from-bundle.t
414 test-mq-pull-from-bundle.t
415 test-mq-qclone-http.t
415 test-mq-qclone-http.t
416 test-mq-qdelete.t
416 test-mq-qdelete.t
417 test-mq-qdiff.t
417 test-mq-qdiff.t
418 test-mq-qfold.t
418 test-mq-qfold.t
419 test-mq-qgoto.t
419 test-mq-qgoto.t
420 test-mq-qimport-fail-cleanup.t
420 test-mq-qimport-fail-cleanup.t
421 test-mq-qimport.t
421 test-mq-qimport.t
422 test-mq-qnew.t
422 test-mq-qnew.t
423 test-mq-qpush-exact.t
423 test-mq-qpush-exact.t
424 test-mq-qpush-fail.t
424 test-mq-qpush-fail.t
425 test-mq-qqueue.t
425 test-mq-qqueue.t
426 test-mq-qrefresh-interactive.t
426 test-mq-qrefresh-interactive.t
427 test-mq-qrefresh-replace-log-message.t
427 test-mq-qrefresh-replace-log-message.t
428 test-mq-qrefresh.t
428 test-mq-qrefresh.t
429 test-mq-qrename.t
429 test-mq-qrename.t
430 test-mq-qsave.t
430 test-mq-qsave.t
431 test-mq-safety.t
431 test-mq-safety.t
432 test-mq-subrepo.t
432 test-mq-subrepo.t
433 test-mq-symlinks.t
433 test-mq-symlinks.t
434 test-mq.t
434 test-mq.t
435 test-mv-cp-st-diff.t
435 test-mv-cp-st-diff.t
436 test-narrow-acl.t
436 test-narrow-acl.t
437 test-narrow-archive.t
437 test-narrow-archive.t
438 test-narrow-clone-no-ellipsis.t
438 test-narrow-clone-no-ellipsis.t
439 test-narrow-clone-non-narrow-server.t
439 test-narrow-clone-non-narrow-server.t
440 test-narrow-clone-nonlinear.t
440 test-narrow-clone-nonlinear.t
441 test-narrow-clone-stream.t
441 test-narrow-clone-stream.t
442 test-narrow-clone.t
442 test-narrow-clone.t
443 test-narrow-commit.t
443 test-narrow-commit.t
444 test-narrow-copies.t
444 test-narrow-copies.t
445 test-narrow-debugcommands.t
445 test-narrow-debugcommands.t
446 test-narrow-debugrebuilddirstate.t
446 test-narrow-debugrebuilddirstate.t
447 test-narrow-exchange-merges.t
447 test-narrow-exchange-merges.t
448 test-narrow-exchange.t
448 test-narrow-exchange.t
449 test-narrow-expanddirstate.t
449 test-narrow-expanddirstate.t
450 test-narrow-merge.t
450 test-narrow-merge.t
451 test-narrow-patch.t
451 test-narrow-patch.t
452 test-narrow-patterns.t
452 test-narrow-patterns.t
453 test-narrow-pull.t
453 test-narrow-pull.t
454 test-narrow-rebase.t
454 test-narrow-rebase.t
455 test-narrow-shallow-merges.t
455 test-narrow-shallow-merges.t
456 test-narrow-shallow.t
456 test-narrow-shallow.t
457 test-narrow-share.t
457 test-narrow-share.t
458 test-narrow-sparse.t
458 test-narrow-sparse.t
459 test-narrow-strip.t
459 test-narrow-strip.t
460 test-narrow-trackedcmd.t
460 test-narrow-trackedcmd.t
461 test-narrow-update.t
461 test-narrow-update.t
462 test-narrow-widen-no-ellipsis.t
462 test-narrow-widen-no-ellipsis.t
463 test-narrow-widen.t
463 test-narrow-widen.t
464 test-narrow.t
464 test-narrow.t
465 test-nested-repo.t
465 test-nested-repo.t
466 test-newbranch.t
466 test-newbranch.t
467 test-newcgi.t
467 test-newcgi.t
468 test-newercgi.t
468 test-newercgi.t
469 test-nointerrupt.t
469 test-nointerrupt.t
470 test-notify-changegroup.t
470 test-notify-changegroup.t
471 test-obshistory.t
471 test-obshistory.t
472 test-obsmarker-template.t
472 test-obsmarker-template.t
473 test-obsmarkers-effectflag.t
473 test-obsmarkers-effectflag.t
474 test-obsolete-bounds-checking.t
474 test-obsolete-bounds-checking.t
475 test-obsolete-bundle-strip.t
475 test-obsolete-bundle-strip.t
476 test-obsolete-changeset-exchange.t
476 test-obsolete-changeset-exchange.t
477 test-obsolete-checkheads.t
477 test-obsolete-checkheads.t
478 test-obsolete-distributed.t
478 test-obsolete-distributed.t
479 test-obsolete-divergent.t
479 test-obsolete-divergent.t
480 test-obsolete-tag-cache.t
480 test-obsolete-tag-cache.t
481 test-obsolete.t
481 test-obsolete.t
482 test-oldcgi.t
482 test-oldcgi.t
483 test-origbackup-conflict.t
483 test-origbackup-conflict.t
484 test-pager-legacy.t
484 test-pager-legacy.t
485 test-pager.t
485 test-pager.t
486 test-parents.t
486 test-parents.t
487 test-parse-date.t
487 test-parse-date.t
488 test-parseindex.t
488 test-parseindex.t
489 test-parseindex2.py
489 test-parseindex2.py
490 test-patch-offset.t
490 test-patch-offset.t
491 test-patch.t
491 test-patch.t
492 test-patchbomb-bookmark.t
492 test-patchbomb-bookmark.t
493 test-patchbomb-tls.t
493 test-patchbomb-tls.t
494 test-patchbomb.t
494 test-patchbomb.t
495 test-pathconflicts-basic.t
495 test-pathconflicts-basic.t
496 test-pathconflicts-merge.t
496 test-pathconflicts-merge.t
497 test-pathconflicts-update.t
497 test-pathconflicts-update.t
498 test-pathencode.py
498 test-pathencode.py
499 test-pending.t
499 test-pending.t
500 test-permissions.t
500 test-permissions.t
501 test-phases-exchange.t
501 test-phases-exchange.t
502 test-phases.t
502 test-phases.t
503 test-profile.t
503 test-profile.t
504 test-progress.t
504 test-progress.t
505 test-propertycache.py
505 test-propertycache.py
506 test-pull-branch.t
506 test-pull-branch.t
507 test-pull-bundle.t
507 test-pull-http.t
508 test-pull-http.t
508 test-pull-permission.t
509 test-pull-permission.t
509 test-pull-pull-corruption.t
510 test-pull-pull-corruption.t
510 test-pull-r.t
511 test-pull-r.t
511 test-pull-update.t
512 test-pull-update.t
512 test-pull.t
513 test-pull.t
513 test-purge.t
514 test-purge.t
514 test-push-cgi.t
515 test-push-cgi.t
515 test-push-checkheads-partial-C1.t
516 test-push-checkheads-partial-C1.t
516 test-push-checkheads-partial-C2.t
517 test-push-checkheads-partial-C2.t
517 test-push-checkheads-partial-C3.t
518 test-push-checkheads-partial-C3.t
518 test-push-checkheads-partial-C4.t
519 test-push-checkheads-partial-C4.t
519 test-push-checkheads-pruned-B1.t
520 test-push-checkheads-pruned-B1.t
520 test-push-checkheads-pruned-B2.t
521 test-push-checkheads-pruned-B2.t
521 test-push-checkheads-pruned-B3.t
522 test-push-checkheads-pruned-B3.t
522 test-push-checkheads-pruned-B4.t
523 test-push-checkheads-pruned-B4.t
523 test-push-checkheads-pruned-B5.t
524 test-push-checkheads-pruned-B5.t
524 test-push-checkheads-pruned-B6.t
525 test-push-checkheads-pruned-B6.t
525 test-push-checkheads-pruned-B7.t
526 test-push-checkheads-pruned-B7.t
526 test-push-checkheads-pruned-B8.t
527 test-push-checkheads-pruned-B8.t
527 test-push-checkheads-superceed-A1.t
528 test-push-checkheads-superceed-A1.t
528 test-push-checkheads-superceed-A2.t
529 test-push-checkheads-superceed-A2.t
529 test-push-checkheads-superceed-A3.t
530 test-push-checkheads-superceed-A3.t
530 test-push-checkheads-superceed-A4.t
531 test-push-checkheads-superceed-A4.t
531 test-push-checkheads-superceed-A5.t
532 test-push-checkheads-superceed-A5.t
532 test-push-checkheads-superceed-A6.t
533 test-push-checkheads-superceed-A6.t
533 test-push-checkheads-superceed-A7.t
534 test-push-checkheads-superceed-A7.t
534 test-push-checkheads-superceed-A8.t
535 test-push-checkheads-superceed-A8.t
535 test-push-checkheads-unpushed-D1.t
536 test-push-checkheads-unpushed-D1.t
536 test-push-checkheads-unpushed-D2.t
537 test-push-checkheads-unpushed-D2.t
537 test-push-checkheads-unpushed-D3.t
538 test-push-checkheads-unpushed-D3.t
538 test-push-checkheads-unpushed-D4.t
539 test-push-checkheads-unpushed-D4.t
539 test-push-checkheads-unpushed-D5.t
540 test-push-checkheads-unpushed-D5.t
540 test-push-checkheads-unpushed-D6.t
541 test-push-checkheads-unpushed-D6.t
541 test-push-checkheads-unpushed-D7.t
542 test-push-checkheads-unpushed-D7.t
542 test-push-http.t
543 test-push-http.t
543 test-push-race.t
544 test-push-race.t
544 test-push-warn.t
545 test-push-warn.t
545 test-push.t
546 test-push.t
546 test-pushvars.t
547 test-pushvars.t
547 test-qrecord.t
548 test-qrecord.t
548 test-rebase-abort.t
549 test-rebase-abort.t
549 test-rebase-backup.t
550 test-rebase-backup.t
550 test-rebase-base-flag.t
551 test-rebase-base-flag.t
551 test-rebase-bookmarks.t
552 test-rebase-bookmarks.t
552 test-rebase-brute-force.t
553 test-rebase-brute-force.t
553 test-rebase-cache.t
554 test-rebase-cache.t
554 test-rebase-check-restore.t
555 test-rebase-check-restore.t
555 test-rebase-collapse.t
556 test-rebase-collapse.t
556 test-rebase-conflicts.t
557 test-rebase-conflicts.t
557 test-rebase-dest.t
558 test-rebase-dest.t
558 test-rebase-detach.t
559 test-rebase-detach.t
559 test-rebase-emptycommit.t
560 test-rebase-emptycommit.t
560 test-rebase-inmemory.t
561 test-rebase-inmemory.t
561 test-rebase-interruptions.t
562 test-rebase-interruptions.t
562 test-rebase-issue-noparam-single-rev.t
563 test-rebase-issue-noparam-single-rev.t
563 test-rebase-legacy.t
564 test-rebase-legacy.t
564 test-rebase-mq-skip.t
565 test-rebase-mq-skip.t
565 test-rebase-mq.t
566 test-rebase-mq.t
566 test-rebase-named-branches.t
567 test-rebase-named-branches.t
567 test-rebase-newancestor.t
568 test-rebase-newancestor.t
568 test-rebase-obsolete.t
569 test-rebase-obsolete.t
569 test-rebase-parameters.t
570 test-rebase-parameters.t
570 test-rebase-partial.t
571 test-rebase-partial.t
571 test-rebase-pull.t
572 test-rebase-pull.t
572 test-rebase-rename.t
573 test-rebase-rename.t
573 test-rebase-scenario-global.t
574 test-rebase-scenario-global.t
574 test-rebase-templates.t
575 test-rebase-templates.t
575 test-rebase-transaction.t
576 test-rebase-transaction.t
576 test-rebuildstate.t
577 test-rebuildstate.t
577 test-record.t
578 test-record.t
578 test-releasenotes-formatting.t
579 test-releasenotes-formatting.t
579 test-releasenotes-merging.t
580 test-releasenotes-merging.t
580 test-releasenotes-parsing.t
581 test-releasenotes-parsing.t
581 test-relink.t
582 test-relink.t
582 test-remotefilelog-bad-configs.t
583 test-remotefilelog-bad-configs.t
583 test-remotefilelog-bgprefetch.t
584 test-remotefilelog-bgprefetch.t
584 test-remotefilelog-blame.t
585 test-remotefilelog-blame.t
585 test-remotefilelog-bundle2.t
586 test-remotefilelog-bundle2.t
586 test-remotefilelog-bundles.t
587 test-remotefilelog-bundles.t
587 test-remotefilelog-cacheprocess.t
588 test-remotefilelog-cacheprocess.t
588 test-remotefilelog-clone-tree.t
589 test-remotefilelog-clone-tree.t
589 test-remotefilelog-clone.t
590 test-remotefilelog-clone.t
590 test-remotefilelog-gcrepack.t
591 test-remotefilelog-gcrepack.t
591 test-remotefilelog-histpack.py
592 test-remotefilelog-histpack.py
592 test-remotefilelog-http.t
593 test-remotefilelog-http.t
593 test-remotefilelog-keepset.t
594 test-remotefilelog-keepset.t
594 test-remotefilelog-local.t
595 test-remotefilelog-local.t
595 test-remotefilelog-log.t
596 test-remotefilelog-log.t
596 test-remotefilelog-partial-shallow.t
597 test-remotefilelog-partial-shallow.t
597 test-remotefilelog-permissions.t
598 test-remotefilelog-permissions.t
598 test-remotefilelog-permisssions.t
599 test-remotefilelog-permisssions.t
599 test-remotefilelog-prefetch.t
600 test-remotefilelog-prefetch.t
600 test-remotefilelog-pull-noshallow.t
601 test-remotefilelog-pull-noshallow.t
601 test-remotefilelog-share.t
602 test-remotefilelog-share.t
602 test-remotefilelog-sparse.t
603 test-remotefilelog-sparse.t
603 test-remotefilelog-tags.t
604 test-remotefilelog-tags.t
604 test-remotefilelog-wireproto.t
605 test-remotefilelog-wireproto.t
605 test-remove.t
606 test-remove.t
606 test-removeemptydirs.t
607 test-removeemptydirs.t
607 test-rename-after-merge.t
608 test-rename-after-merge.t
608 test-rename-dir-merge.t
609 test-rename-dir-merge.t
609 test-rename-merge1.t
610 test-rename-merge1.t
610 test-rename-merge2.t
611 test-rename-merge2.t
611 test-rename.t
612 test-rename.t
612 test-repair-strip.t
613 test-repair-strip.t
613 test-repo-compengines.t
614 test-repo-compengines.t
614 test-requires.t
615 test-requires.t
615 test-resolve.t
616 test-resolve.t
616 test-revert-flags.t
617 test-revert-flags.t
617 test-revert-interactive.t
618 test-revert-interactive.t
618 test-revert-unknown.t
619 test-revert-unknown.t
619 test-revert.t
620 test-revert.t
620 test-revisions.t
621 test-revisions.t
621 test-revlog-ancestry.py
622 test-revlog-ancestry.py
622 test-revlog-group-emptyiter.t
623 test-revlog-group-emptyiter.t
623 test-revlog-mmapindex.t
624 test-revlog-mmapindex.t
624 test-revlog-packentry.t
625 test-revlog-packentry.t
625 test-revlog-raw.py
626 test-revlog-raw.py
626 test-revlog-v2.t
627 test-revlog-v2.t
627 test-revlog.t
628 test-revlog.t
628 test-revset-dirstate-parents.t
629 test-revset-dirstate-parents.t
629 test-revset-legacy-lookup.t
630 test-revset-legacy-lookup.t
630 test-revset-outgoing.t
631 test-revset-outgoing.t
631 test-rollback.t
632 test-rollback.t
632 test-run-tests.py
633 test-run-tests.py
633 test-run-tests.t
634 test-run-tests.t
634 test-rust-ancestor.py
635 test-rust-ancestor.py
635 test-schemes.t
636 test-schemes.t
636 test-serve.t
637 test-serve.t
637 test-setdiscovery.t
638 test-setdiscovery.t
638 test-share.t
639 test-share.t
639 test-shelve.t
640 test-shelve.t
640 test-shelve2.t
641 test-shelve2.t
641 test-show-stack.t
642 test-show-stack.t
642 test-show-work.t
643 test-show-work.t
643 test-show.t
644 test-show.t
644 test-simple-update.t
645 test-simple-update.t
645 test-simplekeyvaluefile.py
646 test-simplekeyvaluefile.py
646 test-simplemerge.py
647 test-simplemerge.py
647 test-single-head.t
648 test-single-head.t
648 test-sparse-clear.t
649 test-sparse-clear.t
649 test-sparse-clone.t
650 test-sparse-clone.t
650 test-sparse-import.t
651 test-sparse-import.t
651 test-sparse-merges.t
652 test-sparse-merges.t
652 test-sparse-profiles.t
653 test-sparse-profiles.t
653 test-sparse-requirement.t
654 test-sparse-requirement.t
654 test-sparse-verbose-json.t
655 test-sparse-verbose-json.t
655 test-sparse.t
656 test-sparse.t
656 test-split.t
657 test-split.t
657 test-ssh-bundle1.t
658 test-ssh-bundle1.t
658 test-ssh-clone-r.t
659 test-ssh-clone-r.t
659 test-ssh-proto-unbundle.t
660 test-ssh-proto-unbundle.t
660 test-ssh-proto.t
661 test-ssh-proto.t
661 test-ssh-repoerror.t
662 test-ssh-repoerror.t
662 test-ssh.t
663 test-ssh.t
663 test-sshserver.py
664 test-sshserver.py
664 test-stack.t
665 test-stack.t
665 test-static-http.t
666 test-static-http.t
666 test-status-color.t
667 test-status-color.t
667 test-status-inprocess.py
668 test-status-inprocess.py
668 test-status-rev.t
669 test-status-rev.t
669 test-status-terse.t
670 test-status-terse.t
670 test-status.t
671 test-status.t
671 test-storage.py
672 test-storage.py
672 test-stream-bundle-v2.t
673 test-stream-bundle-v2.t
673 test-strict.t
674 test-strict.t
674 test-strip-cross.t
675 test-strip-cross.t
675 test-strip.t
676 test-strip.t
676 test-subrepo-deep-nested-change.t
677 test-subrepo-deep-nested-change.t
677 test-subrepo-missing.t
678 test-subrepo-missing.t
678 test-subrepo-paths.t
679 test-subrepo-paths.t
679 test-subrepo-recursion.t
680 test-subrepo-recursion.t
680 test-subrepo-relative-path.t
681 test-subrepo-relative-path.t
681 test-subrepo.t
682 test-subrepo.t
682 test-symlink-os-yes-fs-no.py
683 test-symlink-os-yes-fs-no.py
683 test-symlink-placeholder.t
684 test-symlink-placeholder.t
684 test-symlinks.t
685 test-symlinks.t
685 test-tag.t
686 test-tag.t
686 test-tags.t
687 test-tags.t
687 test-template-basic.t
688 test-template-basic.t
688 test-template-functions.t
689 test-template-functions.t
689 test-template-keywords.t
690 test-template-keywords.t
690 test-template-map.t
691 test-template-map.t
691 test-tools.t
692 test-tools.t
692 test-transplant.t
693 test-transplant.t
693 test-treediscovery-legacy.t
694 test-treediscovery-legacy.t
694 test-treediscovery.t
695 test-treediscovery.t
695 test-treemanifest.t
696 test-treemanifest.t
696 test-ui-color.py
697 test-ui-color.py
697 test-ui-config.py
698 test-ui-config.py
698 test-ui-verbosity.py
699 test-ui-verbosity.py
699 test-unamend.t
700 test-unamend.t
700 test-unbundlehash.t
701 test-unbundlehash.t
701 test-uncommit.t
702 test-uncommit.t
702 test-unified-test.t
703 test-unified-test.t
703 test-unionrepo.t
704 test-unionrepo.t
704 test-unrelated-pull.t
705 test-unrelated-pull.t
705 test-up-local-change.t
706 test-up-local-change.t
706 test-update-atomic.t
707 test-update-atomic.t
707 test-update-branches.t
708 test-update-branches.t
708 test-update-dest.t
709 test-update-dest.t
709 test-update-issue1456.t
710 test-update-issue1456.t
710 test-update-names.t
711 test-update-names.t
711 test-update-reverse.t
712 test-update-reverse.t
712 test-upgrade-repo.t
713 test-upgrade-repo.t
713 test-url-download.t
714 test-url-download.t
714 test-url-rev.t
715 test-url-rev.t
715 test-url.py
716 test-url.py
716 test-username-newline.t
717 test-username-newline.t
717 test-util.py
718 test-util.py
718 test-verify.t
719 test-verify.t
719 test-walk.t
720 test-walk.t
720 test-walkrepo.py
721 test-walkrepo.py
721 test-websub.t
722 test-websub.t
722 test-win32text.t
723 test-win32text.t
723 test-wireproto-caching.t
724 test-wireproto-caching.t
724 test-wireproto-clientreactor.py
725 test-wireproto-clientreactor.py
725 test-wireproto-command-branchmap.t
726 test-wireproto-command-branchmap.t
726 test-wireproto-command-capabilities.t
727 test-wireproto-command-capabilities.t
727 test-wireproto-command-changesetdata.t
728 test-wireproto-command-changesetdata.t
728 test-wireproto-command-filedata.t
729 test-wireproto-command-filedata.t
729 test-wireproto-command-filesdata.t
730 test-wireproto-command-filesdata.t
730 test-wireproto-command-heads.t
731 test-wireproto-command-heads.t
731 test-wireproto-command-known.t
732 test-wireproto-command-known.t
732 test-wireproto-command-listkeys.t
733 test-wireproto-command-listkeys.t
733 test-wireproto-command-lookup.t
734 test-wireproto-command-lookup.t
734 test-wireproto-command-manifestdata.t
735 test-wireproto-command-manifestdata.t
735 test-wireproto-command-pushkey.t
736 test-wireproto-command-pushkey.t
736 test-wireproto-command-rawstorefiledata.t
737 test-wireproto-command-rawstorefiledata.t
737 test-wireproto-content-redirects.t
738 test-wireproto-content-redirects.t
738 test-wireproto-exchangev2.t
739 test-wireproto-exchangev2.t
739 test-wireproto-framing.py
740 test-wireproto-framing.py
740 test-wireproto-serverreactor.py
741 test-wireproto-serverreactor.py
741 test-wireproto.py
742 test-wireproto.py
742 test-wireproto.t
743 test-wireproto.t
743 test-wsgirequest.py
744 test-wsgirequest.py
744 test-xdg.t
745 test-xdg.t
@@ -1,670 +1,671 b''
1 # wireprotov1server.py - Wire protocol version 1 server functionality
1 # wireprotov1server.py - Wire protocol version 1 server functionality
2 #
2 #
3 # Copyright 2005-2010 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2010 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 binascii
10 import os
11 import os
11
12
12 from .i18n import _
13 from .i18n import _
13 from .node import (
14 from .node import (
14 hex,
15 hex,
15 nullid,
16 nullid,
16 )
17 )
17
18
18 from . import (
19 from . import (
19 bundle2,
20 bundle2,
20 changegroup as changegroupmod,
21 changegroup as changegroupmod,
21 discovery,
22 discovery,
22 encoding,
23 encoding,
23 error,
24 error,
24 exchange,
25 exchange,
25 pushkey as pushkeymod,
26 pushkey as pushkeymod,
26 pycompat,
27 pycompat,
27 streamclone,
28 streamclone,
28 util,
29 util,
29 wireprototypes,
30 wireprototypes,
30 )
31 )
31
32
32 from .utils import (
33 from .utils import (
33 procutil,
34 procutil,
34 stringutil,
35 stringutil,
35 )
36 )
36
37
37 urlerr = util.urlerr
38 urlerr = util.urlerr
38 urlreq = util.urlreq
39 urlreq = util.urlreq
39
40
40 bundle2requiredmain = _('incompatible Mercurial client; bundle2 required')
41 bundle2requiredmain = _('incompatible Mercurial client; bundle2 required')
41 bundle2requiredhint = _('see https://www.mercurial-scm.org/wiki/'
42 bundle2requiredhint = _('see https://www.mercurial-scm.org/wiki/'
42 'IncompatibleClient')
43 'IncompatibleClient')
43 bundle2required = '%s\n(%s)\n' % (bundle2requiredmain, bundle2requiredhint)
44 bundle2required = '%s\n(%s)\n' % (bundle2requiredmain, bundle2requiredhint)
44
45
45 def clientcompressionsupport(proto):
46 def clientcompressionsupport(proto):
46 """Returns a list of compression methods supported by the client.
47 """Returns a list of compression methods supported by the client.
47
48
48 Returns a list of the compression methods supported by the client
49 Returns a list of the compression methods supported by the client
49 according to the protocol capabilities. If no such capability has
50 according to the protocol capabilities. If no such capability has
50 been announced, fallback to the default of zlib and uncompressed.
51 been announced, fallback to the default of zlib and uncompressed.
51 """
52 """
52 for cap in proto.getprotocaps():
53 for cap in proto.getprotocaps():
53 if cap.startswith('comp='):
54 if cap.startswith('comp='):
54 return cap[5:].split(',')
55 return cap[5:].split(',')
55 return ['zlib', 'none']
56 return ['zlib', 'none']
56
57
57 # wire protocol command can either return a string or one of these classes.
58 # wire protocol command can either return a string or one of these classes.
58
59
59 def getdispatchrepo(repo, proto, command):
60 def getdispatchrepo(repo, proto, command):
60 """Obtain the repo used for processing wire protocol commands.
61 """Obtain the repo used for processing wire protocol commands.
61
62
62 The intent of this function is to serve as a monkeypatch point for
63 The intent of this function is to serve as a monkeypatch point for
63 extensions that need commands to operate on different repo views under
64 extensions that need commands to operate on different repo views under
64 specialized circumstances.
65 specialized circumstances.
65 """
66 """
66 return repo.filtered('served')
67 return repo.filtered('served')
67
68
68 def dispatch(repo, proto, command):
69 def dispatch(repo, proto, command):
69 repo = getdispatchrepo(repo, proto, command)
70 repo = getdispatchrepo(repo, proto, command)
70
71
71 func, spec = commands[command]
72 func, spec = commands[command]
72 args = proto.getargs(spec)
73 args = proto.getargs(spec)
73
74
74 return func(repo, proto, *args)
75 return func(repo, proto, *args)
75
76
76 def options(cmd, keys, others):
77 def options(cmd, keys, others):
77 opts = {}
78 opts = {}
78 for k in keys:
79 for k in keys:
79 if k in others:
80 if k in others:
80 opts[k] = others[k]
81 opts[k] = others[k]
81 del others[k]
82 del others[k]
82 if others:
83 if others:
83 procutil.stderr.write("warning: %s ignored unexpected arguments %s\n"
84 procutil.stderr.write("warning: %s ignored unexpected arguments %s\n"
84 % (cmd, ",".join(others)))
85 % (cmd, ",".join(others)))
85 return opts
86 return opts
86
87
87 def bundle1allowed(repo, action):
88 def bundle1allowed(repo, action):
88 """Whether a bundle1 operation is allowed from the server.
89 """Whether a bundle1 operation is allowed from the server.
89
90
90 Priority is:
91 Priority is:
91
92
92 1. server.bundle1gd.<action> (if generaldelta active)
93 1. server.bundle1gd.<action> (if generaldelta active)
93 2. server.bundle1.<action>
94 2. server.bundle1.<action>
94 3. server.bundle1gd (if generaldelta active)
95 3. server.bundle1gd (if generaldelta active)
95 4. server.bundle1
96 4. server.bundle1
96 """
97 """
97 ui = repo.ui
98 ui = repo.ui
98 gd = 'generaldelta' in repo.requirements
99 gd = 'generaldelta' in repo.requirements
99
100
100 if gd:
101 if gd:
101 v = ui.configbool('server', 'bundle1gd.%s' % action)
102 v = ui.configbool('server', 'bundle1gd.%s' % action)
102 if v is not None:
103 if v is not None:
103 return v
104 return v
104
105
105 v = ui.configbool('server', 'bundle1.%s' % action)
106 v = ui.configbool('server', 'bundle1.%s' % action)
106 if v is not None:
107 if v is not None:
107 return v
108 return v
108
109
109 if gd:
110 if gd:
110 v = ui.configbool('server', 'bundle1gd')
111 v = ui.configbool('server', 'bundle1gd')
111 if v is not None:
112 if v is not None:
112 return v
113 return v
113
114
114 return ui.configbool('server', 'bundle1')
115 return ui.configbool('server', 'bundle1')
115
116
116 commands = wireprototypes.commanddict()
117 commands = wireprototypes.commanddict()
117
118
118 def wireprotocommand(name, args=None, permission='push'):
119 def wireprotocommand(name, args=None, permission='push'):
119 """Decorator to declare a wire protocol command.
120 """Decorator to declare a wire protocol command.
120
121
121 ``name`` is the name of the wire protocol command being provided.
122 ``name`` is the name of the wire protocol command being provided.
122
123
123 ``args`` defines the named arguments accepted by the command. It is
124 ``args`` defines the named arguments accepted by the command. It is
124 a space-delimited list of argument names. ``*`` denotes a special value
125 a space-delimited list of argument names. ``*`` denotes a special value
125 that says to accept all named arguments.
126 that says to accept all named arguments.
126
127
127 ``permission`` defines the permission type needed to run this command.
128 ``permission`` defines the permission type needed to run this command.
128 Can be ``push`` or ``pull``. These roughly map to read-write and read-only,
129 Can be ``push`` or ``pull``. These roughly map to read-write and read-only,
129 respectively. Default is to assume command requires ``push`` permissions
130 respectively. Default is to assume command requires ``push`` permissions
130 because otherwise commands not declaring their permissions could modify
131 because otherwise commands not declaring their permissions could modify
131 a repository that is supposed to be read-only.
132 a repository that is supposed to be read-only.
132 """
133 """
133 transports = {k for k, v in wireprototypes.TRANSPORTS.items()
134 transports = {k for k, v in wireprototypes.TRANSPORTS.items()
134 if v['version'] == 1}
135 if v['version'] == 1}
135
136
136 # Because SSHv2 is a mirror of SSHv1, we allow "batch" commands through to
137 # Because SSHv2 is a mirror of SSHv1, we allow "batch" commands through to
137 # SSHv2.
138 # SSHv2.
138 # TODO undo this hack when SSH is using the unified frame protocol.
139 # TODO undo this hack when SSH is using the unified frame protocol.
139 if name == b'batch':
140 if name == b'batch':
140 transports.add(wireprototypes.SSHV2)
141 transports.add(wireprototypes.SSHV2)
141
142
142 if permission not in ('push', 'pull'):
143 if permission not in ('push', 'pull'):
143 raise error.ProgrammingError('invalid wire protocol permission; '
144 raise error.ProgrammingError('invalid wire protocol permission; '
144 'got %s; expected "push" or "pull"' %
145 'got %s; expected "push" or "pull"' %
145 permission)
146 permission)
146
147
147 if args is None:
148 if args is None:
148 args = ''
149 args = ''
149
150
150 if not isinstance(args, bytes):
151 if not isinstance(args, bytes):
151 raise error.ProgrammingError('arguments for version 1 commands '
152 raise error.ProgrammingError('arguments for version 1 commands '
152 'must be declared as bytes')
153 'must be declared as bytes')
153
154
154 def register(func):
155 def register(func):
155 if name in commands:
156 if name in commands:
156 raise error.ProgrammingError('%s command already registered '
157 raise error.ProgrammingError('%s command already registered '
157 'for version 1' % name)
158 'for version 1' % name)
158 commands[name] = wireprototypes.commandentry(
159 commands[name] = wireprototypes.commandentry(
159 func, args=args, transports=transports, permission=permission)
160 func, args=args, transports=transports, permission=permission)
160
161
161 return func
162 return func
162 return register
163 return register
163
164
164 # TODO define a more appropriate permissions type to use for this.
165 # TODO define a more appropriate permissions type to use for this.
165 @wireprotocommand('batch', 'cmds *', permission='pull')
166 @wireprotocommand('batch', 'cmds *', permission='pull')
166 def batch(repo, proto, cmds, others):
167 def batch(repo, proto, cmds, others):
167 unescapearg = wireprototypes.unescapebatcharg
168 unescapearg = wireprototypes.unescapebatcharg
168 repo = repo.filtered("served")
169 repo = repo.filtered("served")
169 res = []
170 res = []
170 for pair in cmds.split(';'):
171 for pair in cmds.split(';'):
171 op, args = pair.split(' ', 1)
172 op, args = pair.split(' ', 1)
172 vals = {}
173 vals = {}
173 for a in args.split(','):
174 for a in args.split(','):
174 if a:
175 if a:
175 n, v = a.split('=')
176 n, v = a.split('=')
176 vals[unescapearg(n)] = unescapearg(v)
177 vals[unescapearg(n)] = unescapearg(v)
177 func, spec = commands[op]
178 func, spec = commands[op]
178
179
179 # Validate that client has permissions to perform this command.
180 # Validate that client has permissions to perform this command.
180 perm = commands[op].permission
181 perm = commands[op].permission
181 assert perm in ('push', 'pull')
182 assert perm in ('push', 'pull')
182 proto.checkperm(perm)
183 proto.checkperm(perm)
183
184
184 if spec:
185 if spec:
185 keys = spec.split()
186 keys = spec.split()
186 data = {}
187 data = {}
187 for k in keys:
188 for k in keys:
188 if k == '*':
189 if k == '*':
189 star = {}
190 star = {}
190 for key in vals.keys():
191 for key in vals.keys():
191 if key not in keys:
192 if key not in keys:
192 star[key] = vals[key]
193 star[key] = vals[key]
193 data['*'] = star
194 data['*'] = star
194 else:
195 else:
195 data[k] = vals[k]
196 data[k] = vals[k]
196 result = func(repo, proto, *[data[k] for k in keys])
197 result = func(repo, proto, *[data[k] for k in keys])
197 else:
198 else:
198 result = func(repo, proto)
199 result = func(repo, proto)
199 if isinstance(result, wireprototypes.ooberror):
200 if isinstance(result, wireprototypes.ooberror):
200 return result
201 return result
201
202
202 # For now, all batchable commands must return bytesresponse or
203 # For now, all batchable commands must return bytesresponse or
203 # raw bytes (for backwards compatibility).
204 # raw bytes (for backwards compatibility).
204 assert isinstance(result, (wireprototypes.bytesresponse, bytes))
205 assert isinstance(result, (wireprototypes.bytesresponse, bytes))
205 if isinstance(result, wireprototypes.bytesresponse):
206 if isinstance(result, wireprototypes.bytesresponse):
206 result = result.data
207 result = result.data
207 res.append(wireprototypes.escapebatcharg(result))
208 res.append(wireprototypes.escapebatcharg(result))
208
209
209 return wireprototypes.bytesresponse(';'.join(res))
210 return wireprototypes.bytesresponse(';'.join(res))
210
211
211 @wireprotocommand('between', 'pairs', permission='pull')
212 @wireprotocommand('between', 'pairs', permission='pull')
212 def between(repo, proto, pairs):
213 def between(repo, proto, pairs):
213 pairs = [wireprototypes.decodelist(p, '-') for p in pairs.split(" ")]
214 pairs = [wireprototypes.decodelist(p, '-') for p in pairs.split(" ")]
214 r = []
215 r = []
215 for b in repo.between(pairs):
216 for b in repo.between(pairs):
216 r.append(wireprototypes.encodelist(b) + "\n")
217 r.append(wireprototypes.encodelist(b) + "\n")
217
218
218 return wireprototypes.bytesresponse(''.join(r))
219 return wireprototypes.bytesresponse(''.join(r))
219
220
220 @wireprotocommand('branchmap', permission='pull')
221 @wireprotocommand('branchmap', permission='pull')
221 def branchmap(repo, proto):
222 def branchmap(repo, proto):
222 branchmap = repo.branchmap()
223 branchmap = repo.branchmap()
223 heads = []
224 heads = []
224 for branch, nodes in branchmap.iteritems():
225 for branch, nodes in branchmap.iteritems():
225 branchname = urlreq.quote(encoding.fromlocal(branch))
226 branchname = urlreq.quote(encoding.fromlocal(branch))
226 branchnodes = wireprototypes.encodelist(nodes)
227 branchnodes = wireprototypes.encodelist(nodes)
227 heads.append('%s %s' % (branchname, branchnodes))
228 heads.append('%s %s' % (branchname, branchnodes))
228
229
229 return wireprototypes.bytesresponse('\n'.join(heads))
230 return wireprototypes.bytesresponse('\n'.join(heads))
230
231
231 @wireprotocommand('branches', 'nodes', permission='pull')
232 @wireprotocommand('branches', 'nodes', permission='pull')
232 def branches(repo, proto, nodes):
233 def branches(repo, proto, nodes):
233 nodes = wireprototypes.decodelist(nodes)
234 nodes = wireprototypes.decodelist(nodes)
234 r = []
235 r = []
235 for b in repo.branches(nodes):
236 for b in repo.branches(nodes):
236 r.append(wireprototypes.encodelist(b) + "\n")
237 r.append(wireprototypes.encodelist(b) + "\n")
237
238
238 return wireprototypes.bytesresponse(''.join(r))
239 return wireprototypes.bytesresponse(''.join(r))
239
240
240 @wireprotocommand('clonebundles', '', permission='pull')
241 @wireprotocommand('clonebundles', '', permission='pull')
241 def clonebundles(repo, proto):
242 def clonebundles(repo, proto):
242 """Server command for returning info for available bundles to seed clones.
243 """Server command for returning info for available bundles to seed clones.
243
244
244 Clients will parse this response and determine what bundle to fetch.
245 Clients will parse this response and determine what bundle to fetch.
245
246
246 Extensions may wrap this command to filter or dynamically emit data
247 Extensions may wrap this command to filter or dynamically emit data
247 depending on the request. e.g. you could advertise URLs for the closest
248 depending on the request. e.g. you could advertise URLs for the closest
248 data center given the client's IP address.
249 data center given the client's IP address.
249 """
250 """
250 return wireprototypes.bytesresponse(
251 return wireprototypes.bytesresponse(
251 repo.vfs.tryread('clonebundles.manifest'))
252 repo.vfs.tryread('clonebundles.manifest'))
252
253
253 wireprotocaps = ['lookup', 'branchmap', 'pushkey',
254 wireprotocaps = ['lookup', 'branchmap', 'pushkey',
254 'known', 'getbundle', 'unbundlehash']
255 'known', 'getbundle', 'unbundlehash']
255
256
256 def _capabilities(repo, proto):
257 def _capabilities(repo, proto):
257 """return a list of capabilities for a repo
258 """return a list of capabilities for a repo
258
259
259 This function exists to allow extensions to easily wrap capabilities
260 This function exists to allow extensions to easily wrap capabilities
260 computation
261 computation
261
262
262 - returns a lists: easy to alter
263 - returns a lists: easy to alter
263 - change done here will be propagated to both `capabilities` and `hello`
264 - change done here will be propagated to both `capabilities` and `hello`
264 command without any other action needed.
265 command without any other action needed.
265 """
266 """
266 # copy to prevent modification of the global list
267 # copy to prevent modification of the global list
267 caps = list(wireprotocaps)
268 caps = list(wireprotocaps)
268
269
269 # Command of same name as capability isn't exposed to version 1 of
270 # Command of same name as capability isn't exposed to version 1 of
270 # transports. So conditionally add it.
271 # transports. So conditionally add it.
271 if commands.commandavailable('changegroupsubset', proto):
272 if commands.commandavailable('changegroupsubset', proto):
272 caps.append('changegroupsubset')
273 caps.append('changegroupsubset')
273
274
274 if streamclone.allowservergeneration(repo):
275 if streamclone.allowservergeneration(repo):
275 if repo.ui.configbool('server', 'preferuncompressed'):
276 if repo.ui.configbool('server', 'preferuncompressed'):
276 caps.append('stream-preferred')
277 caps.append('stream-preferred')
277 requiredformats = repo.requirements & repo.supportedformats
278 requiredformats = repo.requirements & repo.supportedformats
278 # if our local revlogs are just revlogv1, add 'stream' cap
279 # if our local revlogs are just revlogv1, add 'stream' cap
279 if not requiredformats - {'revlogv1'}:
280 if not requiredformats - {'revlogv1'}:
280 caps.append('stream')
281 caps.append('stream')
281 # otherwise, add 'streamreqs' detailing our local revlog format
282 # otherwise, add 'streamreqs' detailing our local revlog format
282 else:
283 else:
283 caps.append('streamreqs=%s' % ','.join(sorted(requiredformats)))
284 caps.append('streamreqs=%s' % ','.join(sorted(requiredformats)))
284 if repo.ui.configbool('experimental', 'bundle2-advertise'):
285 if repo.ui.configbool('experimental', 'bundle2-advertise'):
285 capsblob = bundle2.encodecaps(bundle2.getrepocaps(repo, role='server'))
286 capsblob = bundle2.encodecaps(bundle2.getrepocaps(repo, role='server'))
286 caps.append('bundle2=' + urlreq.quote(capsblob))
287 caps.append('bundle2=' + urlreq.quote(capsblob))
287 caps.append('unbundle=%s' % ','.join(bundle2.bundlepriority))
288 caps.append('unbundle=%s' % ','.join(bundle2.bundlepriority))
288
289
289 if repo.ui.configbool('experimental', 'narrow'):
290 if repo.ui.configbool('experimental', 'narrow'):
290 caps.append(wireprototypes.NARROWCAP)
291 caps.append(wireprototypes.NARROWCAP)
291 if repo.ui.configbool('experimental', 'narrowservebrokenellipses'):
292 if repo.ui.configbool('experimental', 'narrowservebrokenellipses'):
292 caps.append(wireprototypes.ELLIPSESCAP)
293 caps.append(wireprototypes.ELLIPSESCAP)
293
294
294 return proto.addcapabilities(repo, caps)
295 return proto.addcapabilities(repo, caps)
295
296
296 # If you are writing an extension and consider wrapping this function. Wrap
297 # If you are writing an extension and consider wrapping this function. Wrap
297 # `_capabilities` instead.
298 # `_capabilities` instead.
298 @wireprotocommand('capabilities', permission='pull')
299 @wireprotocommand('capabilities', permission='pull')
299 def capabilities(repo, proto):
300 def capabilities(repo, proto):
300 caps = _capabilities(repo, proto)
301 caps = _capabilities(repo, proto)
301 return wireprototypes.bytesresponse(' '.join(sorted(caps)))
302 return wireprototypes.bytesresponse(' '.join(sorted(caps)))
302
303
303 @wireprotocommand('changegroup', 'roots', permission='pull')
304 @wireprotocommand('changegroup', 'roots', permission='pull')
304 def changegroup(repo, proto, roots):
305 def changegroup(repo, proto, roots):
305 nodes = wireprototypes.decodelist(roots)
306 nodes = wireprototypes.decodelist(roots)
306 outgoing = discovery.outgoing(repo, missingroots=nodes,
307 outgoing = discovery.outgoing(repo, missingroots=nodes,
307 missingheads=repo.heads())
308 missingheads=repo.heads())
308 cg = changegroupmod.makechangegroup(repo, outgoing, '01', 'serve')
309 cg = changegroupmod.makechangegroup(repo, outgoing, '01', 'serve')
309 gen = iter(lambda: cg.read(32768), '')
310 gen = iter(lambda: cg.read(32768), '')
310 return wireprototypes.streamres(gen=gen)
311 return wireprototypes.streamres(gen=gen)
311
312
312 @wireprotocommand('changegroupsubset', 'bases heads',
313 @wireprotocommand('changegroupsubset', 'bases heads',
313 permission='pull')
314 permission='pull')
314 def changegroupsubset(repo, proto, bases, heads):
315 def changegroupsubset(repo, proto, bases, heads):
315 bases = wireprototypes.decodelist(bases)
316 bases = wireprototypes.decodelist(bases)
316 heads = wireprototypes.decodelist(heads)
317 heads = wireprototypes.decodelist(heads)
317 outgoing = discovery.outgoing(repo, missingroots=bases,
318 outgoing = discovery.outgoing(repo, missingroots=bases,
318 missingheads=heads)
319 missingheads=heads)
319 cg = changegroupmod.makechangegroup(repo, outgoing, '01', 'serve')
320 cg = changegroupmod.makechangegroup(repo, outgoing, '01', 'serve')
320 gen = iter(lambda: cg.read(32768), '')
321 gen = iter(lambda: cg.read(32768), '')
321 return wireprototypes.streamres(gen=gen)
322 return wireprototypes.streamres(gen=gen)
322
323
323 @wireprotocommand('debugwireargs', 'one two *',
324 @wireprotocommand('debugwireargs', 'one two *',
324 permission='pull')
325 permission='pull')
325 def debugwireargs(repo, proto, one, two, others):
326 def debugwireargs(repo, proto, one, two, others):
326 # only accept optional args from the known set
327 # only accept optional args from the known set
327 opts = options('debugwireargs', ['three', 'four'], others)
328 opts = options('debugwireargs', ['three', 'four'], others)
328 return wireprototypes.bytesresponse(repo.debugwireargs(
329 return wireprototypes.bytesresponse(repo.debugwireargs(
329 one, two, **pycompat.strkwargs(opts)))
330 one, two, **pycompat.strkwargs(opts)))
330
331
331 def find_pullbundle(repo, proto, opts, clheads, heads, common):
332 def find_pullbundle(repo, proto, opts, clheads, heads, common):
332 """Return a file object for the first matching pullbundle.
333 """Return a file object for the first matching pullbundle.
333
334
334 Pullbundles are specified in .hg/pullbundles.manifest similar to
335 Pullbundles are specified in .hg/pullbundles.manifest similar to
335 clonebundles.
336 clonebundles.
336 For each entry, the bundle specification is checked for compatibility:
337 For each entry, the bundle specification is checked for compatibility:
337 - Client features vs the BUNDLESPEC.
338 - Client features vs the BUNDLESPEC.
338 - Revisions shared with the clients vs base revisions of the bundle.
339 - Revisions shared with the clients vs base revisions of the bundle.
339 A bundle can be applied only if all its base revisions are known by
340 A bundle can be applied only if all its base revisions are known by
340 the client.
341 the client.
341 - At least one leaf of the bundle's DAG is missing on the client.
342 - At least one leaf of the bundle's DAG is missing on the client.
342 - Every leaf of the bundle's DAG is part of node set the client wants.
343 - Every leaf of the bundle's DAG is part of node set the client wants.
343 E.g. do not send a bundle of all changes if the client wants only
344 E.g. do not send a bundle of all changes if the client wants only
344 one specific branch of many.
345 one specific branch of many.
345 """
346 """
346 def decodehexstring(s):
347 def decodehexstring(s):
347 return set([h.decode('hex') for h in s.split(';')])
348 return set([binascii.unhexlify(h) for h in s.split(';')])
348
349
349 manifest = repo.vfs.tryread('pullbundles.manifest')
350 manifest = repo.vfs.tryread('pullbundles.manifest')
350 if not manifest:
351 if not manifest:
351 return None
352 return None
352 res = exchange.parseclonebundlesmanifest(repo, manifest)
353 res = exchange.parseclonebundlesmanifest(repo, manifest)
353 res = exchange.filterclonebundleentries(repo, res)
354 res = exchange.filterclonebundleentries(repo, res)
354 if not res:
355 if not res:
355 return None
356 return None
356 cl = repo.changelog
357 cl = repo.changelog
357 heads_anc = cl.ancestors([cl.rev(rev) for rev in heads], inclusive=True)
358 heads_anc = cl.ancestors([cl.rev(rev) for rev in heads], inclusive=True)
358 common_anc = cl.ancestors([cl.rev(rev) for rev in common], inclusive=True)
359 common_anc = cl.ancestors([cl.rev(rev) for rev in common], inclusive=True)
359 compformats = clientcompressionsupport(proto)
360 compformats = clientcompressionsupport(proto)
360 for entry in res:
361 for entry in res:
361 comp = entry.get('COMPRESSION')
362 comp = entry.get('COMPRESSION')
362 altcomp = util.compengines._bundlenames.get(comp)
363 altcomp = util.compengines._bundlenames.get(comp)
363 if comp and comp not in compformats and altcomp not in compformats:
364 if comp and comp not in compformats and altcomp not in compformats:
364 continue
365 continue
365 # No test yet for VERSION, since V2 is supported by any client
366 # No test yet for VERSION, since V2 is supported by any client
366 # that advertises partial pulls
367 # that advertises partial pulls
367 if 'heads' in entry:
368 if 'heads' in entry:
368 try:
369 try:
369 bundle_heads = decodehexstring(entry['heads'])
370 bundle_heads = decodehexstring(entry['heads'])
370 except TypeError:
371 except TypeError:
371 # Bad heads entry
372 # Bad heads entry
372 continue
373 continue
373 if bundle_heads.issubset(common):
374 if bundle_heads.issubset(common):
374 continue # Nothing new
375 continue # Nothing new
375 if all(cl.rev(rev) in common_anc for rev in bundle_heads):
376 if all(cl.rev(rev) in common_anc for rev in bundle_heads):
376 continue # Still nothing new
377 continue # Still nothing new
377 if any(cl.rev(rev) not in heads_anc and
378 if any(cl.rev(rev) not in heads_anc and
378 cl.rev(rev) not in common_anc for rev in bundle_heads):
379 cl.rev(rev) not in common_anc for rev in bundle_heads):
379 continue
380 continue
380 if 'bases' in entry:
381 if 'bases' in entry:
381 try:
382 try:
382 bundle_bases = decodehexstring(entry['bases'])
383 bundle_bases = decodehexstring(entry['bases'])
383 except TypeError:
384 except TypeError:
384 # Bad bases entry
385 # Bad bases entry
385 continue
386 continue
386 if not all(cl.rev(rev) in common_anc for rev in bundle_bases):
387 if not all(cl.rev(rev) in common_anc for rev in bundle_bases):
387 continue
388 continue
388 path = entry['URL']
389 path = entry['URL']
389 repo.ui.debug('sending pullbundle "%s"\n' % path)
390 repo.ui.debug('sending pullbundle "%s"\n' % path)
390 try:
391 try:
391 return repo.vfs.open(path)
392 return repo.vfs.open(path)
392 except IOError:
393 except IOError:
393 repo.ui.debug('pullbundle "%s" not accessible\n' % path)
394 repo.ui.debug('pullbundle "%s" not accessible\n' % path)
394 continue
395 continue
395 return None
396 return None
396
397
397 @wireprotocommand('getbundle', '*', permission='pull')
398 @wireprotocommand('getbundle', '*', permission='pull')
398 def getbundle(repo, proto, others):
399 def getbundle(repo, proto, others):
399 opts = options('getbundle', wireprototypes.GETBUNDLE_ARGUMENTS.keys(),
400 opts = options('getbundle', wireprototypes.GETBUNDLE_ARGUMENTS.keys(),
400 others)
401 others)
401 for k, v in opts.iteritems():
402 for k, v in opts.iteritems():
402 keytype = wireprototypes.GETBUNDLE_ARGUMENTS[k]
403 keytype = wireprototypes.GETBUNDLE_ARGUMENTS[k]
403 if keytype == 'nodes':
404 if keytype == 'nodes':
404 opts[k] = wireprototypes.decodelist(v)
405 opts[k] = wireprototypes.decodelist(v)
405 elif keytype == 'csv':
406 elif keytype == 'csv':
406 opts[k] = list(v.split(','))
407 opts[k] = list(v.split(','))
407 elif keytype == 'scsv':
408 elif keytype == 'scsv':
408 opts[k] = set(v.split(','))
409 opts[k] = set(v.split(','))
409 elif keytype == 'boolean':
410 elif keytype == 'boolean':
410 # Client should serialize False as '0', which is a non-empty string
411 # Client should serialize False as '0', which is a non-empty string
411 # so it evaluates as a True bool.
412 # so it evaluates as a True bool.
412 if v == '0':
413 if v == '0':
413 opts[k] = False
414 opts[k] = False
414 else:
415 else:
415 opts[k] = bool(v)
416 opts[k] = bool(v)
416 elif keytype != 'plain':
417 elif keytype != 'plain':
417 raise KeyError('unknown getbundle option type %s'
418 raise KeyError('unknown getbundle option type %s'
418 % keytype)
419 % keytype)
419
420
420 if not bundle1allowed(repo, 'pull'):
421 if not bundle1allowed(repo, 'pull'):
421 if not exchange.bundle2requested(opts.get('bundlecaps')):
422 if not exchange.bundle2requested(opts.get('bundlecaps')):
422 if proto.name == 'http-v1':
423 if proto.name == 'http-v1':
423 return wireprototypes.ooberror(bundle2required)
424 return wireprototypes.ooberror(bundle2required)
424 raise error.Abort(bundle2requiredmain,
425 raise error.Abort(bundle2requiredmain,
425 hint=bundle2requiredhint)
426 hint=bundle2requiredhint)
426
427
427 try:
428 try:
428 clheads = set(repo.changelog.heads())
429 clheads = set(repo.changelog.heads())
429 heads = set(opts.get('heads', set()))
430 heads = set(opts.get('heads', set()))
430 common = set(opts.get('common', set()))
431 common = set(opts.get('common', set()))
431 common.discard(nullid)
432 common.discard(nullid)
432 if (repo.ui.configbool('server', 'pullbundle') and
433 if (repo.ui.configbool('server', 'pullbundle') and
433 'partial-pull' in proto.getprotocaps()):
434 'partial-pull' in proto.getprotocaps()):
434 # Check if a pre-built bundle covers this request.
435 # Check if a pre-built bundle covers this request.
435 bundle = find_pullbundle(repo, proto, opts, clheads, heads, common)
436 bundle = find_pullbundle(repo, proto, opts, clheads, heads, common)
436 if bundle:
437 if bundle:
437 return wireprototypes.streamres(gen=util.filechunkiter(bundle),
438 return wireprototypes.streamres(gen=util.filechunkiter(bundle),
438 prefer_uncompressed=True)
439 prefer_uncompressed=True)
439
440
440 if repo.ui.configbool('server', 'disablefullbundle'):
441 if repo.ui.configbool('server', 'disablefullbundle'):
441 # Check to see if this is a full clone.
442 # Check to see if this is a full clone.
442 changegroup = opts.get('cg', True)
443 changegroup = opts.get('cg', True)
443 if changegroup and not common and clheads == heads:
444 if changegroup and not common and clheads == heads:
444 raise error.Abort(
445 raise error.Abort(
445 _('server has pull-based clones disabled'),
446 _('server has pull-based clones disabled'),
446 hint=_('remove --pull if specified or upgrade Mercurial'))
447 hint=_('remove --pull if specified or upgrade Mercurial'))
447
448
448 info, chunks = exchange.getbundlechunks(repo, 'serve',
449 info, chunks = exchange.getbundlechunks(repo, 'serve',
449 **pycompat.strkwargs(opts))
450 **pycompat.strkwargs(opts))
450 prefercompressed = info.get('prefercompressed', True)
451 prefercompressed = info.get('prefercompressed', True)
451 except error.Abort as exc:
452 except error.Abort as exc:
452 # cleanly forward Abort error to the client
453 # cleanly forward Abort error to the client
453 if not exchange.bundle2requested(opts.get('bundlecaps')):
454 if not exchange.bundle2requested(opts.get('bundlecaps')):
454 if proto.name == 'http-v1':
455 if proto.name == 'http-v1':
455 return wireprototypes.ooberror(pycompat.bytestr(exc) + '\n')
456 return wireprototypes.ooberror(pycompat.bytestr(exc) + '\n')
456 raise # cannot do better for bundle1 + ssh
457 raise # cannot do better for bundle1 + ssh
457 # bundle2 request expect a bundle2 reply
458 # bundle2 request expect a bundle2 reply
458 bundler = bundle2.bundle20(repo.ui)
459 bundler = bundle2.bundle20(repo.ui)
459 manargs = [('message', pycompat.bytestr(exc))]
460 manargs = [('message', pycompat.bytestr(exc))]
460 advargs = []
461 advargs = []
461 if exc.hint is not None:
462 if exc.hint is not None:
462 advargs.append(('hint', exc.hint))
463 advargs.append(('hint', exc.hint))
463 bundler.addpart(bundle2.bundlepart('error:abort',
464 bundler.addpart(bundle2.bundlepart('error:abort',
464 manargs, advargs))
465 manargs, advargs))
465 chunks = bundler.getchunks()
466 chunks = bundler.getchunks()
466 prefercompressed = False
467 prefercompressed = False
467
468
468 return wireprototypes.streamres(
469 return wireprototypes.streamres(
469 gen=chunks, prefer_uncompressed=not prefercompressed)
470 gen=chunks, prefer_uncompressed=not prefercompressed)
470
471
471 @wireprotocommand('heads', permission='pull')
472 @wireprotocommand('heads', permission='pull')
472 def heads(repo, proto):
473 def heads(repo, proto):
473 h = repo.heads()
474 h = repo.heads()
474 return wireprototypes.bytesresponse(wireprototypes.encodelist(h) + '\n')
475 return wireprototypes.bytesresponse(wireprototypes.encodelist(h) + '\n')
475
476
476 @wireprotocommand('hello', permission='pull')
477 @wireprotocommand('hello', permission='pull')
477 def hello(repo, proto):
478 def hello(repo, proto):
478 """Called as part of SSH handshake to obtain server info.
479 """Called as part of SSH handshake to obtain server info.
479
480
480 Returns a list of lines describing interesting things about the
481 Returns a list of lines describing interesting things about the
481 server, in an RFC822-like format.
482 server, in an RFC822-like format.
482
483
483 Currently, the only one defined is ``capabilities``, which consists of a
484 Currently, the only one defined is ``capabilities``, which consists of a
484 line of space separated tokens describing server abilities:
485 line of space separated tokens describing server abilities:
485
486
486 capabilities: <token0> <token1> <token2>
487 capabilities: <token0> <token1> <token2>
487 """
488 """
488 caps = capabilities(repo, proto).data
489 caps = capabilities(repo, proto).data
489 return wireprototypes.bytesresponse('capabilities: %s\n' % caps)
490 return wireprototypes.bytesresponse('capabilities: %s\n' % caps)
490
491
491 @wireprotocommand('listkeys', 'namespace', permission='pull')
492 @wireprotocommand('listkeys', 'namespace', permission='pull')
492 def listkeys(repo, proto, namespace):
493 def listkeys(repo, proto, namespace):
493 d = sorted(repo.listkeys(encoding.tolocal(namespace)).items())
494 d = sorted(repo.listkeys(encoding.tolocal(namespace)).items())
494 return wireprototypes.bytesresponse(pushkeymod.encodekeys(d))
495 return wireprototypes.bytesresponse(pushkeymod.encodekeys(d))
495
496
496 @wireprotocommand('lookup', 'key', permission='pull')
497 @wireprotocommand('lookup', 'key', permission='pull')
497 def lookup(repo, proto, key):
498 def lookup(repo, proto, key):
498 try:
499 try:
499 k = encoding.tolocal(key)
500 k = encoding.tolocal(key)
500 n = repo.lookup(k)
501 n = repo.lookup(k)
501 r = hex(n)
502 r = hex(n)
502 success = 1
503 success = 1
503 except Exception as inst:
504 except Exception as inst:
504 r = stringutil.forcebytestr(inst)
505 r = stringutil.forcebytestr(inst)
505 success = 0
506 success = 0
506 return wireprototypes.bytesresponse('%d %s\n' % (success, r))
507 return wireprototypes.bytesresponse('%d %s\n' % (success, r))
507
508
508 @wireprotocommand('known', 'nodes *', permission='pull')
509 @wireprotocommand('known', 'nodes *', permission='pull')
509 def known(repo, proto, nodes, others):
510 def known(repo, proto, nodes, others):
510 v = ''.join(b and '1' or '0'
511 v = ''.join(b and '1' or '0'
511 for b in repo.known(wireprototypes.decodelist(nodes)))
512 for b in repo.known(wireprototypes.decodelist(nodes)))
512 return wireprototypes.bytesresponse(v)
513 return wireprototypes.bytesresponse(v)
513
514
514 @wireprotocommand('protocaps', 'caps', permission='pull')
515 @wireprotocommand('protocaps', 'caps', permission='pull')
515 def protocaps(repo, proto, caps):
516 def protocaps(repo, proto, caps):
516 if proto.name == wireprototypes.SSHV1:
517 if proto.name == wireprototypes.SSHV1:
517 proto._protocaps = set(caps.split(' '))
518 proto._protocaps = set(caps.split(' '))
518 return wireprototypes.bytesresponse('OK')
519 return wireprototypes.bytesresponse('OK')
519
520
520 @wireprotocommand('pushkey', 'namespace key old new', permission='push')
521 @wireprotocommand('pushkey', 'namespace key old new', permission='push')
521 def pushkey(repo, proto, namespace, key, old, new):
522 def pushkey(repo, proto, namespace, key, old, new):
522 # compatibility with pre-1.8 clients which were accidentally
523 # compatibility with pre-1.8 clients which were accidentally
523 # sending raw binary nodes rather than utf-8-encoded hex
524 # sending raw binary nodes rather than utf-8-encoded hex
524 if len(new) == 20 and stringutil.escapestr(new) != new:
525 if len(new) == 20 and stringutil.escapestr(new) != new:
525 # looks like it could be a binary node
526 # looks like it could be a binary node
526 try:
527 try:
527 new.decode('utf-8')
528 new.decode('utf-8')
528 new = encoding.tolocal(new) # but cleanly decodes as UTF-8
529 new = encoding.tolocal(new) # but cleanly decodes as UTF-8
529 except UnicodeDecodeError:
530 except UnicodeDecodeError:
530 pass # binary, leave unmodified
531 pass # binary, leave unmodified
531 else:
532 else:
532 new = encoding.tolocal(new) # normal path
533 new = encoding.tolocal(new) # normal path
533
534
534 with proto.mayberedirectstdio() as output:
535 with proto.mayberedirectstdio() as output:
535 r = repo.pushkey(encoding.tolocal(namespace), encoding.tolocal(key),
536 r = repo.pushkey(encoding.tolocal(namespace), encoding.tolocal(key),
536 encoding.tolocal(old), new) or False
537 encoding.tolocal(old), new) or False
537
538
538 output = output.getvalue() if output else ''
539 output = output.getvalue() if output else ''
539 return wireprototypes.bytesresponse('%d\n%s' % (int(r), output))
540 return wireprototypes.bytesresponse('%d\n%s' % (int(r), output))
540
541
541 @wireprotocommand('stream_out', permission='pull')
542 @wireprotocommand('stream_out', permission='pull')
542 def stream(repo, proto):
543 def stream(repo, proto):
543 '''If the server supports streaming clone, it advertises the "stream"
544 '''If the server supports streaming clone, it advertises the "stream"
544 capability with a value representing the version and flags of the repo
545 capability with a value representing the version and flags of the repo
545 it is serving. Client checks to see if it understands the format.
546 it is serving. Client checks to see if it understands the format.
546 '''
547 '''
547 return wireprototypes.streamreslegacy(
548 return wireprototypes.streamreslegacy(
548 streamclone.generatev1wireproto(repo))
549 streamclone.generatev1wireproto(repo))
549
550
550 @wireprotocommand('unbundle', 'heads', permission='push')
551 @wireprotocommand('unbundle', 'heads', permission='push')
551 def unbundle(repo, proto, heads):
552 def unbundle(repo, proto, heads):
552 their_heads = wireprototypes.decodelist(heads)
553 their_heads = wireprototypes.decodelist(heads)
553
554
554 with proto.mayberedirectstdio() as output:
555 with proto.mayberedirectstdio() as output:
555 try:
556 try:
556 exchange.check_heads(repo, their_heads, 'preparing changes')
557 exchange.check_heads(repo, their_heads, 'preparing changes')
557 cleanup = lambda: None
558 cleanup = lambda: None
558 try:
559 try:
559 payload = proto.getpayload()
560 payload = proto.getpayload()
560 if repo.ui.configbool('server', 'streamunbundle'):
561 if repo.ui.configbool('server', 'streamunbundle'):
561 def cleanup():
562 def cleanup():
562 # Ensure that the full payload is consumed, so
563 # Ensure that the full payload is consumed, so
563 # that the connection doesn't contain trailing garbage.
564 # that the connection doesn't contain trailing garbage.
564 for p in payload:
565 for p in payload:
565 pass
566 pass
566 fp = util.chunkbuffer(payload)
567 fp = util.chunkbuffer(payload)
567 else:
568 else:
568 # write bundle data to temporary file as it can be big
569 # write bundle data to temporary file as it can be big
569 fp, tempname = None, None
570 fp, tempname = None, None
570 def cleanup():
571 def cleanup():
571 if fp:
572 if fp:
572 fp.close()
573 fp.close()
573 if tempname:
574 if tempname:
574 os.unlink(tempname)
575 os.unlink(tempname)
575 fd, tempname = pycompat.mkstemp(prefix='hg-unbundle-')
576 fd, tempname = pycompat.mkstemp(prefix='hg-unbundle-')
576 repo.ui.debug('redirecting incoming bundle to %s\n' %
577 repo.ui.debug('redirecting incoming bundle to %s\n' %
577 tempname)
578 tempname)
578 fp = os.fdopen(fd, pycompat.sysstr('wb+'))
579 fp = os.fdopen(fd, pycompat.sysstr('wb+'))
579 for p in payload:
580 for p in payload:
580 fp.write(p)
581 fp.write(p)
581 fp.seek(0)
582 fp.seek(0)
582
583
583 gen = exchange.readbundle(repo.ui, fp, None)
584 gen = exchange.readbundle(repo.ui, fp, None)
584 if (isinstance(gen, changegroupmod.cg1unpacker)
585 if (isinstance(gen, changegroupmod.cg1unpacker)
585 and not bundle1allowed(repo, 'push')):
586 and not bundle1allowed(repo, 'push')):
586 if proto.name == 'http-v1':
587 if proto.name == 'http-v1':
587 # need to special case http because stderr do not get to
588 # need to special case http because stderr do not get to
588 # the http client on failed push so we need to abuse
589 # the http client on failed push so we need to abuse
589 # some other error type to make sure the message get to
590 # some other error type to make sure the message get to
590 # the user.
591 # the user.
591 return wireprototypes.ooberror(bundle2required)
592 return wireprototypes.ooberror(bundle2required)
592 raise error.Abort(bundle2requiredmain,
593 raise error.Abort(bundle2requiredmain,
593 hint=bundle2requiredhint)
594 hint=bundle2requiredhint)
594
595
595 r = exchange.unbundle(repo, gen, their_heads, 'serve',
596 r = exchange.unbundle(repo, gen, their_heads, 'serve',
596 proto.client())
597 proto.client())
597 if util.safehasattr(r, 'addpart'):
598 if util.safehasattr(r, 'addpart'):
598 # The return looks streamable, we are in the bundle2 case
599 # The return looks streamable, we are in the bundle2 case
599 # and should return a stream.
600 # and should return a stream.
600 return wireprototypes.streamreslegacy(gen=r.getchunks())
601 return wireprototypes.streamreslegacy(gen=r.getchunks())
601 return wireprototypes.pushres(
602 return wireprototypes.pushres(
602 r, output.getvalue() if output else '')
603 r, output.getvalue() if output else '')
603
604
604 finally:
605 finally:
605 cleanup()
606 cleanup()
606
607
607 except (error.BundleValueError, error.Abort, error.PushRaced) as exc:
608 except (error.BundleValueError, error.Abort, error.PushRaced) as exc:
608 # handle non-bundle2 case first
609 # handle non-bundle2 case first
609 if not getattr(exc, 'duringunbundle2', False):
610 if not getattr(exc, 'duringunbundle2', False):
610 try:
611 try:
611 raise
612 raise
612 except error.Abort:
613 except error.Abort:
613 # The old code we moved used procutil.stderr directly.
614 # The old code we moved used procutil.stderr directly.
614 # We did not change it to minimise code change.
615 # We did not change it to minimise code change.
615 # This need to be moved to something proper.
616 # This need to be moved to something proper.
616 # Feel free to do it.
617 # Feel free to do it.
617 procutil.stderr.write("abort: %s\n" % exc)
618 procutil.stderr.write("abort: %s\n" % exc)
618 if exc.hint is not None:
619 if exc.hint is not None:
619 procutil.stderr.write("(%s)\n" % exc.hint)
620 procutil.stderr.write("(%s)\n" % exc.hint)
620 procutil.stderr.flush()
621 procutil.stderr.flush()
621 return wireprototypes.pushres(
622 return wireprototypes.pushres(
622 0, output.getvalue() if output else '')
623 0, output.getvalue() if output else '')
623 except error.PushRaced:
624 except error.PushRaced:
624 return wireprototypes.pusherr(
625 return wireprototypes.pusherr(
625 pycompat.bytestr(exc),
626 pycompat.bytestr(exc),
626 output.getvalue() if output else '')
627 output.getvalue() if output else '')
627
628
628 bundler = bundle2.bundle20(repo.ui)
629 bundler = bundle2.bundle20(repo.ui)
629 for out in getattr(exc, '_bundle2salvagedoutput', ()):
630 for out in getattr(exc, '_bundle2salvagedoutput', ()):
630 bundler.addpart(out)
631 bundler.addpart(out)
631 try:
632 try:
632 try:
633 try:
633 raise
634 raise
634 except error.PushkeyFailed as exc:
635 except error.PushkeyFailed as exc:
635 # check client caps
636 # check client caps
636 remotecaps = getattr(exc, '_replycaps', None)
637 remotecaps = getattr(exc, '_replycaps', None)
637 if (remotecaps is not None
638 if (remotecaps is not None
638 and 'pushkey' not in remotecaps.get('error', ())):
639 and 'pushkey' not in remotecaps.get('error', ())):
639 # no support remote side, fallback to Abort handler.
640 # no support remote side, fallback to Abort handler.
640 raise
641 raise
641 part = bundler.newpart('error:pushkey')
642 part = bundler.newpart('error:pushkey')
642 part.addparam('in-reply-to', exc.partid)
643 part.addparam('in-reply-to', exc.partid)
643 if exc.namespace is not None:
644 if exc.namespace is not None:
644 part.addparam('namespace', exc.namespace,
645 part.addparam('namespace', exc.namespace,
645 mandatory=False)
646 mandatory=False)
646 if exc.key is not None:
647 if exc.key is not None:
647 part.addparam('key', exc.key, mandatory=False)
648 part.addparam('key', exc.key, mandatory=False)
648 if exc.new is not None:
649 if exc.new is not None:
649 part.addparam('new', exc.new, mandatory=False)
650 part.addparam('new', exc.new, mandatory=False)
650 if exc.old is not None:
651 if exc.old is not None:
651 part.addparam('old', exc.old, mandatory=False)
652 part.addparam('old', exc.old, mandatory=False)
652 if exc.ret is not None:
653 if exc.ret is not None:
653 part.addparam('ret', exc.ret, mandatory=False)
654 part.addparam('ret', exc.ret, mandatory=False)
654 except error.BundleValueError as exc:
655 except error.BundleValueError as exc:
655 errpart = bundler.newpart('error:unsupportedcontent')
656 errpart = bundler.newpart('error:unsupportedcontent')
656 if exc.parttype is not None:
657 if exc.parttype is not None:
657 errpart.addparam('parttype', exc.parttype)
658 errpart.addparam('parttype', exc.parttype)
658 if exc.params:
659 if exc.params:
659 errpart.addparam('params', '\0'.join(exc.params))
660 errpart.addparam('params', '\0'.join(exc.params))
660 except error.Abort as exc:
661 except error.Abort as exc:
661 manargs = [('message', stringutil.forcebytestr(exc))]
662 manargs = [('message', stringutil.forcebytestr(exc))]
662 advargs = []
663 advargs = []
663 if exc.hint is not None:
664 if exc.hint is not None:
664 advargs.append(('hint', exc.hint))
665 advargs.append(('hint', exc.hint))
665 bundler.addpart(bundle2.bundlepart('error:abort',
666 bundler.addpart(bundle2.bundlepart('error:abort',
666 manargs, advargs))
667 manargs, advargs))
667 except error.PushRaced as exc:
668 except error.PushRaced as exc:
668 bundler.newpart('error:pushraced',
669 bundler.newpart('error:pushraced',
669 [('message', stringutil.forcebytestr(exc))])
670 [('message', stringutil.forcebytestr(exc))])
670 return wireprototypes.streamreslegacy(gen=bundler.getchunks())
671 return wireprototypes.streamreslegacy(gen=bundler.getchunks())
General Comments 0
You need to be logged in to leave comments. Login now