##// END OF EJS Templates
dirstate-v2: skip evaluation of hgignore regex on cached directories...
Arseniy Alekseyev -
r50415:eb02decd default
parent child Browse files
Show More
@@ -1,1277 +1,1284 b''
1 # This file is automatically @generated by Cargo.
1 # This file is automatically @generated by Cargo.
2 # It is not intended for manual editing.
2 # It is not intended for manual editing.
3 version = 3
3 version = 3
4
4
5 [[package]]
5 [[package]]
6 name = "Inflector"
6 name = "Inflector"
7 version = "0.11.4"
7 version = "0.11.4"
8 source = "registry+https://github.com/rust-lang/crates.io-index"
8 source = "registry+https://github.com/rust-lang/crates.io-index"
9 checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3"
9 checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3"
10
10
11 [[package]]
11 [[package]]
12 name = "adler"
12 name = "adler"
13 version = "0.2.3"
13 version = "0.2.3"
14 source = "registry+https://github.com/rust-lang/crates.io-index"
14 source = "registry+https://github.com/rust-lang/crates.io-index"
15 checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e"
15 checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e"
16
16
17 [[package]]
17 [[package]]
18 name = "ahash"
18 name = "ahash"
19 version = "0.4.7"
19 version = "0.4.7"
20 source = "registry+https://github.com/rust-lang/crates.io-index"
20 source = "registry+https://github.com/rust-lang/crates.io-index"
21 checksum = "739f4a8db6605981345c5654f3a85b056ce52f37a39d34da03f25bf2151ea16e"
21 checksum = "739f4a8db6605981345c5654f3a85b056ce52f37a39d34da03f25bf2151ea16e"
22
22
23 [[package]]
23 [[package]]
24 name = "aho-corasick"
24 name = "aho-corasick"
25 version = "0.7.18"
25 version = "0.7.18"
26 source = "registry+https://github.com/rust-lang/crates.io-index"
26 source = "registry+https://github.com/rust-lang/crates.io-index"
27 checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
27 checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
28 dependencies = [
28 dependencies = [
29 "memchr",
29 "memchr",
30 ]
30 ]
31
31
32 [[package]]
32 [[package]]
33 name = "aliasable"
33 name = "aliasable"
34 version = "0.1.3"
34 version = "0.1.3"
35 source = "registry+https://github.com/rust-lang/crates.io-index"
35 source = "registry+https://github.com/rust-lang/crates.io-index"
36 checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd"
36 checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd"
37
37
38 [[package]]
38 [[package]]
39 name = "ansi_term"
39 name = "ansi_term"
40 version = "0.12.1"
40 version = "0.12.1"
41 source = "registry+https://github.com/rust-lang/crates.io-index"
41 source = "registry+https://github.com/rust-lang/crates.io-index"
42 checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
42 checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
43 dependencies = [
43 dependencies = [
44 "winapi",
44 "winapi",
45 ]
45 ]
46
46
47 [[package]]
47 [[package]]
48 name = "atty"
48 name = "atty"
49 version = "0.2.14"
49 version = "0.2.14"
50 source = "registry+https://github.com/rust-lang/crates.io-index"
50 source = "registry+https://github.com/rust-lang/crates.io-index"
51 checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
51 checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
52 dependencies = [
52 dependencies = [
53 "hermit-abi",
53 "hermit-abi",
54 "libc",
54 "libc",
55 "winapi",
55 "winapi",
56 ]
56 ]
57
57
58 [[package]]
58 [[package]]
59 name = "autocfg"
59 name = "autocfg"
60 version = "1.0.1"
60 version = "1.0.1"
61 source = "registry+https://github.com/rust-lang/crates.io-index"
61 source = "registry+https://github.com/rust-lang/crates.io-index"
62 checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
62 checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
63
63
64 [[package]]
64 [[package]]
65 name = "bitflags"
65 name = "bitflags"
66 version = "1.3.2"
66 version = "1.3.2"
67 source = "registry+https://github.com/rust-lang/crates.io-index"
67 source = "registry+https://github.com/rust-lang/crates.io-index"
68 checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
68 checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
69
69
70 [[package]]
70 [[package]]
71 name = "bitmaps"
71 name = "bitmaps"
72 version = "2.1.0"
72 version = "2.1.0"
73 source = "registry+https://github.com/rust-lang/crates.io-index"
73 source = "registry+https://github.com/rust-lang/crates.io-index"
74 checksum = "031043d04099746d8db04daf1fa424b2bc8bd69d92b25962dcde24da39ab64a2"
74 checksum = "031043d04099746d8db04daf1fa424b2bc8bd69d92b25962dcde24da39ab64a2"
75 dependencies = [
75 dependencies = [
76 "typenum",
76 "typenum",
77 ]
77 ]
78
78
79 [[package]]
79 [[package]]
80 name = "block-buffer"
80 name = "block-buffer"
81 version = "0.9.0"
81 version = "0.9.0"
82 source = "registry+https://github.com/rust-lang/crates.io-index"
82 source = "registry+https://github.com/rust-lang/crates.io-index"
83 checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
83 checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
84 dependencies = [
84 dependencies = [
85 "generic-array",
85 "generic-array",
86 ]
86 ]
87
87
88 [[package]]
88 [[package]]
89 name = "block-buffer"
89 name = "block-buffer"
90 version = "0.10.2"
90 version = "0.10.2"
91 source = "registry+https://github.com/rust-lang/crates.io-index"
91 source = "registry+https://github.com/rust-lang/crates.io-index"
92 checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324"
92 checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324"
93 dependencies = [
93 dependencies = [
94 "generic-array",
94 "generic-array",
95 ]
95 ]
96
96
97 [[package]]
97 [[package]]
98 name = "byteorder"
98 name = "byteorder"
99 version = "1.4.3"
99 version = "1.4.3"
100 source = "registry+https://github.com/rust-lang/crates.io-index"
100 source = "registry+https://github.com/rust-lang/crates.io-index"
101 checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
101 checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
102
102
103 [[package]]
103 [[package]]
104 name = "bytes-cast"
104 name = "bytes-cast"
105 version = "0.2.0"
105 version = "0.2.0"
106 source = "registry+https://github.com/rust-lang/crates.io-index"
106 source = "registry+https://github.com/rust-lang/crates.io-index"
107 checksum = "0d434f9a4ecbe987e7ccfda7274b6f82ea52c9b63742565a65cb5e8ba0f2c452"
107 checksum = "0d434f9a4ecbe987e7ccfda7274b6f82ea52c9b63742565a65cb5e8ba0f2c452"
108 dependencies = [
108 dependencies = [
109 "bytes-cast-derive",
109 "bytes-cast-derive",
110 ]
110 ]
111
111
112 [[package]]
112 [[package]]
113 name = "bytes-cast-derive"
113 name = "bytes-cast-derive"
114 version = "0.1.0"
114 version = "0.1.0"
115 source = "registry+https://github.com/rust-lang/crates.io-index"
115 source = "registry+https://github.com/rust-lang/crates.io-index"
116 checksum = "cb936af9de38476664d6b58e529aff30d482e4ce1c5e150293d00730b0d81fdb"
116 checksum = "cb936af9de38476664d6b58e529aff30d482e4ce1c5e150293d00730b0d81fdb"
117 dependencies = [
117 dependencies = [
118 "proc-macro2",
118 "proc-macro2",
119 "quote",
119 "quote",
120 "syn",
120 "syn",
121 ]
121 ]
122
122
123 [[package]]
123 [[package]]
124 name = "cc"
124 name = "cc"
125 version = "1.0.66"
125 version = "1.0.66"
126 source = "registry+https://github.com/rust-lang/crates.io-index"
126 source = "registry+https://github.com/rust-lang/crates.io-index"
127 checksum = "4c0496836a84f8d0495758516b8621a622beb77c0fed418570e50764093ced48"
127 checksum = "4c0496836a84f8d0495758516b8621a622beb77c0fed418570e50764093ced48"
128 dependencies = [
128 dependencies = [
129 "jobserver",
129 "jobserver",
130 ]
130 ]
131
131
132 [[package]]
132 [[package]]
133 name = "cfg-if"
133 name = "cfg-if"
134 version = "0.1.10"
134 version = "0.1.10"
135 source = "registry+https://github.com/rust-lang/crates.io-index"
135 source = "registry+https://github.com/rust-lang/crates.io-index"
136 checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
136 checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
137
137
138 [[package]]
138 [[package]]
139 name = "cfg-if"
139 name = "cfg-if"
140 version = "1.0.0"
140 version = "1.0.0"
141 source = "registry+https://github.com/rust-lang/crates.io-index"
141 source = "registry+https://github.com/rust-lang/crates.io-index"
142 checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
142 checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
143
143
144 [[package]]
144 [[package]]
145 name = "chrono"
145 name = "chrono"
146 version = "0.4.19"
146 version = "0.4.19"
147 source = "registry+https://github.com/rust-lang/crates.io-index"
147 source = "registry+https://github.com/rust-lang/crates.io-index"
148 checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
148 checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
149 dependencies = [
149 dependencies = [
150 "libc",
150 "libc",
151 "num-integer",
151 "num-integer",
152 "num-traits",
152 "num-traits",
153 "time",
153 "time",
154 "winapi",
154 "winapi",
155 ]
155 ]
156
156
157 [[package]]
157 [[package]]
158 name = "clap"
158 name = "clap"
159 version = "2.34.0"
159 version = "2.34.0"
160 source = "registry+https://github.com/rust-lang/crates.io-index"
160 source = "registry+https://github.com/rust-lang/crates.io-index"
161 checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
161 checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
162 dependencies = [
162 dependencies = [
163 "ansi_term",
163 "ansi_term",
164 "atty",
164 "atty",
165 "bitflags",
165 "bitflags",
166 "strsim",
166 "strsim",
167 "textwrap",
167 "textwrap",
168 "unicode-width",
168 "unicode-width",
169 "vec_map",
169 "vec_map",
170 ]
170 ]
171
171
172 [[package]]
172 [[package]]
173 name = "const_fn"
173 name = "const_fn"
174 version = "0.4.4"
174 version = "0.4.4"
175 source = "registry+https://github.com/rust-lang/crates.io-index"
175 source = "registry+https://github.com/rust-lang/crates.io-index"
176 checksum = "cd51eab21ab4fd6a3bf889e2d0958c0a6e3a61ad04260325e919e652a2a62826"
176 checksum = "cd51eab21ab4fd6a3bf889e2d0958c0a6e3a61ad04260325e919e652a2a62826"
177
177
178 [[package]]
178 [[package]]
179 name = "convert_case"
179 name = "convert_case"
180 version = "0.4.0"
180 version = "0.4.0"
181 source = "registry+https://github.com/rust-lang/crates.io-index"
181 source = "registry+https://github.com/rust-lang/crates.io-index"
182 checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
182 checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
183
183
184 [[package]]
184 [[package]]
185 name = "cpufeatures"
185 name = "cpufeatures"
186 version = "0.1.4"
186 version = "0.1.4"
187 source = "registry+https://github.com/rust-lang/crates.io-index"
187 source = "registry+https://github.com/rust-lang/crates.io-index"
188 checksum = "ed00c67cb5d0a7d64a44f6ad2668db7e7530311dd53ea79bcd4fb022c64911c8"
188 checksum = "ed00c67cb5d0a7d64a44f6ad2668db7e7530311dd53ea79bcd4fb022c64911c8"
189 dependencies = [
189 dependencies = [
190 "libc",
190 "libc",
191 ]
191 ]
192
192
193 [[package]]
193 [[package]]
194 name = "cpufeatures"
194 name = "cpufeatures"
195 version = "0.2.1"
195 version = "0.2.1"
196 source = "registry+https://github.com/rust-lang/crates.io-index"
196 source = "registry+https://github.com/rust-lang/crates.io-index"
197 checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469"
197 checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469"
198 dependencies = [
198 dependencies = [
199 "libc",
199 "libc",
200 ]
200 ]
201
201
202 [[package]]
202 [[package]]
203 name = "cpython"
203 name = "cpython"
204 version = "0.7.0"
204 version = "0.7.0"
205 source = "registry+https://github.com/rust-lang/crates.io-index"
205 source = "registry+https://github.com/rust-lang/crates.io-index"
206 checksum = "b7d46ba8ace7f3a1d204ac5060a706d0a68de6b42eafb6a586cc08bebcffe664"
206 checksum = "b7d46ba8ace7f3a1d204ac5060a706d0a68de6b42eafb6a586cc08bebcffe664"
207 dependencies = [
207 dependencies = [
208 "libc",
208 "libc",
209 "num-traits",
209 "num-traits",
210 "paste",
210 "paste",
211 "python3-sys",
211 "python3-sys",
212 ]
212 ]
213
213
214 [[package]]
214 [[package]]
215 name = "crc32fast"
215 name = "crc32fast"
216 version = "1.2.1"
216 version = "1.2.1"
217 source = "registry+https://github.com/rust-lang/crates.io-index"
217 source = "registry+https://github.com/rust-lang/crates.io-index"
218 checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
218 checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
219 dependencies = [
219 dependencies = [
220 "cfg-if 1.0.0",
220 "cfg-if 1.0.0",
221 ]
221 ]
222
222
223 [[package]]
223 [[package]]
224 name = "crossbeam-channel"
224 name = "crossbeam-channel"
225 version = "0.5.2"
225 version = "0.5.2"
226 source = "registry+https://github.com/rust-lang/crates.io-index"
226 source = "registry+https://github.com/rust-lang/crates.io-index"
227 checksum = "e54ea8bc3fb1ee042f5aace6e3c6e025d3874866da222930f70ce62aceba0bfa"
227 checksum = "e54ea8bc3fb1ee042f5aace6e3c6e025d3874866da222930f70ce62aceba0bfa"
228 dependencies = [
228 dependencies = [
229 "cfg-if 1.0.0",
229 "cfg-if 1.0.0",
230 "crossbeam-utils",
230 "crossbeam-utils",
231 ]
231 ]
232
232
233 [[package]]
233 [[package]]
234 name = "crossbeam-deque"
234 name = "crossbeam-deque"
235 version = "0.8.0"
235 version = "0.8.0"
236 source = "registry+https://github.com/rust-lang/crates.io-index"
236 source = "registry+https://github.com/rust-lang/crates.io-index"
237 checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9"
237 checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9"
238 dependencies = [
238 dependencies = [
239 "cfg-if 1.0.0",
239 "cfg-if 1.0.0",
240 "crossbeam-epoch",
240 "crossbeam-epoch",
241 "crossbeam-utils",
241 "crossbeam-utils",
242 ]
242 ]
243
243
244 [[package]]
244 [[package]]
245 name = "crossbeam-epoch"
245 name = "crossbeam-epoch"
246 version = "0.9.1"
246 version = "0.9.1"
247 source = "registry+https://github.com/rust-lang/crates.io-index"
247 source = "registry+https://github.com/rust-lang/crates.io-index"
248 checksum = "a1aaa739f95311c2c7887a76863f500026092fb1dce0161dab577e559ef3569d"
248 checksum = "a1aaa739f95311c2c7887a76863f500026092fb1dce0161dab577e559ef3569d"
249 dependencies = [
249 dependencies = [
250 "cfg-if 1.0.0",
250 "cfg-if 1.0.0",
251 "const_fn",
251 "const_fn",
252 "crossbeam-utils",
252 "crossbeam-utils",
253 "lazy_static",
253 "lazy_static",
254 "memoffset",
254 "memoffset",
255 "scopeguard",
255 "scopeguard",
256 ]
256 ]
257
257
258 [[package]]
258 [[package]]
259 name = "crossbeam-utils"
259 name = "crossbeam-utils"
260 version = "0.8.1"
260 version = "0.8.1"
261 source = "registry+https://github.com/rust-lang/crates.io-index"
261 source = "registry+https://github.com/rust-lang/crates.io-index"
262 checksum = "02d96d1e189ef58269ebe5b97953da3274d83a93af647c2ddd6f9dab28cedb8d"
262 checksum = "02d96d1e189ef58269ebe5b97953da3274d83a93af647c2ddd6f9dab28cedb8d"
263 dependencies = [
263 dependencies = [
264 "autocfg",
264 "autocfg",
265 "cfg-if 1.0.0",
265 "cfg-if 1.0.0",
266 "lazy_static",
266 "lazy_static",
267 ]
267 ]
268
268
269 [[package]]
269 [[package]]
270 name = "crypto-common"
270 name = "crypto-common"
271 version = "0.1.2"
271 version = "0.1.2"
272 source = "registry+https://github.com/rust-lang/crates.io-index"
272 source = "registry+https://github.com/rust-lang/crates.io-index"
273 checksum = "a4600d695eb3f6ce1cd44e6e291adceb2cc3ab12f20a33777ecd0bf6eba34e06"
273 checksum = "a4600d695eb3f6ce1cd44e6e291adceb2cc3ab12f20a33777ecd0bf6eba34e06"
274 dependencies = [
274 dependencies = [
275 "generic-array",
275 "generic-array",
276 ]
276 ]
277
277
278 [[package]]
278 [[package]]
279 name = "ctor"
279 name = "ctor"
280 version = "0.1.16"
280 version = "0.1.16"
281 source = "registry+https://github.com/rust-lang/crates.io-index"
281 source = "registry+https://github.com/rust-lang/crates.io-index"
282 checksum = "7fbaabec2c953050352311293be5c6aba8e141ba19d6811862b232d6fd020484"
282 checksum = "7fbaabec2c953050352311293be5c6aba8e141ba19d6811862b232d6fd020484"
283 dependencies = [
283 dependencies = [
284 "quote",
284 "quote",
285 "syn",
285 "syn",
286 ]
286 ]
287
287
288 [[package]]
288 [[package]]
289 name = "derive_more"
289 name = "derive_more"
290 version = "0.99.17"
290 version = "0.99.17"
291 source = "registry+https://github.com/rust-lang/crates.io-index"
291 source = "registry+https://github.com/rust-lang/crates.io-index"
292 checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321"
292 checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321"
293 dependencies = [
293 dependencies = [
294 "convert_case",
294 "convert_case",
295 "proc-macro2",
295 "proc-macro2",
296 "quote",
296 "quote",
297 "rustc_version",
297 "rustc_version",
298 "syn",
298 "syn",
299 ]
299 ]
300
300
301 [[package]]
301 [[package]]
302 name = "diff"
302 name = "diff"
303 version = "0.1.12"
303 version = "0.1.12"
304 source = "registry+https://github.com/rust-lang/crates.io-index"
304 source = "registry+https://github.com/rust-lang/crates.io-index"
305 checksum = "0e25ea47919b1560c4e3b7fe0aaab9becf5b84a10325ddf7db0f0ba5e1026499"
305 checksum = "0e25ea47919b1560c4e3b7fe0aaab9becf5b84a10325ddf7db0f0ba5e1026499"
306
306
307 [[package]]
307 [[package]]
308 name = "digest"
308 name = "digest"
309 version = "0.9.0"
309 version = "0.9.0"
310 source = "registry+https://github.com/rust-lang/crates.io-index"
310 source = "registry+https://github.com/rust-lang/crates.io-index"
311 checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
311 checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
312 dependencies = [
312 dependencies = [
313 "generic-array",
313 "generic-array",
314 ]
314 ]
315
315
316 [[package]]
316 [[package]]
317 name = "digest"
317 name = "digest"
318 version = "0.10.2"
318 version = "0.10.2"
319 source = "registry+https://github.com/rust-lang/crates.io-index"
319 source = "registry+https://github.com/rust-lang/crates.io-index"
320 checksum = "8cb780dce4f9a8f5c087362b3a4595936b2019e7c8b30f2c3e9a7e94e6ae9837"
320 checksum = "8cb780dce4f9a8f5c087362b3a4595936b2019e7c8b30f2c3e9a7e94e6ae9837"
321 dependencies = [
321 dependencies = [
322 "block-buffer 0.10.2",
322 "block-buffer 0.10.2",
323 "crypto-common",
323 "crypto-common",
324 ]
324 ]
325
325
326 [[package]]
326 [[package]]
327 name = "either"
327 name = "either"
328 version = "1.6.1"
328 version = "1.6.1"
329 source = "registry+https://github.com/rust-lang/crates.io-index"
329 source = "registry+https://github.com/rust-lang/crates.io-index"
330 checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
330 checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
331
331
332 [[package]]
332 [[package]]
333 name = "env_logger"
333 name = "env_logger"
334 version = "0.9.0"
334 version = "0.9.0"
335 source = "registry+https://github.com/rust-lang/crates.io-index"
335 source = "registry+https://github.com/rust-lang/crates.io-index"
336 checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3"
336 checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3"
337 dependencies = [
337 dependencies = [
338 "atty",
338 "atty",
339 "humantime",
339 "humantime",
340 "log",
340 "log",
341 "regex",
341 "regex",
342 "termcolor",
342 "termcolor",
343 ]
343 ]
344
344
345 [[package]]
345 [[package]]
346 name = "fastrand"
346 name = "fastrand"
347 version = "1.7.0"
347 version = "1.7.0"
348 source = "registry+https://github.com/rust-lang/crates.io-index"
348 source = "registry+https://github.com/rust-lang/crates.io-index"
349 checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf"
349 checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf"
350 dependencies = [
350 dependencies = [
351 "instant",
351 "instant",
352 ]
352 ]
353
353
354 [[package]]
354 [[package]]
355 name = "flate2"
355 name = "flate2"
356 version = "1.0.22"
356 version = "1.0.22"
357 source = "registry+https://github.com/rust-lang/crates.io-index"
357 source = "registry+https://github.com/rust-lang/crates.io-index"
358 checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f"
358 checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f"
359 dependencies = [
359 dependencies = [
360 "cfg-if 1.0.0",
360 "cfg-if 1.0.0",
361 "crc32fast",
361 "crc32fast",
362 "libc",
362 "libc",
363 "libz-sys",
363 "libz-sys",
364 "miniz_oxide",
364 "miniz_oxide",
365 ]
365 ]
366
366
367 [[package]]
367 [[package]]
368 name = "format-bytes"
368 name = "format-bytes"
369 version = "0.3.0"
369 version = "0.3.0"
370 source = "registry+https://github.com/rust-lang/crates.io-index"
370 source = "registry+https://github.com/rust-lang/crates.io-index"
371 checksum = "48942366ef93975da38e175ac9e10068c6fc08ca9e85930d4f098f4d5b14c2fd"
371 checksum = "48942366ef93975da38e175ac9e10068c6fc08ca9e85930d4f098f4d5b14c2fd"
372 dependencies = [
372 dependencies = [
373 "format-bytes-macros",
373 "format-bytes-macros",
374 ]
374 ]
375
375
376 [[package]]
376 [[package]]
377 name = "format-bytes-macros"
377 name = "format-bytes-macros"
378 version = "0.4.0"
378 version = "0.4.0"
379 source = "registry+https://github.com/rust-lang/crates.io-index"
379 source = "registry+https://github.com/rust-lang/crates.io-index"
380 checksum = "203aadebefcc73d12038296c228eabf830f99cba991b0032adf20e9fa6ce7e4f"
380 checksum = "203aadebefcc73d12038296c228eabf830f99cba991b0032adf20e9fa6ce7e4f"
381 dependencies = [
381 dependencies = [
382 "proc-macro2",
382 "proc-macro2",
383 "quote",
383 "quote",
384 "syn",
384 "syn",
385 ]
385 ]
386
386
387 [[package]]
387 [[package]]
388 name = "generic-array"
388 name = "generic-array"
389 version = "0.14.4"
389 version = "0.14.4"
390 source = "registry+https://github.com/rust-lang/crates.io-index"
390 source = "registry+https://github.com/rust-lang/crates.io-index"
391 checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817"
391 checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817"
392 dependencies = [
392 dependencies = [
393 "typenum",
393 "typenum",
394 "version_check",
394 "version_check",
395 ]
395 ]
396
396
397 [[package]]
397 [[package]]
398 name = "getrandom"
398 name = "getrandom"
399 version = "0.1.15"
399 version = "0.1.15"
400 source = "registry+https://github.com/rust-lang/crates.io-index"
400 source = "registry+https://github.com/rust-lang/crates.io-index"
401 checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6"
401 checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6"
402 dependencies = [
402 dependencies = [
403 "cfg-if 0.1.10",
403 "cfg-if 0.1.10",
404 "libc",
404 "libc",
405 "wasi 0.9.0+wasi-snapshot-preview1",
405 "wasi 0.9.0+wasi-snapshot-preview1",
406 ]
406 ]
407
407
408 [[package]]
408 [[package]]
409 name = "getrandom"
409 name = "getrandom"
410 version = "0.2.4"
410 version = "0.2.4"
411 source = "registry+https://github.com/rust-lang/crates.io-index"
411 source = "registry+https://github.com/rust-lang/crates.io-index"
412 checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c"
412 checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c"
413 dependencies = [
413 dependencies = [
414 "cfg-if 1.0.0",
414 "cfg-if 1.0.0",
415 "libc",
415 "libc",
416 "wasi 0.10.0+wasi-snapshot-preview1",
416 "wasi 0.10.0+wasi-snapshot-preview1",
417 ]
417 ]
418
418
419 [[package]]
419 [[package]]
420 name = "glob"
420 name = "glob"
421 version = "0.3.0"
421 version = "0.3.0"
422 source = "registry+https://github.com/rust-lang/crates.io-index"
422 source = "registry+https://github.com/rust-lang/crates.io-index"
423 checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
423 checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
424
424
425 [[package]]
425 [[package]]
426 name = "hashbrown"
426 name = "hashbrown"
427 version = "0.9.1"
427 version = "0.9.1"
428 source = "registry+https://github.com/rust-lang/crates.io-index"
428 source = "registry+https://github.com/rust-lang/crates.io-index"
429 checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
429 checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
430 dependencies = [
430 dependencies = [
431 "ahash",
431 "ahash",
432 "rayon",
432 "rayon",
433 ]
433 ]
434
434
435 [[package]]
435 [[package]]
436 name = "hermit-abi"
436 name = "hermit-abi"
437 version = "0.1.17"
437 version = "0.1.17"
438 source = "registry+https://github.com/rust-lang/crates.io-index"
438 source = "registry+https://github.com/rust-lang/crates.io-index"
439 checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8"
439 checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8"
440 dependencies = [
440 dependencies = [
441 "libc",
441 "libc",
442 ]
442 ]
443
443
444 [[package]]
444 [[package]]
445 name = "hex"
445 name = "hex"
446 version = "0.4.3"
446 version = "0.4.3"
447 source = "registry+https://github.com/rust-lang/crates.io-index"
447 source = "registry+https://github.com/rust-lang/crates.io-index"
448 checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
448 checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
449
449
450 [[package]]
450 [[package]]
451 name = "hg-core"
451 name = "hg-core"
452 version = "0.1.0"
452 version = "0.1.0"
453 dependencies = [
453 dependencies = [
454 "bitflags",
454 "bitflags",
455 "byteorder",
455 "byteorder",
456 "bytes-cast",
456 "bytes-cast",
457 "clap",
457 "clap",
458 "crossbeam-channel",
458 "crossbeam-channel",
459 "derive_more",
459 "derive_more",
460 "flate2",
460 "flate2",
461 "format-bytes",
461 "format-bytes",
462 "hashbrown",
462 "hashbrown",
463 "home",
463 "home",
464 "im-rc",
464 "im-rc",
465 "itertools 0.10.3",
465 "itertools 0.10.3",
466 "lazy_static",
466 "lazy_static",
467 "libc",
467 "libc",
468 "log",
468 "log",
469 "memmap2",
469 "memmap2",
470 "micro-timer",
470 "micro-timer",
471 "once_cell",
471 "ouroboros",
472 "ouroboros",
472 "pretty_assertions",
473 "pretty_assertions",
473 "rand 0.8.5",
474 "rand 0.8.5",
474 "rand_distr",
475 "rand_distr",
475 "rand_pcg",
476 "rand_pcg",
476 "rayon",
477 "rayon",
477 "regex",
478 "regex",
478 "same-file",
479 "same-file",
479 "sha-1 0.10.0",
480 "sha-1 0.10.0",
480 "tempfile",
481 "tempfile",
481 "twox-hash",
482 "twox-hash",
482 "zstd",
483 "zstd",
483 ]
484 ]
484
485
485 [[package]]
486 [[package]]
486 name = "hg-cpython"
487 name = "hg-cpython"
487 version = "0.1.0"
488 version = "0.1.0"
488 dependencies = [
489 dependencies = [
489 "cpython",
490 "cpython",
490 "crossbeam-channel",
491 "crossbeam-channel",
491 "env_logger",
492 "env_logger",
492 "hg-core",
493 "hg-core",
493 "libc",
494 "libc",
494 "log",
495 "log",
495 "stable_deref_trait",
496 "stable_deref_trait",
496 "vcsgraph",
497 "vcsgraph",
497 ]
498 ]
498
499
499 [[package]]
500 [[package]]
500 name = "home"
501 name = "home"
501 version = "0.5.3"
502 version = "0.5.3"
502 source = "registry+https://github.com/rust-lang/crates.io-index"
503 source = "registry+https://github.com/rust-lang/crates.io-index"
503 checksum = "2456aef2e6b6a9784192ae780c0f15bc57df0e918585282325e8c8ac27737654"
504 checksum = "2456aef2e6b6a9784192ae780c0f15bc57df0e918585282325e8c8ac27737654"
504 dependencies = [
505 dependencies = [
505 "winapi",
506 "winapi",
506 ]
507 ]
507
508
508 [[package]]
509 [[package]]
509 name = "humantime"
510 name = "humantime"
510 version = "2.1.0"
511 version = "2.1.0"
511 source = "registry+https://github.com/rust-lang/crates.io-index"
512 source = "registry+https://github.com/rust-lang/crates.io-index"
512 checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
513 checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
513
514
514 [[package]]
515 [[package]]
515 name = "im-rc"
516 name = "im-rc"
516 version = "15.0.0"
517 version = "15.0.0"
517 source = "registry+https://github.com/rust-lang/crates.io-index"
518 source = "registry+https://github.com/rust-lang/crates.io-index"
518 checksum = "3ca8957e71f04a205cb162508f9326aea04676c8dfd0711220190d6b83664f3f"
519 checksum = "3ca8957e71f04a205cb162508f9326aea04676c8dfd0711220190d6b83664f3f"
519 dependencies = [
520 dependencies = [
520 "bitmaps",
521 "bitmaps",
521 "rand_core 0.5.1",
522 "rand_core 0.5.1",
522 "rand_xoshiro",
523 "rand_xoshiro",
523 "sized-chunks",
524 "sized-chunks",
524 "typenum",
525 "typenum",
525 "version_check",
526 "version_check",
526 ]
527 ]
527
528
528 [[package]]
529 [[package]]
529 name = "instant"
530 name = "instant"
530 version = "0.1.12"
531 version = "0.1.12"
531 source = "registry+https://github.com/rust-lang/crates.io-index"
532 source = "registry+https://github.com/rust-lang/crates.io-index"
532 checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
533 checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
533 dependencies = [
534 dependencies = [
534 "cfg-if 1.0.0",
535 "cfg-if 1.0.0",
535 ]
536 ]
536
537
537 [[package]]
538 [[package]]
538 name = "itertools"
539 name = "itertools"
539 version = "0.9.0"
540 version = "0.9.0"
540 source = "registry+https://github.com/rust-lang/crates.io-index"
541 source = "registry+https://github.com/rust-lang/crates.io-index"
541 checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b"
542 checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b"
542 dependencies = [
543 dependencies = [
543 "either",
544 "either",
544 ]
545 ]
545
546
546 [[package]]
547 [[package]]
547 name = "itertools"
548 name = "itertools"
548 version = "0.10.3"
549 version = "0.10.3"
549 source = "registry+https://github.com/rust-lang/crates.io-index"
550 source = "registry+https://github.com/rust-lang/crates.io-index"
550 checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3"
551 checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3"
551 dependencies = [
552 dependencies = [
552 "either",
553 "either",
553 ]
554 ]
554
555
555 [[package]]
556 [[package]]
556 name = "jobserver"
557 name = "jobserver"
557 version = "0.1.21"
558 version = "0.1.21"
558 source = "registry+https://github.com/rust-lang/crates.io-index"
559 source = "registry+https://github.com/rust-lang/crates.io-index"
559 checksum = "5c71313ebb9439f74b00d9d2dcec36440beaf57a6aa0623068441dd7cd81a7f2"
560 checksum = "5c71313ebb9439f74b00d9d2dcec36440beaf57a6aa0623068441dd7cd81a7f2"
560 dependencies = [
561 dependencies = [
561 "libc",
562 "libc",
562 ]
563 ]
563
564
564 [[package]]
565 [[package]]
565 name = "lazy_static"
566 name = "lazy_static"
566 version = "1.4.0"
567 version = "1.4.0"
567 source = "registry+https://github.com/rust-lang/crates.io-index"
568 source = "registry+https://github.com/rust-lang/crates.io-index"
568 checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
569 checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
569
570
570 [[package]]
571 [[package]]
571 name = "libc"
572 name = "libc"
572 version = "0.2.124"
573 version = "0.2.124"
573 source = "registry+https://github.com/rust-lang/crates.io-index"
574 source = "registry+https://github.com/rust-lang/crates.io-index"
574 checksum = "21a41fed9d98f27ab1c6d161da622a4fa35e8a54a8adc24bbf3ddd0ef70b0e50"
575 checksum = "21a41fed9d98f27ab1c6d161da622a4fa35e8a54a8adc24bbf3ddd0ef70b0e50"
575
576
576 [[package]]
577 [[package]]
577 name = "libm"
578 name = "libm"
578 version = "0.2.1"
579 version = "0.2.1"
579 source = "registry+https://github.com/rust-lang/crates.io-index"
580 source = "registry+https://github.com/rust-lang/crates.io-index"
580 checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a"
581 checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a"
581
582
582 [[package]]
583 [[package]]
583 name = "libz-sys"
584 name = "libz-sys"
584 version = "1.1.2"
585 version = "1.1.2"
585 source = "registry+https://github.com/rust-lang/crates.io-index"
586 source = "registry+https://github.com/rust-lang/crates.io-index"
586 checksum = "602113192b08db8f38796c4e85c39e960c145965140e918018bcde1952429655"
587 checksum = "602113192b08db8f38796c4e85c39e960c145965140e918018bcde1952429655"
587 dependencies = [
588 dependencies = [
588 "cc",
589 "cc",
589 "pkg-config",
590 "pkg-config",
590 "vcpkg",
591 "vcpkg",
591 ]
592 ]
592
593
593 [[package]]
594 [[package]]
594 name = "log"
595 name = "log"
595 version = "0.4.14"
596 version = "0.4.14"
596 source = "registry+https://github.com/rust-lang/crates.io-index"
597 source = "registry+https://github.com/rust-lang/crates.io-index"
597 checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
598 checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
598 dependencies = [
599 dependencies = [
599 "cfg-if 1.0.0",
600 "cfg-if 1.0.0",
600 ]
601 ]
601
602
602 [[package]]
603 [[package]]
603 name = "memchr"
604 name = "memchr"
604 version = "2.4.1"
605 version = "2.4.1"
605 source = "registry+https://github.com/rust-lang/crates.io-index"
606 source = "registry+https://github.com/rust-lang/crates.io-index"
606 checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
607 checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
607
608
608 [[package]]
609 [[package]]
609 name = "memmap2"
610 name = "memmap2"
610 version = "0.5.7"
611 version = "0.5.7"
611 source = "registry+https://github.com/rust-lang/crates.io-index"
612 source = "registry+https://github.com/rust-lang/crates.io-index"
612 checksum = "95af15f345b17af2efc8ead6080fb8bc376f8cec1b35277b935637595fe77498"
613 checksum = "95af15f345b17af2efc8ead6080fb8bc376f8cec1b35277b935637595fe77498"
613 dependencies = [
614 dependencies = [
614 "libc",
615 "libc",
615 "stable_deref_trait",
616 "stable_deref_trait",
616 ]
617 ]
617
618
618 [[package]]
619 [[package]]
619 name = "memoffset"
620 name = "memoffset"
620 version = "0.6.1"
621 version = "0.6.1"
621 source = "registry+https://github.com/rust-lang/crates.io-index"
622 source = "registry+https://github.com/rust-lang/crates.io-index"
622 checksum = "157b4208e3059a8f9e78d559edc658e13df41410cb3ae03979c83130067fdd87"
623 checksum = "157b4208e3059a8f9e78d559edc658e13df41410cb3ae03979c83130067fdd87"
623 dependencies = [
624 dependencies = [
624 "autocfg",
625 "autocfg",
625 ]
626 ]
626
627
627 [[package]]
628 [[package]]
628 name = "micro-timer"
629 name = "micro-timer"
629 version = "0.4.0"
630 version = "0.4.0"
630 source = "registry+https://github.com/rust-lang/crates.io-index"
631 source = "registry+https://github.com/rust-lang/crates.io-index"
631 checksum = "5de32cb59a062672560d6f0842c4aa7714727457b9fe2daf8987d995a176a405"
632 checksum = "5de32cb59a062672560d6f0842c4aa7714727457b9fe2daf8987d995a176a405"
632 dependencies = [
633 dependencies = [
633 "micro-timer-macros",
634 "micro-timer-macros",
634 "scopeguard",
635 "scopeguard",
635 ]
636 ]
636
637
637 [[package]]
638 [[package]]
638 name = "micro-timer-macros"
639 name = "micro-timer-macros"
639 version = "0.4.0"
640 version = "0.4.0"
640 source = "registry+https://github.com/rust-lang/crates.io-index"
641 source = "registry+https://github.com/rust-lang/crates.io-index"
641 checksum = "cee948b94700125b52dfb68dd17c19f6326696c1df57f92c05ee857463c93ba1"
642 checksum = "cee948b94700125b52dfb68dd17c19f6326696c1df57f92c05ee857463c93ba1"
642 dependencies = [
643 dependencies = [
643 "proc-macro2",
644 "proc-macro2",
644 "quote",
645 "quote",
645 "scopeguard",
646 "scopeguard",
646 "syn",
647 "syn",
647 ]
648 ]
648
649
649 [[package]]
650 [[package]]
650 name = "miniz_oxide"
651 name = "miniz_oxide"
651 version = "0.4.3"
652 version = "0.4.3"
652 source = "registry+https://github.com/rust-lang/crates.io-index"
653 source = "registry+https://github.com/rust-lang/crates.io-index"
653 checksum = "0f2d26ec3309788e423cfbf68ad1800f061638098d76a83681af979dc4eda19d"
654 checksum = "0f2d26ec3309788e423cfbf68ad1800f061638098d76a83681af979dc4eda19d"
654 dependencies = [
655 dependencies = [
655 "adler",
656 "adler",
656 "autocfg",
657 "autocfg",
657 ]
658 ]
658
659
659 [[package]]
660 [[package]]
660 name = "num-integer"
661 name = "num-integer"
661 version = "0.1.44"
662 version = "0.1.44"
662 source = "registry+https://github.com/rust-lang/crates.io-index"
663 source = "registry+https://github.com/rust-lang/crates.io-index"
663 checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
664 checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
664 dependencies = [
665 dependencies = [
665 "autocfg",
666 "autocfg",
666 "num-traits",
667 "num-traits",
667 ]
668 ]
668
669
669 [[package]]
670 [[package]]
670 name = "num-traits"
671 name = "num-traits"
671 version = "0.2.14"
672 version = "0.2.14"
672 source = "registry+https://github.com/rust-lang/crates.io-index"
673 source = "registry+https://github.com/rust-lang/crates.io-index"
673 checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
674 checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
674 dependencies = [
675 dependencies = [
675 "autocfg",
676 "autocfg",
676 "libm",
677 "libm",
677 ]
678 ]
678
679
679 [[package]]
680 [[package]]
680 name = "num_cpus"
681 name = "num_cpus"
681 version = "1.13.0"
682 version = "1.13.0"
682 source = "registry+https://github.com/rust-lang/crates.io-index"
683 source = "registry+https://github.com/rust-lang/crates.io-index"
683 checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
684 checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
684 dependencies = [
685 dependencies = [
685 "hermit-abi",
686 "hermit-abi",
686 "libc",
687 "libc",
687 ]
688 ]
688
689
689 [[package]]
690 [[package]]
691 name = "once_cell"
692 version = "1.14.0"
693 source = "registry+https://github.com/rust-lang/crates.io-index"
694 checksum = "2f7254b99e31cad77da24b08ebf628882739a608578bb1bcdfc1f9c21260d7c0"
695
696 [[package]]
690 name = "opaque-debug"
697 name = "opaque-debug"
691 version = "0.3.0"
698 version = "0.3.0"
692 source = "registry+https://github.com/rust-lang/crates.io-index"
699 source = "registry+https://github.com/rust-lang/crates.io-index"
693 checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
700 checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
694
701
695 [[package]]
702 [[package]]
696 name = "ouroboros"
703 name = "ouroboros"
697 version = "0.15.0"
704 version = "0.15.0"
698 source = "registry+https://github.com/rust-lang/crates.io-index"
705 source = "registry+https://github.com/rust-lang/crates.io-index"
699 checksum = "9f31a3b678685b150cba82b702dcdc5e155893f63610cf388d30cd988d4ca2bf"
706 checksum = "9f31a3b678685b150cba82b702dcdc5e155893f63610cf388d30cd988d4ca2bf"
700 dependencies = [
707 dependencies = [
701 "aliasable",
708 "aliasable",
702 "ouroboros_macro",
709 "ouroboros_macro",
703 "stable_deref_trait",
710 "stable_deref_trait",
704 ]
711 ]
705
712
706 [[package]]
713 [[package]]
707 name = "ouroboros_macro"
714 name = "ouroboros_macro"
708 version = "0.15.0"
715 version = "0.15.0"
709 source = "registry+https://github.com/rust-lang/crates.io-index"
716 source = "registry+https://github.com/rust-lang/crates.io-index"
710 checksum = "084fd65d5dd8b3772edccb5ffd1e4b7eba43897ecd0f9401e330e8c542959408"
717 checksum = "084fd65d5dd8b3772edccb5ffd1e4b7eba43897ecd0f9401e330e8c542959408"
711 dependencies = [
718 dependencies = [
712 "Inflector",
719 "Inflector",
713 "proc-macro-error",
720 "proc-macro-error",
714 "proc-macro2",
721 "proc-macro2",
715 "quote",
722 "quote",
716 "syn",
723 "syn",
717 ]
724 ]
718
725
719 [[package]]
726 [[package]]
720 name = "output_vt100"
727 name = "output_vt100"
721 version = "0.1.2"
728 version = "0.1.2"
722 source = "registry+https://github.com/rust-lang/crates.io-index"
729 source = "registry+https://github.com/rust-lang/crates.io-index"
723 checksum = "53cdc5b785b7a58c5aad8216b3dfa114df64b0b06ae6e1501cef91df2fbdf8f9"
730 checksum = "53cdc5b785b7a58c5aad8216b3dfa114df64b0b06ae6e1501cef91df2fbdf8f9"
724 dependencies = [
731 dependencies = [
725 "winapi",
732 "winapi",
726 ]
733 ]
727
734
728 [[package]]
735 [[package]]
729 name = "paste"
736 name = "paste"
730 version = "1.0.5"
737 version = "1.0.5"
731 source = "registry+https://github.com/rust-lang/crates.io-index"
738 source = "registry+https://github.com/rust-lang/crates.io-index"
732 checksum = "acbf547ad0c65e31259204bd90935776d1c693cec2f4ff7abb7a1bbbd40dfe58"
739 checksum = "acbf547ad0c65e31259204bd90935776d1c693cec2f4ff7abb7a1bbbd40dfe58"
733
740
734 [[package]]
741 [[package]]
735 name = "pkg-config"
742 name = "pkg-config"
736 version = "0.3.19"
743 version = "0.3.19"
737 source = "registry+https://github.com/rust-lang/crates.io-index"
744 source = "registry+https://github.com/rust-lang/crates.io-index"
738 checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c"
745 checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c"
739
746
740 [[package]]
747 [[package]]
741 name = "ppv-lite86"
748 name = "ppv-lite86"
742 version = "0.2.10"
749 version = "0.2.10"
743 source = "registry+https://github.com/rust-lang/crates.io-index"
750 source = "registry+https://github.com/rust-lang/crates.io-index"
744 checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
751 checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
745
752
746 [[package]]
753 [[package]]
747 name = "pretty_assertions"
754 name = "pretty_assertions"
748 version = "1.1.0"
755 version = "1.1.0"
749 source = "registry+https://github.com/rust-lang/crates.io-index"
756 source = "registry+https://github.com/rust-lang/crates.io-index"
750 checksum = "76d5b548b725018ab5496482b45cb8bef21e9fed1858a6d674e3a8a0f0bb5d50"
757 checksum = "76d5b548b725018ab5496482b45cb8bef21e9fed1858a6d674e3a8a0f0bb5d50"
751 dependencies = [
758 dependencies = [
752 "ansi_term",
759 "ansi_term",
753 "ctor",
760 "ctor",
754 "diff",
761 "diff",
755 "output_vt100",
762 "output_vt100",
756 ]
763 ]
757
764
758 [[package]]
765 [[package]]
759 name = "proc-macro-error"
766 name = "proc-macro-error"
760 version = "1.0.4"
767 version = "1.0.4"
761 source = "registry+https://github.com/rust-lang/crates.io-index"
768 source = "registry+https://github.com/rust-lang/crates.io-index"
762 checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
769 checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
763 dependencies = [
770 dependencies = [
764 "proc-macro-error-attr",
771 "proc-macro-error-attr",
765 "proc-macro2",
772 "proc-macro2",
766 "quote",
773 "quote",
767 "syn",
774 "syn",
768 "version_check",
775 "version_check",
769 ]
776 ]
770
777
771 [[package]]
778 [[package]]
772 name = "proc-macro-error-attr"
779 name = "proc-macro-error-attr"
773 version = "1.0.4"
780 version = "1.0.4"
774 source = "registry+https://github.com/rust-lang/crates.io-index"
781 source = "registry+https://github.com/rust-lang/crates.io-index"
775 checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
782 checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
776 dependencies = [
783 dependencies = [
777 "proc-macro2",
784 "proc-macro2",
778 "quote",
785 "quote",
779 "version_check",
786 "version_check",
780 ]
787 ]
781
788
782 [[package]]
789 [[package]]
783 name = "proc-macro2"
790 name = "proc-macro2"
784 version = "1.0.24"
791 version = "1.0.24"
785 source = "registry+https://github.com/rust-lang/crates.io-index"
792 source = "registry+https://github.com/rust-lang/crates.io-index"
786 checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
793 checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
787 dependencies = [
794 dependencies = [
788 "unicode-xid",
795 "unicode-xid",
789 ]
796 ]
790
797
791 [[package]]
798 [[package]]
792 name = "python3-sys"
799 name = "python3-sys"
793 version = "0.7.0"
800 version = "0.7.0"
794 source = "registry+https://github.com/rust-lang/crates.io-index"
801 source = "registry+https://github.com/rust-lang/crates.io-index"
795 checksum = "b18b32e64c103d5045f44644d7ddddd65336f7a0521f6fde673240a9ecceb77e"
802 checksum = "b18b32e64c103d5045f44644d7ddddd65336f7a0521f6fde673240a9ecceb77e"
796 dependencies = [
803 dependencies = [
797 "libc",
804 "libc",
798 "regex",
805 "regex",
799 ]
806 ]
800
807
801 [[package]]
808 [[package]]
802 name = "quote"
809 name = "quote"
803 version = "1.0.7"
810 version = "1.0.7"
804 source = "registry+https://github.com/rust-lang/crates.io-index"
811 source = "registry+https://github.com/rust-lang/crates.io-index"
805 checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
812 checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
806 dependencies = [
813 dependencies = [
807 "proc-macro2",
814 "proc-macro2",
808 ]
815 ]
809
816
810 [[package]]
817 [[package]]
811 name = "rand"
818 name = "rand"
812 version = "0.7.3"
819 version = "0.7.3"
813 source = "registry+https://github.com/rust-lang/crates.io-index"
820 source = "registry+https://github.com/rust-lang/crates.io-index"
814 checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
821 checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
815 dependencies = [
822 dependencies = [
816 "getrandom 0.1.15",
823 "getrandom 0.1.15",
817 "libc",
824 "libc",
818 "rand_chacha 0.2.2",
825 "rand_chacha 0.2.2",
819 "rand_core 0.5.1",
826 "rand_core 0.5.1",
820 "rand_hc",
827 "rand_hc",
821 ]
828 ]
822
829
823 [[package]]
830 [[package]]
824 name = "rand"
831 name = "rand"
825 version = "0.8.5"
832 version = "0.8.5"
826 source = "registry+https://github.com/rust-lang/crates.io-index"
833 source = "registry+https://github.com/rust-lang/crates.io-index"
827 checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
834 checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
828 dependencies = [
835 dependencies = [
829 "libc",
836 "libc",
830 "rand_chacha 0.3.1",
837 "rand_chacha 0.3.1",
831 "rand_core 0.6.3",
838 "rand_core 0.6.3",
832 ]
839 ]
833
840
834 [[package]]
841 [[package]]
835 name = "rand_chacha"
842 name = "rand_chacha"
836 version = "0.2.2"
843 version = "0.2.2"
837 source = "registry+https://github.com/rust-lang/crates.io-index"
844 source = "registry+https://github.com/rust-lang/crates.io-index"
838 checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
845 checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
839 dependencies = [
846 dependencies = [
840 "ppv-lite86",
847 "ppv-lite86",
841 "rand_core 0.5.1",
848 "rand_core 0.5.1",
842 ]
849 ]
843
850
844 [[package]]
851 [[package]]
845 name = "rand_chacha"
852 name = "rand_chacha"
846 version = "0.3.1"
853 version = "0.3.1"
847 source = "registry+https://github.com/rust-lang/crates.io-index"
854 source = "registry+https://github.com/rust-lang/crates.io-index"
848 checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
855 checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
849 dependencies = [
856 dependencies = [
850 "ppv-lite86",
857 "ppv-lite86",
851 "rand_core 0.6.3",
858 "rand_core 0.6.3",
852 ]
859 ]
853
860
854 [[package]]
861 [[package]]
855 name = "rand_core"
862 name = "rand_core"
856 version = "0.5.1"
863 version = "0.5.1"
857 source = "registry+https://github.com/rust-lang/crates.io-index"
864 source = "registry+https://github.com/rust-lang/crates.io-index"
858 checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
865 checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
859 dependencies = [
866 dependencies = [
860 "getrandom 0.1.15",
867 "getrandom 0.1.15",
861 ]
868 ]
862
869
863 [[package]]
870 [[package]]
864 name = "rand_core"
871 name = "rand_core"
865 version = "0.6.3"
872 version = "0.6.3"
866 source = "registry+https://github.com/rust-lang/crates.io-index"
873 source = "registry+https://github.com/rust-lang/crates.io-index"
867 checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
874 checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
868 dependencies = [
875 dependencies = [
869 "getrandom 0.2.4",
876 "getrandom 0.2.4",
870 ]
877 ]
871
878
872 [[package]]
879 [[package]]
873 name = "rand_distr"
880 name = "rand_distr"
874 version = "0.4.3"
881 version = "0.4.3"
875 source = "registry+https://github.com/rust-lang/crates.io-index"
882 source = "registry+https://github.com/rust-lang/crates.io-index"
876 checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31"
883 checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31"
877 dependencies = [
884 dependencies = [
878 "num-traits",
885 "num-traits",
879 "rand 0.8.5",
886 "rand 0.8.5",
880 ]
887 ]
881
888
882 [[package]]
889 [[package]]
883 name = "rand_hc"
890 name = "rand_hc"
884 version = "0.2.0"
891 version = "0.2.0"
885 source = "registry+https://github.com/rust-lang/crates.io-index"
892 source = "registry+https://github.com/rust-lang/crates.io-index"
886 checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
893 checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
887 dependencies = [
894 dependencies = [
888 "rand_core 0.5.1",
895 "rand_core 0.5.1",
889 ]
896 ]
890
897
891 [[package]]
898 [[package]]
892 name = "rand_pcg"
899 name = "rand_pcg"
893 version = "0.3.1"
900 version = "0.3.1"
894 source = "registry+https://github.com/rust-lang/crates.io-index"
901 source = "registry+https://github.com/rust-lang/crates.io-index"
895 checksum = "59cad018caf63deb318e5a4586d99a24424a364f40f1e5778c29aca23f4fc73e"
902 checksum = "59cad018caf63deb318e5a4586d99a24424a364f40f1e5778c29aca23f4fc73e"
896 dependencies = [
903 dependencies = [
897 "rand_core 0.6.3",
904 "rand_core 0.6.3",
898 ]
905 ]
899
906
900 [[package]]
907 [[package]]
901 name = "rand_xoshiro"
908 name = "rand_xoshiro"
902 version = "0.4.0"
909 version = "0.4.0"
903 source = "registry+https://github.com/rust-lang/crates.io-index"
910 source = "registry+https://github.com/rust-lang/crates.io-index"
904 checksum = "a9fcdd2e881d02f1d9390ae47ad8e5696a9e4be7b547a1da2afbc61973217004"
911 checksum = "a9fcdd2e881d02f1d9390ae47ad8e5696a9e4be7b547a1da2afbc61973217004"
905 dependencies = [
912 dependencies = [
906 "rand_core 0.5.1",
913 "rand_core 0.5.1",
907 ]
914 ]
908
915
909 [[package]]
916 [[package]]
910 name = "rayon"
917 name = "rayon"
911 version = "1.5.1"
918 version = "1.5.1"
912 source = "registry+https://github.com/rust-lang/crates.io-index"
919 source = "registry+https://github.com/rust-lang/crates.io-index"
913 checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90"
920 checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90"
914 dependencies = [
921 dependencies = [
915 "autocfg",
922 "autocfg",
916 "crossbeam-deque",
923 "crossbeam-deque",
917 "either",
924 "either",
918 "rayon-core",
925 "rayon-core",
919 ]
926 ]
920
927
921 [[package]]
928 [[package]]
922 name = "rayon-core"
929 name = "rayon-core"
923 version = "1.9.1"
930 version = "1.9.1"
924 source = "registry+https://github.com/rust-lang/crates.io-index"
931 source = "registry+https://github.com/rust-lang/crates.io-index"
925 checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e"
932 checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e"
926 dependencies = [
933 dependencies = [
927 "crossbeam-channel",
934 "crossbeam-channel",
928 "crossbeam-deque",
935 "crossbeam-deque",
929 "crossbeam-utils",
936 "crossbeam-utils",
930 "lazy_static",
937 "lazy_static",
931 "num_cpus",
938 "num_cpus",
932 ]
939 ]
933
940
934 [[package]]
941 [[package]]
935 name = "redox_syscall"
942 name = "redox_syscall"
936 version = "0.2.11"
943 version = "0.2.11"
937 source = "registry+https://github.com/rust-lang/crates.io-index"
944 source = "registry+https://github.com/rust-lang/crates.io-index"
938 checksum = "8380fe0152551244f0747b1bf41737e0f8a74f97a14ccefd1148187271634f3c"
945 checksum = "8380fe0152551244f0747b1bf41737e0f8a74f97a14ccefd1148187271634f3c"
939 dependencies = [
946 dependencies = [
940 "bitflags",
947 "bitflags",
941 ]
948 ]
942
949
943 [[package]]
950 [[package]]
944 name = "regex"
951 name = "regex"
945 version = "1.5.5"
952 version = "1.5.5"
946 source = "registry+https://github.com/rust-lang/crates.io-index"
953 source = "registry+https://github.com/rust-lang/crates.io-index"
947 checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286"
954 checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286"
948 dependencies = [
955 dependencies = [
949 "aho-corasick",
956 "aho-corasick",
950 "memchr",
957 "memchr",
951 "regex-syntax",
958 "regex-syntax",
952 ]
959 ]
953
960
954 [[package]]
961 [[package]]
955 name = "regex-syntax"
962 name = "regex-syntax"
956 version = "0.6.25"
963 version = "0.6.25"
957 source = "registry+https://github.com/rust-lang/crates.io-index"
964 source = "registry+https://github.com/rust-lang/crates.io-index"
958 checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
965 checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
959
966
960 [[package]]
967 [[package]]
961 name = "remove_dir_all"
968 name = "remove_dir_all"
962 version = "0.5.3"
969 version = "0.5.3"
963 source = "registry+https://github.com/rust-lang/crates.io-index"
970 source = "registry+https://github.com/rust-lang/crates.io-index"
964 checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
971 checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
965 dependencies = [
972 dependencies = [
966 "winapi",
973 "winapi",
967 ]
974 ]
968
975
969 [[package]]
976 [[package]]
970 name = "rhg"
977 name = "rhg"
971 version = "0.1.0"
978 version = "0.1.0"
972 dependencies = [
979 dependencies = [
973 "atty",
980 "atty",
974 "chrono",
981 "chrono",
975 "clap",
982 "clap",
976 "derive_more",
983 "derive_more",
977 "env_logger",
984 "env_logger",
978 "format-bytes",
985 "format-bytes",
979 "hg-core",
986 "hg-core",
980 "home",
987 "home",
981 "lazy_static",
988 "lazy_static",
982 "log",
989 "log",
983 "micro-timer",
990 "micro-timer",
984 "rayon",
991 "rayon",
985 "regex",
992 "regex",
986 "users",
993 "users",
987 "which",
994 "which",
988 ]
995 ]
989
996
990 [[package]]
997 [[package]]
991 name = "rustc_version"
998 name = "rustc_version"
992 version = "0.4.0"
999 version = "0.4.0"
993 source = "registry+https://github.com/rust-lang/crates.io-index"
1000 source = "registry+https://github.com/rust-lang/crates.io-index"
994 checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
1001 checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
995 dependencies = [
1002 dependencies = [
996 "semver",
1003 "semver",
997 ]
1004 ]
998
1005
999 [[package]]
1006 [[package]]
1000 name = "same-file"
1007 name = "same-file"
1001 version = "1.0.6"
1008 version = "1.0.6"
1002 source = "registry+https://github.com/rust-lang/crates.io-index"
1009 source = "registry+https://github.com/rust-lang/crates.io-index"
1003 checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
1010 checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
1004 dependencies = [
1011 dependencies = [
1005 "winapi-util",
1012 "winapi-util",
1006 ]
1013 ]
1007
1014
1008 [[package]]
1015 [[package]]
1009 name = "scopeguard"
1016 name = "scopeguard"
1010 version = "1.1.0"
1017 version = "1.1.0"
1011 source = "registry+https://github.com/rust-lang/crates.io-index"
1018 source = "registry+https://github.com/rust-lang/crates.io-index"
1012 checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
1019 checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
1013
1020
1014 [[package]]
1021 [[package]]
1015 name = "semver"
1022 name = "semver"
1016 version = "1.0.6"
1023 version = "1.0.6"
1017 source = "registry+https://github.com/rust-lang/crates.io-index"
1024 source = "registry+https://github.com/rust-lang/crates.io-index"
1018 checksum = "a4a3381e03edd24287172047536f20cabde766e2cd3e65e6b00fb3af51c4f38d"
1025 checksum = "a4a3381e03edd24287172047536f20cabde766e2cd3e65e6b00fb3af51c4f38d"
1019
1026
1020 [[package]]
1027 [[package]]
1021 name = "sha-1"
1028 name = "sha-1"
1022 version = "0.9.6"
1029 version = "0.9.6"
1023 source = "registry+https://github.com/rust-lang/crates.io-index"
1030 source = "registry+https://github.com/rust-lang/crates.io-index"
1024 checksum = "8c4cfa741c5832d0ef7fab46cabed29c2aae926db0b11bb2069edd8db5e64e16"
1031 checksum = "8c4cfa741c5832d0ef7fab46cabed29c2aae926db0b11bb2069edd8db5e64e16"
1025 dependencies = [
1032 dependencies = [
1026 "block-buffer 0.9.0",
1033 "block-buffer 0.9.0",
1027 "cfg-if 1.0.0",
1034 "cfg-if 1.0.0",
1028 "cpufeatures 0.1.4",
1035 "cpufeatures 0.1.4",
1029 "digest 0.9.0",
1036 "digest 0.9.0",
1030 "opaque-debug",
1037 "opaque-debug",
1031 ]
1038 ]
1032
1039
1033 [[package]]
1040 [[package]]
1034 name = "sha-1"
1041 name = "sha-1"
1035 version = "0.10.0"
1042 version = "0.10.0"
1036 source = "registry+https://github.com/rust-lang/crates.io-index"
1043 source = "registry+https://github.com/rust-lang/crates.io-index"
1037 checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f"
1044 checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f"
1038 dependencies = [
1045 dependencies = [
1039 "cfg-if 1.0.0",
1046 "cfg-if 1.0.0",
1040 "cpufeatures 0.2.1",
1047 "cpufeatures 0.2.1",
1041 "digest 0.10.2",
1048 "digest 0.10.2",
1042 ]
1049 ]
1043
1050
1044 [[package]]
1051 [[package]]
1045 name = "sized-chunks"
1052 name = "sized-chunks"
1046 version = "0.6.2"
1053 version = "0.6.2"
1047 source = "registry+https://github.com/rust-lang/crates.io-index"
1054 source = "registry+https://github.com/rust-lang/crates.io-index"
1048 checksum = "1ec31ceca5644fa6d444cc77548b88b67f46db6f7c71683b0f9336e671830d2f"
1055 checksum = "1ec31ceca5644fa6d444cc77548b88b67f46db6f7c71683b0f9336e671830d2f"
1049 dependencies = [
1056 dependencies = [
1050 "bitmaps",
1057 "bitmaps",
1051 "typenum",
1058 "typenum",
1052 ]
1059 ]
1053
1060
1054 [[package]]
1061 [[package]]
1055 name = "stable_deref_trait"
1062 name = "stable_deref_trait"
1056 version = "1.2.0"
1063 version = "1.2.0"
1057 source = "registry+https://github.com/rust-lang/crates.io-index"
1064 source = "registry+https://github.com/rust-lang/crates.io-index"
1058 checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
1065 checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
1059
1066
1060 [[package]]
1067 [[package]]
1061 name = "static_assertions"
1068 name = "static_assertions"
1062 version = "1.1.0"
1069 version = "1.1.0"
1063 source = "registry+https://github.com/rust-lang/crates.io-index"
1070 source = "registry+https://github.com/rust-lang/crates.io-index"
1064 checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
1071 checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
1065
1072
1066 [[package]]
1073 [[package]]
1067 name = "strsim"
1074 name = "strsim"
1068 version = "0.8.0"
1075 version = "0.8.0"
1069 source = "registry+https://github.com/rust-lang/crates.io-index"
1076 source = "registry+https://github.com/rust-lang/crates.io-index"
1070 checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
1077 checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
1071
1078
1072 [[package]]
1079 [[package]]
1073 name = "syn"
1080 name = "syn"
1074 version = "1.0.54"
1081 version = "1.0.54"
1075 source = "registry+https://github.com/rust-lang/crates.io-index"
1082 source = "registry+https://github.com/rust-lang/crates.io-index"
1076 checksum = "9a2af957a63d6bd42255c359c93d9bfdb97076bd3b820897ce55ffbfbf107f44"
1083 checksum = "9a2af957a63d6bd42255c359c93d9bfdb97076bd3b820897ce55ffbfbf107f44"
1077 dependencies = [
1084 dependencies = [
1078 "proc-macro2",
1085 "proc-macro2",
1079 "quote",
1086 "quote",
1080 "unicode-xid",
1087 "unicode-xid",
1081 ]
1088 ]
1082
1089
1083 [[package]]
1090 [[package]]
1084 name = "tempfile"
1091 name = "tempfile"
1085 version = "3.3.0"
1092 version = "3.3.0"
1086 source = "registry+https://github.com/rust-lang/crates.io-index"
1093 source = "registry+https://github.com/rust-lang/crates.io-index"
1087 checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4"
1094 checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4"
1088 dependencies = [
1095 dependencies = [
1089 "cfg-if 1.0.0",
1096 "cfg-if 1.0.0",
1090 "fastrand",
1097 "fastrand",
1091 "libc",
1098 "libc",
1092 "redox_syscall",
1099 "redox_syscall",
1093 "remove_dir_all",
1100 "remove_dir_all",
1094 "winapi",
1101 "winapi",
1095 ]
1102 ]
1096
1103
1097 [[package]]
1104 [[package]]
1098 name = "termcolor"
1105 name = "termcolor"
1099 version = "1.1.2"
1106 version = "1.1.2"
1100 source = "registry+https://github.com/rust-lang/crates.io-index"
1107 source = "registry+https://github.com/rust-lang/crates.io-index"
1101 checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
1108 checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
1102 dependencies = [
1109 dependencies = [
1103 "winapi-util",
1110 "winapi-util",
1104 ]
1111 ]
1105
1112
1106 [[package]]
1113 [[package]]
1107 name = "textwrap"
1114 name = "textwrap"
1108 version = "0.11.0"
1115 version = "0.11.0"
1109 source = "registry+https://github.com/rust-lang/crates.io-index"
1116 source = "registry+https://github.com/rust-lang/crates.io-index"
1110 checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
1117 checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
1111 dependencies = [
1118 dependencies = [
1112 "unicode-width",
1119 "unicode-width",
1113 ]
1120 ]
1114
1121
1115 [[package]]
1122 [[package]]
1116 name = "time"
1123 name = "time"
1117 version = "0.1.44"
1124 version = "0.1.44"
1118 source = "registry+https://github.com/rust-lang/crates.io-index"
1125 source = "registry+https://github.com/rust-lang/crates.io-index"
1119 checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
1126 checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
1120 dependencies = [
1127 dependencies = [
1121 "libc",
1128 "libc",
1122 "wasi 0.10.0+wasi-snapshot-preview1",
1129 "wasi 0.10.0+wasi-snapshot-preview1",
1123 "winapi",
1130 "winapi",
1124 ]
1131 ]
1125
1132
1126 [[package]]
1133 [[package]]
1127 name = "twox-hash"
1134 name = "twox-hash"
1128 version = "1.6.2"
1135 version = "1.6.2"
1129 source = "registry+https://github.com/rust-lang/crates.io-index"
1136 source = "registry+https://github.com/rust-lang/crates.io-index"
1130 checksum = "4ee73e6e4924fe940354b8d4d98cad5231175d615cd855b758adc658c0aac6a0"
1137 checksum = "4ee73e6e4924fe940354b8d4d98cad5231175d615cd855b758adc658c0aac6a0"
1131 dependencies = [
1138 dependencies = [
1132 "cfg-if 1.0.0",
1139 "cfg-if 1.0.0",
1133 "rand 0.8.5",
1140 "rand 0.8.5",
1134 "static_assertions",
1141 "static_assertions",
1135 ]
1142 ]
1136
1143
1137 [[package]]
1144 [[package]]
1138 name = "typenum"
1145 name = "typenum"
1139 version = "1.12.0"
1146 version = "1.12.0"
1140 source = "registry+https://github.com/rust-lang/crates.io-index"
1147 source = "registry+https://github.com/rust-lang/crates.io-index"
1141 checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33"
1148 checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33"
1142
1149
1143 [[package]]
1150 [[package]]
1144 name = "unicode-width"
1151 name = "unicode-width"
1145 version = "0.1.9"
1152 version = "0.1.9"
1146 source = "registry+https://github.com/rust-lang/crates.io-index"
1153 source = "registry+https://github.com/rust-lang/crates.io-index"
1147 checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
1154 checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
1148
1155
1149 [[package]]
1156 [[package]]
1150 name = "unicode-xid"
1157 name = "unicode-xid"
1151 version = "0.2.1"
1158 version = "0.2.1"
1152 source = "registry+https://github.com/rust-lang/crates.io-index"
1159 source = "registry+https://github.com/rust-lang/crates.io-index"
1153 checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
1160 checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
1154
1161
1155 [[package]]
1162 [[package]]
1156 name = "users"
1163 name = "users"
1157 version = "0.11.0"
1164 version = "0.11.0"
1158 source = "registry+https://github.com/rust-lang/crates.io-index"
1165 source = "registry+https://github.com/rust-lang/crates.io-index"
1159 checksum = "24cc0f6d6f267b73e5a2cadf007ba8f9bc39c6a6f9666f8cf25ea809a153b032"
1166 checksum = "24cc0f6d6f267b73e5a2cadf007ba8f9bc39c6a6f9666f8cf25ea809a153b032"
1160 dependencies = [
1167 dependencies = [
1161 "libc",
1168 "libc",
1162 "log",
1169 "log",
1163 ]
1170 ]
1164
1171
1165 [[package]]
1172 [[package]]
1166 name = "vcpkg"
1173 name = "vcpkg"
1167 version = "0.2.11"
1174 version = "0.2.11"
1168 source = "registry+https://github.com/rust-lang/crates.io-index"
1175 source = "registry+https://github.com/rust-lang/crates.io-index"
1169 checksum = "b00bca6106a5e23f3eee943593759b7fcddb00554332e856d990c893966879fb"
1176 checksum = "b00bca6106a5e23f3eee943593759b7fcddb00554332e856d990c893966879fb"
1170
1177
1171 [[package]]
1178 [[package]]
1172 name = "vcsgraph"
1179 name = "vcsgraph"
1173 version = "0.2.0"
1180 version = "0.2.0"
1174 source = "registry+https://github.com/rust-lang/crates.io-index"
1181 source = "registry+https://github.com/rust-lang/crates.io-index"
1175 checksum = "4cb68c231e2575f7503a7c19213875f9d4ec2e84e963a56ce3de4b6bee351ef7"
1182 checksum = "4cb68c231e2575f7503a7c19213875f9d4ec2e84e963a56ce3de4b6bee351ef7"
1176 dependencies = [
1183 dependencies = [
1177 "hex",
1184 "hex",
1178 "rand 0.7.3",
1185 "rand 0.7.3",
1179 "sha-1 0.9.6",
1186 "sha-1 0.9.6",
1180 ]
1187 ]
1181
1188
1182 [[package]]
1189 [[package]]
1183 name = "vec_map"
1190 name = "vec_map"
1184 version = "0.8.2"
1191 version = "0.8.2"
1185 source = "registry+https://github.com/rust-lang/crates.io-index"
1192 source = "registry+https://github.com/rust-lang/crates.io-index"
1186 checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
1193 checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
1187
1194
1188 [[package]]
1195 [[package]]
1189 name = "version_check"
1196 name = "version_check"
1190 version = "0.9.2"
1197 version = "0.9.2"
1191 source = "registry+https://github.com/rust-lang/crates.io-index"
1198 source = "registry+https://github.com/rust-lang/crates.io-index"
1192 checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
1199 checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
1193
1200
1194 [[package]]
1201 [[package]]
1195 name = "wasi"
1202 name = "wasi"
1196 version = "0.9.0+wasi-snapshot-preview1"
1203 version = "0.9.0+wasi-snapshot-preview1"
1197 source = "registry+https://github.com/rust-lang/crates.io-index"
1204 source = "registry+https://github.com/rust-lang/crates.io-index"
1198 checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
1205 checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
1199
1206
1200 [[package]]
1207 [[package]]
1201 name = "wasi"
1208 name = "wasi"
1202 version = "0.10.0+wasi-snapshot-preview1"
1209 version = "0.10.0+wasi-snapshot-preview1"
1203 source = "registry+https://github.com/rust-lang/crates.io-index"
1210 source = "registry+https://github.com/rust-lang/crates.io-index"
1204 checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
1211 checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
1205
1212
1206 [[package]]
1213 [[package]]
1207 name = "which"
1214 name = "which"
1208 version = "4.2.5"
1215 version = "4.2.5"
1209 source = "registry+https://github.com/rust-lang/crates.io-index"
1216 source = "registry+https://github.com/rust-lang/crates.io-index"
1210 checksum = "5c4fb54e6113b6a8772ee41c3404fb0301ac79604489467e0a9ce1f3e97c24ae"
1217 checksum = "5c4fb54e6113b6a8772ee41c3404fb0301ac79604489467e0a9ce1f3e97c24ae"
1211 dependencies = [
1218 dependencies = [
1212 "either",
1219 "either",
1213 "lazy_static",
1220 "lazy_static",
1214 "libc",
1221 "libc",
1215 ]
1222 ]
1216
1223
1217 [[package]]
1224 [[package]]
1218 name = "winapi"
1225 name = "winapi"
1219 version = "0.3.9"
1226 version = "0.3.9"
1220 source = "registry+https://github.com/rust-lang/crates.io-index"
1227 source = "registry+https://github.com/rust-lang/crates.io-index"
1221 checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
1228 checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
1222 dependencies = [
1229 dependencies = [
1223 "winapi-i686-pc-windows-gnu",
1230 "winapi-i686-pc-windows-gnu",
1224 "winapi-x86_64-pc-windows-gnu",
1231 "winapi-x86_64-pc-windows-gnu",
1225 ]
1232 ]
1226
1233
1227 [[package]]
1234 [[package]]
1228 name = "winapi-i686-pc-windows-gnu"
1235 name = "winapi-i686-pc-windows-gnu"
1229 version = "0.4.0"
1236 version = "0.4.0"
1230 source = "registry+https://github.com/rust-lang/crates.io-index"
1237 source = "registry+https://github.com/rust-lang/crates.io-index"
1231 checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
1238 checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
1232
1239
1233 [[package]]
1240 [[package]]
1234 name = "winapi-util"
1241 name = "winapi-util"
1235 version = "0.1.5"
1242 version = "0.1.5"
1236 source = "registry+https://github.com/rust-lang/crates.io-index"
1243 source = "registry+https://github.com/rust-lang/crates.io-index"
1237 checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
1244 checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
1238 dependencies = [
1245 dependencies = [
1239 "winapi",
1246 "winapi",
1240 ]
1247 ]
1241
1248
1242 [[package]]
1249 [[package]]
1243 name = "winapi-x86_64-pc-windows-gnu"
1250 name = "winapi-x86_64-pc-windows-gnu"
1244 version = "0.4.0"
1251 version = "0.4.0"
1245 source = "registry+https://github.com/rust-lang/crates.io-index"
1252 source = "registry+https://github.com/rust-lang/crates.io-index"
1246 checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
1253 checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
1247
1254
1248 [[package]]
1255 [[package]]
1249 name = "zstd"
1256 name = "zstd"
1250 version = "0.5.4+zstd.1.4.7"
1257 version = "0.5.4+zstd.1.4.7"
1251 source = "registry+https://github.com/rust-lang/crates.io-index"
1258 source = "registry+https://github.com/rust-lang/crates.io-index"
1252 checksum = "69996ebdb1ba8b1517f61387a883857818a66c8a295f487b1ffd8fd9d2c82910"
1259 checksum = "69996ebdb1ba8b1517f61387a883857818a66c8a295f487b1ffd8fd9d2c82910"
1253 dependencies = [
1260 dependencies = [
1254 "zstd-safe",
1261 "zstd-safe",
1255 ]
1262 ]
1256
1263
1257 [[package]]
1264 [[package]]
1258 name = "zstd-safe"
1265 name = "zstd-safe"
1259 version = "2.0.6+zstd.1.4.7"
1266 version = "2.0.6+zstd.1.4.7"
1260 source = "registry+https://github.com/rust-lang/crates.io-index"
1267 source = "registry+https://github.com/rust-lang/crates.io-index"
1261 checksum = "98aa931fb69ecee256d44589d19754e61851ae4769bf963b385119b1cc37a49e"
1268 checksum = "98aa931fb69ecee256d44589d19754e61851ae4769bf963b385119b1cc37a49e"
1262 dependencies = [
1269 dependencies = [
1263 "libc",
1270 "libc",
1264 "zstd-sys",
1271 "zstd-sys",
1265 ]
1272 ]
1266
1273
1267 [[package]]
1274 [[package]]
1268 name = "zstd-sys"
1275 name = "zstd-sys"
1269 version = "1.4.18+zstd.1.4.7"
1276 version = "1.4.18+zstd.1.4.7"
1270 source = "registry+https://github.com/rust-lang/crates.io-index"
1277 source = "registry+https://github.com/rust-lang/crates.io-index"
1271 checksum = "a1e6e8778706838f43f771d80d37787cb2fe06dafe89dd3aebaf6721b9eaec81"
1278 checksum = "a1e6e8778706838f43f771d80d37787cb2fe06dafe89dd3aebaf6721b9eaec81"
1272 dependencies = [
1279 dependencies = [
1273 "cc",
1280 "cc",
1274 "glob",
1281 "glob",
1275 "itertools 0.9.0",
1282 "itertools 0.9.0",
1276 "libc",
1283 "libc",
1277 ]
1284 ]
@@ -1,48 +1,51 b''
1 [package]
1 [package]
2 name = "hg-core"
2 name = "hg-core"
3 version = "0.1.0"
3 version = "0.1.0"
4 authors = ["Georges Racinet <gracinet@anybox.fr>"]
4 authors = ["Georges Racinet <gracinet@anybox.fr>"]
5 description = "Mercurial pure Rust core library, with no assumption on Python bindings (FFI)"
5 description = "Mercurial pure Rust core library, with no assumption on Python bindings (FFI)"
6 edition = "2018"
6 edition = "2018"
7
7
8 [lib]
8 [lib]
9 name = "hg"
9 name = "hg"
10
10
11 [dependencies]
11 [dependencies]
12 bitflags = "1.3.2"
12 bitflags = "1.3.2"
13 bytes-cast = "0.2.0"
13 bytes-cast = "0.2.0"
14 byteorder = "1.4.3"
14 byteorder = "1.4.3"
15 derive_more = "0.99.17"
15 derive_more = "0.99.17"
16 hashbrown = { version = "0.9.1", features = ["rayon"] }
16 hashbrown = { version = "0.9.1", features = ["rayon"] }
17 home = "0.5.3"
17 home = "0.5.3"
18 im-rc = "15.0"
18 im-rc = "15.0"
19 itertools = "0.10.3"
19 itertools = "0.10.3"
20 lazy_static = "1.4.0"
20 lazy_static = "1.4.0"
21 libc = "0.2"
21 libc = "0.2"
22 ouroboros = "0.15.0"
22 ouroboros = "0.15.0"
23 rand = "0.8.4"
23 rand = "0.8.4"
24 rand_pcg = "0.3.1"
24 rand_pcg = "0.3.1"
25 rand_distr = "0.4.3"
25 rand_distr = "0.4.3"
26 rayon = "1.5.1"
26 rayon = "1.5.1"
27 regex = "1.5.5"
27 regex = "1.5.5"
28 sha-1 = "0.10.0"
28 sha-1 = "0.10.0"
29 twox-hash = "1.6.2"
29 twox-hash = "1.6.2"
30 same-file = "1.0.6"
30 same-file = "1.0.6"
31 tempfile = "3.1.0"
31 tempfile = "3.1.0"
32 crossbeam-channel = "0.5.0"
32 crossbeam-channel = "0.5.0"
33 micro-timer = "0.4.0"
33 micro-timer = "0.4.0"
34 log = "0.4.8"
34 log = "0.4.8"
35 memmap2 = { version = "0.5.3", features = ["stable_deref_trait"] }
35 memmap2 = { version = "0.5.3", features = ["stable_deref_trait"] }
36 zstd = "0.5.3"
36 zstd = "0.5.3"
37 format-bytes = "0.3.0"
37 format-bytes = "0.3.0"
38 # once_cell 1.15 uses edition 2021, while the heptapod CI
39 # uses an old version of Cargo that doesn't support it.
40 once_cell = "=1.14.0"
38
41
39 # We don't use the `miniz-oxide` backend to not change rhg benchmarks and until
42 # We don't use the `miniz-oxide` backend to not change rhg benchmarks and until
40 # we have a clearer view of which backend is the fastest.
43 # we have a clearer view of which backend is the fastest.
41 [dependencies.flate2]
44 [dependencies.flate2]
42 version = "1.0.22"
45 version = "1.0.22"
43 features = ["zlib"]
46 features = ["zlib"]
44 default-features = false
47 default-features = false
45
48
46 [dev-dependencies]
49 [dev-dependencies]
47 clap = "2.34.0"
50 clap = "2.34.0"
48 pretty_assertions = "1.1.0"
51 pretty_assertions = "1.1.0"
@@ -1,863 +1,901 b''
1 use crate::dirstate::entry::TruncatedTimestamp;
1 use crate::dirstate::entry::TruncatedTimestamp;
2 use crate::dirstate::status::IgnoreFnType;
2 use crate::dirstate::status::IgnoreFnType;
3 use crate::dirstate::status::StatusPath;
3 use crate::dirstate::status::StatusPath;
4 use crate::dirstate_tree::dirstate_map::BorrowedPath;
4 use crate::dirstate_tree::dirstate_map::BorrowedPath;
5 use crate::dirstate_tree::dirstate_map::ChildNodesRef;
5 use crate::dirstate_tree::dirstate_map::ChildNodesRef;
6 use crate::dirstate_tree::dirstate_map::DirstateMap;
6 use crate::dirstate_tree::dirstate_map::DirstateMap;
7 use crate::dirstate_tree::dirstate_map::DirstateVersion;
7 use crate::dirstate_tree::dirstate_map::DirstateVersion;
8 use crate::dirstate_tree::dirstate_map::NodeRef;
8 use crate::dirstate_tree::dirstate_map::NodeRef;
9 use crate::dirstate_tree::on_disk::DirstateV2ParseError;
9 use crate::dirstate_tree::on_disk::DirstateV2ParseError;
10 use crate::matchers::get_ignore_function;
10 use crate::matchers::get_ignore_function;
11 use crate::matchers::Matcher;
11 use crate::matchers::Matcher;
12 use crate::utils::files::get_bytes_from_os_string;
12 use crate::utils::files::get_bytes_from_os_string;
13 use crate::utils::files::get_path_from_bytes;
13 use crate::utils::files::get_path_from_bytes;
14 use crate::utils::hg_path::HgPath;
14 use crate::utils::hg_path::HgPath;
15 use crate::BadMatch;
15 use crate::BadMatch;
16 use crate::DirstateStatus;
16 use crate::DirstateStatus;
17 use crate::HgPathBuf;
17 use crate::HgPathBuf;
18 use crate::HgPathCow;
18 use crate::HgPathCow;
19 use crate::PatternFileWarning;
19 use crate::PatternFileWarning;
20 use crate::StatusError;
20 use crate::StatusError;
21 use crate::StatusOptions;
21 use crate::StatusOptions;
22 use micro_timer::timed;
22 use micro_timer::timed;
23 use once_cell::sync::OnceCell;
23 use rayon::prelude::*;
24 use rayon::prelude::*;
24 use sha1::{Digest, Sha1};
25 use sha1::{Digest, Sha1};
25 use std::borrow::Cow;
26 use std::borrow::Cow;
26 use std::io;
27 use std::io;
27 use std::path::Path;
28 use std::path::Path;
28 use std::path::PathBuf;
29 use std::path::PathBuf;
29 use std::sync::Mutex;
30 use std::sync::Mutex;
30 use std::time::SystemTime;
31 use std::time::SystemTime;
31
32
32 /// Returns the status of the working directory compared to its parent
33 /// Returns the status of the working directory compared to its parent
33 /// changeset.
34 /// changeset.
34 ///
35 ///
35 /// This algorithm is based on traversing the filesystem tree (`fs` in function
36 /// This algorithm is based on traversing the filesystem tree (`fs` in function
36 /// and variable names) and dirstate tree at the same time. The core of this
37 /// and variable names) and dirstate tree at the same time. The core of this
37 /// traversal is the recursive `traverse_fs_directory_and_dirstate` function
38 /// traversal is the recursive `traverse_fs_directory_and_dirstate` function
38 /// and its use of `itertools::merge_join_by`. When reaching a path that only
39 /// and its use of `itertools::merge_join_by`. When reaching a path that only
39 /// exists in one of the two trees, depending on information requested by
40 /// exists in one of the two trees, depending on information requested by
40 /// `options` we may need to traverse the remaining subtree.
41 /// `options` we may need to traverse the remaining subtree.
41 #[timed]
42 #[timed]
42 pub fn status<'dirstate>(
43 pub fn status<'dirstate>(
43 dmap: &'dirstate mut DirstateMap,
44 dmap: &'dirstate mut DirstateMap,
44 matcher: &(dyn Matcher + Sync),
45 matcher: &(dyn Matcher + Sync),
45 root_dir: PathBuf,
46 root_dir: PathBuf,
46 ignore_files: Vec<PathBuf>,
47 ignore_files: Vec<PathBuf>,
47 options: StatusOptions,
48 options: StatusOptions,
48 ) -> Result<(DirstateStatus<'dirstate>, Vec<PatternFileWarning>), StatusError>
49 ) -> Result<(DirstateStatus<'dirstate>, Vec<PatternFileWarning>), StatusError>
49 {
50 {
50 // Force the global rayon threadpool to not exceed 16 concurrent threads.
51 // Force the global rayon threadpool to not exceed 16 concurrent threads.
51 // This is a stop-gap measure until we figure out why using more than 16
52 // This is a stop-gap measure until we figure out why using more than 16
52 // threads makes `status` slower for each additional thread.
53 // threads makes `status` slower for each additional thread.
53 // We use `ok()` in case the global threadpool has already been
54 // We use `ok()` in case the global threadpool has already been
54 // instantiated in `rhg` or some other caller.
55 // instantiated in `rhg` or some other caller.
55 // TODO find the underlying cause and fix it, then remove this.
56 // TODO find the underlying cause and fix it, then remove this.
56 rayon::ThreadPoolBuilder::new()
57 rayon::ThreadPoolBuilder::new()
57 .num_threads(16)
58 .num_threads(16)
58 .build_global()
59 .build_global()
59 .ok();
60 .ok();
60
61
61 let (ignore_fn, warnings, patterns_changed): (IgnoreFnType, _, _) =
62 let (ignore_fn, warnings, patterns_changed): (IgnoreFnType, _, _) =
62 if options.list_ignored || options.list_unknown {
63 if options.list_ignored || options.list_unknown {
63 let (ignore_fn, warnings, changed) = match dmap.dirstate_version {
64 let (ignore_fn, warnings, changed) = match dmap.dirstate_version {
64 DirstateVersion::V1 => {
65 DirstateVersion::V1 => {
65 let (ignore_fn, warnings) = get_ignore_function(
66 let (ignore_fn, warnings) = get_ignore_function(
66 ignore_files,
67 ignore_files,
67 &root_dir,
68 &root_dir,
68 &mut |_pattern_bytes| {},
69 &mut |_pattern_bytes| {},
69 )?;
70 )?;
70 (ignore_fn, warnings, None)
71 (ignore_fn, warnings, None)
71 }
72 }
72 DirstateVersion::V2 => {
73 DirstateVersion::V2 => {
73 let mut hasher = Sha1::new();
74 let mut hasher = Sha1::new();
74 let (ignore_fn, warnings) = get_ignore_function(
75 let (ignore_fn, warnings) = get_ignore_function(
75 ignore_files,
76 ignore_files,
76 &root_dir,
77 &root_dir,
77 &mut |pattern_bytes| hasher.update(pattern_bytes),
78 &mut |pattern_bytes| hasher.update(pattern_bytes),
78 )?;
79 )?;
79 let new_hash = *hasher.finalize().as_ref();
80 let new_hash = *hasher.finalize().as_ref();
80 let changed = new_hash != dmap.ignore_patterns_hash;
81 let changed = new_hash != dmap.ignore_patterns_hash;
81 dmap.ignore_patterns_hash = new_hash;
82 dmap.ignore_patterns_hash = new_hash;
82 (ignore_fn, warnings, Some(changed))
83 (ignore_fn, warnings, Some(changed))
83 }
84 }
84 };
85 };
85 (ignore_fn, warnings, changed)
86 (ignore_fn, warnings, changed)
86 } else {
87 } else {
87 (Box::new(|&_| true), vec![], None)
88 (Box::new(|&_| true), vec![], None)
88 };
89 };
89
90
90 let filesystem_time_at_status_start =
91 let filesystem_time_at_status_start =
91 filesystem_now(&root_dir).ok().map(TruncatedTimestamp::from);
92 filesystem_now(&root_dir).ok().map(TruncatedTimestamp::from);
92
93
93 // If the repository is under the current directory, prefer using a
94 // If the repository is under the current directory, prefer using a
94 // relative path, so the kernel needs to traverse fewer directory in every
95 // relative path, so the kernel needs to traverse fewer directory in every
95 // call to `read_dir` or `symlink_metadata`.
96 // call to `read_dir` or `symlink_metadata`.
96 // This is effective in the common case where the current directory is the
97 // This is effective in the common case where the current directory is the
97 // repository root.
98 // repository root.
98
99
99 // TODO: Better yet would be to use libc functions like `openat` and
100 // TODO: Better yet would be to use libc functions like `openat` and
100 // `fstatat` to remove such repeated traversals entirely, but the standard
101 // `fstatat` to remove such repeated traversals entirely, but the standard
101 // library does not provide APIs based on those.
102 // library does not provide APIs based on those.
102 // Maybe with a crate like https://crates.io/crates/openat instead?
103 // Maybe with a crate like https://crates.io/crates/openat instead?
103 let root_dir = if let Some(relative) = std::env::current_dir()
104 let root_dir = if let Some(relative) = std::env::current_dir()
104 .ok()
105 .ok()
105 .and_then(|cwd| root_dir.strip_prefix(cwd).ok())
106 .and_then(|cwd| root_dir.strip_prefix(cwd).ok())
106 {
107 {
107 relative
108 relative
108 } else {
109 } else {
109 &root_dir
110 &root_dir
110 };
111 };
111
112
112 let outcome = DirstateStatus {
113 let outcome = DirstateStatus {
113 filesystem_time_at_status_start,
114 filesystem_time_at_status_start,
114 ..Default::default()
115 ..Default::default()
115 };
116 };
116 let common = StatusCommon {
117 let common = StatusCommon {
117 dmap,
118 dmap,
118 options,
119 options,
119 matcher,
120 matcher,
120 ignore_fn,
121 ignore_fn,
121 outcome: Mutex::new(outcome),
122 outcome: Mutex::new(outcome),
122 ignore_patterns_have_changed: patterns_changed,
123 ignore_patterns_have_changed: patterns_changed,
123 new_cachable_directories: Default::default(),
124 new_cachable_directories: Default::default(),
124 outated_cached_directories: Default::default(),
125 outated_cached_directories: Default::default(),
125 filesystem_time_at_status_start,
126 filesystem_time_at_status_start,
126 };
127 };
127 let is_at_repo_root = true;
128 let is_at_repo_root = true;
128 let hg_path = &BorrowedPath::OnDisk(HgPath::new(""));
129 let hg_path = &BorrowedPath::OnDisk(HgPath::new(""));
129 let has_ignored_ancestor = false;
130 let has_ignored_ancestor = HasIgnoredAncestor::create(None, hg_path);
130 let root_cached_mtime = None;
131 let root_cached_mtime = None;
131 let root_dir_metadata = None;
132 let root_dir_metadata = None;
132 // If the path we have for the repository root is a symlink, do follow it.
133 // If the path we have for the repository root is a symlink, do follow it.
133 // (As opposed to symlinks within the working directory which are not
134 // (As opposed to symlinks within the working directory which are not
134 // followed, using `std::fs::symlink_metadata`.)
135 // followed, using `std::fs::symlink_metadata`.)
135 common.traverse_fs_directory_and_dirstate(
136 common.traverse_fs_directory_and_dirstate(
136 has_ignored_ancestor,
137 &has_ignored_ancestor,
137 dmap.root.as_ref(),
138 dmap.root.as_ref(),
138 hg_path,
139 hg_path,
139 &root_dir,
140 &root_dir,
140 root_dir_metadata,
141 root_dir_metadata,
141 root_cached_mtime,
142 root_cached_mtime,
142 is_at_repo_root,
143 is_at_repo_root,
143 )?;
144 )?;
144 let mut outcome = common.outcome.into_inner().unwrap();
145 let mut outcome = common.outcome.into_inner().unwrap();
145 let new_cachable = common.new_cachable_directories.into_inner().unwrap();
146 let new_cachable = common.new_cachable_directories.into_inner().unwrap();
146 let outdated = common.outated_cached_directories.into_inner().unwrap();
147 let outdated = common.outated_cached_directories.into_inner().unwrap();
147
148
148 outcome.dirty = common.ignore_patterns_have_changed == Some(true)
149 outcome.dirty = common.ignore_patterns_have_changed == Some(true)
149 || !outdated.is_empty()
150 || !outdated.is_empty()
150 || (!new_cachable.is_empty()
151 || (!new_cachable.is_empty()
151 && dmap.dirstate_version == DirstateVersion::V2);
152 && dmap.dirstate_version == DirstateVersion::V2);
152
153
153 // Remove outdated mtimes before adding new mtimes, in case a given
154 // Remove outdated mtimes before adding new mtimes, in case a given
154 // directory is both
155 // directory is both
155 for path in &outdated {
156 for path in &outdated {
156 dmap.clear_cached_mtime(path)?;
157 dmap.clear_cached_mtime(path)?;
157 }
158 }
158 for (path, mtime) in &new_cachable {
159 for (path, mtime) in &new_cachable {
159 dmap.set_cached_mtime(path, *mtime)?;
160 dmap.set_cached_mtime(path, *mtime)?;
160 }
161 }
161
162
162 Ok((outcome, warnings))
163 Ok((outcome, warnings))
163 }
164 }
164
165
165 /// Bag of random things needed by various parts of the algorithm. Reduces the
166 /// Bag of random things needed by various parts of the algorithm. Reduces the
166 /// number of parameters passed to functions.
167 /// number of parameters passed to functions.
167 struct StatusCommon<'a, 'tree, 'on_disk: 'tree> {
168 struct StatusCommon<'a, 'tree, 'on_disk: 'tree> {
168 dmap: &'tree DirstateMap<'on_disk>,
169 dmap: &'tree DirstateMap<'on_disk>,
169 options: StatusOptions,
170 options: StatusOptions,
170 matcher: &'a (dyn Matcher + Sync),
171 matcher: &'a (dyn Matcher + Sync),
171 ignore_fn: IgnoreFnType<'a>,
172 ignore_fn: IgnoreFnType<'a>,
172 outcome: Mutex<DirstateStatus<'on_disk>>,
173 outcome: Mutex<DirstateStatus<'on_disk>>,
173 new_cachable_directories:
174 new_cachable_directories:
174 Mutex<Vec<(Cow<'on_disk, HgPath>, TruncatedTimestamp)>>,
175 Mutex<Vec<(Cow<'on_disk, HgPath>, TruncatedTimestamp)>>,
175 outated_cached_directories: Mutex<Vec<Cow<'on_disk, HgPath>>>,
176 outated_cached_directories: Mutex<Vec<Cow<'on_disk, HgPath>>>,
176
177
177 /// Whether ignore files like `.hgignore` have changed since the previous
178 /// Whether ignore files like `.hgignore` have changed since the previous
178 /// time a `status()` call wrote their hash to the dirstate. `None` means
179 /// time a `status()` call wrote their hash to the dirstate. `None` means
179 /// we don’t know as this run doesn’t list either ignored or uknown files
180 /// we don’t know as this run doesn’t list either ignored or uknown files
180 /// and therefore isn’t reading `.hgignore`.
181 /// and therefore isn’t reading `.hgignore`.
181 ignore_patterns_have_changed: Option<bool>,
182 ignore_patterns_have_changed: Option<bool>,
182
183
183 /// The current time at the start of the `status()` algorithm, as measured
184 /// The current time at the start of the `status()` algorithm, as measured
184 /// and possibly truncated by the filesystem.
185 /// and possibly truncated by the filesystem.
185 filesystem_time_at_status_start: Option<TruncatedTimestamp>,
186 filesystem_time_at_status_start: Option<TruncatedTimestamp>,
186 }
187 }
187
188
188 enum Outcome {
189 enum Outcome {
189 Modified,
190 Modified,
190 Added,
191 Added,
191 Removed,
192 Removed,
192 Deleted,
193 Deleted,
193 Clean,
194 Clean,
194 Ignored,
195 Ignored,
195 Unknown,
196 Unknown,
196 Unsure,
197 Unsure,
197 }
198 }
198
199
200 /// Lazy computation of whether a given path has a hgignored
201 /// ancestor.
202 struct HasIgnoredAncestor<'a> {
203 /// `path` and `parent` constitute the inputs to the computation,
204 /// `cache` stores the outcome.
205 path: &'a HgPath,
206 parent: Option<&'a HasIgnoredAncestor<'a>>,
207 cache: OnceCell<bool>,
208 }
209
210 impl<'a> HasIgnoredAncestor<'a> {
211 fn create(
212 parent: Option<&'a HasIgnoredAncestor<'a>>,
213 path: &'a HgPath,
214 ) -> HasIgnoredAncestor<'a> {
215 Self {
216 path,
217 parent,
218 cache: OnceCell::new(),
219 }
220 }
221
222 fn force<'b>(&self, ignore_fn: &IgnoreFnType<'b>) -> bool {
223 match self.parent {
224 None => false,
225 Some(parent) => {
226 *(parent.cache.get_or_init(|| {
227 parent.force(ignore_fn) || ignore_fn(&self.path)
228 }))
229 }
230 }
231 }
232 }
233
199 impl<'a, 'tree, 'on_disk> StatusCommon<'a, 'tree, 'on_disk> {
234 impl<'a, 'tree, 'on_disk> StatusCommon<'a, 'tree, 'on_disk> {
200 fn push_outcome(
235 fn push_outcome(
201 &self,
236 &self,
202 which: Outcome,
237 which: Outcome,
203 dirstate_node: &NodeRef<'tree, 'on_disk>,
238 dirstate_node: &NodeRef<'tree, 'on_disk>,
204 ) -> Result<(), DirstateV2ParseError> {
239 ) -> Result<(), DirstateV2ParseError> {
205 let path = dirstate_node
240 let path = dirstate_node
206 .full_path_borrowed(self.dmap.on_disk)?
241 .full_path_borrowed(self.dmap.on_disk)?
207 .detach_from_tree();
242 .detach_from_tree();
208 let copy_source = if self.options.list_copies {
243 let copy_source = if self.options.list_copies {
209 dirstate_node
244 dirstate_node
210 .copy_source_borrowed(self.dmap.on_disk)?
245 .copy_source_borrowed(self.dmap.on_disk)?
211 .map(|source| source.detach_from_tree())
246 .map(|source| source.detach_from_tree())
212 } else {
247 } else {
213 None
248 None
214 };
249 };
215 self.push_outcome_common(which, path, copy_source);
250 self.push_outcome_common(which, path, copy_source);
216 Ok(())
251 Ok(())
217 }
252 }
218
253
219 fn push_outcome_without_copy_source(
254 fn push_outcome_without_copy_source(
220 &self,
255 &self,
221 which: Outcome,
256 which: Outcome,
222 path: &BorrowedPath<'_, 'on_disk>,
257 path: &BorrowedPath<'_, 'on_disk>,
223 ) {
258 ) {
224 self.push_outcome_common(which, path.detach_from_tree(), None)
259 self.push_outcome_common(which, path.detach_from_tree(), None)
225 }
260 }
226
261
227 fn push_outcome_common(
262 fn push_outcome_common(
228 &self,
263 &self,
229 which: Outcome,
264 which: Outcome,
230 path: HgPathCow<'on_disk>,
265 path: HgPathCow<'on_disk>,
231 copy_source: Option<HgPathCow<'on_disk>>,
266 copy_source: Option<HgPathCow<'on_disk>>,
232 ) {
267 ) {
233 let mut outcome = self.outcome.lock().unwrap();
268 let mut outcome = self.outcome.lock().unwrap();
234 let vec = match which {
269 let vec = match which {
235 Outcome::Modified => &mut outcome.modified,
270 Outcome::Modified => &mut outcome.modified,
236 Outcome::Added => &mut outcome.added,
271 Outcome::Added => &mut outcome.added,
237 Outcome::Removed => &mut outcome.removed,
272 Outcome::Removed => &mut outcome.removed,
238 Outcome::Deleted => &mut outcome.deleted,
273 Outcome::Deleted => &mut outcome.deleted,
239 Outcome::Clean => &mut outcome.clean,
274 Outcome::Clean => &mut outcome.clean,
240 Outcome::Ignored => &mut outcome.ignored,
275 Outcome::Ignored => &mut outcome.ignored,
241 Outcome::Unknown => &mut outcome.unknown,
276 Outcome::Unknown => &mut outcome.unknown,
242 Outcome::Unsure => &mut outcome.unsure,
277 Outcome::Unsure => &mut outcome.unsure,
243 };
278 };
244 vec.push(StatusPath { path, copy_source });
279 vec.push(StatusPath { path, copy_source });
245 }
280 }
246
281
247 fn read_dir(
282 fn read_dir(
248 &self,
283 &self,
249 hg_path: &HgPath,
284 hg_path: &HgPath,
250 fs_path: &Path,
285 fs_path: &Path,
251 is_at_repo_root: bool,
286 is_at_repo_root: bool,
252 ) -> Result<Vec<DirEntry>, ()> {
287 ) -> Result<Vec<DirEntry>, ()> {
253 DirEntry::read_dir(fs_path, is_at_repo_root)
288 DirEntry::read_dir(fs_path, is_at_repo_root)
254 .map_err(|error| self.io_error(error, hg_path))
289 .map_err(|error| self.io_error(error, hg_path))
255 }
290 }
256
291
257 fn io_error(&self, error: std::io::Error, hg_path: &HgPath) {
292 fn io_error(&self, error: std::io::Error, hg_path: &HgPath) {
258 let errno = error.raw_os_error().expect("expected real OS error");
293 let errno = error.raw_os_error().expect("expected real OS error");
259 self.outcome
294 self.outcome
260 .lock()
295 .lock()
261 .unwrap()
296 .unwrap()
262 .bad
297 .bad
263 .push((hg_path.to_owned().into(), BadMatch::OsError(errno)))
298 .push((hg_path.to_owned().into(), BadMatch::OsError(errno)))
264 }
299 }
265
300
266 fn check_for_outdated_directory_cache(
301 fn check_for_outdated_directory_cache(
267 &self,
302 &self,
268 dirstate_node: &NodeRef<'tree, 'on_disk>,
303 dirstate_node: &NodeRef<'tree, 'on_disk>,
269 ) -> Result<(), DirstateV2ParseError> {
304 ) -> Result<(), DirstateV2ParseError> {
270 if self.ignore_patterns_have_changed == Some(true)
305 if self.ignore_patterns_have_changed == Some(true)
271 && dirstate_node.cached_directory_mtime()?.is_some()
306 && dirstate_node.cached_directory_mtime()?.is_some()
272 {
307 {
273 self.outated_cached_directories.lock().unwrap().push(
308 self.outated_cached_directories.lock().unwrap().push(
274 dirstate_node
309 dirstate_node
275 .full_path_borrowed(self.dmap.on_disk)?
310 .full_path_borrowed(self.dmap.on_disk)?
276 .detach_from_tree(),
311 .detach_from_tree(),
277 )
312 )
278 }
313 }
279 Ok(())
314 Ok(())
280 }
315 }
281
316
282 /// If this returns true, we can get accurate results by only using
317 /// If this returns true, we can get accurate results by only using
283 /// `symlink_metadata` for child nodes that exist in the dirstate and don’t
318 /// `symlink_metadata` for child nodes that exist in the dirstate and don’t
284 /// need to call `read_dir`.
319 /// need to call `read_dir`.
285 fn can_skip_fs_readdir(
320 fn can_skip_fs_readdir(
286 &self,
321 &self,
287 directory_metadata: Option<&std::fs::Metadata>,
322 directory_metadata: Option<&std::fs::Metadata>,
288 cached_directory_mtime: Option<TruncatedTimestamp>,
323 cached_directory_mtime: Option<TruncatedTimestamp>,
289 ) -> bool {
324 ) -> bool {
290 if !self.options.list_unknown && !self.options.list_ignored {
325 if !self.options.list_unknown && !self.options.list_ignored {
291 // All states that we care about listing have corresponding
326 // All states that we care about listing have corresponding
292 // dirstate entries.
327 // dirstate entries.
293 // This happens for example with `hg status -mard`.
328 // This happens for example with `hg status -mard`.
294 return true;
329 return true;
295 }
330 }
296 if !self.options.list_ignored
331 if !self.options.list_ignored
297 && self.ignore_patterns_have_changed == Some(false)
332 && self.ignore_patterns_have_changed == Some(false)
298 {
333 {
299 if let Some(cached_mtime) = cached_directory_mtime {
334 if let Some(cached_mtime) = cached_directory_mtime {
300 // The dirstate contains a cached mtime for this directory, set
335 // The dirstate contains a cached mtime for this directory, set
301 // by a previous run of the `status` algorithm which found this
336 // by a previous run of the `status` algorithm which found this
302 // directory eligible for `read_dir` caching.
337 // directory eligible for `read_dir` caching.
303 if let Some(meta) = directory_metadata {
338 if let Some(meta) = directory_metadata {
304 if cached_mtime
339 if cached_mtime
305 .likely_equal_to_mtime_of(meta)
340 .likely_equal_to_mtime_of(meta)
306 .unwrap_or(false)
341 .unwrap_or(false)
307 {
342 {
308 // The mtime of that directory has not changed
343 // The mtime of that directory has not changed
309 // since then, which means that the results of
344 // since then, which means that the results of
310 // `read_dir` should also be unchanged.
345 // `read_dir` should also be unchanged.
311 return true;
346 return true;
312 }
347 }
313 }
348 }
314 }
349 }
315 }
350 }
316 false
351 false
317 }
352 }
318
353
319 /// Returns whether all child entries of the filesystem directory have a
354 /// Returns whether all child entries of the filesystem directory have a
320 /// corresponding dirstate node or are ignored.
355 /// corresponding dirstate node or are ignored.
321 fn traverse_fs_directory_and_dirstate(
356 fn traverse_fs_directory_and_dirstate<'ancestor>(
322 &self,
357 &self,
323 has_ignored_ancestor: bool,
358 has_ignored_ancestor: &'ancestor HasIgnoredAncestor<'ancestor>,
324 dirstate_nodes: ChildNodesRef<'tree, 'on_disk>,
359 dirstate_nodes: ChildNodesRef<'tree, 'on_disk>,
325 directory_hg_path: &BorrowedPath<'tree, 'on_disk>,
360 directory_hg_path: &BorrowedPath<'tree, 'on_disk>,
326 directory_fs_path: &Path,
361 directory_fs_path: &Path,
327 directory_metadata: Option<&std::fs::Metadata>,
362 directory_metadata: Option<&std::fs::Metadata>,
328 cached_directory_mtime: Option<TruncatedTimestamp>,
363 cached_directory_mtime: Option<TruncatedTimestamp>,
329 is_at_repo_root: bool,
364 is_at_repo_root: bool,
330 ) -> Result<bool, DirstateV2ParseError> {
365 ) -> Result<bool, DirstateV2ParseError> {
331 if self.can_skip_fs_readdir(directory_metadata, cached_directory_mtime)
366 if self.can_skip_fs_readdir(directory_metadata, cached_directory_mtime)
332 {
367 {
333 dirstate_nodes
368 dirstate_nodes
334 .par_iter()
369 .par_iter()
335 .map(|dirstate_node| {
370 .map(|dirstate_node| {
336 let fs_path = directory_fs_path.join(get_path_from_bytes(
371 let fs_path = directory_fs_path.join(get_path_from_bytes(
337 dirstate_node.base_name(self.dmap.on_disk)?.as_bytes(),
372 dirstate_node.base_name(self.dmap.on_disk)?.as_bytes(),
338 ));
373 ));
339 match std::fs::symlink_metadata(&fs_path) {
374 match std::fs::symlink_metadata(&fs_path) {
340 Ok(fs_metadata) => self.traverse_fs_and_dirstate(
375 Ok(fs_metadata) => self.traverse_fs_and_dirstate(
341 &fs_path,
376 &fs_path,
342 &fs_metadata,
377 &fs_metadata,
343 dirstate_node,
378 dirstate_node,
344 has_ignored_ancestor,
379 has_ignored_ancestor,
345 ),
380 ),
346 Err(e) if e.kind() == std::io::ErrorKind::NotFound => {
381 Err(e) if e.kind() == std::io::ErrorKind::NotFound => {
347 self.traverse_dirstate_only(dirstate_node)
382 self.traverse_dirstate_only(dirstate_node)
348 }
383 }
349 Err(error) => {
384 Err(error) => {
350 let hg_path =
385 let hg_path =
351 dirstate_node.full_path(self.dmap.on_disk)?;
386 dirstate_node.full_path(self.dmap.on_disk)?;
352 Ok(self.io_error(error, hg_path))
387 Ok(self.io_error(error, hg_path))
353 }
388 }
354 }
389 }
355 })
390 })
356 .collect::<Result<_, _>>()?;
391 .collect::<Result<_, _>>()?;
357
392
358 // We don’t know, so conservatively say this isn’t the case
393 // We don’t know, so conservatively say this isn’t the case
359 let children_all_have_dirstate_node_or_are_ignored = false;
394 let children_all_have_dirstate_node_or_are_ignored = false;
360
395
361 return Ok(children_all_have_dirstate_node_or_are_ignored);
396 return Ok(children_all_have_dirstate_node_or_are_ignored);
362 }
397 }
363
398
364 let mut fs_entries = if let Ok(entries) = self.read_dir(
399 let mut fs_entries = if let Ok(entries) = self.read_dir(
365 directory_hg_path,
400 directory_hg_path,
366 directory_fs_path,
401 directory_fs_path,
367 is_at_repo_root,
402 is_at_repo_root,
368 ) {
403 ) {
369 entries
404 entries
370 } else {
405 } else {
371 // Treat an unreadable directory (typically because of insufficient
406 // Treat an unreadable directory (typically because of insufficient
372 // permissions) like an empty directory. `self.read_dir` has
407 // permissions) like an empty directory. `self.read_dir` has
373 // already called `self.io_error` so a warning will be emitted.
408 // already called `self.io_error` so a warning will be emitted.
374 Vec::new()
409 Vec::new()
375 };
410 };
376
411
377 // `merge_join_by` requires both its input iterators to be sorted:
412 // `merge_join_by` requires both its input iterators to be sorted:
378
413
379 let dirstate_nodes = dirstate_nodes.sorted();
414 let dirstate_nodes = dirstate_nodes.sorted();
380 // `sort_unstable_by_key` doesn’t allow keys borrowing from the value:
415 // `sort_unstable_by_key` doesn’t allow keys borrowing from the value:
381 // https://github.com/rust-lang/rust/issues/34162
416 // https://github.com/rust-lang/rust/issues/34162
382 fs_entries.sort_unstable_by(|e1, e2| e1.base_name.cmp(&e2.base_name));
417 fs_entries.sort_unstable_by(|e1, e2| e1.base_name.cmp(&e2.base_name));
383
418
384 // Propagate here any error that would happen inside the comparison
419 // Propagate here any error that would happen inside the comparison
385 // callback below
420 // callback below
386 for dirstate_node in &dirstate_nodes {
421 for dirstate_node in &dirstate_nodes {
387 dirstate_node.base_name(self.dmap.on_disk)?;
422 dirstate_node.base_name(self.dmap.on_disk)?;
388 }
423 }
389 itertools::merge_join_by(
424 itertools::merge_join_by(
390 dirstate_nodes,
425 dirstate_nodes,
391 &fs_entries,
426 &fs_entries,
392 |dirstate_node, fs_entry| {
427 |dirstate_node, fs_entry| {
393 // This `unwrap` never panics because we already propagated
428 // This `unwrap` never panics because we already propagated
394 // those errors above
429 // those errors above
395 dirstate_node
430 dirstate_node
396 .base_name(self.dmap.on_disk)
431 .base_name(self.dmap.on_disk)
397 .unwrap()
432 .unwrap()
398 .cmp(&fs_entry.base_name)
433 .cmp(&fs_entry.base_name)
399 },
434 },
400 )
435 )
401 .par_bridge()
436 .par_bridge()
402 .map(|pair| {
437 .map(|pair| {
403 use itertools::EitherOrBoth::*;
438 use itertools::EitherOrBoth::*;
404 let has_dirstate_node_or_is_ignored;
439 let has_dirstate_node_or_is_ignored;
405 match pair {
440 match pair {
406 Both(dirstate_node, fs_entry) => {
441 Both(dirstate_node, fs_entry) => {
407 self.traverse_fs_and_dirstate(
442 self.traverse_fs_and_dirstate(
408 &fs_entry.full_path,
443 &fs_entry.full_path,
409 &fs_entry.metadata,
444 &fs_entry.metadata,
410 dirstate_node,
445 dirstate_node,
411 has_ignored_ancestor,
446 has_ignored_ancestor,
412 )?;
447 )?;
413 has_dirstate_node_or_is_ignored = true
448 has_dirstate_node_or_is_ignored = true
414 }
449 }
415 Left(dirstate_node) => {
450 Left(dirstate_node) => {
416 self.traverse_dirstate_only(dirstate_node)?;
451 self.traverse_dirstate_only(dirstate_node)?;
417 has_dirstate_node_or_is_ignored = true;
452 has_dirstate_node_or_is_ignored = true;
418 }
453 }
419 Right(fs_entry) => {
454 Right(fs_entry) => {
420 has_dirstate_node_or_is_ignored = self.traverse_fs_only(
455 has_dirstate_node_or_is_ignored = self.traverse_fs_only(
421 has_ignored_ancestor,
456 has_ignored_ancestor.force(&self.ignore_fn),
422 directory_hg_path,
457 directory_hg_path,
423 fs_entry,
458 fs_entry,
424 )
459 )
425 }
460 }
426 }
461 }
427 Ok(has_dirstate_node_or_is_ignored)
462 Ok(has_dirstate_node_or_is_ignored)
428 })
463 })
429 .try_reduce(|| true, |a, b| Ok(a && b))
464 .try_reduce(|| true, |a, b| Ok(a && b))
430 }
465 }
431
466
432 fn traverse_fs_and_dirstate(
467 fn traverse_fs_and_dirstate<'ancestor>(
433 &self,
468 &self,
434 fs_path: &Path,
469 fs_path: &Path,
435 fs_metadata: &std::fs::Metadata,
470 fs_metadata: &std::fs::Metadata,
436 dirstate_node: NodeRef<'tree, 'on_disk>,
471 dirstate_node: NodeRef<'tree, 'on_disk>,
437 has_ignored_ancestor: bool,
472 has_ignored_ancestor: &'ancestor HasIgnoredAncestor<'ancestor>,
438 ) -> Result<(), DirstateV2ParseError> {
473 ) -> Result<(), DirstateV2ParseError> {
439 self.check_for_outdated_directory_cache(&dirstate_node)?;
474 self.check_for_outdated_directory_cache(&dirstate_node)?;
440 let hg_path = &dirstate_node.full_path_borrowed(self.dmap.on_disk)?;
475 let hg_path = &dirstate_node.full_path_borrowed(self.dmap.on_disk)?;
441 let file_type = fs_metadata.file_type();
476 let file_type = fs_metadata.file_type();
442 let file_or_symlink = file_type.is_file() || file_type.is_symlink();
477 let file_or_symlink = file_type.is_file() || file_type.is_symlink();
443 if !file_or_symlink {
478 if !file_or_symlink {
444 // If we previously had a file here, it was removed (with
479 // If we previously had a file here, it was removed (with
445 // `hg rm` or similar) or deleted before it could be
480 // `hg rm` or similar) or deleted before it could be
446 // replaced by a directory or something else.
481 // replaced by a directory or something else.
447 self.mark_removed_or_deleted_if_file(&dirstate_node)?;
482 self.mark_removed_or_deleted_if_file(&dirstate_node)?;
448 }
483 }
449 if file_type.is_dir() {
484 if file_type.is_dir() {
450 if self.options.collect_traversed_dirs {
485 if self.options.collect_traversed_dirs {
451 self.outcome
486 self.outcome
452 .lock()
487 .lock()
453 .unwrap()
488 .unwrap()
454 .traversed
489 .traversed
455 .push(hg_path.detach_from_tree())
490 .push(hg_path.detach_from_tree())
456 }
491 }
457 let is_ignored = has_ignored_ancestor || (self.ignore_fn)(hg_path);
492 let is_ignored = HasIgnoredAncestor::create(
493 Some(&has_ignored_ancestor),
494 hg_path,
495 );
458 let is_at_repo_root = false;
496 let is_at_repo_root = false;
459 let children_all_have_dirstate_node_or_are_ignored = self
497 let children_all_have_dirstate_node_or_are_ignored = self
460 .traverse_fs_directory_and_dirstate(
498 .traverse_fs_directory_and_dirstate(
461 is_ignored,
499 &is_ignored,
462 dirstate_node.children(self.dmap.on_disk)?,
500 dirstate_node.children(self.dmap.on_disk)?,
463 hg_path,
501 hg_path,
464 fs_path,
502 fs_path,
465 Some(fs_metadata),
503 Some(fs_metadata),
466 dirstate_node.cached_directory_mtime()?,
504 dirstate_node.cached_directory_mtime()?,
467 is_at_repo_root,
505 is_at_repo_root,
468 )?;
506 )?;
469 self.maybe_save_directory_mtime(
507 self.maybe_save_directory_mtime(
470 children_all_have_dirstate_node_or_are_ignored,
508 children_all_have_dirstate_node_or_are_ignored,
471 fs_metadata,
509 fs_metadata,
472 dirstate_node,
510 dirstate_node,
473 )?
511 )?
474 } else {
512 } else {
475 if file_or_symlink && self.matcher.matches(hg_path) {
513 if file_or_symlink && self.matcher.matches(&hg_path) {
476 if let Some(entry) = dirstate_node.entry()? {
514 if let Some(entry) = dirstate_node.entry()? {
477 if !entry.any_tracked() {
515 if !entry.any_tracked() {
478 // Forward-compat if we start tracking unknown/ignored
516 // Forward-compat if we start tracking unknown/ignored
479 // files for caching reasons
517 // files for caching reasons
480 self.mark_unknown_or_ignored(
518 self.mark_unknown_or_ignored(
481 has_ignored_ancestor,
519 has_ignored_ancestor.force(&self.ignore_fn),
482 hg_path,
520 &hg_path,
483 );
521 );
484 }
522 }
485 if entry.added() {
523 if entry.added() {
486 self.push_outcome(Outcome::Added, &dirstate_node)?;
524 self.push_outcome(Outcome::Added, &dirstate_node)?;
487 } else if entry.removed() {
525 } else if entry.removed() {
488 self.push_outcome(Outcome::Removed, &dirstate_node)?;
526 self.push_outcome(Outcome::Removed, &dirstate_node)?;
489 } else if entry.modified() {
527 } else if entry.modified() {
490 self.push_outcome(Outcome::Modified, &dirstate_node)?;
528 self.push_outcome(Outcome::Modified, &dirstate_node)?;
491 } else {
529 } else {
492 self.handle_normal_file(&dirstate_node, fs_metadata)?;
530 self.handle_normal_file(&dirstate_node, fs_metadata)?;
493 }
531 }
494 } else {
532 } else {
495 // `node.entry.is_none()` indicates a "directory"
533 // `node.entry.is_none()` indicates a "directory"
496 // node, but the filesystem has a file
534 // node, but the filesystem has a file
497 self.mark_unknown_or_ignored(
535 self.mark_unknown_or_ignored(
498 has_ignored_ancestor,
536 has_ignored_ancestor.force(&self.ignore_fn),
499 hg_path,
537 hg_path,
500 );
538 );
501 }
539 }
502 }
540 }
503
541
504 for child_node in dirstate_node.children(self.dmap.on_disk)?.iter()
542 for child_node in dirstate_node.children(self.dmap.on_disk)?.iter()
505 {
543 {
506 self.traverse_dirstate_only(child_node)?
544 self.traverse_dirstate_only(child_node)?
507 }
545 }
508 }
546 }
509 Ok(())
547 Ok(())
510 }
548 }
511
549
512 fn maybe_save_directory_mtime(
550 fn maybe_save_directory_mtime(
513 &self,
551 &self,
514 children_all_have_dirstate_node_or_are_ignored: bool,
552 children_all_have_dirstate_node_or_are_ignored: bool,
515 directory_metadata: &std::fs::Metadata,
553 directory_metadata: &std::fs::Metadata,
516 dirstate_node: NodeRef<'tree, 'on_disk>,
554 dirstate_node: NodeRef<'tree, 'on_disk>,
517 ) -> Result<(), DirstateV2ParseError> {
555 ) -> Result<(), DirstateV2ParseError> {
518 if !children_all_have_dirstate_node_or_are_ignored {
556 if !children_all_have_dirstate_node_or_are_ignored {
519 return Ok(());
557 return Ok(());
520 }
558 }
521 // All filesystem directory entries from `read_dir` have a
559 // All filesystem directory entries from `read_dir` have a
522 // corresponding node in the dirstate, so we can reconstitute the
560 // corresponding node in the dirstate, so we can reconstitute the
523 // names of those entries without calling `read_dir` again.
561 // names of those entries without calling `read_dir` again.
524
562
525 // TODO: use let-else here and below when available:
563 // TODO: use let-else here and below when available:
526 // https://github.com/rust-lang/rust/issues/87335
564 // https://github.com/rust-lang/rust/issues/87335
527 let status_start = if let Some(status_start) =
565 let status_start = if let Some(status_start) =
528 &self.filesystem_time_at_status_start
566 &self.filesystem_time_at_status_start
529 {
567 {
530 status_start
568 status_start
531 } else {
569 } else {
532 return Ok(());
570 return Ok(());
533 };
571 };
534
572
535 // Although the Rust standard library’s `SystemTime` type
573 // Although the Rust standard library’s `SystemTime` type
536 // has nanosecond precision, the times reported for a
574 // has nanosecond precision, the times reported for a
537 // directory’s (or file’s) modified time may have lower
575 // directory’s (or file’s) modified time may have lower
538 // resolution based on the filesystem (for example ext3
576 // resolution based on the filesystem (for example ext3
539 // only stores integer seconds), kernel (see
577 // only stores integer seconds), kernel (see
540 // https://stackoverflow.com/a/14393315/1162888), etc.
578 // https://stackoverflow.com/a/14393315/1162888), etc.
541 let directory_mtime = if let Ok(option) =
579 let directory_mtime = if let Ok(option) =
542 TruncatedTimestamp::for_reliable_mtime_of(
580 TruncatedTimestamp::for_reliable_mtime_of(
543 directory_metadata,
581 directory_metadata,
544 status_start,
582 status_start,
545 ) {
583 ) {
546 if let Some(directory_mtime) = option {
584 if let Some(directory_mtime) = option {
547 directory_mtime
585 directory_mtime
548 } else {
586 } else {
549 // The directory was modified too recently,
587 // The directory was modified too recently,
550 // don’t cache its `read_dir` results.
588 // don’t cache its `read_dir` results.
551 //
589 //
552 // 1. A change to this directory (direct child was
590 // 1. A change to this directory (direct child was
553 // added or removed) cause its mtime to be set
591 // added or removed) cause its mtime to be set
554 // (possibly truncated) to `directory_mtime`
592 // (possibly truncated) to `directory_mtime`
555 // 2. This `status` algorithm calls `read_dir`
593 // 2. This `status` algorithm calls `read_dir`
556 // 3. An other change is made to the same directory is
594 // 3. An other change is made to the same directory is
557 // made so that calling `read_dir` agin would give
595 // made so that calling `read_dir` agin would give
558 // different results, but soon enough after 1. that
596 // different results, but soon enough after 1. that
559 // the mtime stays the same
597 // the mtime stays the same
560 //
598 //
561 // On a system where the time resolution poor, this
599 // On a system where the time resolution poor, this
562 // scenario is not unlikely if all three steps are caused
600 // scenario is not unlikely if all three steps are caused
563 // by the same script.
601 // by the same script.
564 return Ok(());
602 return Ok(());
565 }
603 }
566 } else {
604 } else {
567 // OS/libc does not support mtime?
605 // OS/libc does not support mtime?
568 return Ok(());
606 return Ok(());
569 };
607 };
570 // We’ve observed (through `status_start`) that time has
608 // We’ve observed (through `status_start`) that time has
571 // “progressed” since `directory_mtime`, so any further
609 // “progressed” since `directory_mtime`, so any further
572 // change to this directory is extremely likely to cause a
610 // change to this directory is extremely likely to cause a
573 // different mtime.
611 // different mtime.
574 //
612 //
575 // Having the same mtime again is not entirely impossible
613 // Having the same mtime again is not entirely impossible
576 // since the system clock is not monotonous. It could jump
614 // since the system clock is not monotonous. It could jump
577 // backward to some point before `directory_mtime`, then a
615 // backward to some point before `directory_mtime`, then a
578 // directory change could potentially happen during exactly
616 // directory change could potentially happen during exactly
579 // the wrong tick.
617 // the wrong tick.
580 //
618 //
581 // We deem this scenario (unlike the previous one) to be
619 // We deem this scenario (unlike the previous one) to be
582 // unlikely enough in practice.
620 // unlikely enough in practice.
583
621
584 let is_up_to_date =
622 let is_up_to_date =
585 if let Some(cached) = dirstate_node.cached_directory_mtime()? {
623 if let Some(cached) = dirstate_node.cached_directory_mtime()? {
586 cached.likely_equal(directory_mtime)
624 cached.likely_equal(directory_mtime)
587 } else {
625 } else {
588 false
626 false
589 };
627 };
590 if !is_up_to_date {
628 if !is_up_to_date {
591 let hg_path = dirstate_node
629 let hg_path = dirstate_node
592 .full_path_borrowed(self.dmap.on_disk)?
630 .full_path_borrowed(self.dmap.on_disk)?
593 .detach_from_tree();
631 .detach_from_tree();
594 self.new_cachable_directories
632 self.new_cachable_directories
595 .lock()
633 .lock()
596 .unwrap()
634 .unwrap()
597 .push((hg_path, directory_mtime))
635 .push((hg_path, directory_mtime))
598 }
636 }
599 Ok(())
637 Ok(())
600 }
638 }
601
639
602 /// A file that is clean in the dirstate was found in the filesystem
640 /// A file that is clean in the dirstate was found in the filesystem
603 fn handle_normal_file(
641 fn handle_normal_file(
604 &self,
642 &self,
605 dirstate_node: &NodeRef<'tree, 'on_disk>,
643 dirstate_node: &NodeRef<'tree, 'on_disk>,
606 fs_metadata: &std::fs::Metadata,
644 fs_metadata: &std::fs::Metadata,
607 ) -> Result<(), DirstateV2ParseError> {
645 ) -> Result<(), DirstateV2ParseError> {
608 // Keep the low 31 bits
646 // Keep the low 31 bits
609 fn truncate_u64(value: u64) -> i32 {
647 fn truncate_u64(value: u64) -> i32 {
610 (value & 0x7FFF_FFFF) as i32
648 (value & 0x7FFF_FFFF) as i32
611 }
649 }
612
650
613 let entry = dirstate_node
651 let entry = dirstate_node
614 .entry()?
652 .entry()?
615 .expect("handle_normal_file called with entry-less node");
653 .expect("handle_normal_file called with entry-less node");
616 let mode_changed =
654 let mode_changed =
617 || self.options.check_exec && entry.mode_changed(fs_metadata);
655 || self.options.check_exec && entry.mode_changed(fs_metadata);
618 let size = entry.size();
656 let size = entry.size();
619 let size_changed = size != truncate_u64(fs_metadata.len());
657 let size_changed = size != truncate_u64(fs_metadata.len());
620 if size >= 0 && size_changed && fs_metadata.file_type().is_symlink() {
658 if size >= 0 && size_changed && fs_metadata.file_type().is_symlink() {
621 // issue6456: Size returned may be longer due to encryption
659 // issue6456: Size returned may be longer due to encryption
622 // on EXT-4 fscrypt. TODO maybe only do it on EXT4?
660 // on EXT-4 fscrypt. TODO maybe only do it on EXT4?
623 self.push_outcome(Outcome::Unsure, dirstate_node)?
661 self.push_outcome(Outcome::Unsure, dirstate_node)?
624 } else if dirstate_node.has_copy_source()
662 } else if dirstate_node.has_copy_source()
625 || entry.is_from_other_parent()
663 || entry.is_from_other_parent()
626 || (size >= 0 && (size_changed || mode_changed()))
664 || (size >= 0 && (size_changed || mode_changed()))
627 {
665 {
628 self.push_outcome(Outcome::Modified, dirstate_node)?
666 self.push_outcome(Outcome::Modified, dirstate_node)?
629 } else {
667 } else {
630 let mtime_looks_clean;
668 let mtime_looks_clean;
631 if let Some(dirstate_mtime) = entry.truncated_mtime() {
669 if let Some(dirstate_mtime) = entry.truncated_mtime() {
632 let fs_mtime = TruncatedTimestamp::for_mtime_of(fs_metadata)
670 let fs_mtime = TruncatedTimestamp::for_mtime_of(fs_metadata)
633 .expect("OS/libc does not support mtime?");
671 .expect("OS/libc does not support mtime?");
634 // There might be a change in the future if for example the
672 // There might be a change in the future if for example the
635 // internal clock become off while process run, but this is a
673 // internal clock become off while process run, but this is a
636 // case where the issues the user would face
674 // case where the issues the user would face
637 // would be a lot worse and there is nothing we
675 // would be a lot worse and there is nothing we
638 // can really do.
676 // can really do.
639 mtime_looks_clean = fs_mtime.likely_equal(dirstate_mtime)
677 mtime_looks_clean = fs_mtime.likely_equal(dirstate_mtime)
640 } else {
678 } else {
641 // No mtime in the dirstate entry
679 // No mtime in the dirstate entry
642 mtime_looks_clean = false
680 mtime_looks_clean = false
643 };
681 };
644 if !mtime_looks_clean {
682 if !mtime_looks_clean {
645 self.push_outcome(Outcome::Unsure, dirstate_node)?
683 self.push_outcome(Outcome::Unsure, dirstate_node)?
646 } else if self.options.list_clean {
684 } else if self.options.list_clean {
647 self.push_outcome(Outcome::Clean, dirstate_node)?
685 self.push_outcome(Outcome::Clean, dirstate_node)?
648 }
686 }
649 }
687 }
650 Ok(())
688 Ok(())
651 }
689 }
652
690
653 /// A node in the dirstate tree has no corresponding filesystem entry
691 /// A node in the dirstate tree has no corresponding filesystem entry
654 fn traverse_dirstate_only(
692 fn traverse_dirstate_only(
655 &self,
693 &self,
656 dirstate_node: NodeRef<'tree, 'on_disk>,
694 dirstate_node: NodeRef<'tree, 'on_disk>,
657 ) -> Result<(), DirstateV2ParseError> {
695 ) -> Result<(), DirstateV2ParseError> {
658 self.check_for_outdated_directory_cache(&dirstate_node)?;
696 self.check_for_outdated_directory_cache(&dirstate_node)?;
659 self.mark_removed_or_deleted_if_file(&dirstate_node)?;
697 self.mark_removed_or_deleted_if_file(&dirstate_node)?;
660 dirstate_node
698 dirstate_node
661 .children(self.dmap.on_disk)?
699 .children(self.dmap.on_disk)?
662 .par_iter()
700 .par_iter()
663 .map(|child_node| self.traverse_dirstate_only(child_node))
701 .map(|child_node| self.traverse_dirstate_only(child_node))
664 .collect()
702 .collect()
665 }
703 }
666
704
667 /// A node in the dirstate tree has no corresponding *file* on the
705 /// A node in the dirstate tree has no corresponding *file* on the
668 /// filesystem
706 /// filesystem
669 ///
707 ///
670 /// Does nothing on a "directory" node
708 /// Does nothing on a "directory" node
671 fn mark_removed_or_deleted_if_file(
709 fn mark_removed_or_deleted_if_file(
672 &self,
710 &self,
673 dirstate_node: &NodeRef<'tree, 'on_disk>,
711 dirstate_node: &NodeRef<'tree, 'on_disk>,
674 ) -> Result<(), DirstateV2ParseError> {
712 ) -> Result<(), DirstateV2ParseError> {
675 if let Some(entry) = dirstate_node.entry()? {
713 if let Some(entry) = dirstate_node.entry()? {
676 if !entry.any_tracked() {
714 if !entry.any_tracked() {
677 // Future-compat for when we start storing ignored and unknown
715 // Future-compat for when we start storing ignored and unknown
678 // files for caching reasons
716 // files for caching reasons
679 return Ok(());
717 return Ok(());
680 }
718 }
681 let path = dirstate_node.full_path(self.dmap.on_disk)?;
719 let path = dirstate_node.full_path(self.dmap.on_disk)?;
682 if self.matcher.matches(path) {
720 if self.matcher.matches(path) {
683 if entry.removed() {
721 if entry.removed() {
684 self.push_outcome(Outcome::Removed, dirstate_node)?
722 self.push_outcome(Outcome::Removed, dirstate_node)?
685 } else {
723 } else {
686 self.push_outcome(Outcome::Deleted, &dirstate_node)?
724 self.push_outcome(Outcome::Deleted, &dirstate_node)?
687 }
725 }
688 }
726 }
689 }
727 }
690 Ok(())
728 Ok(())
691 }
729 }
692
730
693 /// Something in the filesystem has no corresponding dirstate node
731 /// Something in the filesystem has no corresponding dirstate node
694 ///
732 ///
695 /// Returns whether that path is ignored
733 /// Returns whether that path is ignored
696 fn traverse_fs_only(
734 fn traverse_fs_only(
697 &self,
735 &self,
698 has_ignored_ancestor: bool,
736 has_ignored_ancestor: bool,
699 directory_hg_path: &HgPath,
737 directory_hg_path: &HgPath,
700 fs_entry: &DirEntry,
738 fs_entry: &DirEntry,
701 ) -> bool {
739 ) -> bool {
702 let hg_path = directory_hg_path.join(&fs_entry.base_name);
740 let hg_path = directory_hg_path.join(&fs_entry.base_name);
703 let file_type = fs_entry.metadata.file_type();
741 let file_type = fs_entry.metadata.file_type();
704 let file_or_symlink = file_type.is_file() || file_type.is_symlink();
742 let file_or_symlink = file_type.is_file() || file_type.is_symlink();
705 if file_type.is_dir() {
743 if file_type.is_dir() {
706 let is_ignored =
744 let is_ignored =
707 has_ignored_ancestor || (self.ignore_fn)(&hg_path);
745 has_ignored_ancestor || (self.ignore_fn)(&hg_path);
708 let traverse_children = if is_ignored {
746 let traverse_children = if is_ignored {
709 // Descendants of an ignored directory are all ignored
747 // Descendants of an ignored directory are all ignored
710 self.options.list_ignored
748 self.options.list_ignored
711 } else {
749 } else {
712 // Descendants of an unknown directory may be either unknown or
750 // Descendants of an unknown directory may be either unknown or
713 // ignored
751 // ignored
714 self.options.list_unknown || self.options.list_ignored
752 self.options.list_unknown || self.options.list_ignored
715 };
753 };
716 if traverse_children {
754 if traverse_children {
717 let is_at_repo_root = false;
755 let is_at_repo_root = false;
718 if let Ok(children_fs_entries) = self.read_dir(
756 if let Ok(children_fs_entries) = self.read_dir(
719 &hg_path,
757 &hg_path,
720 &fs_entry.full_path,
758 &fs_entry.full_path,
721 is_at_repo_root,
759 is_at_repo_root,
722 ) {
760 ) {
723 children_fs_entries.par_iter().for_each(|child_fs_entry| {
761 children_fs_entries.par_iter().for_each(|child_fs_entry| {
724 self.traverse_fs_only(
762 self.traverse_fs_only(
725 is_ignored,
763 is_ignored,
726 &hg_path,
764 &hg_path,
727 child_fs_entry,
765 child_fs_entry,
728 );
766 );
729 })
767 })
730 }
768 }
731 if self.options.collect_traversed_dirs {
769 if self.options.collect_traversed_dirs {
732 self.outcome.lock().unwrap().traversed.push(hg_path.into())
770 self.outcome.lock().unwrap().traversed.push(hg_path.into())
733 }
771 }
734 }
772 }
735 is_ignored
773 is_ignored
736 } else {
774 } else {
737 if file_or_symlink {
775 if file_or_symlink {
738 if self.matcher.matches(&hg_path) {
776 if self.matcher.matches(&hg_path) {
739 self.mark_unknown_or_ignored(
777 self.mark_unknown_or_ignored(
740 has_ignored_ancestor,
778 has_ignored_ancestor,
741 &BorrowedPath::InMemory(&hg_path),
779 &BorrowedPath::InMemory(&hg_path),
742 )
780 )
743 } else {
781 } else {
744 // We haven’t computed whether this path is ignored. It
782 // We haven’t computed whether this path is ignored. It
745 // might not be, and a future run of status might have a
783 // might not be, and a future run of status might have a
746 // different matcher that matches it. So treat it as not
784 // different matcher that matches it. So treat it as not
747 // ignored. That is, inhibit readdir caching of the parent
785 // ignored. That is, inhibit readdir caching of the parent
748 // directory.
786 // directory.
749 false
787 false
750 }
788 }
751 } else {
789 } else {
752 // This is neither a directory, a plain file, or a symlink.
790 // This is neither a directory, a plain file, or a symlink.
753 // Treat it like an ignored file.
791 // Treat it like an ignored file.
754 true
792 true
755 }
793 }
756 }
794 }
757 }
795 }
758
796
759 /// Returns whether that path is ignored
797 /// Returns whether that path is ignored
760 fn mark_unknown_or_ignored(
798 fn mark_unknown_or_ignored(
761 &self,
799 &self,
762 has_ignored_ancestor: bool,
800 has_ignored_ancestor: bool,
763 hg_path: &BorrowedPath<'_, 'on_disk>,
801 hg_path: &BorrowedPath<'_, 'on_disk>,
764 ) -> bool {
802 ) -> bool {
765 let is_ignored = has_ignored_ancestor || (self.ignore_fn)(&hg_path);
803 let is_ignored = has_ignored_ancestor || (self.ignore_fn)(&hg_path);
766 if is_ignored {
804 if is_ignored {
767 if self.options.list_ignored {
805 if self.options.list_ignored {
768 self.push_outcome_without_copy_source(
806 self.push_outcome_without_copy_source(
769 Outcome::Ignored,
807 Outcome::Ignored,
770 hg_path,
808 hg_path,
771 )
809 )
772 }
810 }
773 } else {
811 } else {
774 if self.options.list_unknown {
812 if self.options.list_unknown {
775 self.push_outcome_without_copy_source(
813 self.push_outcome_without_copy_source(
776 Outcome::Unknown,
814 Outcome::Unknown,
777 hg_path,
815 hg_path,
778 )
816 )
779 }
817 }
780 }
818 }
781 is_ignored
819 is_ignored
782 }
820 }
783 }
821 }
784
822
785 struct DirEntry {
823 struct DirEntry {
786 base_name: HgPathBuf,
824 base_name: HgPathBuf,
787 full_path: PathBuf,
825 full_path: PathBuf,
788 metadata: std::fs::Metadata,
826 metadata: std::fs::Metadata,
789 }
827 }
790
828
791 impl DirEntry {
829 impl DirEntry {
792 /// Returns **unsorted** entries in the given directory, with name and
830 /// Returns **unsorted** entries in the given directory, with name and
793 /// metadata.
831 /// metadata.
794 ///
832 ///
795 /// If a `.hg` sub-directory is encountered:
833 /// If a `.hg` sub-directory is encountered:
796 ///
834 ///
797 /// * At the repository root, ignore that sub-directory
835 /// * At the repository root, ignore that sub-directory
798 /// * Elsewhere, we’re listing the content of a sub-repo. Return an empty
836 /// * Elsewhere, we’re listing the content of a sub-repo. Return an empty
799 /// list instead.
837 /// list instead.
800 fn read_dir(path: &Path, is_at_repo_root: bool) -> io::Result<Vec<Self>> {
838 fn read_dir(path: &Path, is_at_repo_root: bool) -> io::Result<Vec<Self>> {
801 // `read_dir` returns a "not found" error for the empty path
839 // `read_dir` returns a "not found" error for the empty path
802 let at_cwd = path == Path::new("");
840 let at_cwd = path == Path::new("");
803 let read_dir_path = if at_cwd { Path::new(".") } else { path };
841 let read_dir_path = if at_cwd { Path::new(".") } else { path };
804 let mut results = Vec::new();
842 let mut results = Vec::new();
805 for entry in read_dir_path.read_dir()? {
843 for entry in read_dir_path.read_dir()? {
806 let entry = entry?;
844 let entry = entry?;
807 let metadata = match entry.metadata() {
845 let metadata = match entry.metadata() {
808 Ok(v) => v,
846 Ok(v) => v,
809 Err(e) => {
847 Err(e) => {
810 // race with file deletion?
848 // race with file deletion?
811 if e.kind() == std::io::ErrorKind::NotFound {
849 if e.kind() == std::io::ErrorKind::NotFound {
812 continue;
850 continue;
813 } else {
851 } else {
814 return Err(e);
852 return Err(e);
815 }
853 }
816 }
854 }
817 };
855 };
818 let file_name = entry.file_name();
856 let file_name = entry.file_name();
819 // FIXME don't do this when cached
857 // FIXME don't do this when cached
820 if file_name == ".hg" {
858 if file_name == ".hg" {
821 if is_at_repo_root {
859 if is_at_repo_root {
822 // Skip the repo’s own .hg (might be a symlink)
860 // Skip the repo’s own .hg (might be a symlink)
823 continue;
861 continue;
824 } else if metadata.is_dir() {
862 } else if metadata.is_dir() {
825 // A .hg sub-directory at another location means a subrepo,
863 // A .hg sub-directory at another location means a subrepo,
826 // skip it entirely.
864 // skip it entirely.
827 return Ok(Vec::new());
865 return Ok(Vec::new());
828 }
866 }
829 }
867 }
830 let full_path = if at_cwd {
868 let full_path = if at_cwd {
831 file_name.clone().into()
869 file_name.clone().into()
832 } else {
870 } else {
833 entry.path()
871 entry.path()
834 };
872 };
835 let base_name = get_bytes_from_os_string(file_name).into();
873 let base_name = get_bytes_from_os_string(file_name).into();
836 results.push(DirEntry {
874 results.push(DirEntry {
837 base_name,
875 base_name,
838 full_path,
876 full_path,
839 metadata,
877 metadata,
840 })
878 })
841 }
879 }
842 Ok(results)
880 Ok(results)
843 }
881 }
844 }
882 }
845
883
846 /// Return the `mtime` of a temporary file newly-created in the `.hg` directory
884 /// Return the `mtime` of a temporary file newly-created in the `.hg` directory
847 /// of the give repository.
885 /// of the give repository.
848 ///
886 ///
849 /// This is similar to `SystemTime::now()`, with the result truncated to the
887 /// This is similar to `SystemTime::now()`, with the result truncated to the
850 /// same time resolution as other files’ modification times. Using `.hg`
888 /// same time resolution as other files’ modification times. Using `.hg`
851 /// instead of the system’s default temporary directory (such as `/tmp`) makes
889 /// instead of the system’s default temporary directory (such as `/tmp`) makes
852 /// it more likely the temporary file is in the same disk partition as contents
890 /// it more likely the temporary file is in the same disk partition as contents
853 /// of the working directory, which can matter since different filesystems may
891 /// of the working directory, which can matter since different filesystems may
854 /// store timestamps with different resolutions.
892 /// store timestamps with different resolutions.
855 ///
893 ///
856 /// This may fail, typically if we lack write permissions. In that case we
894 /// This may fail, typically if we lack write permissions. In that case we
857 /// should continue the `status()` algoritm anyway and consider the current
895 /// should continue the `status()` algoritm anyway and consider the current
858 /// date/time to be unknown.
896 /// date/time to be unknown.
859 fn filesystem_now(repo_root: &Path) -> Result<SystemTime, io::Error> {
897 fn filesystem_now(repo_root: &Path) -> Result<SystemTime, io::Error> {
860 tempfile::tempfile_in(repo_root.join(".hg"))?
898 tempfile::tempfile_in(repo_root.join(".hg"))?
861 .metadata()?
899 .metadata()?
862 .modified()
900 .modified()
863 }
901 }
General Comments 0
You need to be logged in to leave comments. Login now