##// END OF EJS Templates
rust: Rewrite dirstate parsing usin the `bytes-cast` crate...
Simon Sapin -
r47336:f88e8ae0 default
parent child Browse files
Show More
@@ -1,1050 +1,1049
1 1 # This file is automatically @generated by Cargo.
2 2 # It is not intended for manual editing.
3 3 [[package]]
4 4 name = "adler"
5 5 version = "0.2.3"
6 6 source = "registry+https://github.com/rust-lang/crates.io-index"
7 7
8 8 [[package]]
9 9 name = "aho-corasick"
10 10 version = "0.7.15"
11 11 source = "registry+https://github.com/rust-lang/crates.io-index"
12 12 dependencies = [
13 13 "memchr 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
14 14 ]
15 15
16 16 [[package]]
17 17 name = "ansi_term"
18 18 version = "0.11.0"
19 19 source = "registry+https://github.com/rust-lang/crates.io-index"
20 20 dependencies = [
21 21 "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
22 22 ]
23 23
24 24 [[package]]
25 25 name = "atty"
26 26 version = "0.2.14"
27 27 source = "registry+https://github.com/rust-lang/crates.io-index"
28 28 dependencies = [
29 29 "hermit-abi 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
30 30 "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)",
31 31 "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
32 32 ]
33 33
34 34 [[package]]
35 35 name = "autocfg"
36 36 version = "1.0.1"
37 37 source = "registry+https://github.com/rust-lang/crates.io-index"
38 38
39 39 [[package]]
40 40 name = "bitflags"
41 41 version = "1.2.1"
42 42 source = "registry+https://github.com/rust-lang/crates.io-index"
43 43
44 44 [[package]]
45 45 name = "bitmaps"
46 46 version = "2.1.0"
47 47 source = "registry+https://github.com/rust-lang/crates.io-index"
48 48 dependencies = [
49 49 "typenum 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
50 50 ]
51 51
52 52 [[package]]
53 53 name = "byteorder"
54 54 version = "1.3.4"
55 55 source = "registry+https://github.com/rust-lang/crates.io-index"
56 56
57 57 [[package]]
58 58 name = "bytes-cast"
59 59 version = "0.1.0"
60 60 source = "registry+https://github.com/rust-lang/crates.io-index"
61 61 dependencies = [
62 62 "bytes-cast-derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
63 63 ]
64 64
65 65 [[package]]
66 66 name = "bytes-cast-derive"
67 67 version = "0.1.0"
68 68 source = "registry+https://github.com/rust-lang/crates.io-index"
69 69 dependencies = [
70 70 "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)",
71 71 "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
72 72 "syn 1.0.54 (registry+https://github.com/rust-lang/crates.io-index)",
73 73 ]
74 74
75 75 [[package]]
76 76 name = "cc"
77 77 version = "1.0.66"
78 78 source = "registry+https://github.com/rust-lang/crates.io-index"
79 79 dependencies = [
80 80 "jobserver 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
81 81 ]
82 82
83 83 [[package]]
84 84 name = "cfg-if"
85 85 version = "0.1.10"
86 86 source = "registry+https://github.com/rust-lang/crates.io-index"
87 87
88 88 [[package]]
89 89 name = "cfg-if"
90 90 version = "1.0.0"
91 91 source = "registry+https://github.com/rust-lang/crates.io-index"
92 92
93 93 [[package]]
94 94 name = "clap"
95 95 version = "2.33.3"
96 96 source = "registry+https://github.com/rust-lang/crates.io-index"
97 97 dependencies = [
98 98 "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
99 99 "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
100 100 "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
101 101 "strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
102 102 "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
103 103 "unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
104 104 "vec_map 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
105 105 ]
106 106
107 107 [[package]]
108 108 name = "const_fn"
109 109 version = "0.4.4"
110 110 source = "registry+https://github.com/rust-lang/crates.io-index"
111 111
112 112 [[package]]
113 113 name = "cpython"
114 114 version = "0.4.1"
115 115 source = "registry+https://github.com/rust-lang/crates.io-index"
116 116 dependencies = [
117 117 "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)",
118 118 "num-traits 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
119 119 "python27-sys 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
120 120 "python3-sys 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
121 121 ]
122 122
123 123 [[package]]
124 124 name = "crc32fast"
125 125 version = "1.2.1"
126 126 source = "registry+https://github.com/rust-lang/crates.io-index"
127 127 dependencies = [
128 128 "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
129 129 ]
130 130
131 131 [[package]]
132 132 name = "crossbeam-channel"
133 133 version = "0.4.4"
134 134 source = "registry+https://github.com/rust-lang/crates.io-index"
135 135 dependencies = [
136 136 "crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
137 137 "maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
138 138 ]
139 139
140 140 [[package]]
141 141 name = "crossbeam-channel"
142 142 version = "0.5.0"
143 143 source = "registry+https://github.com/rust-lang/crates.io-index"
144 144 dependencies = [
145 145 "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
146 146 "crossbeam-utils 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
147 147 ]
148 148
149 149 [[package]]
150 150 name = "crossbeam-deque"
151 151 version = "0.8.0"
152 152 source = "registry+https://github.com/rust-lang/crates.io-index"
153 153 dependencies = [
154 154 "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
155 155 "crossbeam-epoch 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
156 156 "crossbeam-utils 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
157 157 ]
158 158
159 159 [[package]]
160 160 name = "crossbeam-epoch"
161 161 version = "0.9.1"
162 162 source = "registry+https://github.com/rust-lang/crates.io-index"
163 163 dependencies = [
164 164 "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
165 165 "const_fn 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
166 166 "crossbeam-utils 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
167 167 "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
168 168 "memoffset 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
169 169 "scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
170 170 ]
171 171
172 172 [[package]]
173 173 name = "crossbeam-utils"
174 174 version = "0.7.2"
175 175 source = "registry+https://github.com/rust-lang/crates.io-index"
176 176 dependencies = [
177 177 "autocfg 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
178 178 "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
179 179 "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
180 180 ]
181 181
182 182 [[package]]
183 183 name = "crossbeam-utils"
184 184 version = "0.8.1"
185 185 source = "registry+https://github.com/rust-lang/crates.io-index"
186 186 dependencies = [
187 187 "autocfg 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
188 188 "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
189 189 "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
190 190 ]
191 191
192 192 [[package]]
193 193 name = "ctor"
194 194 version = "0.1.16"
195 195 source = "registry+https://github.com/rust-lang/crates.io-index"
196 196 dependencies = [
197 197 "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
198 198 "syn 1.0.54 (registry+https://github.com/rust-lang/crates.io-index)",
199 199 ]
200 200
201 201 [[package]]
202 202 name = "derive_more"
203 203 version = "0.99.11"
204 204 source = "registry+https://github.com/rust-lang/crates.io-index"
205 205 dependencies = [
206 206 "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)",
207 207 "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
208 208 "syn 1.0.54 (registry+https://github.com/rust-lang/crates.io-index)",
209 209 ]
210 210
211 211 [[package]]
212 212 name = "difference"
213 213 version = "2.0.0"
214 214 source = "registry+https://github.com/rust-lang/crates.io-index"
215 215
216 216 [[package]]
217 217 name = "either"
218 218 version = "1.6.1"
219 219 source = "registry+https://github.com/rust-lang/crates.io-index"
220 220
221 221 [[package]]
222 222 name = "env_logger"
223 223 version = "0.7.1"
224 224 source = "registry+https://github.com/rust-lang/crates.io-index"
225 225 dependencies = [
226 226 "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
227 227 "humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
228 228 "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
229 229 "regex 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
230 230 "termcolor 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
231 231 ]
232 232
233 233 [[package]]
234 234 name = "flate2"
235 235 version = "1.0.19"
236 236 source = "registry+https://github.com/rust-lang/crates.io-index"
237 237 dependencies = [
238 238 "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
239 239 "crc32fast 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
240 240 "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)",
241 241 "libz-sys 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
242 242 "miniz_oxide 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
243 243 ]
244 244
245 245 [[package]]
246 246 name = "format-bytes"
247 247 version = "0.2.0"
248 248 source = "registry+https://github.com/rust-lang/crates.io-index"
249 249 dependencies = [
250 250 "format-bytes-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
251 251 "proc-macro-hack 0.5.19 (registry+https://github.com/rust-lang/crates.io-index)",
252 252 ]
253 253
254 254 [[package]]
255 255 name = "format-bytes-macros"
256 256 version = "0.3.0"
257 257 source = "registry+https://github.com/rust-lang/crates.io-index"
258 258 dependencies = [
259 259 "proc-macro-hack 0.5.19 (registry+https://github.com/rust-lang/crates.io-index)",
260 260 "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)",
261 261 "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
262 262 "syn 1.0.54 (registry+https://github.com/rust-lang/crates.io-index)",
263 263 ]
264 264
265 265 [[package]]
266 266 name = "fuchsia-cprng"
267 267 version = "0.1.1"
268 268 source = "registry+https://github.com/rust-lang/crates.io-index"
269 269
270 270 [[package]]
271 271 name = "gcc"
272 272 version = "0.3.55"
273 273 source = "registry+https://github.com/rust-lang/crates.io-index"
274 274
275 275 [[package]]
276 276 name = "getrandom"
277 277 version = "0.1.15"
278 278 source = "registry+https://github.com/rust-lang/crates.io-index"
279 279 dependencies = [
280 280 "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
281 281 "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)",
282 282 "wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)",
283 283 ]
284 284
285 285 [[package]]
286 286 name = "glob"
287 287 version = "0.3.0"
288 288 source = "registry+https://github.com/rust-lang/crates.io-index"
289 289
290 290 [[package]]
291 291 name = "hermit-abi"
292 292 version = "0.1.17"
293 293 source = "registry+https://github.com/rust-lang/crates.io-index"
294 294 dependencies = [
295 295 "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)",
296 296 ]
297 297
298 298 [[package]]
299 299 name = "hg-core"
300 300 version = "0.1.0"
301 301 dependencies = [
302 302 "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
303 303 "bytes-cast 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
304 304 "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)",
305 305 "crossbeam-channel 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
306 306 "derive_more 0.99.11 (registry+https://github.com/rust-lang/crates.io-index)",
307 307 "flate2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
308 308 "format-bytes 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
309 309 "home 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
310 310 "im-rc 15.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
311 311 "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
312 312 "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
313 "memchr 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
314 313 "memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
315 314 "micro-timer 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
316 315 "pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
317 316 "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
318 317 "rand_distr 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
319 318 "rand_pcg 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
320 319 "rayon 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
321 320 "regex 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
322 321 "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
323 322 "same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
324 323 "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
325 324 "twox-hash 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
326 325 "zstd 0.5.3+zstd.1.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
327 326 ]
328 327
329 328 [[package]]
330 329 name = "hg-cpython"
331 330 version = "0.1.0"
332 331 dependencies = [
333 332 "cpython 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
334 333 "crossbeam-channel 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
335 334 "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
336 335 "hg-core 0.1.0",
337 336 "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)",
338 337 "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
339 338 ]
340 339
341 340 [[package]]
342 341 name = "home"
343 342 version = "0.5.3"
344 343 source = "registry+https://github.com/rust-lang/crates.io-index"
345 344 dependencies = [
346 345 "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
347 346 ]
348 347
349 348 [[package]]
350 349 name = "humantime"
351 350 version = "1.3.0"
352 351 source = "registry+https://github.com/rust-lang/crates.io-index"
353 352 dependencies = [
354 353 "quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
355 354 ]
356 355
357 356 [[package]]
358 357 name = "im-rc"
359 358 version = "15.0.0"
360 359 source = "registry+https://github.com/rust-lang/crates.io-index"
361 360 dependencies = [
362 361 "bitmaps 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
363 362 "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
364 363 "rand_xoshiro 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
365 364 "sized-chunks 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
366 365 "typenum 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
367 366 "version_check 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
368 367 ]
369 368
370 369 [[package]]
371 370 name = "itertools"
372 371 version = "0.9.0"
373 372 source = "registry+https://github.com/rust-lang/crates.io-index"
374 373 dependencies = [
375 374 "either 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
376 375 ]
377 376
378 377 [[package]]
379 378 name = "jobserver"
380 379 version = "0.1.21"
381 380 source = "registry+https://github.com/rust-lang/crates.io-index"
382 381 dependencies = [
383 382 "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)",
384 383 ]
385 384
386 385 [[package]]
387 386 name = "lazy_static"
388 387 version = "1.4.0"
389 388 source = "registry+https://github.com/rust-lang/crates.io-index"
390 389
391 390 [[package]]
392 391 name = "libc"
393 392 version = "0.2.81"
394 393 source = "registry+https://github.com/rust-lang/crates.io-index"
395 394
396 395 [[package]]
397 396 name = "libz-sys"
398 397 version = "1.1.2"
399 398 source = "registry+https://github.com/rust-lang/crates.io-index"
400 399 dependencies = [
401 400 "cc 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
402 401 "pkg-config 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
403 402 "vcpkg 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
404 403 ]
405 404
406 405 [[package]]
407 406 name = "log"
408 407 version = "0.4.11"
409 408 source = "registry+https://github.com/rust-lang/crates.io-index"
410 409 dependencies = [
411 410 "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
412 411 ]
413 412
414 413 [[package]]
415 414 name = "maybe-uninit"
416 415 version = "2.0.0"
417 416 source = "registry+https://github.com/rust-lang/crates.io-index"
418 417
419 418 [[package]]
420 419 name = "memchr"
421 420 version = "2.3.4"
422 421 source = "registry+https://github.com/rust-lang/crates.io-index"
423 422
424 423 [[package]]
425 424 name = "memmap"
426 425 version = "0.7.0"
427 426 source = "registry+https://github.com/rust-lang/crates.io-index"
428 427 dependencies = [
429 428 "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)",
430 429 "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
431 430 ]
432 431
433 432 [[package]]
434 433 name = "memoffset"
435 434 version = "0.6.1"
436 435 source = "registry+https://github.com/rust-lang/crates.io-index"
437 436 dependencies = [
438 437 "autocfg 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
439 438 ]
440 439
441 440 [[package]]
442 441 name = "micro-timer"
443 442 version = "0.3.1"
444 443 source = "registry+https://github.com/rust-lang/crates.io-index"
445 444 dependencies = [
446 445 "micro-timer-macros 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
447 446 "scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
448 447 ]
449 448
450 449 [[package]]
451 450 name = "micro-timer-macros"
452 451 version = "0.3.1"
453 452 source = "registry+https://github.com/rust-lang/crates.io-index"
454 453 dependencies = [
455 454 "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)",
456 455 "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
457 456 "scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
458 457 "syn 1.0.54 (registry+https://github.com/rust-lang/crates.io-index)",
459 458 ]
460 459
461 460 [[package]]
462 461 name = "miniz_oxide"
463 462 version = "0.4.3"
464 463 source = "registry+https://github.com/rust-lang/crates.io-index"
465 464 dependencies = [
466 465 "adler 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
467 466 "autocfg 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
468 467 ]
469 468
470 469 [[package]]
471 470 name = "num-traits"
472 471 version = "0.2.14"
473 472 source = "registry+https://github.com/rust-lang/crates.io-index"
474 473 dependencies = [
475 474 "autocfg 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
476 475 ]
477 476
478 477 [[package]]
479 478 name = "num_cpus"
480 479 version = "1.13.0"
481 480 source = "registry+https://github.com/rust-lang/crates.io-index"
482 481 dependencies = [
483 482 "hermit-abi 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
484 483 "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)",
485 484 ]
486 485
487 486 [[package]]
488 487 name = "output_vt100"
489 488 version = "0.1.2"
490 489 source = "registry+https://github.com/rust-lang/crates.io-index"
491 490 dependencies = [
492 491 "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
493 492 ]
494 493
495 494 [[package]]
496 495 name = "pkg-config"
497 496 version = "0.3.19"
498 497 source = "registry+https://github.com/rust-lang/crates.io-index"
499 498
500 499 [[package]]
501 500 name = "ppv-lite86"
502 501 version = "0.2.10"
503 502 source = "registry+https://github.com/rust-lang/crates.io-index"
504 503
505 504 [[package]]
506 505 name = "pretty_assertions"
507 506 version = "0.6.1"
508 507 source = "registry+https://github.com/rust-lang/crates.io-index"
509 508 dependencies = [
510 509 "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
511 510 "ctor 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
512 511 "difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
513 512 "output_vt100 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
514 513 ]
515 514
516 515 [[package]]
517 516 name = "proc-macro-hack"
518 517 version = "0.5.19"
519 518 source = "registry+https://github.com/rust-lang/crates.io-index"
520 519
521 520 [[package]]
522 521 name = "proc-macro2"
523 522 version = "1.0.24"
524 523 source = "registry+https://github.com/rust-lang/crates.io-index"
525 524 dependencies = [
526 525 "unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
527 526 ]
528 527
529 528 [[package]]
530 529 name = "python27-sys"
531 530 version = "0.4.1"
532 531 source = "registry+https://github.com/rust-lang/crates.io-index"
533 532 dependencies = [
534 533 "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)",
535 534 "regex 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
536 535 ]
537 536
538 537 [[package]]
539 538 name = "python3-sys"
540 539 version = "0.4.1"
541 540 source = "registry+https://github.com/rust-lang/crates.io-index"
542 541 dependencies = [
543 542 "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)",
544 543 "regex 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
545 544 ]
546 545
547 546 [[package]]
548 547 name = "quick-error"
549 548 version = "1.2.3"
550 549 source = "registry+https://github.com/rust-lang/crates.io-index"
551 550
552 551 [[package]]
553 552 name = "quote"
554 553 version = "1.0.7"
555 554 source = "registry+https://github.com/rust-lang/crates.io-index"
556 555 dependencies = [
557 556 "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)",
558 557 ]
559 558
560 559 [[package]]
561 560 name = "rand"
562 561 version = "0.3.23"
563 562 source = "registry+https://github.com/rust-lang/crates.io-index"
564 563 dependencies = [
565 564 "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)",
566 565 "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
567 566 ]
568 567
569 568 [[package]]
570 569 name = "rand"
571 570 version = "0.4.6"
572 571 source = "registry+https://github.com/rust-lang/crates.io-index"
573 572 dependencies = [
574 573 "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
575 574 "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)",
576 575 "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
577 576 "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
578 577 "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
579 578 ]
580 579
581 580 [[package]]
582 581 name = "rand"
583 582 version = "0.7.3"
584 583 source = "registry+https://github.com/rust-lang/crates.io-index"
585 584 dependencies = [
586 585 "getrandom 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
587 586 "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)",
588 587 "rand_chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
589 588 "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
590 589 "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
591 590 ]
592 591
593 592 [[package]]
594 593 name = "rand_chacha"
595 594 version = "0.2.2"
596 595 source = "registry+https://github.com/rust-lang/crates.io-index"
597 596 dependencies = [
598 597 "ppv-lite86 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
599 598 "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
600 599 ]
601 600
602 601 [[package]]
603 602 name = "rand_core"
604 603 version = "0.3.1"
605 604 source = "registry+https://github.com/rust-lang/crates.io-index"
606 605 dependencies = [
607 606 "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
608 607 ]
609 608
610 609 [[package]]
611 610 name = "rand_core"
612 611 version = "0.4.2"
613 612 source = "registry+https://github.com/rust-lang/crates.io-index"
614 613
615 614 [[package]]
616 615 name = "rand_core"
617 616 version = "0.5.1"
618 617 source = "registry+https://github.com/rust-lang/crates.io-index"
619 618 dependencies = [
620 619 "getrandom 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
621 620 ]
622 621
623 622 [[package]]
624 623 name = "rand_distr"
625 624 version = "0.2.2"
626 625 source = "registry+https://github.com/rust-lang/crates.io-index"
627 626 dependencies = [
628 627 "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
629 628 ]
630 629
631 630 [[package]]
632 631 name = "rand_hc"
633 632 version = "0.2.0"
634 633 source = "registry+https://github.com/rust-lang/crates.io-index"
635 634 dependencies = [
636 635 "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
637 636 ]
638 637
639 638 [[package]]
640 639 name = "rand_pcg"
641 640 version = "0.2.1"
642 641 source = "registry+https://github.com/rust-lang/crates.io-index"
643 642 dependencies = [
644 643 "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
645 644 ]
646 645
647 646 [[package]]
648 647 name = "rand_xoshiro"
649 648 version = "0.4.0"
650 649 source = "registry+https://github.com/rust-lang/crates.io-index"
651 650 dependencies = [
652 651 "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
653 652 ]
654 653
655 654 [[package]]
656 655 name = "rayon"
657 656 version = "1.5.0"
658 657 source = "registry+https://github.com/rust-lang/crates.io-index"
659 658 dependencies = [
660 659 "autocfg 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
661 660 "crossbeam-deque 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
662 661 "either 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
663 662 "rayon-core 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
664 663 ]
665 664
666 665 [[package]]
667 666 name = "rayon-core"
668 667 version = "1.9.0"
669 668 source = "registry+https://github.com/rust-lang/crates.io-index"
670 669 dependencies = [
671 670 "crossbeam-channel 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
672 671 "crossbeam-deque 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
673 672 "crossbeam-utils 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
674 673 "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
675 674 "num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
676 675 ]
677 676
678 677 [[package]]
679 678 name = "rdrand"
680 679 version = "0.4.0"
681 680 source = "registry+https://github.com/rust-lang/crates.io-index"
682 681 dependencies = [
683 682 "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
684 683 ]
685 684
686 685 [[package]]
687 686 name = "redox_syscall"
688 687 version = "0.1.57"
689 688 source = "registry+https://github.com/rust-lang/crates.io-index"
690 689
691 690 [[package]]
692 691 name = "regex"
693 692 version = "1.4.2"
694 693 source = "registry+https://github.com/rust-lang/crates.io-index"
695 694 dependencies = [
696 695 "aho-corasick 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
697 696 "memchr 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
698 697 "regex-syntax 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)",
699 698 "thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
700 699 ]
701 700
702 701 [[package]]
703 702 name = "regex-syntax"
704 703 version = "0.6.21"
705 704 source = "registry+https://github.com/rust-lang/crates.io-index"
706 705
707 706 [[package]]
708 707 name = "remove_dir_all"
709 708 version = "0.5.3"
710 709 source = "registry+https://github.com/rust-lang/crates.io-index"
711 710 dependencies = [
712 711 "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
713 712 ]
714 713
715 714 [[package]]
716 715 name = "rhg"
717 716 version = "0.1.0"
718 717 dependencies = [
719 718 "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)",
720 719 "derive_more 0.99.11 (registry+https://github.com/rust-lang/crates.io-index)",
721 720 "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
722 721 "format-bytes 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
723 722 "hg-core 0.1.0",
724 723 "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
725 724 "micro-timer 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
726 725 ]
727 726
728 727 [[package]]
729 728 name = "rust-crypto"
730 729 version = "0.2.36"
731 730 source = "registry+https://github.com/rust-lang/crates.io-index"
732 731 dependencies = [
733 732 "gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)",
734 733 "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)",
735 734 "rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)",
736 735 "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
737 736 "time 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)",
738 737 ]
739 738
740 739 [[package]]
741 740 name = "rustc-serialize"
742 741 version = "0.3.24"
743 742 source = "registry+https://github.com/rust-lang/crates.io-index"
744 743
745 744 [[package]]
746 745 name = "same-file"
747 746 version = "1.0.6"
748 747 source = "registry+https://github.com/rust-lang/crates.io-index"
749 748 dependencies = [
750 749 "winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
751 750 ]
752 751
753 752 [[package]]
754 753 name = "scopeguard"
755 754 version = "1.1.0"
756 755 source = "registry+https://github.com/rust-lang/crates.io-index"
757 756
758 757 [[package]]
759 758 name = "sized-chunks"
760 759 version = "0.6.2"
761 760 source = "registry+https://github.com/rust-lang/crates.io-index"
762 761 dependencies = [
763 762 "bitmaps 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
764 763 "typenum 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
765 764 ]
766 765
767 766 [[package]]
768 767 name = "static_assertions"
769 768 version = "1.1.0"
770 769 source = "registry+https://github.com/rust-lang/crates.io-index"
771 770
772 771 [[package]]
773 772 name = "strsim"
774 773 version = "0.8.0"
775 774 source = "registry+https://github.com/rust-lang/crates.io-index"
776 775
777 776 [[package]]
778 777 name = "syn"
779 778 version = "1.0.54"
780 779 source = "registry+https://github.com/rust-lang/crates.io-index"
781 780 dependencies = [
782 781 "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)",
783 782 "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
784 783 "unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
785 784 ]
786 785
787 786 [[package]]
788 787 name = "tempfile"
789 788 version = "3.1.0"
790 789 source = "registry+https://github.com/rust-lang/crates.io-index"
791 790 dependencies = [
792 791 "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
793 792 "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)",
794 793 "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
795 794 "redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)",
796 795 "remove_dir_all 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
797 796 "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
798 797 ]
799 798
800 799 [[package]]
801 800 name = "termcolor"
802 801 version = "1.1.2"
803 802 source = "registry+https://github.com/rust-lang/crates.io-index"
804 803 dependencies = [
805 804 "winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
806 805 ]
807 806
808 807 [[package]]
809 808 name = "textwrap"
810 809 version = "0.11.0"
811 810 source = "registry+https://github.com/rust-lang/crates.io-index"
812 811 dependencies = [
813 812 "unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
814 813 ]
815 814
816 815 [[package]]
817 816 name = "thread_local"
818 817 version = "1.0.1"
819 818 source = "registry+https://github.com/rust-lang/crates.io-index"
820 819 dependencies = [
821 820 "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
822 821 ]
823 822
824 823 [[package]]
825 824 name = "time"
826 825 version = "0.1.44"
827 826 source = "registry+https://github.com/rust-lang/crates.io-index"
828 827 dependencies = [
829 828 "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)",
830 829 "wasi 0.10.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)",
831 830 "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
832 831 ]
833 832
834 833 [[package]]
835 834 name = "twox-hash"
836 835 version = "1.6.0"
837 836 source = "registry+https://github.com/rust-lang/crates.io-index"
838 837 dependencies = [
839 838 "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
840 839 "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
841 840 "static_assertions 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
842 841 ]
843 842
844 843 [[package]]
845 844 name = "typenum"
846 845 version = "1.12.0"
847 846 source = "registry+https://github.com/rust-lang/crates.io-index"
848 847
849 848 [[package]]
850 849 name = "unicode-width"
851 850 version = "0.1.8"
852 851 source = "registry+https://github.com/rust-lang/crates.io-index"
853 852
854 853 [[package]]
855 854 name = "unicode-xid"
856 855 version = "0.2.1"
857 856 source = "registry+https://github.com/rust-lang/crates.io-index"
858 857
859 858 [[package]]
860 859 name = "vcpkg"
861 860 version = "0.2.11"
862 861 source = "registry+https://github.com/rust-lang/crates.io-index"
863 862
864 863 [[package]]
865 864 name = "vec_map"
866 865 version = "0.8.2"
867 866 source = "registry+https://github.com/rust-lang/crates.io-index"
868 867
869 868 [[package]]
870 869 name = "version_check"
871 870 version = "0.9.2"
872 871 source = "registry+https://github.com/rust-lang/crates.io-index"
873 872
874 873 [[package]]
875 874 name = "wasi"
876 875 version = "0.9.0+wasi-snapshot-preview1"
877 876 source = "registry+https://github.com/rust-lang/crates.io-index"
878 877
879 878 [[package]]
880 879 name = "wasi"
881 880 version = "0.10.0+wasi-snapshot-preview1"
882 881 source = "registry+https://github.com/rust-lang/crates.io-index"
883 882
884 883 [[package]]
885 884 name = "winapi"
886 885 version = "0.3.9"
887 886 source = "registry+https://github.com/rust-lang/crates.io-index"
888 887 dependencies = [
889 888 "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
890 889 "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
891 890 ]
892 891
893 892 [[package]]
894 893 name = "winapi-i686-pc-windows-gnu"
895 894 version = "0.4.0"
896 895 source = "registry+https://github.com/rust-lang/crates.io-index"
897 896
898 897 [[package]]
899 898 name = "winapi-util"
900 899 version = "0.1.5"
901 900 source = "registry+https://github.com/rust-lang/crates.io-index"
902 901 dependencies = [
903 902 "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
904 903 ]
905 904
906 905 [[package]]
907 906 name = "winapi-x86_64-pc-windows-gnu"
908 907 version = "0.4.0"
909 908 source = "registry+https://github.com/rust-lang/crates.io-index"
910 909
911 910 [[package]]
912 911 name = "zstd"
913 912 version = "0.5.3+zstd.1.4.5"
914 913 source = "registry+https://github.com/rust-lang/crates.io-index"
915 914 dependencies = [
916 915 "zstd-safe 2.0.5+zstd.1.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
917 916 ]
918 917
919 918 [[package]]
920 919 name = "zstd-safe"
921 920 version = "2.0.5+zstd.1.4.5"
922 921 source = "registry+https://github.com/rust-lang/crates.io-index"
923 922 dependencies = [
924 923 "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)",
925 924 "zstd-sys 1.4.17+zstd.1.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
926 925 ]
927 926
928 927 [[package]]
929 928 name = "zstd-sys"
930 929 version = "1.4.17+zstd.1.4.5"
931 930 source = "registry+https://github.com/rust-lang/crates.io-index"
932 931 dependencies = [
933 932 "cc 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
934 933 "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
935 934 "itertools 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
936 935 "libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)",
937 936 ]
938 937
939 938 [metadata]
940 939 "checksum adler 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e"
941 940 "checksum aho-corasick 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5"
942 941 "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
943 942 "checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
944 943 "checksum autocfg 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
945 944 "checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
946 945 "checksum bitmaps 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "031043d04099746d8db04daf1fa424b2bc8bd69d92b25962dcde24da39ab64a2"
947 946 "checksum byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
948 947 "checksum bytes-cast 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3196ba300c7bc9282a4331e878496cb3e9603a898a8f1446601317163e16ca52"
949 948 "checksum bytes-cast-derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cb936af9de38476664d6b58e529aff30d482e4ce1c5e150293d00730b0d81fdb"
950 949 "checksum cc 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)" = "4c0496836a84f8d0495758516b8621a622beb77c0fed418570e50764093ced48"
951 950 "checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
952 951 "checksum cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
953 952 "checksum clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)" = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
954 953 "checksum const_fn 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cd51eab21ab4fd6a3bf889e2d0958c0a6e3a61ad04260325e919e652a2a62826"
955 954 "checksum cpython 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bfaf3847ab963e40c4f6dd8d6be279bdf74007ae2413786a0dcbb28c52139a95"
956 955 "checksum crc32fast 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
957 956 "checksum crossbeam-channel 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b153fe7cbef478c567df0f972e02e6d736db11affe43dfc9c56a9374d1adfb87"
958 957 "checksum crossbeam-channel 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775"
959 958 "checksum crossbeam-deque 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9"
960 959 "checksum crossbeam-epoch 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a1aaa739f95311c2c7887a76863f500026092fb1dce0161dab577e559ef3569d"
961 960 "checksum crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
962 961 "checksum crossbeam-utils 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "02d96d1e189ef58269ebe5b97953da3274d83a93af647c2ddd6f9dab28cedb8d"
963 962 "checksum ctor 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "7fbaabec2c953050352311293be5c6aba8e141ba19d6811862b232d6fd020484"
964 963 "checksum derive_more 0.99.11 (registry+https://github.com/rust-lang/crates.io-index)" = "41cb0e6161ad61ed084a36ba71fbba9e3ac5aee3606fb607fe08da6acbcf3d8c"
965 964 "checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
966 965 "checksum either 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
967 966 "checksum env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36"
968 967 "checksum flate2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)" = "7411863d55df97a419aa64cb4d2f167103ea9d767e2c54a1868b7ac3f6b47129"
969 968 "checksum format-bytes 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cc35f5e45d6b31053cea13078ffc6fa52fa8617aa54b7ac2011720d9c009e04f"
970 969 "checksum format-bytes-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b05089e341a0460449e2210c3bf7b61597860b07f0deae58da38dbed0a4c6b6d"
971 970 "checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
972 971 "checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2"
973 972 "checksum getrandom 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6"
974 973 "checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
975 974 "checksum hermit-abi 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8"
976 975 "checksum home 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2456aef2e6b6a9784192ae780c0f15bc57df0e918585282325e8c8ac27737654"
977 976 "checksum humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
978 977 "checksum im-rc 15.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ca8957e71f04a205cb162508f9326aea04676c8dfd0711220190d6b83664f3f"
979 978 "checksum itertools 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b"
980 979 "checksum jobserver 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "5c71313ebb9439f74b00d9d2dcec36440beaf57a6aa0623068441dd7cd81a7f2"
981 980 "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
982 981 "checksum libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)" = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb"
983 982 "checksum libz-sys 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "602113192b08db8f38796c4e85c39e960c145965140e918018bcde1952429655"
984 983 "checksum log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
985 984 "checksum maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
986 985 "checksum memchr 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
987 986 "checksum memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b"
988 987 "checksum memoffset 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "157b4208e3059a8f9e78d559edc658e13df41410cb3ae03979c83130067fdd87"
989 988 "checksum micro-timer 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2620153e1d903d26b72b89f0e9c48d8c4756cba941c185461dddc234980c298c"
990 989 "checksum micro-timer-macros 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e28a3473e6abd6e9aab36aaeef32ad22ae0bd34e79f376643594c2b152ec1c5d"
991 990 "checksum miniz_oxide 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0f2d26ec3309788e423cfbf68ad1800f061638098d76a83681af979dc4eda19d"
992 991 "checksum num-traits 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
993 992 "checksum num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
994 993 "checksum output_vt100 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "53cdc5b785b7a58c5aad8216b3dfa114df64b0b06ae6e1501cef91df2fbdf8f9"
995 994 "checksum pkg-config 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)" = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c"
996 995 "checksum ppv-lite86 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
997 996 "checksum pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3f81e1644e1b54f5a68959a29aa86cde704219254669da328ecfdf6a1f09d427"
998 997 "checksum proc-macro-hack 0.5.19 (registry+https://github.com/rust-lang/crates.io-index)" = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
999 998 "checksum proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
1000 999 "checksum python27-sys 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "67cb041de8615111bf224dd75667af5f25c6e032118251426fed7f1b70ce4c8c"
1001 1000 "checksum python3-sys 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90af11779515a1e530af60782d273b59ac79d33b0e253c071a728563957c76d4"
1002 1001 "checksum quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
1003 1002 "checksum quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
1004 1003 "checksum rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)" = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c"
1005 1004 "checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293"
1006 1005 "checksum rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
1007 1006 "checksum rand_chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
1008 1007 "checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
1009 1008 "checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
1010 1009 "checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
1011 1010 "checksum rand_distr 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "96977acbdd3a6576fb1d27391900035bf3863d4a16422973a409b488cf29ffb2"
1012 1011 "checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
1013 1012 "checksum rand_pcg 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429"
1014 1013 "checksum rand_xoshiro 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9fcdd2e881d02f1d9390ae47ad8e5696a9e4be7b547a1da2afbc61973217004"
1015 1014 "checksum rayon 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674"
1016 1015 "checksum rayon-core 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a"
1017 1016 "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
1018 1017 "checksum redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)" = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
1019 1018 "checksum regex 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "38cf2c13ed4745de91a5eb834e11c00bcc3709e773173b2ce4c56c9fbde04b9c"
1020 1019 "checksum regex-syntax 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)" = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189"
1021 1020 "checksum remove_dir_all 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
1022 1021 "checksum rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a"
1023 1022 "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
1024 1023 "checksum same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
1025 1024 "checksum scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
1026 1025 "checksum sized-chunks 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1ec31ceca5644fa6d444cc77548b88b67f46db6f7c71683b0f9336e671830d2f"
1027 1026 "checksum static_assertions 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
1028 1027 "checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
1029 1028 "checksum syn 1.0.54 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2af957a63d6bd42255c359c93d9bfdb97076bd3b820897ce55ffbfbf107f44"
1030 1029 "checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
1031 1030 "checksum termcolor 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
1032 1031 "checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
1033 1032 "checksum thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
1034 1033 "checksum time 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)" = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
1035 1034 "checksum twox-hash 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "04f8ab788026715fa63b31960869617cba39117e520eb415b0139543e325ab59"
1036 1035 "checksum typenum 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33"
1037 1036 "checksum unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
1038 1037 "checksum unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
1039 1038 "checksum vcpkg 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b00bca6106a5e23f3eee943593759b7fcddb00554332e856d990c893966879fb"
1040 1039 "checksum vec_map 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
1041 1040 "checksum version_check 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
1042 1041 "checksum wasi 0.10.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
1043 1042 "checksum wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
1044 1043 "checksum winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
1045 1044 "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
1046 1045 "checksum winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
1047 1046 "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
1048 1047 "checksum zstd 0.5.3+zstd.1.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "01b32eaf771efa709e8308605bbf9319bf485dc1503179ec0469b611937c0cd8"
1049 1048 "checksum zstd-safe 2.0.5+zstd.1.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1cfb642e0d27f64729a639c52db457e0ae906e7bc6f5fe8f5c453230400f1055"
1050 1049 "checksum zstd-sys 1.4.17+zstd.1.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b89249644df056b522696b1bb9e7c18c87e8ffa3e2f0dc3b0155875d6498f01b"
@@ -1,50 +1,49
1 1 [package]
2 2 name = "hg-core"
3 3 version = "0.1.0"
4 4 authors = ["Georges Racinet <gracinet@anybox.fr>"]
5 5 description = "Mercurial pure Rust core library, with no assumption on Python bindings (FFI)"
6 6 edition = "2018"
7 7
8 8 [lib]
9 9 name = "hg"
10 10
11 11 [dependencies]
12 12 bytes-cast = "0.1"
13 13 byteorder = "1.3.4"
14 14 derive_more = "0.99"
15 15 home = "0.5"
16 16 im-rc = "15.0.*"
17 17 lazy_static = "1.4.0"
18 memchr = "2.3.3"
19 18 rand = "0.7.3"
20 19 rand_pcg = "0.2.1"
21 20 rand_distr = "0.2.2"
22 21 rayon = "1.3.0"
23 22 regex = "1.3.9"
24 23 twox-hash = "1.5.0"
25 24 same-file = "1.0.6"
26 25 crossbeam-channel = "0.4"
27 26 micro-timer = "0.3.0"
28 27 log = "0.4.8"
29 28 memmap = "0.7.0"
30 29 zstd = "0.5.3"
31 30 rust-crypto = "0.2.36"
32 31 format-bytes = "0.2.0"
33 32
34 33 # We don't use the `miniz-oxide` backend to not change rhg benchmarks and until
35 34 # we have a clearer view of which backend is the fastest.
36 35 [dependencies.flate2]
37 36 version = "1.0.16"
38 37 features = ["zlib"]
39 38 default-features = false
40 39
41 40 [dev-dependencies]
42 41 clap = "*"
43 42 pretty_assertions = "0.6.1"
44 43 tempfile = "3.1.0"
45 44
46 45 [features]
47 46 # Use a (still unoptimized) tree for the dirstate instead of the current flat
48 47 # dirstate. This is not yet recommended for performance reasons. A future
49 48 # version might make it the default, or make it a runtime option.
50 49 dirstate-tree = []
@@ -1,91 +1,103
1 1 // dirstate module
2 2 //
3 3 // Copyright 2019 Raphaël Gomès <rgomes@octobus.net>
4 4 //
5 5 // This software may be used and distributed according to the terms of the
6 6 // GNU General Public License version 2 or any later version.
7 7
8 8 use crate::errors::HgError;
9 9 use crate::{utils::hg_path::HgPathBuf, FastHashMap};
10 use bytes_cast::{unaligned, BytesCast};
10 11 use std::collections::hash_map;
11 12 use std::convert::TryFrom;
12 13
13 14 pub mod dirs_multiset;
14 15 pub mod dirstate_map;
15 16 #[cfg(feature = "dirstate-tree")]
16 17 pub mod dirstate_tree;
17 18 pub mod parsers;
18 19 pub mod status;
19 20
20 #[derive(Debug, PartialEq, Clone)]
21 #[derive(Debug, PartialEq, Clone, BytesCast)]
22 #[repr(C)]
21 23 pub struct DirstateParents {
22 24 pub p1: [u8; 20],
23 25 pub p2: [u8; 20],
24 26 }
25 27
26 28 /// The C implementation uses all signed types. This will be an issue
27 29 /// either when 4GB+ source files are commonplace or in 2038, whichever
28 30 /// comes first.
29 31 #[derive(Debug, PartialEq, Copy, Clone)]
30 32 pub struct DirstateEntry {
31 33 pub state: EntryState,
32 34 pub mode: i32,
33 35 pub mtime: i32,
34 36 pub size: i32,
35 37 }
36 38
39 #[derive(BytesCast)]
40 #[repr(C)]
41 struct RawEntry {
42 state: u8,
43 mode: unaligned::I32Be,
44 size: unaligned::I32Be,
45 mtime: unaligned::I32Be,
46 length: unaligned::I32Be,
47 }
48
37 49 /// A `DirstateEntry` with a size of `-2` means that it was merged from the
38 50 /// other parent. This allows revert to pick the right status back during a
39 51 /// merge.
40 52 pub const SIZE_FROM_OTHER_PARENT: i32 = -2;
41 53
42 54 #[cfg(not(feature = "dirstate-tree"))]
43 55 pub type StateMap = FastHashMap<HgPathBuf, DirstateEntry>;
44 56 #[cfg(not(feature = "dirstate-tree"))]
45 57 pub type StateMapIter<'a> = hash_map::Iter<'a, HgPathBuf, DirstateEntry>;
46 58
47 59 #[cfg(feature = "dirstate-tree")]
48 60 pub type StateMap = dirstate_tree::tree::Tree;
49 61 #[cfg(feature = "dirstate-tree")]
50 62 pub type StateMapIter<'a> = dirstate_tree::iter::Iter<'a>;
51 63 pub type CopyMap = FastHashMap<HgPathBuf, HgPathBuf>;
52 64 pub type CopyMapIter<'a> = hash_map::Iter<'a, HgPathBuf, HgPathBuf>;
53 65
54 66 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
55 67 pub enum EntryState {
56 68 Normal,
57 69 Added,
58 70 Removed,
59 71 Merged,
60 72 Unknown,
61 73 }
62 74
63 75 impl TryFrom<u8> for EntryState {
64 76 type Error = HgError;
65 77
66 78 fn try_from(value: u8) -> Result<Self, Self::Error> {
67 79 match value {
68 80 b'n' => Ok(EntryState::Normal),
69 81 b'a' => Ok(EntryState::Added),
70 82 b'r' => Ok(EntryState::Removed),
71 83 b'm' => Ok(EntryState::Merged),
72 84 b'?' => Ok(EntryState::Unknown),
73 85 _ => Err(HgError::CorruptedRepository(format!(
74 86 "Incorrect dirstate entry state {}",
75 87 value
76 88 ))),
77 89 }
78 90 }
79 91 }
80 92
81 93 impl Into<u8> for EntryState {
82 94 fn into(self) -> u8 {
83 95 match self {
84 96 EntryState::Normal => b'n',
85 97 EntryState::Added => b'a',
86 98 EntryState::Removed => b'r',
87 99 EntryState::Merged => b'm',
88 100 EntryState::Unknown => b'?',
89 101 }
90 102 }
91 103 }
@@ -1,549 +1,549
1 1 // dirstate_map.rs
2 2 //
3 3 // Copyright 2019 Raphaël Gomès <rgomes@octobus.net>
4 4 //
5 5 // This software may be used and distributed according to the terms of the
6 6 // GNU General Public License version 2 or any later version.
7 7
8 8 use crate::errors::HgError;
9 9 use crate::revlog::node::NULL_NODE_ID;
10 10 use crate::{
11 11 dirstate::{parsers::PARENT_SIZE, EntryState, SIZE_FROM_OTHER_PARENT},
12 12 pack_dirstate, parse_dirstate,
13 13 utils::{
14 14 files::normalize_case,
15 15 hg_path::{HgPath, HgPathBuf},
16 16 },
17 17 CopyMap, DirsMultiset, DirstateEntry, DirstateError, DirstateMapError,
18 18 DirstateParents, FastHashMap, StateMap,
19 19 };
20 20 use micro_timer::timed;
21 21 use std::collections::HashSet;
22 22 use std::convert::TryInto;
23 23 use std::iter::FromIterator;
24 24 use std::ops::Deref;
25 25 use std::time::Duration;
26 26
27 27 pub type FileFoldMap = FastHashMap<HgPathBuf, HgPathBuf>;
28 28
29 29 const MTIME_UNSET: i32 = -1;
30 30
31 31 #[derive(Default)]
32 32 pub struct DirstateMap {
33 33 state_map: StateMap,
34 34 pub copy_map: CopyMap,
35 35 file_fold_map: Option<FileFoldMap>,
36 36 pub dirs: Option<DirsMultiset>,
37 37 pub all_dirs: Option<DirsMultiset>,
38 38 non_normal_set: Option<HashSet<HgPathBuf>>,
39 39 other_parent_set: Option<HashSet<HgPathBuf>>,
40 40 parents: Option<DirstateParents>,
41 41 dirty_parents: bool,
42 42 }
43 43
44 44 /// Should only really be used in python interface code, for clarity
45 45 impl Deref for DirstateMap {
46 46 type Target = StateMap;
47 47
48 48 fn deref(&self) -> &Self::Target {
49 49 &self.state_map
50 50 }
51 51 }
52 52
53 53 impl FromIterator<(HgPathBuf, DirstateEntry)> for DirstateMap {
54 54 fn from_iter<I: IntoIterator<Item = (HgPathBuf, DirstateEntry)>>(
55 55 iter: I,
56 56 ) -> Self {
57 57 Self {
58 58 state_map: iter.into_iter().collect(),
59 59 ..Self::default()
60 60 }
61 61 }
62 62 }
63 63
64 64 impl DirstateMap {
65 65 pub fn new() -> Self {
66 66 Self::default()
67 67 }
68 68
69 69 pub fn clear(&mut self) {
70 70 self.state_map = StateMap::default();
71 71 self.copy_map.clear();
72 72 self.file_fold_map = None;
73 73 self.non_normal_set = None;
74 74 self.other_parent_set = None;
75 75 self.set_parents(&DirstateParents {
76 76 p1: NULL_NODE_ID,
77 77 p2: NULL_NODE_ID,
78 78 })
79 79 }
80 80
81 81 /// Add a tracked file to the dirstate
82 82 pub fn add_file(
83 83 &mut self,
84 84 filename: &HgPath,
85 85 old_state: EntryState,
86 86 entry: DirstateEntry,
87 87 ) -> Result<(), DirstateMapError> {
88 88 if old_state == EntryState::Unknown || old_state == EntryState::Removed
89 89 {
90 90 if let Some(ref mut dirs) = self.dirs {
91 91 dirs.add_path(filename)?;
92 92 }
93 93 }
94 94 if old_state == EntryState::Unknown {
95 95 if let Some(ref mut all_dirs) = self.all_dirs {
96 96 all_dirs.add_path(filename)?;
97 97 }
98 98 }
99 99 self.state_map.insert(filename.to_owned(), entry.to_owned());
100 100
101 101 if entry.state != EntryState::Normal || entry.mtime == MTIME_UNSET {
102 102 self.get_non_normal_other_parent_entries()
103 103 .0
104 104 .insert(filename.to_owned());
105 105 }
106 106
107 107 if entry.size == SIZE_FROM_OTHER_PARENT {
108 108 self.get_non_normal_other_parent_entries()
109 109 .1
110 110 .insert(filename.to_owned());
111 111 }
112 112 Ok(())
113 113 }
114 114
115 115 /// Mark a file as removed in the dirstate.
116 116 ///
117 117 /// The `size` parameter is used to store sentinel values that indicate
118 118 /// the file's previous state. In the future, we should refactor this
119 119 /// to be more explicit about what that state is.
120 120 pub fn remove_file(
121 121 &mut self,
122 122 filename: &HgPath,
123 123 old_state: EntryState,
124 124 size: i32,
125 125 ) -> Result<(), DirstateMapError> {
126 126 if old_state != EntryState::Unknown && old_state != EntryState::Removed
127 127 {
128 128 if let Some(ref mut dirs) = self.dirs {
129 129 dirs.delete_path(filename)?;
130 130 }
131 131 }
132 132 if old_state == EntryState::Unknown {
133 133 if let Some(ref mut all_dirs) = self.all_dirs {
134 134 all_dirs.add_path(filename)?;
135 135 }
136 136 }
137 137
138 138 if let Some(ref mut file_fold_map) = self.file_fold_map {
139 139 file_fold_map.remove(&normalize_case(filename));
140 140 }
141 141 self.state_map.insert(
142 142 filename.to_owned(),
143 143 DirstateEntry {
144 144 state: EntryState::Removed,
145 145 mode: 0,
146 146 size,
147 147 mtime: 0,
148 148 },
149 149 );
150 150 self.get_non_normal_other_parent_entries()
151 151 .0
152 152 .insert(filename.to_owned());
153 153 Ok(())
154 154 }
155 155
156 156 /// Remove a file from the dirstate.
157 157 /// Returns `true` if the file was previously recorded.
158 158 pub fn drop_file(
159 159 &mut self,
160 160 filename: &HgPath,
161 161 old_state: EntryState,
162 162 ) -> Result<bool, DirstateMapError> {
163 163 let exists = self.state_map.remove(filename).is_some();
164 164
165 165 if exists {
166 166 if old_state != EntryState::Removed {
167 167 if let Some(ref mut dirs) = self.dirs {
168 168 dirs.delete_path(filename)?;
169 169 }
170 170 }
171 171 if let Some(ref mut all_dirs) = self.all_dirs {
172 172 all_dirs.delete_path(filename)?;
173 173 }
174 174 }
175 175 if let Some(ref mut file_fold_map) = self.file_fold_map {
176 176 file_fold_map.remove(&normalize_case(filename));
177 177 }
178 178 self.get_non_normal_other_parent_entries()
179 179 .0
180 180 .remove(filename);
181 181
182 182 Ok(exists)
183 183 }
184 184
185 185 pub fn clear_ambiguous_times(
186 186 &mut self,
187 187 filenames: Vec<HgPathBuf>,
188 188 now: i32,
189 189 ) {
190 190 for filename in filenames {
191 191 let mut changed = false;
192 192 if let Some(entry) = self.state_map.get_mut(&filename) {
193 193 if entry.state == EntryState::Normal && entry.mtime == now {
194 194 changed = true;
195 195 *entry = DirstateEntry {
196 196 mtime: MTIME_UNSET,
197 197 ..*entry
198 198 };
199 199 }
200 200 }
201 201 if changed {
202 202 self.get_non_normal_other_parent_entries()
203 203 .0
204 204 .insert(filename.to_owned());
205 205 }
206 206 }
207 207 }
208 208
209 209 pub fn non_normal_entries_remove(
210 210 &mut self,
211 211 key: impl AsRef<HgPath>,
212 212 ) -> bool {
213 213 self.get_non_normal_other_parent_entries()
214 214 .0
215 215 .remove(key.as_ref())
216 216 }
217 217 pub fn non_normal_entries_union(
218 218 &mut self,
219 219 other: HashSet<HgPathBuf>,
220 220 ) -> Vec<HgPathBuf> {
221 221 self.get_non_normal_other_parent_entries()
222 222 .0
223 223 .union(&other)
224 224 .map(ToOwned::to_owned)
225 225 .collect()
226 226 }
227 227
228 228 pub fn get_non_normal_other_parent_entries(
229 229 &mut self,
230 230 ) -> (&mut HashSet<HgPathBuf>, &mut HashSet<HgPathBuf>) {
231 231 self.set_non_normal_other_parent_entries(false);
232 232 (
233 233 self.non_normal_set.as_mut().unwrap(),
234 234 self.other_parent_set.as_mut().unwrap(),
235 235 )
236 236 }
237 237
238 238 /// Useful to get immutable references to those sets in contexts where
239 239 /// you only have an immutable reference to the `DirstateMap`, like when
240 240 /// sharing references with Python.
241 241 ///
242 242 /// TODO, get rid of this along with the other "setter/getter" stuff when
243 243 /// a nice typestate plan is defined.
244 244 ///
245 245 /// # Panics
246 246 ///
247 247 /// Will panic if either set is `None`.
248 248 pub fn get_non_normal_other_parent_entries_panic(
249 249 &self,
250 250 ) -> (&HashSet<HgPathBuf>, &HashSet<HgPathBuf>) {
251 251 (
252 252 self.non_normal_set.as_ref().unwrap(),
253 253 self.other_parent_set.as_ref().unwrap(),
254 254 )
255 255 }
256 256
257 257 #[cfg(not(feature = "dirstate-tree"))]
258 258 pub fn set_non_normal_other_parent_entries(&mut self, force: bool) {
259 259 if !force
260 260 && self.non_normal_set.is_some()
261 261 && self.other_parent_set.is_some()
262 262 {
263 263 return;
264 264 }
265 265 let mut non_normal = HashSet::new();
266 266 let mut other_parent = HashSet::new();
267 267
268 268 for (
269 269 filename,
270 270 DirstateEntry {
271 271 state, size, mtime, ..
272 272 },
273 273 ) in self.state_map.iter()
274 274 {
275 275 if *state != EntryState::Normal || *mtime == MTIME_UNSET {
276 276 non_normal.insert(filename.to_owned());
277 277 }
278 278 if *state == EntryState::Normal && *size == SIZE_FROM_OTHER_PARENT
279 279 {
280 280 other_parent.insert(filename.to_owned());
281 281 }
282 282 }
283 283 self.non_normal_set = Some(non_normal);
284 284 self.other_parent_set = Some(other_parent);
285 285 }
286 286 #[cfg(feature = "dirstate-tree")]
287 287 pub fn set_non_normal_other_parent_entries(&mut self, force: bool) {
288 288 if !force
289 289 && self.non_normal_set.is_some()
290 290 && self.other_parent_set.is_some()
291 291 {
292 292 return;
293 293 }
294 294 let mut non_normal = HashSet::new();
295 295 let mut other_parent = HashSet::new();
296 296
297 297 for (
298 298 filename,
299 299 DirstateEntry {
300 300 state, size, mtime, ..
301 301 },
302 302 ) in self.state_map.iter()
303 303 {
304 304 if state != EntryState::Normal || mtime == MTIME_UNSET {
305 305 non_normal.insert(filename.to_owned());
306 306 }
307 307 if state == EntryState::Normal && size == SIZE_FROM_OTHER_PARENT {
308 308 other_parent.insert(filename.to_owned());
309 309 }
310 310 }
311 311 self.non_normal_set = Some(non_normal);
312 312 self.other_parent_set = Some(other_parent);
313 313 }
314 314
315 315 /// Both of these setters and their uses appear to be the simplest way to
316 316 /// emulate a Python lazy property, but it is ugly and unidiomatic.
317 317 /// TODO One day, rewriting this struct using the typestate might be a
318 318 /// good idea.
319 319 pub fn set_all_dirs(&mut self) -> Result<(), DirstateMapError> {
320 320 if self.all_dirs.is_none() {
321 321 self.all_dirs =
322 322 Some(DirsMultiset::from_dirstate(&self.state_map, None)?);
323 323 }
324 324 Ok(())
325 325 }
326 326
327 327 pub fn set_dirs(&mut self) -> Result<(), DirstateMapError> {
328 328 if self.dirs.is_none() {
329 329 self.dirs = Some(DirsMultiset::from_dirstate(
330 330 &self.state_map,
331 331 Some(EntryState::Removed),
332 332 )?);
333 333 }
334 334 Ok(())
335 335 }
336 336
337 337 pub fn has_tracked_dir(
338 338 &mut self,
339 339 directory: &HgPath,
340 340 ) -> Result<bool, DirstateMapError> {
341 341 self.set_dirs()?;
342 342 Ok(self.dirs.as_ref().unwrap().contains(directory))
343 343 }
344 344
345 345 pub fn has_dir(
346 346 &mut self,
347 347 directory: &HgPath,
348 348 ) -> Result<bool, DirstateMapError> {
349 349 self.set_all_dirs()?;
350 350 Ok(self.all_dirs.as_ref().unwrap().contains(directory))
351 351 }
352 352
353 353 pub fn parents(
354 354 &mut self,
355 355 file_contents: &[u8],
356 356 ) -> Result<&DirstateParents, DirstateError> {
357 357 if let Some(ref parents) = self.parents {
358 358 return Ok(parents);
359 359 }
360 360 let parents;
361 361 if file_contents.len() == PARENT_SIZE * 2 {
362 362 parents = DirstateParents {
363 363 p1: file_contents[..PARENT_SIZE].try_into().unwrap(),
364 364 p2: file_contents[PARENT_SIZE..PARENT_SIZE * 2]
365 365 .try_into()
366 366 .unwrap(),
367 367 };
368 368 } else if file_contents.is_empty() {
369 369 parents = DirstateParents {
370 370 p1: NULL_NODE_ID,
371 371 p2: NULL_NODE_ID,
372 372 };
373 373 } else {
374 374 return Err(
375 375 HgError::corrupted("Dirstate appears to be damaged").into()
376 376 );
377 377 }
378 378
379 379 self.parents = Some(parents);
380 380 Ok(self.parents.as_ref().unwrap())
381 381 }
382 382
383 383 pub fn set_parents(&mut self, parents: &DirstateParents) {
384 384 self.parents = Some(parents.clone());
385 385 self.dirty_parents = true;
386 386 }
387 387
388 388 #[timed]
389 pub fn read(
389 pub fn read<'a>(
390 390 &mut self,
391 file_contents: &[u8],
392 ) -> Result<Option<DirstateParents>, DirstateError> {
391 file_contents: &'a [u8],
392 ) -> Result<Option<&'a DirstateParents>, DirstateError> {
393 393 if file_contents.is_empty() {
394 394 return Ok(None);
395 395 }
396 396
397 397 let (parents, entries, copies) = parse_dirstate(file_contents)?;
398 398 self.state_map.extend(
399 399 entries
400 400 .into_iter()
401 401 .map(|(path, entry)| (path.to_owned(), entry)),
402 402 );
403 403 self.copy_map.extend(
404 404 copies
405 405 .into_iter()
406 406 .map(|(path, copy)| (path.to_owned(), copy.to_owned())),
407 407 );
408 408
409 409 if !self.dirty_parents {
410 410 self.set_parents(&parents);
411 411 }
412 412
413 413 Ok(Some(parents))
414 414 }
415 415
416 416 pub fn pack(
417 417 &mut self,
418 418 parents: DirstateParents,
419 419 now: Duration,
420 420 ) -> Result<Vec<u8>, DirstateError> {
421 421 let packed =
422 422 pack_dirstate(&mut self.state_map, &self.copy_map, parents, now)?;
423 423
424 424 self.dirty_parents = false;
425 425
426 426 self.set_non_normal_other_parent_entries(true);
427 427 Ok(packed)
428 428 }
429 429 #[cfg(not(feature = "dirstate-tree"))]
430 430 pub fn build_file_fold_map(&mut self) -> &FileFoldMap {
431 431 if let Some(ref file_fold_map) = self.file_fold_map {
432 432 return file_fold_map;
433 433 }
434 434 let mut new_file_fold_map = FileFoldMap::default();
435 435
436 436 for (filename, DirstateEntry { state, .. }) in self.state_map.iter() {
437 437 if *state != EntryState::Removed {
438 438 new_file_fold_map
439 439 .insert(normalize_case(&filename), filename.to_owned());
440 440 }
441 441 }
442 442 self.file_fold_map = Some(new_file_fold_map);
443 443 self.file_fold_map.as_ref().unwrap()
444 444 }
445 445 #[cfg(feature = "dirstate-tree")]
446 446 pub fn build_file_fold_map(&mut self) -> &FileFoldMap {
447 447 if let Some(ref file_fold_map) = self.file_fold_map {
448 448 return file_fold_map;
449 449 }
450 450 let mut new_file_fold_map = FileFoldMap::default();
451 451
452 452 for (filename, DirstateEntry { state, .. }) in self.state_map.iter() {
453 453 if state != EntryState::Removed {
454 454 new_file_fold_map
455 455 .insert(normalize_case(&filename), filename.to_owned());
456 456 }
457 457 }
458 458 self.file_fold_map = Some(new_file_fold_map);
459 459 self.file_fold_map.as_ref().unwrap()
460 460 }
461 461 }
462 462
463 463 #[cfg(test)]
464 464 mod tests {
465 465 use super::*;
466 466
467 467 #[test]
468 468 fn test_dirs_multiset() {
469 469 let mut map = DirstateMap::new();
470 470 assert!(map.dirs.is_none());
471 471 assert!(map.all_dirs.is_none());
472 472
473 473 assert_eq!(map.has_dir(HgPath::new(b"nope")).unwrap(), false);
474 474 assert!(map.all_dirs.is_some());
475 475 assert!(map.dirs.is_none());
476 476
477 477 assert_eq!(map.has_tracked_dir(HgPath::new(b"nope")).unwrap(), false);
478 478 assert!(map.dirs.is_some());
479 479 }
480 480
481 481 #[test]
482 482 fn test_add_file() {
483 483 let mut map = DirstateMap::new();
484 484
485 485 assert_eq!(0, map.len());
486 486
487 487 map.add_file(
488 488 HgPath::new(b"meh"),
489 489 EntryState::Normal,
490 490 DirstateEntry {
491 491 state: EntryState::Normal,
492 492 mode: 1337,
493 493 mtime: 1337,
494 494 size: 1337,
495 495 },
496 496 )
497 497 .unwrap();
498 498
499 499 assert_eq!(1, map.len());
500 500 assert_eq!(0, map.get_non_normal_other_parent_entries().0.len());
501 501 assert_eq!(0, map.get_non_normal_other_parent_entries().1.len());
502 502 }
503 503
504 504 #[test]
505 505 fn test_non_normal_other_parent_entries() {
506 506 let mut map: DirstateMap = [
507 507 (b"f1", (EntryState::Removed, 1337, 1337, 1337)),
508 508 (b"f2", (EntryState::Normal, 1337, 1337, -1)),
509 509 (b"f3", (EntryState::Normal, 1337, 1337, 1337)),
510 510 (b"f4", (EntryState::Normal, 1337, -2, 1337)),
511 511 (b"f5", (EntryState::Added, 1337, 1337, 1337)),
512 512 (b"f6", (EntryState::Added, 1337, 1337, -1)),
513 513 (b"f7", (EntryState::Merged, 1337, 1337, -1)),
514 514 (b"f8", (EntryState::Merged, 1337, 1337, 1337)),
515 515 (b"f9", (EntryState::Merged, 1337, -2, 1337)),
516 516 (b"fa", (EntryState::Added, 1337, -2, 1337)),
517 517 (b"fb", (EntryState::Removed, 1337, -2, 1337)),
518 518 ]
519 519 .iter()
520 520 .map(|(fname, (state, mode, size, mtime))| {
521 521 (
522 522 HgPathBuf::from_bytes(fname.as_ref()),
523 523 DirstateEntry {
524 524 state: *state,
525 525 mode: *mode,
526 526 size: *size,
527 527 mtime: *mtime,
528 528 },
529 529 )
530 530 })
531 531 .collect();
532 532
533 533 let mut non_normal = [
534 534 b"f1", b"f2", b"f5", b"f6", b"f7", b"f8", b"f9", b"fa", b"fb",
535 535 ]
536 536 .iter()
537 537 .map(|x| HgPathBuf::from_bytes(x.as_ref()))
538 538 .collect();
539 539
540 540 let mut other_parent = HashSet::new();
541 541 other_parent.insert(HgPathBuf::from_bytes(b"f4"));
542 542 let entries = map.get_non_normal_other_parent_entries();
543 543
544 544 assert_eq!(
545 545 (&mut non_normal, &mut other_parent),
546 546 (entries.0, entries.1)
547 547 );
548 548 }
549 549 }
@@ -1,520 +1,500
1 1 // Copyright 2019 Raphaël Gomès <rgomes@octobus.net>
2 2 //
3 3 // This software may be used and distributed according to the terms of the
4 4 // GNU General Public License version 2 or any later version.
5 5
6 6 use crate::errors::HgError;
7 7 use crate::utils::hg_path::HgPath;
8 8 use crate::{
9 dirstate::{CopyMap, EntryState, StateMap},
9 dirstate::{CopyMap, EntryState, RawEntry, StateMap},
10 10 DirstateEntry, DirstateParents,
11 11 };
12 use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
12 use byteorder::{BigEndian, WriteBytesExt};
13 use bytes_cast::BytesCast;
13 14 use micro_timer::timed;
14 15 use std::convert::{TryFrom, TryInto};
15 use std::io::Cursor;
16 16 use std::time::Duration;
17 17
18 18 /// Parents are stored in the dirstate as byte hashes.
19 19 pub const PARENT_SIZE: usize = 20;
20 20 /// Dirstate entries have a static part of 8 + 32 + 32 + 32 + 32 bits.
21 21 const MIN_ENTRY_SIZE: usize = 17;
22 22
23 23 type ParseResult<'a> = (
24 DirstateParents,
24 &'a DirstateParents,
25 25 Vec<(&'a HgPath, DirstateEntry)>,
26 26 Vec<(&'a HgPath, &'a HgPath)>,
27 27 );
28 28
29 29 #[timed]
30 pub fn parse_dirstate(contents: &[u8]) -> Result<ParseResult, HgError> {
31 if contents.len() < PARENT_SIZE * 2 {
32 return Err(HgError::corrupted("Too little data for dirstate."));
33 }
34 let mut copies = vec![];
35 let mut entries = vec![];
30 pub fn parse_dirstate(mut contents: &[u8]) -> Result<ParseResult, HgError> {
31 let mut copies = Vec::new();
32 let mut entries = Vec::new();
36 33
37 let mut curr_pos = PARENT_SIZE * 2;
38 let parents = DirstateParents {
39 p1: contents[..PARENT_SIZE].try_into().unwrap(),
40 p2: contents[PARENT_SIZE..curr_pos].try_into().unwrap(),
41 };
34 let (parents, rest) = DirstateParents::from_bytes(contents)
35 .map_err(|_| HgError::corrupted("Too little data for dirstate."))?;
36 contents = rest;
37 while !contents.is_empty() {
38 let (raw_entry, rest) = RawEntry::from_bytes(contents)
39 .map_err(|_| HgError::corrupted("Overflow in dirstate."))?;
42 40
43 while curr_pos < contents.len() {
44 if curr_pos + MIN_ENTRY_SIZE > contents.len() {
45 return Err(HgError::corrupted("Overflow in dirstate."));
46 }
47 let entry_bytes = &contents[curr_pos..];
41 let entry = DirstateEntry {
42 state: EntryState::try_from(raw_entry.state)?,
43 mode: raw_entry.mode.get(),
44 mtime: raw_entry.mtime.get(),
45 size: raw_entry.size.get(),
46 };
47 let (paths, rest) =
48 u8::slice_from_bytes(rest, raw_entry.length.get() as usize)
49 .map_err(|_| HgError::corrupted("Overflow in dirstate."))?;
48 50
49 let mut cursor = Cursor::new(entry_bytes);
50 // Unwraping errors from `byteorder` as we’ve already checked
51 // `MIN_ENTRY_SIZE` so the input should never be too short.
52 let state = EntryState::try_from(cursor.read_u8().unwrap())?;
53 let mode = cursor.read_i32::<BigEndian>().unwrap();
54 let size = cursor.read_i32::<BigEndian>().unwrap();
55 let mtime = cursor.read_i32::<BigEndian>().unwrap();
56 let path_len = cursor.read_i32::<BigEndian>().unwrap() as usize;
57
58 if path_len > contents.len() - curr_pos {
59 return Err(HgError::corrupted("Overflow in dirstate."));
51 // `paths` is either a single path, or two paths separated by a NULL
52 // byte
53 let mut iter = paths.splitn(2, |&byte| byte == b'\0');
54 let path = HgPath::new(
55 iter.next().expect("splitn always yields at least one item"),
56 );
57 if let Some(copy_source) = iter.next() {
58 copies.push((path, HgPath::new(copy_source)));
60 59 }
61 60
62 // Slice instead of allocating a Vec needed for `read_exact`
63 let path = &entry_bytes[MIN_ENTRY_SIZE..MIN_ENTRY_SIZE + (path_len)];
64
65 let (path, copy) = match memchr::memchr(0, path) {
66 None => (path, None),
67 Some(i) => (&path[..i], Some(&path[(i + 1)..])),
68 };
69
70 if let Some(copy_path) = copy {
71 copies.push((HgPath::new(path), HgPath::new(copy_path)));
72 };
73 entries.push((
74 HgPath::new(path),
75 DirstateEntry {
76 state,
77 mode,
78 size,
79 mtime,
80 },
81 ));
82 curr_pos = curr_pos + MIN_ENTRY_SIZE + (path_len);
61 entries.push((path, entry));
62 contents = rest;
83 63 }
84 64 Ok((parents, entries, copies))
85 65 }
86 66
87 67 /// `now` is the duration in seconds since the Unix epoch
88 68 #[cfg(not(feature = "dirstate-tree"))]
89 69 pub fn pack_dirstate(
90 70 state_map: &mut StateMap,
91 71 copy_map: &CopyMap,
92 72 parents: DirstateParents,
93 73 now: Duration,
94 74 ) -> Result<Vec<u8>, HgError> {
95 75 // TODO move away from i32 before 2038.
96 76 let now: i32 = now.as_secs().try_into().expect("time overflow");
97 77
98 78 let expected_size: usize = state_map
99 79 .iter()
100 80 .map(|(filename, _)| {
101 81 let mut length = MIN_ENTRY_SIZE + filename.len();
102 82 if let Some(copy) = copy_map.get(filename) {
103 83 length += copy.len() + 1;
104 84 }
105 85 length
106 86 })
107 87 .sum();
108 88 let expected_size = expected_size + PARENT_SIZE * 2;
109 89
110 90 let mut packed = Vec::with_capacity(expected_size);
111 91
112 92 packed.extend(&parents.p1);
113 93 packed.extend(&parents.p2);
114 94
115 95 for (filename, entry) in state_map.iter_mut() {
116 96 let new_filename = filename.to_owned();
117 97 let mut new_mtime: i32 = entry.mtime;
118 98 if entry.state == EntryState::Normal && entry.mtime == now {
119 99 // The file was last modified "simultaneously" with the current
120 100 // write to dirstate (i.e. within the same second for file-
121 101 // systems with a granularity of 1 sec). This commonly happens
122 102 // for at least a couple of files on 'update'.
123 103 // The user could change the file without changing its size
124 104 // within the same second. Invalidate the file's mtime in
125 105 // dirstate, forcing future 'status' calls to compare the
126 106 // contents of the file if the size is the same. This prevents
127 107 // mistakenly treating such files as clean.
128 108 new_mtime = -1;
129 109 *entry = DirstateEntry {
130 110 mtime: new_mtime,
131 111 ..*entry
132 112 };
133 113 }
134 114 let mut new_filename = new_filename.into_vec();
135 115 if let Some(copy) = copy_map.get(filename) {
136 116 new_filename.push(b'\0');
137 117 new_filename.extend(copy.bytes());
138 118 }
139 119
140 120 // Unwrapping because `impl std::io::Write for Vec<u8>` never errors
141 121 packed.write_u8(entry.state.into()).unwrap();
142 122 packed.write_i32::<BigEndian>(entry.mode).unwrap();
143 123 packed.write_i32::<BigEndian>(entry.size).unwrap();
144 124 packed.write_i32::<BigEndian>(new_mtime).unwrap();
145 125 packed
146 126 .write_i32::<BigEndian>(new_filename.len() as i32)
147 127 .unwrap();
148 128 packed.extend(new_filename)
149 129 }
150 130
151 131 if packed.len() != expected_size {
152 132 return Err(HgError::CorruptedRepository(format!(
153 133 "bad dirstate size: {} != {}",
154 134 expected_size,
155 135 packed.len()
156 136 )));
157 137 }
158 138
159 139 Ok(packed)
160 140 }
161 141 /// `now` is the duration in seconds since the Unix epoch
162 142 #[cfg(feature = "dirstate-tree")]
163 143 pub fn pack_dirstate(
164 144 state_map: &mut StateMap,
165 145 copy_map: &CopyMap,
166 146 parents: DirstateParents,
167 147 now: Duration,
168 148 ) -> Result<Vec<u8>, DirstatePackError> {
169 149 // TODO move away from i32 before 2038.
170 150 let now: i32 = now.as_secs().try_into().expect("time overflow");
171 151
172 152 let expected_size: usize = state_map
173 153 .iter()
174 154 .map(|(filename, _)| {
175 155 let mut length = MIN_ENTRY_SIZE + filename.len();
176 156 if let Some(copy) = copy_map.get(&filename) {
177 157 length += copy.len() + 1;
178 158 }
179 159 length
180 160 })
181 161 .sum();
182 162 let expected_size = expected_size + PARENT_SIZE * 2;
183 163
184 164 let mut packed = Vec::with_capacity(expected_size);
185 165 let mut new_state_map = vec![];
186 166
187 167 packed.extend(&parents.p1);
188 168 packed.extend(&parents.p2);
189 169
190 170 for (filename, entry) in state_map.iter() {
191 171 let new_filename = filename.to_owned();
192 172 let mut new_mtime: i32 = entry.mtime;
193 173 if entry.state == EntryState::Normal && entry.mtime == now {
194 174 // The file was last modified "simultaneously" with the current
195 175 // write to dirstate (i.e. within the same second for file-
196 176 // systems with a granularity of 1 sec). This commonly happens
197 177 // for at least a couple of files on 'update'.
198 178 // The user could change the file without changing its size
199 179 // within the same second. Invalidate the file's mtime in
200 180 // dirstate, forcing future 'status' calls to compare the
201 181 // contents of the file if the size is the same. This prevents
202 182 // mistakenly treating such files as clean.
203 183 new_mtime = -1;
204 184 new_state_map.push((
205 185 filename.to_owned(),
206 186 DirstateEntry {
207 187 mtime: new_mtime,
208 188 ..entry
209 189 },
210 190 ));
211 191 }
212 192 let mut new_filename = new_filename.into_vec();
213 193 if let Some(copy) = copy_map.get(&filename) {
214 194 new_filename.push(b'\0');
215 195 new_filename.extend(copy.bytes());
216 196 }
217 197
218 198 packed.write_u8(entry.state.into())?;
219 199 packed.write_i32::<BigEndian>(entry.mode)?;
220 200 packed.write_i32::<BigEndian>(entry.size)?;
221 201 packed.write_i32::<BigEndian>(new_mtime)?;
222 202 packed.write_i32::<BigEndian>(new_filename.len() as i32)?;
223 203 packed.extend(new_filename)
224 204 }
225 205
226 206 if packed.len() != expected_size {
227 207 return Err(DirstatePackError::BadSize(expected_size, packed.len()));
228 208 }
229 209
230 210 state_map.extend(new_state_map);
231 211
232 212 Ok(packed)
233 213 }
234 214
235 215 #[cfg(test)]
236 216 mod tests {
237 217 use super::*;
238 218 use crate::{utils::hg_path::HgPathBuf, FastHashMap};
239 219 use pretty_assertions::assert_eq;
240 220
241 221 #[test]
242 222 fn test_pack_dirstate_empty() {
243 223 let mut state_map = StateMap::default();
244 224 let copymap = FastHashMap::default();
245 225 let parents = DirstateParents {
246 226 p1: *b"12345678910111213141",
247 227 p2: *b"00000000000000000000",
248 228 };
249 229 let now = Duration::new(15000000, 0);
250 230 let expected = b"1234567891011121314100000000000000000000".to_vec();
251 231
252 232 assert_eq!(
253 233 expected,
254 234 pack_dirstate(&mut state_map, &copymap, parents, now).unwrap()
255 235 );
256 236
257 237 assert!(state_map.is_empty())
258 238 }
259 239 #[test]
260 240 fn test_pack_dirstate_one_entry() {
261 241 let expected_state_map: StateMap = [(
262 242 HgPathBuf::from_bytes(b"f1"),
263 243 DirstateEntry {
264 244 state: EntryState::Normal,
265 245 mode: 0o644,
266 246 size: 0,
267 247 mtime: 791231220,
268 248 },
269 249 )]
270 250 .iter()
271 251 .cloned()
272 252 .collect();
273 253 let mut state_map = expected_state_map.clone();
274 254
275 255 let copymap = FastHashMap::default();
276 256 let parents = DirstateParents {
277 257 p1: *b"12345678910111213141",
278 258 p2: *b"00000000000000000000",
279 259 };
280 260 let now = Duration::new(15000000, 0);
281 261 let expected = [
282 262 49, 50, 51, 52, 53, 54, 55, 56, 57, 49, 48, 49, 49, 49, 50, 49,
283 263 51, 49, 52, 49, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
284 264 48, 48, 48, 48, 48, 48, 48, 48, 110, 0, 0, 1, 164, 0, 0, 0, 0, 47,
285 265 41, 58, 244, 0, 0, 0, 2, 102, 49,
286 266 ]
287 267 .to_vec();
288 268
289 269 assert_eq!(
290 270 expected,
291 271 pack_dirstate(&mut state_map, &copymap, parents, now).unwrap()
292 272 );
293 273
294 274 assert_eq!(expected_state_map, state_map);
295 275 }
296 276 #[test]
297 277 fn test_pack_dirstate_one_entry_with_copy() {
298 278 let expected_state_map: StateMap = [(
299 279 HgPathBuf::from_bytes(b"f1"),
300 280 DirstateEntry {
301 281 state: EntryState::Normal,
302 282 mode: 0o644,
303 283 size: 0,
304 284 mtime: 791231220,
305 285 },
306 286 )]
307 287 .iter()
308 288 .cloned()
309 289 .collect();
310 290 let mut state_map = expected_state_map.clone();
311 291 let mut copymap = FastHashMap::default();
312 292 copymap.insert(
313 293 HgPathBuf::from_bytes(b"f1"),
314 294 HgPathBuf::from_bytes(b"copyname"),
315 295 );
316 296 let parents = DirstateParents {
317 297 p1: *b"12345678910111213141",
318 298 p2: *b"00000000000000000000",
319 299 };
320 300 let now = Duration::new(15000000, 0);
321 301 let expected = [
322 302 49, 50, 51, 52, 53, 54, 55, 56, 57, 49, 48, 49, 49, 49, 50, 49,
323 303 51, 49, 52, 49, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
324 304 48, 48, 48, 48, 48, 48, 48, 48, 110, 0, 0, 1, 164, 0, 0, 0, 0, 47,
325 305 41, 58, 244, 0, 0, 0, 11, 102, 49, 0, 99, 111, 112, 121, 110, 97,
326 306 109, 101,
327 307 ]
328 308 .to_vec();
329 309
330 310 assert_eq!(
331 311 expected,
332 312 pack_dirstate(&mut state_map, &copymap, parents, now).unwrap()
333 313 );
334 314 assert_eq!(expected_state_map, state_map);
335 315 }
336 316
337 317 #[test]
338 318 fn test_parse_pack_one_entry_with_copy() {
339 319 let mut state_map: StateMap = [(
340 320 HgPathBuf::from_bytes(b"f1"),
341 321 DirstateEntry {
342 322 state: EntryState::Normal,
343 323 mode: 0o644,
344 324 size: 0,
345 325 mtime: 791231220,
346 326 },
347 327 )]
348 328 .iter()
349 329 .cloned()
350 330 .collect();
351 331 let mut copymap = FastHashMap::default();
352 332 copymap.insert(
353 333 HgPathBuf::from_bytes(b"f1"),
354 334 HgPathBuf::from_bytes(b"copyname"),
355 335 );
356 336 let parents = DirstateParents {
357 337 p1: *b"12345678910111213141",
358 338 p2: *b"00000000000000000000",
359 339 };
360 340 let now = Duration::new(15000000, 0);
361 341 let result =
362 342 pack_dirstate(&mut state_map, &copymap, parents.clone(), now)
363 343 .unwrap();
364 344
365 345 let (new_parents, entries, copies) =
366 346 parse_dirstate(result.as_slice()).unwrap();
367 347 let new_state_map: StateMap = entries
368 348 .into_iter()
369 349 .map(|(path, entry)| (path.to_owned(), entry))
370 350 .collect();
371 351 let new_copy_map: CopyMap = copies
372 352 .into_iter()
373 353 .map(|(path, copy)| (path.to_owned(), copy.to_owned()))
374 354 .collect();
375 355
376 356 assert_eq!(
377 (parents, state_map, copymap),
357 (&parents, state_map, copymap),
378 358 (new_parents, new_state_map, new_copy_map)
379 359 )
380 360 }
381 361
382 362 #[test]
383 363 fn test_parse_pack_multiple_entries_with_copy() {
384 364 let mut state_map: StateMap = [
385 365 (
386 366 HgPathBuf::from_bytes(b"f1"),
387 367 DirstateEntry {
388 368 state: EntryState::Normal,
389 369 mode: 0o644,
390 370 size: 0,
391 371 mtime: 791231220,
392 372 },
393 373 ),
394 374 (
395 375 HgPathBuf::from_bytes(b"f2"),
396 376 DirstateEntry {
397 377 state: EntryState::Merged,
398 378 mode: 0o777,
399 379 size: 1000,
400 380 mtime: 791231220,
401 381 },
402 382 ),
403 383 (
404 384 HgPathBuf::from_bytes(b"f3"),
405 385 DirstateEntry {
406 386 state: EntryState::Removed,
407 387 mode: 0o644,
408 388 size: 234553,
409 389 mtime: 791231220,
410 390 },
411 391 ),
412 392 (
413 393 HgPathBuf::from_bytes(b"f4\xF6"),
414 394 DirstateEntry {
415 395 state: EntryState::Added,
416 396 mode: 0o644,
417 397 size: -1,
418 398 mtime: -1,
419 399 },
420 400 ),
421 401 ]
422 402 .iter()
423 403 .cloned()
424 404 .collect();
425 405 let mut copymap = FastHashMap::default();
426 406 copymap.insert(
427 407 HgPathBuf::from_bytes(b"f1"),
428 408 HgPathBuf::from_bytes(b"copyname"),
429 409 );
430 410 copymap.insert(
431 411 HgPathBuf::from_bytes(b"f4\xF6"),
432 412 HgPathBuf::from_bytes(b"copyname2"),
433 413 );
434 414 let parents = DirstateParents {
435 415 p1: *b"12345678910111213141",
436 416 p2: *b"00000000000000000000",
437 417 };
438 418 let now = Duration::new(15000000, 0);
439 419 let result =
440 420 pack_dirstate(&mut state_map, &copymap, parents.clone(), now)
441 421 .unwrap();
442 422
443 423 let (new_parents, entries, copies) =
444 424 parse_dirstate(result.as_slice()).unwrap();
445 425 let new_state_map: StateMap = entries
446 426 .into_iter()
447 427 .map(|(path, entry)| (path.to_owned(), entry))
448 428 .collect();
449 429 let new_copy_map: CopyMap = copies
450 430 .into_iter()
451 431 .map(|(path, copy)| (path.to_owned(), copy.to_owned()))
452 432 .collect();
453 433
454 434 assert_eq!(
455 (parents, state_map, copymap),
435 (&parents, state_map, copymap),
456 436 (new_parents, new_state_map, new_copy_map)
457 437 )
458 438 }
459 439
460 440 #[test]
461 441 /// https://www.mercurial-scm.org/repo/hg/rev/af3f26b6bba4
462 442 fn test_parse_pack_one_entry_with_copy_and_time_conflict() {
463 443 let mut state_map: StateMap = [(
464 444 HgPathBuf::from_bytes(b"f1"),
465 445 DirstateEntry {
466 446 state: EntryState::Normal,
467 447 mode: 0o644,
468 448 size: 0,
469 449 mtime: 15000000,
470 450 },
471 451 )]
472 452 .iter()
473 453 .cloned()
474 454 .collect();
475 455 let mut copymap = FastHashMap::default();
476 456 copymap.insert(
477 457 HgPathBuf::from_bytes(b"f1"),
478 458 HgPathBuf::from_bytes(b"copyname"),
479 459 );
480 460 let parents = DirstateParents {
481 461 p1: *b"12345678910111213141",
482 462 p2: *b"00000000000000000000",
483 463 };
484 464 let now = Duration::new(15000000, 0);
485 465 let result =
486 466 pack_dirstate(&mut state_map, &copymap, parents.clone(), now)
487 467 .unwrap();
488 468
489 469 let (new_parents, entries, copies) =
490 470 parse_dirstate(result.as_slice()).unwrap();
491 471 let new_state_map: StateMap = entries
492 472 .into_iter()
493 473 .map(|(path, entry)| (path.to_owned(), entry))
494 474 .collect();
495 475 let new_copy_map: CopyMap = copies
496 476 .into_iter()
497 477 .map(|(path, copy)| (path.to_owned(), copy.to_owned()))
498 478 .collect();
499 479
500 480 assert_eq!(
501 481 (
502 parents,
482 &parents,
503 483 [(
504 484 HgPathBuf::from_bytes(b"f1"),
505 485 DirstateEntry {
506 486 state: EntryState::Normal,
507 487 mode: 0o644,
508 488 size: 0,
509 489 mtime: -1
510 490 }
511 491 )]
512 492 .iter()
513 493 .cloned()
514 494 .collect::<StateMap>(),
515 495 copymap,
516 496 ),
517 497 (new_parents, new_state_map, new_copy_map)
518 498 )
519 499 }
520 500 }
General Comments 0
You need to be logged in to leave comments. Login now