##// END OF EJS Templates
py3: fix test-remotefilelog-repack.t...
Augie Fackler -
r41642:13dad5cb default
parent child Browse files
Show More
@@ -1,751 +1,752 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-git.t
119 test-convert-git.t
120 test-convert-hg-sink.t
120 test-convert-hg-sink.t
121 test-convert-hg-source.t
121 test-convert-hg-source.t
122 test-convert-hg-startrev.t
122 test-convert-hg-startrev.t
123 test-convert-splicemap.t
123 test-convert-splicemap.t
124 test-convert-svn-sink.t
124 test-convert-svn-sink.t
125 test-convert-tagsbranch-topology.t
125 test-convert-tagsbranch-topology.t
126 test-convert.t
126 test-convert.t
127 test-copy-move-merge.t
127 test-copy-move-merge.t
128 test-copy.t
128 test-copy.t
129 test-copytrace-heuristics.t
129 test-copytrace-heuristics.t
130 test-custom-filters.t
130 test-custom-filters.t
131 test-debugbuilddag.t
131 test-debugbuilddag.t
132 test-debugbundle.t
132 test-debugbundle.t
133 test-debugcommands.t
133 test-debugcommands.t
134 test-debugextensions.t
134 test-debugextensions.t
135 test-debugindexdot.t
135 test-debugindexdot.t
136 test-debugrename.t
136 test-debugrename.t
137 test-default-push.t
137 test-default-push.t
138 test-diff-antipatience.t
138 test-diff-antipatience.t
139 test-diff-binary-file.t
139 test-diff-binary-file.t
140 test-diff-change.t
140 test-diff-change.t
141 test-diff-color.t
141 test-diff-color.t
142 test-diff-copy-depth.t
142 test-diff-copy-depth.t
143 test-diff-hashes.t
143 test-diff-hashes.t
144 test-diff-ignore-whitespace.t
144 test-diff-ignore-whitespace.t
145 test-diff-indent-heuristic.t
145 test-diff-indent-heuristic.t
146 test-diff-issue2761.t
146 test-diff-issue2761.t
147 test-diff-newlines.t
147 test-diff-newlines.t
148 test-diff-reverse.t
148 test-diff-reverse.t
149 test-diff-subdir.t
149 test-diff-subdir.t
150 test-diff-unified.t
150 test-diff-unified.t
151 test-diff-upgrade.t
151 test-diff-upgrade.t
152 test-diffdir.t
152 test-diffdir.t
153 test-diffstat.t
153 test-diffstat.t
154 test-directaccess.t
154 test-directaccess.t
155 test-dirstate-backup.t
155 test-dirstate-backup.t
156 test-dirstate-nonnormalset.t
156 test-dirstate-nonnormalset.t
157 test-dirstate-race.t
157 test-dirstate-race.t
158 test-dirstate.t
158 test-dirstate.t
159 test-dispatch.py
159 test-dispatch.py
160 test-dispatch.t
160 test-dispatch.t
161 test-doctest.py
161 test-doctest.py
162 test-double-merge.t
162 test-double-merge.t
163 test-drawdag.t
163 test-drawdag.t
164 test-duplicateoptions.py
164 test-duplicateoptions.py
165 test-editor-filename.t
165 test-editor-filename.t
166 test-empty-dir.t
166 test-empty-dir.t
167 test-empty-file.t
167 test-empty-file.t
168 test-empty-group.t
168 test-empty-group.t
169 test-empty.t
169 test-empty.t
170 test-encode.t
170 test-encode.t
171 test-encoding-align.t
171 test-encoding-align.t
172 test-encoding-func.py
172 test-encoding-func.py
173 test-encoding-textwrap.t
173 test-encoding-textwrap.t
174 test-encoding.t
174 test-encoding.t
175 test-eol-add.t
175 test-eol-add.t
176 test-eol-clone.t
176 test-eol-clone.t
177 test-eol-hook.t
177 test-eol-hook.t
178 test-eol-patch.t
178 test-eol-patch.t
179 test-eol-tag.t
179 test-eol-tag.t
180 test-eol-update.t
180 test-eol-update.t
181 test-eol.t
181 test-eol.t
182 test-eolfilename.t
182 test-eolfilename.t
183 test-excessive-merge.t
183 test-excessive-merge.t
184 test-exchange-obsmarkers-case-A1.t
184 test-exchange-obsmarkers-case-A1.t
185 test-exchange-obsmarkers-case-A2.t
185 test-exchange-obsmarkers-case-A2.t
186 test-exchange-obsmarkers-case-A3.t
186 test-exchange-obsmarkers-case-A3.t
187 test-exchange-obsmarkers-case-A4.t
187 test-exchange-obsmarkers-case-A4.t
188 test-exchange-obsmarkers-case-A5.t
188 test-exchange-obsmarkers-case-A5.t
189 test-exchange-obsmarkers-case-A6.t
189 test-exchange-obsmarkers-case-A6.t
190 test-exchange-obsmarkers-case-A7.t
190 test-exchange-obsmarkers-case-A7.t
191 test-exchange-obsmarkers-case-B1.t
191 test-exchange-obsmarkers-case-B1.t
192 test-exchange-obsmarkers-case-B2.t
192 test-exchange-obsmarkers-case-B2.t
193 test-exchange-obsmarkers-case-B3.t
193 test-exchange-obsmarkers-case-B3.t
194 test-exchange-obsmarkers-case-B4.t
194 test-exchange-obsmarkers-case-B4.t
195 test-exchange-obsmarkers-case-B5.t
195 test-exchange-obsmarkers-case-B5.t
196 test-exchange-obsmarkers-case-B6.t
196 test-exchange-obsmarkers-case-B6.t
197 test-exchange-obsmarkers-case-B7.t
197 test-exchange-obsmarkers-case-B7.t
198 test-exchange-obsmarkers-case-C1.t
198 test-exchange-obsmarkers-case-C1.t
199 test-exchange-obsmarkers-case-C2.t
199 test-exchange-obsmarkers-case-C2.t
200 test-exchange-obsmarkers-case-C3.t
200 test-exchange-obsmarkers-case-C3.t
201 test-exchange-obsmarkers-case-C4.t
201 test-exchange-obsmarkers-case-C4.t
202 test-exchange-obsmarkers-case-D1.t
202 test-exchange-obsmarkers-case-D1.t
203 test-exchange-obsmarkers-case-D2.t
203 test-exchange-obsmarkers-case-D2.t
204 test-exchange-obsmarkers-case-D3.t
204 test-exchange-obsmarkers-case-D3.t
205 test-exchange-obsmarkers-case-D4.t
205 test-exchange-obsmarkers-case-D4.t
206 test-execute-bit.t
206 test-execute-bit.t
207 test-export.t
207 test-export.t
208 test-extdata.t
208 test-extdata.t
209 test-extdiff.t
209 test-extdiff.t
210 test-extension-timing.t
210 test-extension-timing.t
211 test-extensions-afterloaded.t
211 test-extensions-afterloaded.t
212 test-extensions-wrapfunction.py
212 test-extensions-wrapfunction.py
213 test-extra-filelog-entry.t
213 test-extra-filelog-entry.t
214 test-fastannotate-corrupt.t
214 test-fastannotate-corrupt.t
215 test-fastannotate-diffopts.t
215 test-fastannotate-diffopts.t
216 test-fastannotate-hg.t
216 test-fastannotate-hg.t
217 test-fastannotate-perfhack.t
217 test-fastannotate-perfhack.t
218 test-fastannotate-protocol.t
218 test-fastannotate-protocol.t
219 test-fastannotate-renames.t
219 test-fastannotate-renames.t
220 test-fastannotate-revmap.py
220 test-fastannotate-revmap.py
221 test-fastannotate.t
221 test-fastannotate.t
222 test-fetch.t
222 test-fetch.t
223 test-filebranch.t
223 test-filebranch.t
224 test-filecache.py
224 test-filecache.py
225 test-filelog.py
225 test-filelog.py
226 test-fileset-generated.t
226 test-fileset-generated.t
227 test-fileset.t
227 test-fileset.t
228 test-fix-topology.t
228 test-fix-topology.t
229 test-fix.t
229 test-fix.t
230 test-flags.t
230 test-flags.t
231 test-fncache.t
231 test-fncache.t
232 test-gendoc-da.t
232 test-gendoc-da.t
233 test-gendoc-de.t
233 test-gendoc-de.t
234 test-gendoc-el.t
234 test-gendoc-el.t
235 test-gendoc-fr.t
235 test-gendoc-fr.t
236 test-gendoc-it.t
236 test-gendoc-it.t
237 test-gendoc-ja.t
237 test-gendoc-ja.t
238 test-gendoc-pt_BR.t
238 test-gendoc-pt_BR.t
239 test-gendoc-ro.t
239 test-gendoc-ro.t
240 test-gendoc-ru.t
240 test-gendoc-ru.t
241 test-gendoc-sv.t
241 test-gendoc-sv.t
242 test-gendoc-zh_CN.t
242 test-gendoc-zh_CN.t
243 test-gendoc-zh_TW.t
243 test-gendoc-zh_TW.t
244 test-gendoc.t
244 test-gendoc.t
245 test-generaldelta.t
245 test-generaldelta.t
246 test-getbundle.t
246 test-getbundle.t
247 test-git-export.t
247 test-git-export.t
248 test-githelp.t
248 test-githelp.t
249 test-globalopts.t
249 test-globalopts.t
250 test-glog-beautifygraph.t
250 test-glog-beautifygraph.t
251 test-glog-topological.t
251 test-glog-topological.t
252 test-glog.t
252 test-glog.t
253 test-gpg.t
253 test-gpg.t
254 test-graft.t
254 test-graft.t
255 test-grep.t
255 test-grep.t
256 test-hardlinks.t
256 test-hardlinks.t
257 test-help-hide.t
257 test-help-hide.t
258 test-help.t
258 test-help.t
259 test-hg-parseurl.py
259 test-hg-parseurl.py
260 test-hghave.t
260 test-hghave.t
261 test-hgignore.t
261 test-hgignore.t
262 test-hgk.t
262 test-hgk.t
263 test-hgrc.t
263 test-hgrc.t
264 test-hgweb-annotate-whitespace.t
264 test-hgweb-annotate-whitespace.t
265 test-hgweb-auth.py
265 test-hgweb-auth.py
266 test-hgweb-bundle.t
266 test-hgweb-bundle.t
267 test-hgweb-commands.t
267 test-hgweb-commands.t
268 test-hgweb-csp.t
268 test-hgweb-csp.t
269 test-hgweb-descend-empties.t
269 test-hgweb-descend-empties.t
270 test-hgweb-diffs.t
270 test-hgweb-diffs.t
271 test-hgweb-empty.t
271 test-hgweb-empty.t
272 test-hgweb-filelog.t
272 test-hgweb-filelog.t
273 test-hgweb-no-path-info.t
273 test-hgweb-no-path-info.t
274 test-hgweb-no-request-uri.t
274 test-hgweb-no-request-uri.t
275 test-hgweb-non-interactive.t
275 test-hgweb-non-interactive.t
276 test-hgweb-raw.t
276 test-hgweb-raw.t
277 test-hgweb-removed.t
277 test-hgweb-removed.t
278 test-hgweb-symrev.t
278 test-hgweb-symrev.t
279 test-hgweb.t
279 test-hgweb.t
280 test-hgwebdir-paths.py
280 test-hgwebdir-paths.py
281 test-hgwebdir.t
281 test-hgwebdir.t
282 test-hgwebdirsym.t
282 test-hgwebdirsym.t
283 test-histedit-arguments.t
283 test-histedit-arguments.t
284 test-histedit-base.t
284 test-histedit-base.t
285 test-histedit-bookmark-motion.t
285 test-histedit-bookmark-motion.t
286 test-histedit-commute.t
286 test-histedit-commute.t
287 test-histedit-drop.t
287 test-histedit-drop.t
288 test-histedit-edit.t
288 test-histedit-edit.t
289 test-histedit-fold-non-commute.t
289 test-histedit-fold-non-commute.t
290 test-histedit-fold.t
290 test-histedit-fold.t
291 test-histedit-no-backup.t
291 test-histedit-no-backup.t
292 test-histedit-no-change.t
292 test-histedit-no-change.t
293 test-histedit-non-commute-abort.t
293 test-histedit-non-commute-abort.t
294 test-histedit-non-commute.t
294 test-histedit-non-commute.t
295 test-histedit-obsolete.t
295 test-histedit-obsolete.t
296 test-histedit-outgoing.t
296 test-histedit-outgoing.t
297 test-histedit-templates.t
297 test-histedit-templates.t
298 test-http-api-httpv2.t
298 test-http-api-httpv2.t
299 test-http-api.t
299 test-http-api.t
300 test-http-bad-server.t
300 test-http-bad-server.t
301 test-http-branchmap.t
301 test-http-branchmap.t
302 test-http-bundle1.t
302 test-http-bundle1.t
303 test-http-clone-r.t
303 test-http-clone-r.t
304 test-http-permissions.t
304 test-http-permissions.t
305 test-http-protocol.t
305 test-http-protocol.t
306 test-http.t
306 test-http.t
307 test-hybridencode.py
307 test-hybridencode.py
308 test-i18n.t
308 test-i18n.t
309 test-identify.t
309 test-identify.t
310 test-impexp-branch.t
310 test-impexp-branch.t
311 test-import-bypass.t
311 test-import-bypass.t
312 test-import-context.t
312 test-import-context.t
313 test-import-eol.t
313 test-import-eol.t
314 test-import-git.t
314 test-import-git.t
315 test-import-merge.t
315 test-import-merge.t
316 test-import-unknown.t
316 test-import-unknown.t
317 test-import.t
317 test-import.t
318 test-imports-checker.t
318 test-imports-checker.t
319 test-incoming-outgoing.t
319 test-incoming-outgoing.t
320 test-infinitepush-bundlestore.t
320 test-infinitepush-bundlestore.t
321 test-infinitepush-ci.t
321 test-infinitepush-ci.t
322 test-infinitepush.t
322 test-infinitepush.t
323 test-inherit-mode.t
323 test-inherit-mode.t
324 test-init.t
324 test-init.t
325 test-install.t
325 test-install.t
326 test-issue1089.t
326 test-issue1089.t
327 test-issue1102.t
327 test-issue1102.t
328 test-issue1175.t
328 test-issue1175.t
329 test-issue1306.t
329 test-issue1306.t
330 test-issue1438.t
330 test-issue1438.t
331 test-issue1502.t
331 test-issue1502.t
332 test-issue1802.t
332 test-issue1802.t
333 test-issue1877.t
333 test-issue1877.t
334 test-issue1993.t
334 test-issue1993.t
335 test-issue2137.t
335 test-issue2137.t
336 test-issue3084.t
336 test-issue3084.t
337 test-issue4074.t
337 test-issue4074.t
338 test-issue522.t
338 test-issue522.t
339 test-issue586.t
339 test-issue586.t
340 test-issue5979.t
340 test-issue5979.t
341 test-issue612.t
341 test-issue612.t
342 test-issue619.t
342 test-issue619.t
343 test-issue660.t
343 test-issue660.t
344 test-issue672.t
344 test-issue672.t
345 test-issue842.t
345 test-issue842.t
346 test-journal-exists.t
346 test-journal-exists.t
347 test-journal-share.t
347 test-journal-share.t
348 test-journal.t
348 test-journal.t
349 test-keyword.t
349 test-keyword.t
350 test-known.t
350 test-known.t
351 test-largefiles-cache.t
351 test-largefiles-cache.t
352 test-largefiles-misc.t
352 test-largefiles-misc.t
353 test-largefiles-small-disk.t
353 test-largefiles-small-disk.t
354 test-largefiles-update.t
354 test-largefiles-update.t
355 test-largefiles-wireproto.t
355 test-largefiles-wireproto.t
356 test-largefiles.t
356 test-largefiles.t
357 test-lfconvert.t
357 test-lfconvert.t
358 test-lfs-bundle.t
358 test-lfs-bundle.t
359 test-lfs-largefiles.t
359 test-lfs-largefiles.t
360 test-lfs-pointer.py
360 test-lfs-pointer.py
361 test-lfs-test-server.t
361 test-lfs-test-server.t
362 test-lfs.t
362 test-lfs.t
363 test-linelog.py
363 test-linelog.py
364 test-linerange.py
364 test-linerange.py
365 test-locate.t
365 test-locate.t
366 test-lock-badness.t
366 test-lock-badness.t
367 test-lock.py
367 test-lock.py
368 test-log-exthook.t
368 test-log-exthook.t
369 test-log-linerange.t
369 test-log-linerange.t
370 test-log.t
370 test-log.t
371 test-logexchange.t
371 test-logexchange.t
372 test-logtoprocess.t
372 test-logtoprocess.t
373 test-lrucachedict.py
373 test-lrucachedict.py
374 test-mactext.t
374 test-mactext.t
375 test-mailmap.t
375 test-mailmap.t
376 test-manifest-merging.t
376 test-manifest-merging.t
377 test-manifest.py
377 test-manifest.py
378 test-manifest.t
378 test-manifest.t
379 test-match.py
379 test-match.py
380 test-mdiff.py
380 test-mdiff.py
381 test-merge-changedelete.t
381 test-merge-changedelete.t
382 test-merge-closedheads.t
382 test-merge-closedheads.t
383 test-merge-commit.t
383 test-merge-commit.t
384 test-merge-criss-cross.t
384 test-merge-criss-cross.t
385 test-merge-default.t
385 test-merge-default.t
386 test-merge-force.t
386 test-merge-force.t
387 test-merge-halt.t
387 test-merge-halt.t
388 test-merge-internal-tools-pattern.t
388 test-merge-internal-tools-pattern.t
389 test-merge-local.t
389 test-merge-local.t
390 test-merge-no-file-change.t
390 test-merge-no-file-change.t
391 test-merge-remove.t
391 test-merge-remove.t
392 test-merge-revert.t
392 test-merge-revert.t
393 test-merge-revert2.t
393 test-merge-revert2.t
394 test-merge-subrepos.t
394 test-merge-subrepos.t
395 test-merge-symlinks.t
395 test-merge-symlinks.t
396 test-merge-tools.t
396 test-merge-tools.t
397 test-merge-types.t
397 test-merge-types.t
398 test-merge1.t
398 test-merge1.t
399 test-merge10.t
399 test-merge10.t
400 test-merge2.t
400 test-merge2.t
401 test-merge4.t
401 test-merge4.t
402 test-merge5.t
402 test-merge5.t
403 test-merge6.t
403 test-merge6.t
404 test-merge7.t
404 test-merge7.t
405 test-merge8.t
405 test-merge8.t
406 test-merge9.t
406 test-merge9.t
407 test-minifileset.py
407 test-minifileset.py
408 test-minirst.py
408 test-minirst.py
409 test-missing-capability.t
409 test-missing-capability.t
410 test-mq-eol.t
410 test-mq-eol.t
411 test-mq-git.t
411 test-mq-git.t
412 test-mq-guards.t
412 test-mq-guards.t
413 test-mq-header-date.t
413 test-mq-header-date.t
414 test-mq-header-from.t
414 test-mq-header-from.t
415 test-mq-merge.t
415 test-mq-merge.t
416 test-mq-missingfiles.t
416 test-mq-missingfiles.t
417 test-mq-pull-from-bundle.t
417 test-mq-pull-from-bundle.t
418 test-mq-qclone-http.t
418 test-mq-qclone-http.t
419 test-mq-qdelete.t
419 test-mq-qdelete.t
420 test-mq-qdiff.t
420 test-mq-qdiff.t
421 test-mq-qfold.t
421 test-mq-qfold.t
422 test-mq-qgoto.t
422 test-mq-qgoto.t
423 test-mq-qimport-fail-cleanup.t
423 test-mq-qimport-fail-cleanup.t
424 test-mq-qimport.t
424 test-mq-qimport.t
425 test-mq-qnew.t
425 test-mq-qnew.t
426 test-mq-qpush-exact.t
426 test-mq-qpush-exact.t
427 test-mq-qpush-fail.t
427 test-mq-qpush-fail.t
428 test-mq-qqueue.t
428 test-mq-qqueue.t
429 test-mq-qrefresh-interactive.t
429 test-mq-qrefresh-interactive.t
430 test-mq-qrefresh-replace-log-message.t
430 test-mq-qrefresh-replace-log-message.t
431 test-mq-qrefresh.t
431 test-mq-qrefresh.t
432 test-mq-qrename.t
432 test-mq-qrename.t
433 test-mq-qsave.t
433 test-mq-qsave.t
434 test-mq-safety.t
434 test-mq-safety.t
435 test-mq-subrepo.t
435 test-mq-subrepo.t
436 test-mq-symlinks.t
436 test-mq-symlinks.t
437 test-mq.t
437 test-mq.t
438 test-mv-cp-st-diff.t
438 test-mv-cp-st-diff.t
439 test-narrow-acl.t
439 test-narrow-acl.t
440 test-narrow-archive.t
440 test-narrow-archive.t
441 test-narrow-clone-no-ellipsis.t
441 test-narrow-clone-no-ellipsis.t
442 test-narrow-clone-non-narrow-server.t
442 test-narrow-clone-non-narrow-server.t
443 test-narrow-clone-nonlinear.t
443 test-narrow-clone-nonlinear.t
444 test-narrow-clone-stream.t
444 test-narrow-clone-stream.t
445 test-narrow-clone.t
445 test-narrow-clone.t
446 test-narrow-commit.t
446 test-narrow-commit.t
447 test-narrow-copies.t
447 test-narrow-copies.t
448 test-narrow-debugcommands.t
448 test-narrow-debugcommands.t
449 test-narrow-debugrebuilddirstate.t
449 test-narrow-debugrebuilddirstate.t
450 test-narrow-exchange-merges.t
450 test-narrow-exchange-merges.t
451 test-narrow-exchange.t
451 test-narrow-exchange.t
452 test-narrow-expanddirstate.t
452 test-narrow-expanddirstate.t
453 test-narrow-merge.t
453 test-narrow-merge.t
454 test-narrow-patch.t
454 test-narrow-patch.t
455 test-narrow-patterns.t
455 test-narrow-patterns.t
456 test-narrow-pull.t
456 test-narrow-pull.t
457 test-narrow-rebase.t
457 test-narrow-rebase.t
458 test-narrow-shallow-merges.t
458 test-narrow-shallow-merges.t
459 test-narrow-shallow.t
459 test-narrow-shallow.t
460 test-narrow-share.t
460 test-narrow-share.t
461 test-narrow-sparse.t
461 test-narrow-sparse.t
462 test-narrow-strip.t
462 test-narrow-strip.t
463 test-narrow-trackedcmd.t
463 test-narrow-trackedcmd.t
464 test-narrow-update.t
464 test-narrow-update.t
465 test-narrow-widen-no-ellipsis.t
465 test-narrow-widen-no-ellipsis.t
466 test-narrow-widen.t
466 test-narrow-widen.t
467 test-narrow.t
467 test-narrow.t
468 test-nested-repo.t
468 test-nested-repo.t
469 test-newbranch.t
469 test-newbranch.t
470 test-newcgi.t
470 test-newcgi.t
471 test-newercgi.t
471 test-newercgi.t
472 test-nointerrupt.t
472 test-nointerrupt.t
473 test-notify-changegroup.t
473 test-notify-changegroup.t
474 test-obshistory.t
474 test-obshistory.t
475 test-obsmarker-template.t
475 test-obsmarker-template.t
476 test-obsmarkers-effectflag.t
476 test-obsmarkers-effectflag.t
477 test-obsolete-bounds-checking.t
477 test-obsolete-bounds-checking.t
478 test-obsolete-bundle-strip.t
478 test-obsolete-bundle-strip.t
479 test-obsolete-changeset-exchange.t
479 test-obsolete-changeset-exchange.t
480 test-obsolete-checkheads.t
480 test-obsolete-checkheads.t
481 test-obsolete-distributed.t
481 test-obsolete-distributed.t
482 test-obsolete-divergent.t
482 test-obsolete-divergent.t
483 test-obsolete-tag-cache.t
483 test-obsolete-tag-cache.t
484 test-obsolete.t
484 test-obsolete.t
485 test-oldcgi.t
485 test-oldcgi.t
486 test-origbackup-conflict.t
486 test-origbackup-conflict.t
487 test-pager-legacy.t
487 test-pager-legacy.t
488 test-pager.t
488 test-pager.t
489 test-parents.t
489 test-parents.t
490 test-parse-date.t
490 test-parse-date.t
491 test-parseindex.t
491 test-parseindex.t
492 test-parseindex2.py
492 test-parseindex2.py
493 test-patch-offset.t
493 test-patch-offset.t
494 test-patch.t
494 test-patch.t
495 test-patchbomb-bookmark.t
495 test-patchbomb-bookmark.t
496 test-patchbomb-tls.t
496 test-patchbomb-tls.t
497 test-patchbomb.t
497 test-patchbomb.t
498 test-pathconflicts-basic.t
498 test-pathconflicts-basic.t
499 test-pathconflicts-merge.t
499 test-pathconflicts-merge.t
500 test-pathconflicts-update.t
500 test-pathconflicts-update.t
501 test-pathencode.py
501 test-pathencode.py
502 test-pending.t
502 test-pending.t
503 test-permissions.t
503 test-permissions.t
504 test-phases-exchange.t
504 test-phases-exchange.t
505 test-phases.t
505 test-phases.t
506 test-profile.t
506 test-profile.t
507 test-progress.t
507 test-progress.t
508 test-propertycache.py
508 test-propertycache.py
509 test-pull-branch.t
509 test-pull-branch.t
510 test-pull-bundle.t
510 test-pull-bundle.t
511 test-pull-http.t
511 test-pull-http.t
512 test-pull-permission.t
512 test-pull-permission.t
513 test-pull-pull-corruption.t
513 test-pull-pull-corruption.t
514 test-pull-r.t
514 test-pull-r.t
515 test-pull-update.t
515 test-pull-update.t
516 test-pull.t
516 test-pull.t
517 test-purge.t
517 test-purge.t
518 test-push-cgi.t
518 test-push-cgi.t
519 test-push-checkheads-partial-C1.t
519 test-push-checkheads-partial-C1.t
520 test-push-checkheads-partial-C2.t
520 test-push-checkheads-partial-C2.t
521 test-push-checkheads-partial-C3.t
521 test-push-checkheads-partial-C3.t
522 test-push-checkheads-partial-C4.t
522 test-push-checkheads-partial-C4.t
523 test-push-checkheads-pruned-B1.t
523 test-push-checkheads-pruned-B1.t
524 test-push-checkheads-pruned-B2.t
524 test-push-checkheads-pruned-B2.t
525 test-push-checkheads-pruned-B3.t
525 test-push-checkheads-pruned-B3.t
526 test-push-checkheads-pruned-B4.t
526 test-push-checkheads-pruned-B4.t
527 test-push-checkheads-pruned-B5.t
527 test-push-checkheads-pruned-B5.t
528 test-push-checkheads-pruned-B6.t
528 test-push-checkheads-pruned-B6.t
529 test-push-checkheads-pruned-B7.t
529 test-push-checkheads-pruned-B7.t
530 test-push-checkheads-pruned-B8.t
530 test-push-checkheads-pruned-B8.t
531 test-push-checkheads-superceed-A1.t
531 test-push-checkheads-superceed-A1.t
532 test-push-checkheads-superceed-A2.t
532 test-push-checkheads-superceed-A2.t
533 test-push-checkheads-superceed-A3.t
533 test-push-checkheads-superceed-A3.t
534 test-push-checkheads-superceed-A4.t
534 test-push-checkheads-superceed-A4.t
535 test-push-checkheads-superceed-A5.t
535 test-push-checkheads-superceed-A5.t
536 test-push-checkheads-superceed-A6.t
536 test-push-checkheads-superceed-A6.t
537 test-push-checkheads-superceed-A7.t
537 test-push-checkheads-superceed-A7.t
538 test-push-checkheads-superceed-A8.t
538 test-push-checkheads-superceed-A8.t
539 test-push-checkheads-unpushed-D1.t
539 test-push-checkheads-unpushed-D1.t
540 test-push-checkheads-unpushed-D2.t
540 test-push-checkheads-unpushed-D2.t
541 test-push-checkheads-unpushed-D3.t
541 test-push-checkheads-unpushed-D3.t
542 test-push-checkheads-unpushed-D4.t
542 test-push-checkheads-unpushed-D4.t
543 test-push-checkheads-unpushed-D5.t
543 test-push-checkheads-unpushed-D5.t
544 test-push-checkheads-unpushed-D6.t
544 test-push-checkheads-unpushed-D6.t
545 test-push-checkheads-unpushed-D7.t
545 test-push-checkheads-unpushed-D7.t
546 test-push-http.t
546 test-push-http.t
547 test-push-race.t
547 test-push-race.t
548 test-push-warn.t
548 test-push-warn.t
549 test-push.t
549 test-push.t
550 test-pushvars.t
550 test-pushvars.t
551 test-qrecord.t
551 test-qrecord.t
552 test-rebase-abort.t
552 test-rebase-abort.t
553 test-rebase-backup.t
553 test-rebase-backup.t
554 test-rebase-base-flag.t
554 test-rebase-base-flag.t
555 test-rebase-bookmarks.t
555 test-rebase-bookmarks.t
556 test-rebase-brute-force.t
556 test-rebase-brute-force.t
557 test-rebase-cache.t
557 test-rebase-cache.t
558 test-rebase-check-restore.t
558 test-rebase-check-restore.t
559 test-rebase-collapse.t
559 test-rebase-collapse.t
560 test-rebase-conflicts.t
560 test-rebase-conflicts.t
561 test-rebase-dest.t
561 test-rebase-dest.t
562 test-rebase-detach.t
562 test-rebase-detach.t
563 test-rebase-emptycommit.t
563 test-rebase-emptycommit.t
564 test-rebase-inmemory.t
564 test-rebase-inmemory.t
565 test-rebase-interruptions.t
565 test-rebase-interruptions.t
566 test-rebase-issue-noparam-single-rev.t
566 test-rebase-issue-noparam-single-rev.t
567 test-rebase-legacy.t
567 test-rebase-legacy.t
568 test-rebase-mq-skip.t
568 test-rebase-mq-skip.t
569 test-rebase-mq.t
569 test-rebase-mq.t
570 test-rebase-named-branches.t
570 test-rebase-named-branches.t
571 test-rebase-newancestor.t
571 test-rebase-newancestor.t
572 test-rebase-obsolete.t
572 test-rebase-obsolete.t
573 test-rebase-parameters.t
573 test-rebase-parameters.t
574 test-rebase-partial.t
574 test-rebase-partial.t
575 test-rebase-pull.t
575 test-rebase-pull.t
576 test-rebase-rename.t
576 test-rebase-rename.t
577 test-rebase-scenario-global.t
577 test-rebase-scenario-global.t
578 test-rebase-templates.t
578 test-rebase-templates.t
579 test-rebase-transaction.t
579 test-rebase-transaction.t
580 test-rebuildstate.t
580 test-rebuildstate.t
581 test-record.t
581 test-record.t
582 test-releasenotes-formatting.t
582 test-releasenotes-formatting.t
583 test-releasenotes-merging.t
583 test-releasenotes-merging.t
584 test-releasenotes-parsing.t
584 test-releasenotes-parsing.t
585 test-relink.t
585 test-relink.t
586 test-remotefilelog-bad-configs.t
586 test-remotefilelog-bad-configs.t
587 test-remotefilelog-bgprefetch.t
587 test-remotefilelog-bgprefetch.t
588 test-remotefilelog-blame.t
588 test-remotefilelog-blame.t
589 test-remotefilelog-bundle2.t
589 test-remotefilelog-bundle2.t
590 test-remotefilelog-bundles.t
590 test-remotefilelog-bundles.t
591 test-remotefilelog-cacheprocess.t
591 test-remotefilelog-cacheprocess.t
592 test-remotefilelog-clone-tree.t
592 test-remotefilelog-clone-tree.t
593 test-remotefilelog-clone.t
593 test-remotefilelog-clone.t
594 test-remotefilelog-datapack.py
594 test-remotefilelog-datapack.py
595 test-remotefilelog-gcrepack.t
595 test-remotefilelog-gcrepack.t
596 test-remotefilelog-histpack.py
596 test-remotefilelog-histpack.py
597 test-remotefilelog-http.t
597 test-remotefilelog-http.t
598 test-remotefilelog-keepset.t
598 test-remotefilelog-keepset.t
599 test-remotefilelog-local.t
599 test-remotefilelog-local.t
600 test-remotefilelog-log.t
600 test-remotefilelog-log.t
601 test-remotefilelog-partial-shallow.t
601 test-remotefilelog-partial-shallow.t
602 test-remotefilelog-permissions.t
602 test-remotefilelog-permissions.t
603 test-remotefilelog-permisssions.t
603 test-remotefilelog-permisssions.t
604 test-remotefilelog-prefetch.t
604 test-remotefilelog-prefetch.t
605 test-remotefilelog-pull-noshallow.t
605 test-remotefilelog-pull-noshallow.t
606 test-remotefilelog-repack.t
606 test-remotefilelog-share.t
607 test-remotefilelog-share.t
607 test-remotefilelog-sparse.t
608 test-remotefilelog-sparse.t
608 test-remotefilelog-tags.t
609 test-remotefilelog-tags.t
609 test-remotefilelog-wireproto.t
610 test-remotefilelog-wireproto.t
610 test-remove.t
611 test-remove.t
611 test-removeemptydirs.t
612 test-removeemptydirs.t
612 test-rename-after-merge.t
613 test-rename-after-merge.t
613 test-rename-dir-merge.t
614 test-rename-dir-merge.t
614 test-rename-merge1.t
615 test-rename-merge1.t
615 test-rename-merge2.t
616 test-rename-merge2.t
616 test-rename.t
617 test-rename.t
617 test-repair-strip.t
618 test-repair-strip.t
618 test-repo-compengines.t
619 test-repo-compengines.t
619 test-requires.t
620 test-requires.t
620 test-resolve.t
621 test-resolve.t
621 test-revert-flags.t
622 test-revert-flags.t
622 test-revert-interactive.t
623 test-revert-interactive.t
623 test-revert-unknown.t
624 test-revert-unknown.t
624 test-revert.t
625 test-revert.t
625 test-revisions.t
626 test-revisions.t
626 test-revlog-ancestry.py
627 test-revlog-ancestry.py
627 test-revlog-group-emptyiter.t
628 test-revlog-group-emptyiter.t
628 test-revlog-mmapindex.t
629 test-revlog-mmapindex.t
629 test-revlog-packentry.t
630 test-revlog-packentry.t
630 test-revlog-raw.py
631 test-revlog-raw.py
631 test-revlog-v2.t
632 test-revlog-v2.t
632 test-revlog.t
633 test-revlog.t
633 test-revset-dirstate-parents.t
634 test-revset-dirstate-parents.t
634 test-revset-legacy-lookup.t
635 test-revset-legacy-lookup.t
635 test-revset-outgoing.t
636 test-revset-outgoing.t
636 test-revset2.t
637 test-revset2.t
637 test-rollback.t
638 test-rollback.t
638 test-run-tests.py
639 test-run-tests.py
639 test-run-tests.t
640 test-run-tests.t
640 test-rust-ancestor.py
641 test-rust-ancestor.py
641 test-schemes.t
642 test-schemes.t
642 test-serve.t
643 test-serve.t
643 test-setdiscovery.t
644 test-setdiscovery.t
644 test-share.t
645 test-share.t
645 test-shelve.t
646 test-shelve.t
646 test-shelve2.t
647 test-shelve2.t
647 test-show-stack.t
648 test-show-stack.t
648 test-show-work.t
649 test-show-work.t
649 test-show.t
650 test-show.t
650 test-simple-update.t
651 test-simple-update.t
651 test-simplekeyvaluefile.py
652 test-simplekeyvaluefile.py
652 test-simplemerge.py
653 test-simplemerge.py
653 test-single-head.t
654 test-single-head.t
654 test-sparse-clear.t
655 test-sparse-clear.t
655 test-sparse-clone.t
656 test-sparse-clone.t
656 test-sparse-import.t
657 test-sparse-import.t
657 test-sparse-merges.t
658 test-sparse-merges.t
658 test-sparse-profiles.t
659 test-sparse-profiles.t
659 test-sparse-requirement.t
660 test-sparse-requirement.t
660 test-sparse-verbose-json.t
661 test-sparse-verbose-json.t
661 test-sparse.t
662 test-sparse.t
662 test-split.t
663 test-split.t
663 test-ssh-bundle1.t
664 test-ssh-bundle1.t
664 test-ssh-clone-r.t
665 test-ssh-clone-r.t
665 test-ssh-proto-unbundle.t
666 test-ssh-proto-unbundle.t
666 test-ssh-proto.t
667 test-ssh-proto.t
667 test-ssh-repoerror.t
668 test-ssh-repoerror.t
668 test-ssh.t
669 test-ssh.t
669 test-sshserver.py
670 test-sshserver.py
670 test-stack.t
671 test-stack.t
671 test-static-http.t
672 test-static-http.t
672 test-status-color.t
673 test-status-color.t
673 test-status-inprocess.py
674 test-status-inprocess.py
674 test-status-rev.t
675 test-status-rev.t
675 test-status-terse.t
676 test-status-terse.t
676 test-status.t
677 test-status.t
677 test-storage.py
678 test-storage.py
678 test-stream-bundle-v2.t
679 test-stream-bundle-v2.t
679 test-strict.t
680 test-strict.t
680 test-strip-cross.t
681 test-strip-cross.t
681 test-strip.t
682 test-strip.t
682 test-subrepo-deep-nested-change.t
683 test-subrepo-deep-nested-change.t
683 test-subrepo-git.t
684 test-subrepo-git.t
684 test-subrepo-missing.t
685 test-subrepo-missing.t
685 test-subrepo-paths.t
686 test-subrepo-paths.t
686 test-subrepo-recursion.t
687 test-subrepo-recursion.t
687 test-subrepo-relative-path.t
688 test-subrepo-relative-path.t
688 test-subrepo.t
689 test-subrepo.t
689 test-symlink-os-yes-fs-no.py
690 test-symlink-os-yes-fs-no.py
690 test-symlink-placeholder.t
691 test-symlink-placeholder.t
691 test-symlinks.t
692 test-symlinks.t
692 test-tag.t
693 test-tag.t
693 test-tags.t
694 test-tags.t
694 test-template-basic.t
695 test-template-basic.t
695 test-template-functions.t
696 test-template-functions.t
696 test-template-keywords.t
697 test-template-keywords.t
697 test-template-map.t
698 test-template-map.t
698 test-tools.t
699 test-tools.t
699 test-transplant.t
700 test-transplant.t
700 test-treediscovery-legacy.t
701 test-treediscovery-legacy.t
701 test-treediscovery.t
702 test-treediscovery.t
702 test-treemanifest.t
703 test-treemanifest.t
703 test-ui-color.py
704 test-ui-color.py
704 test-ui-config.py
705 test-ui-config.py
705 test-ui-verbosity.py
706 test-ui-verbosity.py
706 test-unamend.t
707 test-unamend.t
707 test-unbundlehash.t
708 test-unbundlehash.t
708 test-uncommit.t
709 test-uncommit.t
709 test-unified-test.t
710 test-unified-test.t
710 test-unionrepo.t
711 test-unionrepo.t
711 test-unrelated-pull.t
712 test-unrelated-pull.t
712 test-up-local-change.t
713 test-up-local-change.t
713 test-update-atomic.t
714 test-update-atomic.t
714 test-update-branches.t
715 test-update-branches.t
715 test-update-dest.t
716 test-update-dest.t
716 test-update-issue1456.t
717 test-update-issue1456.t
717 test-update-names.t
718 test-update-names.t
718 test-update-reverse.t
719 test-update-reverse.t
719 test-upgrade-repo.t
720 test-upgrade-repo.t
720 test-url-download.t
721 test-url-download.t
721 test-url-rev.t
722 test-url-rev.t
722 test-url.py
723 test-url.py
723 test-username-newline.t
724 test-username-newline.t
724 test-util.py
725 test-util.py
725 test-verify.t
726 test-verify.t
726 test-walk.t
727 test-walk.t
727 test-walkrepo.py
728 test-walkrepo.py
728 test-websub.t
729 test-websub.t
729 test-win32text.t
730 test-win32text.t
730 test-wireproto-caching.t
731 test-wireproto-caching.t
731 test-wireproto-clientreactor.py
732 test-wireproto-clientreactor.py
732 test-wireproto-command-branchmap.t
733 test-wireproto-command-branchmap.t
733 test-wireproto-command-capabilities.t
734 test-wireproto-command-capabilities.t
734 test-wireproto-command-changesetdata.t
735 test-wireproto-command-changesetdata.t
735 test-wireproto-command-filedata.t
736 test-wireproto-command-filedata.t
736 test-wireproto-command-filesdata.t
737 test-wireproto-command-filesdata.t
737 test-wireproto-command-heads.t
738 test-wireproto-command-heads.t
738 test-wireproto-command-known.t
739 test-wireproto-command-known.t
739 test-wireproto-command-listkeys.t
740 test-wireproto-command-listkeys.t
740 test-wireproto-command-lookup.t
741 test-wireproto-command-lookup.t
741 test-wireproto-command-manifestdata.t
742 test-wireproto-command-manifestdata.t
742 test-wireproto-command-pushkey.t
743 test-wireproto-command-pushkey.t
743 test-wireproto-command-rawstorefiledata.t
744 test-wireproto-command-rawstorefiledata.t
744 test-wireproto-content-redirects.t
745 test-wireproto-content-redirects.t
745 test-wireproto-exchangev2.t
746 test-wireproto-exchangev2.t
746 test-wireproto-framing.py
747 test-wireproto-framing.py
747 test-wireproto-serverreactor.py
748 test-wireproto-serverreactor.py
748 test-wireproto.py
749 test-wireproto.py
749 test-wireproto.t
750 test-wireproto.t
750 test-wsgirequest.py
751 test-wsgirequest.py
751 test-xdg.t
752 test-xdg.t
@@ -1,425 +1,427 b''
1 from __future__ import absolute_import
1 from __future__ import absolute_import
2
2
3 import errno
3 import errno
4 import hashlib
4 import hashlib
5 import os
5 import os
6 import shutil
6 import shutil
7 import stat
7 import stat
8 import time
8 import time
9
9
10 from mercurial.i18n import _
10 from mercurial.i18n import _
11 from mercurial.node import bin, hex
11 from mercurial.node import bin, hex
12 from mercurial import (
12 from mercurial import (
13 error,
13 error,
14 pycompat,
14 pycompat,
15 util,
15 util,
16 )
16 )
17 from . import (
17 from . import (
18 constants,
18 constants,
19 shallowutil,
19 shallowutil,
20 )
20 )
21
21
22 class basestore(object):
22 class basestore(object):
23 def __init__(self, repo, path, reponame, shared=False):
23 def __init__(self, repo, path, reponame, shared=False):
24 """Creates a remotefilelog store object for the given repo name.
24 """Creates a remotefilelog store object for the given repo name.
25
25
26 `path` - The file path where this store keeps its data
26 `path` - The file path where this store keeps its data
27 `reponame` - The name of the repo. This is used to partition data from
27 `reponame` - The name of the repo. This is used to partition data from
28 many repos.
28 many repos.
29 `shared` - True if this store is a shared cache of data from the central
29 `shared` - True if this store is a shared cache of data from the central
30 server, for many repos on this machine. False means this store is for
30 server, for many repos on this machine. False means this store is for
31 the local data for one repo.
31 the local data for one repo.
32 """
32 """
33 self.repo = repo
33 self.repo = repo
34 self.ui = repo.ui
34 self.ui = repo.ui
35 self._path = path
35 self._path = path
36 self._reponame = reponame
36 self._reponame = reponame
37 self._shared = shared
37 self._shared = shared
38 self._uid = os.getuid() if not pycompat.iswindows else None
38 self._uid = os.getuid() if not pycompat.iswindows else None
39
39
40 self._validatecachelog = self.ui.config("remotefilelog",
40 self._validatecachelog = self.ui.config("remotefilelog",
41 "validatecachelog")
41 "validatecachelog")
42 self._validatecache = self.ui.config("remotefilelog", "validatecache",
42 self._validatecache = self.ui.config("remotefilelog", "validatecache",
43 'on')
43 'on')
44 if self._validatecache not in ('on', 'strict', 'off'):
44 if self._validatecache not in ('on', 'strict', 'off'):
45 self._validatecache = 'on'
45 self._validatecache = 'on'
46 if self._validatecache == 'off':
46 if self._validatecache == 'off':
47 self._validatecache = False
47 self._validatecache = False
48
48
49 if shared:
49 if shared:
50 shallowutil.mkstickygroupdir(self.ui, path)
50 shallowutil.mkstickygroupdir(self.ui, path)
51
51
52 def getmissing(self, keys):
52 def getmissing(self, keys):
53 missing = []
53 missing = []
54 for name, node in keys:
54 for name, node in keys:
55 filepath = self._getfilepath(name, node)
55 filepath = self._getfilepath(name, node)
56 exists = os.path.exists(filepath)
56 exists = os.path.exists(filepath)
57 if (exists and self._validatecache == 'strict' and
57 if (exists and self._validatecache == 'strict' and
58 not self._validatekey(filepath, 'contains')):
58 not self._validatekey(filepath, 'contains')):
59 exists = False
59 exists = False
60 if not exists:
60 if not exists:
61 missing.append((name, node))
61 missing.append((name, node))
62
62
63 return missing
63 return missing
64
64
65 # BELOW THIS ARE IMPLEMENTATIONS OF REPACK SOURCE
65 # BELOW THIS ARE IMPLEMENTATIONS OF REPACK SOURCE
66
66
67 def markledger(self, ledger, options=None):
67 def markledger(self, ledger, options=None):
68 if options and options.get(constants.OPTION_PACKSONLY):
68 if options and options.get(constants.OPTION_PACKSONLY):
69 return
69 return
70 if self._shared:
70 if self._shared:
71 for filename, nodes in self._getfiles():
71 for filename, nodes in self._getfiles():
72 for node in nodes:
72 for node in nodes:
73 ledger.markdataentry(self, filename, node)
73 ledger.markdataentry(self, filename, node)
74 ledger.markhistoryentry(self, filename, node)
74 ledger.markhistoryentry(self, filename, node)
75
75
76 def cleanup(self, ledger):
76 def cleanup(self, ledger):
77 ui = self.ui
77 ui = self.ui
78 entries = ledger.sources.get(self, [])
78 entries = ledger.sources.get(self, [])
79 count = 0
79 count = 0
80 progress = ui.makeprogress(_("cleaning up"), unit="files",
80 progress = ui.makeprogress(_("cleaning up"), unit="files",
81 total=len(entries))
81 total=len(entries))
82 for entry in entries:
82 for entry in entries:
83 if entry.gced or (entry.datarepacked and entry.historyrepacked):
83 if entry.gced or (entry.datarepacked and entry.historyrepacked):
84 progress.update(count)
84 progress.update(count)
85 path = self._getfilepath(entry.filename, entry.node)
85 path = self._getfilepath(entry.filename, entry.node)
86 util.tryunlink(path)
86 util.tryunlink(path)
87 count += 1
87 count += 1
88 progress.complete()
88 progress.complete()
89
89
90 # Clean up the repo cache directory.
90 # Clean up the repo cache directory.
91 self._cleanupdirectory(self._getrepocachepath())
91 self._cleanupdirectory(self._getrepocachepath())
92
92
93 # BELOW THIS ARE NON-STANDARD APIS
93 # BELOW THIS ARE NON-STANDARD APIS
94
94
95 def _cleanupdirectory(self, rootdir):
95 def _cleanupdirectory(self, rootdir):
96 """Removes the empty directories and unnecessary files within the root
96 """Removes the empty directories and unnecessary files within the root
97 directory recursively. Note that this method does not remove the root
97 directory recursively. Note that this method does not remove the root
98 directory itself. """
98 directory itself. """
99
99
100 oldfiles = set()
100 oldfiles = set()
101 otherfiles = set()
101 otherfiles = set()
102 # osutil.listdir returns stat information which saves some rmdir/listdir
102 # osutil.listdir returns stat information which saves some rmdir/listdir
103 # syscalls.
103 # syscalls.
104 for name, mode in util.osutil.listdir(rootdir):
104 for name, mode in util.osutil.listdir(rootdir):
105 if stat.S_ISDIR(mode):
105 if stat.S_ISDIR(mode):
106 dirpath = os.path.join(rootdir, name)
106 dirpath = os.path.join(rootdir, name)
107 self._cleanupdirectory(dirpath)
107 self._cleanupdirectory(dirpath)
108
108
109 # Now that the directory specified by dirpath is potentially
109 # Now that the directory specified by dirpath is potentially
110 # empty, try and remove it.
110 # empty, try and remove it.
111 try:
111 try:
112 os.rmdir(dirpath)
112 os.rmdir(dirpath)
113 except OSError:
113 except OSError:
114 pass
114 pass
115
115
116 elif stat.S_ISREG(mode):
116 elif stat.S_ISREG(mode):
117 if name.endswith('_old'):
117 if name.endswith('_old'):
118 oldfiles.add(name[:-4])
118 oldfiles.add(name[:-4])
119 else:
119 else:
120 otherfiles.add(name)
120 otherfiles.add(name)
121
121
122 # Remove the files which end with suffix '_old' and have no
122 # Remove the files which end with suffix '_old' and have no
123 # corresponding file without the suffix '_old'. See addremotefilelognode
123 # corresponding file without the suffix '_old'. See addremotefilelognode
124 # method for the generation/purpose of files with '_old' suffix.
124 # method for the generation/purpose of files with '_old' suffix.
125 for filename in oldfiles - otherfiles:
125 for filename in oldfiles - otherfiles:
126 filepath = os.path.join(rootdir, filename + '_old')
126 filepath = os.path.join(rootdir, filename + '_old')
127 util.tryunlink(filepath)
127 util.tryunlink(filepath)
128
128
129 def _getfiles(self):
129 def _getfiles(self):
130 """Return a list of (filename, [node,...]) for all the revisions that
130 """Return a list of (filename, [node,...]) for all the revisions that
131 exist in the store.
131 exist in the store.
132
132
133 This is useful for obtaining a list of all the contents of the store
133 This is useful for obtaining a list of all the contents of the store
134 when performing a repack to another store, since the store API requires
134 when performing a repack to another store, since the store API requires
135 name+node keys and not namehash+node keys.
135 name+node keys and not namehash+node keys.
136 """
136 """
137 existing = {}
137 existing = {}
138 for filenamehash, node in self._listkeys():
138 for filenamehash, node in self._listkeys():
139 existing.setdefault(filenamehash, []).append(node)
139 existing.setdefault(filenamehash, []).append(node)
140
140
141 filenamemap = self._resolvefilenames(existing.keys())
141 filenamemap = self._resolvefilenames(existing.keys())
142
142
143 for filename, sha in filenamemap.iteritems():
143 for filename, sha in filenamemap.iteritems():
144 yield (filename, existing[sha])
144 yield (filename, existing[sha])
145
145
146 def _resolvefilenames(self, hashes):
146 def _resolvefilenames(self, hashes):
147 """Given a list of filename hashes that are present in the
147 """Given a list of filename hashes that are present in the
148 remotefilelog store, return a mapping from filename->hash.
148 remotefilelog store, return a mapping from filename->hash.
149
149
150 This is useful when converting remotefilelog blobs into other storage
150 This is useful when converting remotefilelog blobs into other storage
151 formats.
151 formats.
152 """
152 """
153 if not hashes:
153 if not hashes:
154 return {}
154 return {}
155
155
156 filenames = {}
156 filenames = {}
157 missingfilename = set(hashes)
157 missingfilename = set(hashes)
158
158
159 # Start with a full manifest, since it'll cover the majority of files
159 # Start with a full manifest, since it'll cover the majority of files
160 for filename in self.repo['tip'].manifest():
160 for filename in self.repo['tip'].manifest():
161 sha = hashlib.sha1(filename).digest()
161 sha = hashlib.sha1(filename).digest()
162 if sha in missingfilename:
162 if sha in missingfilename:
163 filenames[filename] = sha
163 filenames[filename] = sha
164 missingfilename.discard(sha)
164 missingfilename.discard(sha)
165
165
166 # Scan the changelog until we've found every file name
166 # Scan the changelog until we've found every file name
167 cl = self.repo.unfiltered().changelog
167 cl = self.repo.unfiltered().changelog
168 for rev in pycompat.xrange(len(cl) - 1, -1, -1):
168 for rev in pycompat.xrange(len(cl) - 1, -1, -1):
169 if not missingfilename:
169 if not missingfilename:
170 break
170 break
171 files = cl.readfiles(cl.node(rev))
171 files = cl.readfiles(cl.node(rev))
172 for filename in files:
172 for filename in files:
173 sha = hashlib.sha1(filename).digest()
173 sha = hashlib.sha1(filename).digest()
174 if sha in missingfilename:
174 if sha in missingfilename:
175 filenames[filename] = sha
175 filenames[filename] = sha
176 missingfilename.discard(sha)
176 missingfilename.discard(sha)
177
177
178 return filenames
178 return filenames
179
179
180 def _getrepocachepath(self):
180 def _getrepocachepath(self):
181 return os.path.join(
181 return os.path.join(
182 self._path, self._reponame) if self._shared else self._path
182 self._path, self._reponame) if self._shared else self._path
183
183
184 def _listkeys(self):
184 def _listkeys(self):
185 """List all the remotefilelog keys that exist in the store.
185 """List all the remotefilelog keys that exist in the store.
186
186
187 Returns a iterator of (filename hash, filecontent hash) tuples.
187 Returns a iterator of (filename hash, filecontent hash) tuples.
188 """
188 """
189
189
190 for root, dirs, files in os.walk(self._getrepocachepath()):
190 for root, dirs, files in os.walk(self._getrepocachepath()):
191 for filename in files:
191 for filename in files:
192 if len(filename) != 40:
192 if len(filename) != 40:
193 continue
193 continue
194 node = filename
194 node = filename
195 if self._shared:
195 if self._shared:
196 # .../1a/85ffda..be21
196 # .../1a/85ffda..be21
197 filenamehash = root[-41:-39] + root[-38:]
197 filenamehash = root[-41:-39] + root[-38:]
198 else:
198 else:
199 filenamehash = root[-40:]
199 filenamehash = root[-40:]
200 yield (bin(filenamehash), bin(node))
200 yield (bin(filenamehash), bin(node))
201
201
202 def _getfilepath(self, name, node):
202 def _getfilepath(self, name, node):
203 node = hex(node)
203 node = hex(node)
204 if self._shared:
204 if self._shared:
205 key = shallowutil.getcachekey(self._reponame, name, node)
205 key = shallowutil.getcachekey(self._reponame, name, node)
206 else:
206 else:
207 key = shallowutil.getlocalkey(name, node)
207 key = shallowutil.getlocalkey(name, node)
208
208
209 return os.path.join(self._path, key)
209 return os.path.join(self._path, key)
210
210
211 def _getdata(self, name, node):
211 def _getdata(self, name, node):
212 filepath = self._getfilepath(name, node)
212 filepath = self._getfilepath(name, node)
213 try:
213 try:
214 data = shallowutil.readfile(filepath)
214 data = shallowutil.readfile(filepath)
215 if self._validatecache and not self._validatedata(data, filepath):
215 if self._validatecache and not self._validatedata(data, filepath):
216 if self._validatecachelog:
216 if self._validatecachelog:
217 with open(self._validatecachelog, 'a+') as f:
217 with open(self._validatecachelog, 'a+') as f:
218 f.write("corrupt %s during read\n" % filepath)
218 f.write("corrupt %s during read\n" % filepath)
219 os.rename(filepath, filepath + ".corrupt")
219 os.rename(filepath, filepath + ".corrupt")
220 raise KeyError("corrupt local cache file %s" % filepath)
220 raise KeyError("corrupt local cache file %s" % filepath)
221 except IOError:
221 except IOError:
222 raise KeyError("no file found at %s for %s:%s" % (filepath, name,
222 raise KeyError("no file found at %s for %s:%s" % (filepath, name,
223 hex(node)))
223 hex(node)))
224
224
225 return data
225 return data
226
226
227 def addremotefilelognode(self, name, node, data):
227 def addremotefilelognode(self, name, node, data):
228 filepath = self._getfilepath(name, node)
228 filepath = self._getfilepath(name, node)
229
229
230 oldumask = os.umask(0o002)
230 oldumask = os.umask(0o002)
231 try:
231 try:
232 # if this node already exists, save the old version for
232 # if this node already exists, save the old version for
233 # recovery/debugging purposes.
233 # recovery/debugging purposes.
234 if os.path.exists(filepath):
234 if os.path.exists(filepath):
235 newfilename = filepath + '_old'
235 newfilename = filepath + '_old'
236 # newfilename can be read-only and shutil.copy will fail.
236 # newfilename can be read-only and shutil.copy will fail.
237 # Delete newfilename to avoid it
237 # Delete newfilename to avoid it
238 if os.path.exists(newfilename):
238 if os.path.exists(newfilename):
239 shallowutil.unlinkfile(newfilename)
239 shallowutil.unlinkfile(newfilename)
240 shutil.copy(filepath, newfilename)
240 shutil.copy(filepath, newfilename)
241
241
242 shallowutil.mkstickygroupdir(self.ui, os.path.dirname(filepath))
242 shallowutil.mkstickygroupdir(self.ui, os.path.dirname(filepath))
243 shallowutil.writefile(filepath, data, readonly=True)
243 shallowutil.writefile(filepath, data, readonly=True)
244
244
245 if self._validatecache:
245 if self._validatecache:
246 if not self._validatekey(filepath, 'write'):
246 if not self._validatekey(filepath, 'write'):
247 raise error.Abort(_("local cache write was corrupted %s") %
247 raise error.Abort(_("local cache write was corrupted %s") %
248 filepath)
248 filepath)
249 finally:
249 finally:
250 os.umask(oldumask)
250 os.umask(oldumask)
251
251
252 def markrepo(self, path):
252 def markrepo(self, path):
253 """Call this to add the given repo path to the store's list of
253 """Call this to add the given repo path to the store's list of
254 repositories that are using it. This is useful later when doing garbage
254 repositories that are using it. This is useful later when doing garbage
255 collection, since it allows us to insecpt the repos to see what nodes
255 collection, since it allows us to insecpt the repos to see what nodes
256 they want to be kept alive in the store.
256 they want to be kept alive in the store.
257 """
257 """
258 repospath = os.path.join(self._path, "repos")
258 repospath = os.path.join(self._path, "repos")
259 with open(repospath, 'ab') as reposfile:
259 with open(repospath, 'ab') as reposfile:
260 reposfile.write(os.path.dirname(path) + "\n")
260 reposfile.write(os.path.dirname(path) + "\n")
261
261
262 repospathstat = os.stat(repospath)
262 repospathstat = os.stat(repospath)
263 if repospathstat.st_uid == self._uid:
263 if repospathstat.st_uid == self._uid:
264 os.chmod(repospath, 0o0664)
264 os.chmod(repospath, 0o0664)
265
265
266 def _validatekey(self, path, action):
266 def _validatekey(self, path, action):
267 with open(path, 'rb') as f:
267 with open(path, 'rb') as f:
268 data = f.read()
268 data = f.read()
269
269
270 if self._validatedata(data, path):
270 if self._validatedata(data, path):
271 return True
271 return True
272
272
273 if self._validatecachelog:
273 if self._validatecachelog:
274 with open(self._validatecachelog, 'ab+') as f:
274 with open(self._validatecachelog, 'ab+') as f:
275 f.write("corrupt %s during %s\n" % (path, action))
275 f.write("corrupt %s during %s\n" % (path, action))
276
276
277 os.rename(path, path + ".corrupt")
277 os.rename(path, path + ".corrupt")
278 return False
278 return False
279
279
280 def _validatedata(self, data, path):
280 def _validatedata(self, data, path):
281 try:
281 try:
282 if len(data) > 0:
282 if len(data) > 0:
283 # see remotefilelogserver.createfileblob for the format
283 # see remotefilelogserver.createfileblob for the format
284 offset, size, flags = shallowutil.parsesizeflags(data)
284 offset, size, flags = shallowutil.parsesizeflags(data)
285 if len(data) <= size:
285 if len(data) <= size:
286 # it is truncated
286 # it is truncated
287 return False
287 return False
288
288
289 # extract the node from the metadata
289 # extract the node from the metadata
290 offset += size
290 offset += size
291 datanode = data[offset:offset + 20]
291 datanode = data[offset:offset + 20]
292
292
293 # and compare against the path
293 # and compare against the path
294 if os.path.basename(path) == hex(datanode):
294 if os.path.basename(path) == hex(datanode):
295 # Content matches the intended path
295 # Content matches the intended path
296 return True
296 return True
297 return False
297 return False
298 except (ValueError, RuntimeError):
298 except (ValueError, RuntimeError):
299 pass
299 pass
300
300
301 return False
301 return False
302
302
303 def gc(self, keepkeys):
303 def gc(self, keepkeys):
304 ui = self.ui
304 ui = self.ui
305 cachepath = self._path
305 cachepath = self._path
306
306
307 # prune cache
307 # prune cache
308 queue = pycompat.queue.PriorityQueue()
308 queue = pycompat.queue.PriorityQueue()
309 originalsize = 0
309 originalsize = 0
310 size = 0
310 size = 0
311 count = 0
311 count = 0
312 removed = 0
312 removed = 0
313
313
314 # keep files newer than a day even if they aren't needed
314 # keep files newer than a day even if they aren't needed
315 limit = time.time() - (60 * 60 * 24)
315 limit = time.time() - (60 * 60 * 24)
316
316
317 progress = ui.makeprogress(_("removing unnecessary files"),
317 progress = ui.makeprogress(_("removing unnecessary files"),
318 unit="files")
318 unit="files")
319 progress.update(0)
319 progress.update(0)
320 for root, dirs, files in os.walk(cachepath):
320 for root, dirs, files in os.walk(cachepath):
321 for file in files:
321 for file in files:
322 if file == 'repos':
322 if file == 'repos':
323 continue
323 continue
324
324
325 # Don't delete pack files
325 # Don't delete pack files
326 if '/packs/' in root:
326 if '/packs/' in root:
327 continue
327 continue
328
328
329 progress.update(count)
329 progress.update(count)
330 path = os.path.join(root, file)
330 path = os.path.join(root, file)
331 key = os.path.relpath(path, cachepath)
331 key = os.path.relpath(path, cachepath)
332 count += 1
332 count += 1
333 try:
333 try:
334 pathstat = os.stat(path)
334 pathstat = os.stat(path)
335 except OSError as e:
335 except OSError as e:
336 # errno.ENOENT = no such file or directory
336 # errno.ENOENT = no such file or directory
337 if e.errno != errno.ENOENT:
337 if e.errno != errno.ENOENT:
338 raise
338 raise
339 msg = _("warning: file %s was removed by another process\n")
339 msg = _("warning: file %s was removed by another process\n")
340 ui.warn(msg % path)
340 ui.warn(msg % path)
341 continue
341 continue
342
342
343 originalsize += pathstat.st_size
343 originalsize += pathstat.st_size
344
344
345 if key in keepkeys or pathstat.st_atime > limit:
345 if key in keepkeys or pathstat.st_atime > limit:
346 queue.put((pathstat.st_atime, path, pathstat))
346 queue.put((pathstat.st_atime, path, pathstat))
347 size += pathstat.st_size
347 size += pathstat.st_size
348 else:
348 else:
349 try:
349 try:
350 shallowutil.unlinkfile(path)
350 shallowutil.unlinkfile(path)
351 except OSError as e:
351 except OSError as e:
352 # errno.ENOENT = no such file or directory
352 # errno.ENOENT = no such file or directory
353 if e.errno != errno.ENOENT:
353 if e.errno != errno.ENOENT:
354 raise
354 raise
355 msg = _("warning: file %s was removed by another "
355 msg = _("warning: file %s was removed by another "
356 "process\n")
356 "process\n")
357 ui.warn(msg % path)
357 ui.warn(msg % path)
358 continue
358 continue
359 removed += 1
359 removed += 1
360 progress.complete()
360 progress.complete()
361
361
362 # remove oldest files until under limit
362 # remove oldest files until under limit
363 limit = ui.configbytes("remotefilelog", "cachelimit")
363 limit = ui.configbytes("remotefilelog", "cachelimit")
364 if size > limit:
364 if size > limit:
365 excess = size - limit
365 excess = size - limit
366 progress = ui.makeprogress(_("enforcing cache limit"), unit="bytes",
366 progress = ui.makeprogress(_("enforcing cache limit"), unit="bytes",
367 total=excess)
367 total=excess)
368 removedexcess = 0
368 removedexcess = 0
369 while queue and size > limit and size > 0:
369 while queue and size > limit and size > 0:
370 progress.update(removedexcess)
370 progress.update(removedexcess)
371 atime, oldpath, oldpathstat = queue.get()
371 atime, oldpath, oldpathstat = queue.get()
372 try:
372 try:
373 shallowutil.unlinkfile(oldpath)
373 shallowutil.unlinkfile(oldpath)
374 except OSError as e:
374 except OSError as e:
375 # errno.ENOENT = no such file or directory
375 # errno.ENOENT = no such file or directory
376 if e.errno != errno.ENOENT:
376 if e.errno != errno.ENOENT:
377 raise
377 raise
378 msg = _("warning: file %s was removed by another process\n")
378 msg = _("warning: file %s was removed by another process\n")
379 ui.warn(msg % oldpath)
379 ui.warn(msg % oldpath)
380 size -= oldpathstat.st_size
380 size -= oldpathstat.st_size
381 removed += 1
381 removed += 1
382 removedexcess += oldpathstat.st_size
382 removedexcess += oldpathstat.st_size
383 progress.complete()
383 progress.complete()
384
384
385 ui.status(_("finished: removed %d of %d files (%0.2f GB to %0.2f GB)\n")
385 ui.status(_("finished: removed %d of %d files (%0.2f GB to %0.2f GB)\n")
386 % (removed, count,
386 % (removed, count,
387 float(originalsize) / 1024.0 / 1024.0 / 1024.0,
387 float(originalsize) / 1024.0 / 1024.0 / 1024.0,
388 float(size) / 1024.0 / 1024.0 / 1024.0))
388 float(size) / 1024.0 / 1024.0 / 1024.0))
389
389
390 class baseunionstore(object):
390 class baseunionstore(object):
391 def __init__(self, *args, **kwargs):
391 def __init__(self, *args, **kwargs):
392 # If one of the functions that iterates all of the stores is about to
392 # If one of the functions that iterates all of the stores is about to
393 # throw a KeyError, try this many times with a full refresh between
393 # throw a KeyError, try this many times with a full refresh between
394 # attempts. A repack operation may have moved data from one store to
394 # attempts. A repack operation may have moved data from one store to
395 # another while we were running.
395 # another while we were running.
396 self.numattempts = kwargs.get(r'numretries', 0) + 1
396 self.numattempts = kwargs.get(r'numretries', 0) + 1
397 # If not-None, call this function on every retry and if the attempts are
397 # If not-None, call this function on every retry and if the attempts are
398 # exhausted.
398 # exhausted.
399 self.retrylog = kwargs.get(r'retrylog', None)
399 self.retrylog = kwargs.get(r'retrylog', None)
400
400
401 def markforrefresh(self):
401 def markforrefresh(self):
402 for store in self.stores:
402 for store in self.stores:
403 if util.safehasattr(store, 'markforrefresh'):
403 if util.safehasattr(store, 'markforrefresh'):
404 store.markforrefresh()
404 store.markforrefresh()
405
405
406 @staticmethod
406 @staticmethod
407 def retriable(fn):
407 def retriable(fn):
408 def noop(*args):
408 def noop(*args):
409 pass
409 pass
410 def wrapped(self, *args, **kwargs):
410 def wrapped(self, *args, **kwargs):
411 retrylog = self.retrylog or noop
411 retrylog = self.retrylog or noop
412 funcname = fn.__name__
412 funcname = fn.__name__
413 for i in pycompat.xrange(self.numattempts):
413 i = 0
414 while i < self.numattempts:
414 if i > 0:
415 if i > 0:
415 retrylog('re-attempting (n=%d) %s\n' % (i, funcname))
416 retrylog('re-attempting (n=%d) %s\n' % (i, funcname))
416 self.markforrefresh()
417 self.markforrefresh()
418 i += 1
417 try:
419 try:
418 return fn(self, *args, **kwargs)
420 return fn(self, *args, **kwargs)
419 except KeyError:
421 except KeyError:
420 pass
422 if i == self.numattempts:
421 # retries exhausted
423 # retries exhausted
422 retrylog('retries exhausted in %s, raising KeyError\n' %
424 retrylog('retries exhausted in %s, raising KeyError\n' %
423 pycompat.sysbytes(funcname))
425 pycompat.sysbytes(funcname))
424 raise
426 raise
425 return wrapped
427 return wrapped
General Comments 0
You need to be logged in to leave comments. Login now